@@ -58,27 +58,6 @@ func (bytesArray *bytesArray) free() {
5858 bytesArray .array = nil
5959}
6060
61- func cBytesArrayToGo (cBytesArray * C.OBX_bytes_array ) [][]byte {
62- size := int (cBytesArray .count )
63- plainBytesArray := make ([][]byte , size )
64-
65- if size > 0 {
66- var sliceOfCBytes []C.OBX_bytes
67- // see cVoidPtrToByteSlice for documentation of the following approach in general
68- header := (* reflect .SliceHeader )(unsafe .Pointer (& sliceOfCBytes ))
69- header .Data = uintptr (unsafe .Pointer (cBytesArray .bytes ))
70- header .Len = size
71- header .Cap = size
72-
73- for i := 0 ; i < size ; i ++ {
74- cBytes := sliceOfCBytes [i ]
75- cVoidPtrToByteSlice (unsafe .Pointer (cBytes .data ), int (cBytes .size ), & (plainBytesArray [i ]))
76- }
77- }
78-
79- return plainBytesArray
80- }
81-
8261func goBytesArrayToC (goArray [][]byte ) (* bytesArray , error ) {
8362 // for native calls/createError()
8463 runtime .LockOSThread ()
@@ -113,19 +92,6 @@ func (array *idsArray) free() {
11392 array .ids = nil
11493}
11594
116- func cIdsArrayToGo (cArray * C.OBX_id_array ) []uint64 {
117- var size = uint (cArray .count )
118- var ids = make ([]uint64 , size )
119- if size > 0 {
120- var cArrayStart = unsafe .Pointer (cArray .ids )
121- var cSize = unsafe .Sizeof (* cArray .ids )
122- for i := uint (0 ); i < size ; i ++ {
123- ids [i ] = * (* uint64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cSize ))
124- }
125- }
126- return ids
127- }
128-
12995func goIdsArrayToC (ids []uint64 ) (* idsArray , error ) {
13096 // for native calls/createError()
13197 runtime .LockOSThread ()
@@ -140,20 +106,20 @@ func goIdsArrayToC(ids []uint64) (*idsArray, error) {
140106 return & idsArray {ids , cArray }, err
141107}
142108
143- type stringArray struct {
109+ type charPtrsArray struct {
144110 cArray * * C.char
145111 size int
146112}
147113
148- func (array * stringArray ) free () {
114+ func (array * charPtrsArray ) free () {
149115 if array .cArray != nil {
150116 C .freeCharArray (array .cArray , C .int (array .size ))
151117 array .cArray = nil
152118 }
153119}
154120
155- func goStringArrayToC (values []string ) * stringArray {
156- result := & stringArray {
121+ func goStringArrayToC (values []string ) * charPtrsArray {
122+ result := & charPtrsArray {
157123 cArray : C .newCharArray (C .int (len (values ))),
158124 size : len (values ),
159125 }
@@ -191,6 +157,230 @@ func cBytesPtr(value []byte) unsafe.Pointer {
191157 return unsafe .Pointer (& value [0 ])
192158}
193159
160+ /**
161+ Functions for reading OBX_*_array to Go. The passed C array still needs to be freed manually.
162+ Generics please!!!
163+ */
164+
165+ // WARN: this function doesn't create a copy of each byte-vector (item) but references it in the C source instead
166+ // Therefore, it's only supposed to be used intra-library (usually inside a read transaction)
167+ func cBytesArrayToGo (cArray * C.OBX_bytes_array ) [][]byte {
168+ size := int (cArray .count )
169+ plainBytesArray := make ([][]byte , size )
170+
171+ if size > 0 {
172+ var sliceOfCBytes []C.OBX_bytes
173+ // see cVoidPtrToByteSlice for documentation of the following approach in general
174+ header := (* reflect .SliceHeader )(unsafe .Pointer (& sliceOfCBytes ))
175+ header .Data = uintptr (unsafe .Pointer (cArray .bytes ))
176+ header .Len = size
177+ header .Cap = size
178+
179+ for i := 0 ; i < size ; i ++ {
180+ cBytes := sliceOfCBytes [i ]
181+ cVoidPtrToByteSlice (unsafe .Pointer (cBytes .data ), int (cBytes .size ), & (plainBytesArray [i ])) // reference
182+ }
183+ }
184+
185+ return plainBytesArray
186+ }
187+
188+ func cStringsArrayToGo (cArray * C.OBX_string_array ) []string {
189+ var size = uint (cArray .count )
190+ var items = make ([]string , size )
191+ if size > 0 {
192+ var cArrayStart = unsafe .Pointer (cArray .items )
193+ var cItemSize = unsafe .Sizeof (* cArray .items )
194+ for i := uint (0 ); i < size ; i ++ {
195+ var cCharPtr = (* * C .char )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize ))
196+ items [i ] = C .GoString (* cCharPtr ) // make a copy
197+ }
198+ }
199+ return items
200+ }
201+
202+ func cIdsArrayToGo (cArray * C.OBX_id_array ) []uint64 {
203+ var size = uint (cArray .count )
204+ var items = make ([]uint64 , size )
205+ if size > 0 {
206+ var cArrayStart = unsafe .Pointer (cArray .ids )
207+ var cItemSize = unsafe .Sizeof (* cArray .ids )
208+ for i := uint (0 ); i < size ; i ++ {
209+ items [i ] = * (* uint64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
210+ }
211+ }
212+ return items
213+ }
214+
215+ func cIntsArrayToGo (cArray * C.OBX_int64_array ) []int {
216+ var size = uint (cArray .count )
217+ var result = make ([]int , size )
218+ if size > 0 {
219+ var cArrayStart = unsafe .Pointer (cArray .items )
220+ var cItemSize = unsafe .Sizeof (* cArray .items )
221+ for i := uint (0 ); i < size ; i ++ {
222+ result [i ] = int (* (* int64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize ))) // make a copy
223+ }
224+ }
225+ return result
226+ }
227+
228+ func cUintsArrayToGo (cArray * C.OBX_int64_array ) []uint {
229+ var size = uint (cArray .count )
230+ var result = make ([]uint , size )
231+ if size > 0 {
232+ var cArrayStart = unsafe .Pointer (cArray .items )
233+ var cItemSize = unsafe .Sizeof (* cArray .items )
234+ for i := uint (0 ); i < size ; i ++ {
235+ result [i ] = uint (* (* uint64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize ))) // make a copy
236+ }
237+ }
238+ return result
239+ }
240+
241+ func cInt64sArrayToGo (cArray * C.OBX_int64_array ) []int64 {
242+ var size = uint (cArray .count )
243+ var result = make ([]int64 , size )
244+ if size > 0 {
245+ var cArrayStart = unsafe .Pointer (cArray .items )
246+ var cItemSize = unsafe .Sizeof (* cArray .items )
247+ for i := uint (0 ); i < size ; i ++ {
248+ result [i ] = * (* int64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
249+ }
250+ }
251+ return result
252+ }
253+
254+ func cUint64sArrayToGo (cArray * C.OBX_int64_array ) []uint64 {
255+ var size = uint (cArray .count )
256+ var result = make ([]uint64 , size )
257+ if size > 0 {
258+ var cArrayStart = unsafe .Pointer (cArray .items )
259+ var cItemSize = unsafe .Sizeof (* cArray .items )
260+ for i := uint (0 ); i < size ; i ++ {
261+ result [i ] = * (* uint64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
262+ }
263+ }
264+ return result
265+ }
266+
267+ func cInt32sArrayToGo (cArray * C.OBX_int32_array ) []int32 {
268+ var size = uint (cArray .count )
269+ var result = make ([]int32 , size )
270+ if size > 0 {
271+ var cArrayStart = unsafe .Pointer (cArray .items )
272+ var cItemSize = unsafe .Sizeof (* cArray .items )
273+ for i := uint (0 ); i < size ; i ++ {
274+ result [i ] = * (* int32 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
275+ }
276+ }
277+ return result
278+ }
279+
280+ func cUint32sArrayToGo (cArray * C.OBX_int32_array ) []uint32 {
281+ var size = uint (cArray .count )
282+ var result = make ([]uint32 , size )
283+ if size > 0 {
284+ var cArrayStart = unsafe .Pointer (cArray .items )
285+ var cItemSize = unsafe .Sizeof (* cArray .items )
286+ for i := uint (0 ); i < size ; i ++ {
287+ result [i ] = * (* uint32 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
288+ }
289+ }
290+ return result
291+ }
292+
293+ func cInt16sArrayToGo (cArray * C.OBX_int16_array ) []int16 {
294+ var size = uint (cArray .count )
295+ var result = make ([]int16 , size )
296+ if size > 0 {
297+ var cArrayStart = unsafe .Pointer (cArray .items )
298+ var cItemSize = unsafe .Sizeof (* cArray .items )
299+ for i := uint (0 ); i < size ; i ++ {
300+ result [i ] = * (* int16 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
301+ }
302+ }
303+ return result
304+ }
305+
306+ func cUint16sArrayToGo (cArray * C.OBX_int16_array ) []uint16 {
307+ var size = uint (cArray .count )
308+ var result = make ([]uint16 , size )
309+ if size > 0 {
310+ var cArrayStart = unsafe .Pointer (cArray .items )
311+ var cItemSize = unsafe .Sizeof (* cArray .items )
312+ for i := uint (0 ); i < size ; i ++ {
313+ result [i ] = * (* uint16 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
314+ }
315+ }
316+ return result
317+ }
318+
319+ func cInt8sArrayToGo (cArray * C.OBX_int8_array ) []int8 {
320+ var size = uint (cArray .count )
321+ var result = make ([]int8 , size )
322+ if size > 0 {
323+ var cArrayStart = unsafe .Pointer (cArray .items )
324+ var cItemSize = unsafe .Sizeof (* cArray .items )
325+ for i := uint (0 ); i < size ; i ++ {
326+ result [i ] = * (* int8 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
327+ }
328+ }
329+ return result
330+ }
331+
332+ func cUint8sArrayToGo (cArray * C.OBX_int8_array ) []uint8 {
333+ var size = uint (cArray .count )
334+ var result = make ([]uint8 , size )
335+ if size > 0 {
336+ var cArrayStart = unsafe .Pointer (cArray .items )
337+ var cItemSize = unsafe .Sizeof (* cArray .items )
338+ for i := uint (0 ); i < size ; i ++ {
339+ result [i ] = * (* uint8 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
340+ }
341+ }
342+ return result
343+ }
344+
345+ func cBoolsArrayToGo (cArray * C.OBX_int8_array ) []bool {
346+ var size = uint (cArray .count )
347+ var result = make ([]bool , size )
348+ if size > 0 {
349+ var cArrayStart = unsafe .Pointer (cArray .items )
350+ var cItemSize = unsafe .Sizeof (* cArray .items )
351+ for i := uint (0 ); i < size ; i ++ {
352+ result [i ] = 1 == * (* uint8 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
353+ }
354+ }
355+ return result
356+ }
357+
358+ func cFloat64sArrayToGo (cArray * C.OBX_double_array ) []float64 {
359+ var size = uint (cArray .count )
360+ var result = make ([]float64 , size )
361+ if size > 0 {
362+ var cArrayStart = unsafe .Pointer (cArray .items )
363+ var cItemSize = unsafe .Sizeof (* cArray .items )
364+ for i := uint (0 ); i < size ; i ++ {
365+ result [i ] = * (* float64 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
366+ }
367+ }
368+ return result
369+ }
370+
371+ func cFloat32sArrayToGo (cArray * C.OBX_float_array ) []float32 {
372+ var size = uint (cArray .count )
373+ var result = make ([]float32 , size )
374+ if size > 0 {
375+ var cArrayStart = unsafe .Pointer (cArray .items )
376+ var cItemSize = unsafe .Sizeof (* cArray .items )
377+ for i := uint (0 ); i < size ; i ++ {
378+ result [i ] = * (* float32 )(unsafe .Pointer (uintptr (cArrayStart ) + uintptr (i )* cItemSize )) // make a copy
379+ }
380+ }
381+ return result
382+ }
383+
194384// Maps a C void* to the given byte-slice. The void* is not garbage collected and must be managed outside.
195385//
196386// Previous alternative without reflect https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
0 commit comments