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 }