in arrow/cdata/cdata.go [316:400]
func (imp *cimporter) doImport(src *CArrowArray) error {
imp.initarr()
// move the array from the src object passed in to the one referenced by
// this importer. That way we can set up a finalizer on the created
// *array.Data object so we clean up our Array's memory when garbage collected.
C.ArrowArrayMove(src, imp.arr)
defer func(arr *CArrowArray) {
if imp.data != nil {
runtime.SetFinalizer(imp.data, func(*array.Data) {
defer C.free(unsafe.Pointer(arr))
C.ArrowArrayRelease(arr)
if C.ArrowArrayIsReleased(arr) != 1 {
panic("did not release C mem")
}
})
} else {
C.free(unsafe.Pointer(arr))
}
}(imp.arr)
// import any children
if err := imp.doImportChildren(); err != nil {
return err
}
if imp.arr.n_buffers > 0 {
// get a view of the buffers, zero-copy. we're just looking at the pointers
const maxlen = 0x7fffffff
imp.cbuffers = (*[maxlen]*C.void)(unsafe.Pointer(imp.arr.buffers))[:imp.arr.n_buffers:imp.arr.n_buffers]
}
// handle each of our type cases
switch dt := imp.dt.(type) {
case *arrow.NullType:
if err := imp.checkNoChildren(); err != nil {
return err
}
imp.data = array.NewData(dt, int(imp.arr.length), nil, nil, int(imp.arr.null_count), int(imp.arr.offset))
case arrow.FixedWidthDataType:
return imp.importFixedSizePrimitive()
case *arrow.StringType:
return imp.importStringLike()
case *arrow.BinaryType:
return imp.importStringLike()
case *arrow.ListType:
return imp.importListLike()
case *arrow.MapType:
return imp.importListLike()
case *arrow.FixedSizeListType:
if err := imp.checkNumChildren(1); err != nil {
return err
}
if err := imp.checkNumBuffers(1); err != nil {
return err
}
nulls, err := imp.importNullBitmap(0)
if err != nil {
return err
}
imp.data = array.NewData(dt, int(imp.arr.length), []*memory.Buffer{nulls}, []*array.Data{imp.children[0].data}, int(imp.arr.null_count), int(imp.arr.offset))
case *arrow.StructType:
if err := imp.checkNumBuffers(1); err != nil {
return err
}
nulls, err := imp.importNullBitmap(0)
if err != nil {
return err
}
children := make([]*array.Data, len(imp.children))
for i := range imp.children {
children[i] = imp.children[i].data
}
imp.data = array.NewData(dt, int(imp.arr.length), []*memory.Buffer{nulls}, children, int(imp.arr.null_count), int(imp.arr.offset))
default:
return xerrors.Errorf("unimplemented type %s", dt)
}
return nil
}