1 // Written in the D programming language. 2 3 module sapnwrfc.data; 4 5 import sapnwrfc.binding; 6 import etc.c.sapnwrfc : RFCTYPE; 7 8 struct FieldType 9 { 10 RFCTYPE type; 11 size_t length; 12 } 13 14 private alias helper(alias T) = T; 15 16 mixin template RfcStructHelper(T) 17 { 18 // Copy RFC structure to D structure 19 void copyTo(RFC_STRUCTURE_HANDLE handle, out T value) 20 { 21 import std.traits : Unqual, isStaticArray; 22 23 foreach(wstring memberName; __traits(allMembers, T)) 24 { 25 alias member = helper!(__traits(getMember, value, memberName)); 26 27 static if (is(typeof(member) == RFC_CHAR)) 28 { 29 RfcGetChars(handle, memberName.ptr, &__traits(getMember, value, memberName), 1); 30 } 31 else static if (is(Unqual!(typeof(member)) == RFC_CHAR[])) 32 { 33 __traits(getMember, value, memberName).length = RfcGetStringLength(handle, memberName.ptr); 34 RfcGetChars(handle, memberName.ptr, __traits(getMember, value, memberName).ptr, cast(uint)__traits(getMember, value, memberName).length); 35 } 36 else static if ((isStaticArray!(typeof(member)) && is(Unqual!(typeof(member[0])) == RFC_CHAR))) 37 { 38 RfcGetChars(handle, memberName.ptr, __traits(getMember, value, memberName).ptr, cast(uint)__traits(getMember, value, memberName).length); 39 } 40 else static if (is(typeof(member) == RFC_BYTE)) 41 { 42 RfcGetBytes(handle, memberName.ptr, &__traits(getMember, value, memberName), 1); 43 } 44 else static if (is(typeof(member) == RFC_BYTE[]) || (isStaticArray!(typeof(member)) && is(typeof(member[0]) == RFC_BYTE))) 45 { 46 RfcGetBytes(handle, memberName.ptr, __traits(getMember, value, memberName).ptr, cast(uint)member.length); 47 } 48 else static if (is(typeof(member) == RFC_INT)) 49 { 50 RfcGetInt(handle, memberName.ptr, __traits(getMember, value, memberName)); 51 } 52 else static if (is(typeof(member) == RFC_INT1)) 53 { 54 RfcGetInt1(handle, memberName.ptr, __traits(getMember, value, memberName)); 55 } 56 else static if (is(typeof(member) == RFC_INT2)) 57 { 58 RfcGetInt2(handle, memberName.ptr, __traits(getMember, value, memberName)); 59 } 60 else static if (is(typeof(member) == RFC_INT8)) 61 { 62 version (sapnwrfc_sdk_750) 63 RfcGetInt8(handle, memberName.ptr, __traits(getMember, value, memberName)); 64 else 65 static assert(false, "RFC_INT8 not supported"); 66 } 67 else static if (is(typeof(member) == RFC_FLOAT)) 68 { 69 RfcGetFloat(handle, memberName.ptr, __traits(getMember, value, memberName)); 70 } 71 else 72 { 73 static assert(false, "Type " ~ typeof(member).stringof ~ "not supported"); 74 } 75 } 76 } 77 78 // Copy RFC structure from D structure 79 void copyFrom(RFC_STRUCTURE_HANDLE handle, in T value) 80 { 81 import std.traits : Unqual, isStaticArray; 82 83 foreach(wstring memberName; __traits(allMembers, T)) 84 { 85 alias member = helper!(__traits(getMember, value, memberName)); 86 87 static if (is(Unqual!(typeof(__traits(getMember, value, memberName))) == RFC_CHAR)) 88 { 89 RfcSetChars(handle, memberName.ptr, &__traits(getMember, value, memberName), 1); 90 } 91 else static if (is(Unqual!(typeof(member)) == RFC_CHAR[]) || (isStaticArray!(typeof(member)) && is(Unqual!(typeof(member[0])) == RFC_CHAR))) 92 { 93 RfcSetString(handle, memberName.ptr, __traits(getMember, value, memberName).ptr, cast(uint)__traits(getMember, value, memberName).length); 94 } 95 else static if (is(Unqual!(typeof(member)) == RFC_BYTE)) 96 { 97 RfcSetBytes(handle, memberName.ptr, &__traits(getMember, value, memberName), 1); 98 } 99 else static if (is(Unqual!(typeof(member)) == RFC_BYTE[]) || (isStaticArray!(typeof(member)) && is(Unqual!(typeof(member[0])) == RFC_BYTE))) 100 { 101 RfcSetBytes(handle, memberName.ptr, __traits(getMember, value, memberName).ptr, cast(uint)member.length); 102 } 103 else static if (is(Unqual!(typeof(member)) == RFC_INT)) 104 { 105 RfcSetInt(handle, memberName.ptr, __traits(getMember, value, memberName)); 106 } 107 else static if (is(Unqual!(typeof(member)) == RFC_INT1)) 108 { 109 RfcSetInt1(handle, memberName.ptr, __traits(getMember, value, memberName)); 110 } 111 else static if (is(Unqual!(typeof(member)) == RFC_INT2)) 112 { 113 RfcSetInt2(handle, memberName.ptr, __traits(getMember, value, memberName)); 114 } 115 else static if (is(Unqual!(typeof(member)) == RFC_INT8)) 116 { 117 version (sapnwrfc_sdk_750) 118 RfcSetInt8(handle, memberName.ptr, __traits(getMember, value, memberName)); 119 else 120 static assert(false, "RFC_INT8 not supported"); 121 } 122 else static if (is(Unqual!(typeof(member)) == RFC_FLOAT)) 123 { 124 RfcSetFloat(handle, memberName.ptr, __traits(getMember, value, memberName)); 125 } 126 else 127 { 128 static assert(false, "Type " ~ typeof(member).stringof ~ "not supported"); 129 } 130 } 131 } 132 } 133 134 mixin template RfcTableHelper(T) 135 { 136 void copyTo(RFC_TABLE_HANDLE handle, out T[] value) 137 { 138 mixin RfcStructHelper!T structHelper; 139 140 value.length = RfcGetRowCount(handle); 141 foreach (i; 0..value.length) 142 { 143 RfcMoveTo(handle, i); 144 auto line = RfcGetCurrentRow(handle); 145 structHelper.copyTo(line, value[i]); 146 } 147 } 148 149 void copyFrom(RFC_TABLE_HANDLE handle, in T[] value) 150 { 151 mixin RfcStructHelper!T structHelper; 152 153 foreach (v; value) 154 { 155 RfcAppendNewRow(handle); 156 structHelper.copyFrom(handle, v); 157 } 158 } 159 }