// Get reads data from the file. func (f *File) Get(name string, something interface{}) error { value := reflect.ValueOf(something) if value.Kind() != reflect.Ptr { return errors.New("expected a pointer") } value = reflect.Indirect(value) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) did := C.H5Dopen2(f.fid, cname, C.H5P_DEFAULT) if did < 0 { return errors.New("cannot find the dataset") } defer C.H5Dclose(did) object := newObject() defer object.free() object.tid = C.H5Dget_type(did) if object.tid < 0 { return errors.New("cannot get the datatype of the dataset") } if err := initializeToGet(object, value); err != nil { return err } if C.H5Dread(did, object.tid, C.H5S_ALL, C.H5S_ALL, C.H5P_DEFAULT, object.data) < 0 { return errors.New("cannot read the dataset from the file") } if err := finalizeToGet(object, value); err != nil { return err } one := C.hsize_t(1) sid := C.H5Screate_simple(1, (*C.hsize_t)(unsafe.Pointer(&one)), nil) if sid < 0 { return errors.New("cannot create a data space") } defer C.H5Sclose(sid) if C.H5Dvlen_reclaim(object.tid, sid, C.H5P_DEFAULT, object.data) < 0 { return errors.New("cannot reclaim memory") } return nil }
// Reads a number of packets from a packet table. // herr_t H5PTread_packets( hid_t table_id, hsize_t start, size_t nrecords, void* data) func (t *Table) ReadPackets(start, nrecords int, data interface{}) error { c_start := C.hsize_t(start) c_nrecords := C.size_t(nrecords) rt := reflect.TypeOf(data) rv := reflect.ValueOf(data) c_data := unsafe.Pointer(nil) switch rt.Kind() { case reflect.Array: //fmt.Printf("--> array\n") if rv.Cap() < nrecords { panic(fmt.Sprintf("not enough capacity in array (cap=%d)", rv.Cap())) } c_data = unsafe.Pointer(rv.Index(0).UnsafeAddr()) //c_nrecords = C.size_t(rv.Cap()) case reflect.Slice: //fmt.Printf("--> slice\n") if rv.Cap() < nrecords { panic(fmt.Sprintf("not enough capacity in slice (cap=%d)", rv.Cap())) // buf_slice := reflect.MakeSlice(rt, nrecords, nrecords) // rv.Set(reflect.AppendSlice(rv, buf_slice)) } slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr())) c_data = unsafe.Pointer(slice.Data) //c_nrecords = C.size_t(rv.Cap()) default: panic(fmt.Sprintf("unhandled kind (%s) need slice or array", rt.Kind())) } err := C.H5PTread_packets(t.id, c_start, c_nrecords, c_data) return togo_err(err) }
// ReadPackets reads a number of packets from a packet table. func (t *Table) ReadPackets(start, nrecords int, data interface{}) error { c_start := C.hsize_t(start) c_nrecords := C.size_t(nrecords) rv := reflect.Indirect(reflect.ValueOf(data)) rt := rv.Type() c_data := unsafe.Pointer(nil) switch rt.Kind() { case reflect.Array: if rv.Len() < nrecords { panic(fmt.Errorf("not enough capacity in array (cap=%d)", rv.Len())) } c_data = unsafe.Pointer(rv.Index(0).UnsafeAddr()) case reflect.Slice: if rv.Len() < nrecords { panic(fmt.Errorf("not enough capacity in slice (cap=%d)", rv.Len())) } slice := (*reflect.SliceHeader)(unsafe.Pointer(rv.UnsafeAddr())) c_data = unsafe.Pointer(slice.Data) default: panic(fmt.Errorf("unhandled kind (%s), need slice or array", rt.Kind())) } err := C.H5PTread_packets(t.id, c_start, c_nrecords, c_data) return h5err(err) }
func createTable(id C.hid_t, name string, dtype *Datatype, chunkSize, compression int) (*Table, error) { c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) chunk := C.hsize_t(chunkSize) compr := C.int(compression) hid := C.H5PTcreate_fl(id, c_name, dtype.id, chunk, compr) if err := checkID(hid); err != nil { return nil, err } return newPacketTable(hid), nil }
// Creates a packet table to store fixed-length packets. // hid_t H5PTcreate_fl( hid_t loc_id, const char * dset_name, hid_t dtype_id, hsize_t chunk_size, int compression ) func (f *File) CreateTable(name string, dtype *DataType, chunk_size, compression int) (*Table, error) { c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) c_chunk := C.hsize_t(chunk_size) c_compr := C.int(compression) hid := C.H5PTcreate_fl(f.id, c_name, dtype.id, c_chunk, c_compr) err := togo_err(C.herr_t(int(hid))) if err != nil { return nil, err } table := new_packet_table(hid) return table, err }
func objectNameByIndex(id C.hid_t, idx uint) (string, error) { cidx := C.hsize_t(idx) size := C.H5Lget_name_by_idx(id, cdot, C.H5_INDEX_NAME, C.H5_ITER_INC, cidx, nil, 0, C.H5P_DEFAULT) if size < 0 { return "", fmt.Errorf("could not get name") } name := make([]C.char, size+1) size = C.H5Lget_name_by_idx(id, cdot, C.H5_INDEX_NAME, C.H5_ITER_INC, cidx, &name[0], C.size_t(size)+1, C.H5P_DEFAULT) if size < 0 { return "", fmt.Errorf("could not get name") } return C.GoString(&name[0]), nil }
func computeArrayLength(tid C.hid_t) (C.hsize_t, error) { nd := C.H5Tget_array_ndims(tid) if nd < 0 { return 0, errors.New("cannot get the dimensionality of an array") } dimensions := make([]C.hsize_t, nd) if C.H5Tget_array_dims2(tid, (*C.hsize_t)(unsafe.Pointer(&dimensions[0]))) != nd { return 0, errors.New("cannot get the dimensions of an array") } length := C.hsize_t(1) for i := range dimensions { length *= dimensions[i] } return length, nil }
func initializeScalarToPut(object *object, value reflect.Value) error { pointer := reflect.New(value.Type()) reflect.Indirect(pointer).Set(value) object.data = unsafe.Pointer(pointer.Pointer()) bid, ok := kindTypeMapping[value.Kind()] if !ok { return errors.New("encountered an unsupported datatype") } one := C.hsize_t(1) object.tid = C.H5Tarray_create2(bid, 1, (*C.hsize_t)(unsafe.Pointer(&one))) if object.tid < 0 { return errors.New("cannot create an array datatype") } return nil }
// ReadPackets reads a number of packets from a packet table. func (t *Table) ReadPackets(start, nrecords int, data interface{}) error { c_start := C.hsize_t(start) c_nrecords := C.size_t(nrecords) rt := reflect.TypeOf(data) rv := reflect.ValueOf(data) c_data := unsafe.Pointer(nil) switch rt.Kind() { case reflect.Array: if rv.Cap() < nrecords { panic(fmt.Sprintf("not enough capacity in array (cap=%d)", rv.Cap())) } c_data = unsafe.Pointer(rv.Index(0).UnsafeAddr()) default: panic(fmt.Sprintf("unhandled kind (%s), need array", rt.Kind())) } err := C.H5PTread_packets(t.id, c_start, c_nrecords, c_data) return h5err(err) }
// Put writes data into the file. func (f *File) Put(name string, something interface{}, dimensions ...uint) error { object := newObject() defer object.free() if err := initializeToPut(object, reflect.ValueOf(something), dimensions...); err != nil { return err } cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) one := C.hsize_t(1) sid := C.H5Screate_simple(1, (*C.hsize_t)(unsafe.Pointer(&one)), nil) if sid < 0 { return errors.New("cannot create a data space") } defer C.H5Sclose(sid) if result := C.H5Lexists(f.fid, cname, C.H5P_DEFAULT); result < 0 { return errors.New("cannot check if the name already exists") } else if result > 0 && C.H5Ldelete(f.fid, cname, C.H5P_DEFAULT) < 0 { return errors.New("cannot overwrite an existing dataset") } did := C.H5Dcreate2(f.fid, cname, object.tid, sid, C.H5P_DEFAULT, C.H5P_DEFAULT, C.H5P_DEFAULT) if did < 0 { return errors.New("cannot create a dataset") } defer C.H5Dclose(did) if C.H5Dwrite(did, object.tid, C.H5S_ALL, C.H5S_ALL, C.H5P_DEFAULT, object.data) < 0 { return errors.New("cannot write the dataset into the file") } return nil }
// Sets a packet table's index. // herr_t H5PTset_index( hid_t table_id, hsize_t pt_index) func (t *Table) SetIndex(index int) error { c_idx := C.hsize_t(index) err := C.H5PTset_index(t.id, c_idx) return togo_err(err) }
// Returns the number of packets in a packet table. // herr_t H5PTget_num_packets( hid_t table_id, hsize_t * nrecords) func (t *Table) NumPackets() (int, error) { c_nrecords := C.hsize_t(0) err := C.H5PTget_num_packets(t.id, &c_nrecords) return int(c_nrecords), togo_err(err) }