// Iterate on a set of keys and their values from an omap // `startAfter`: iterate only on the keys after this specified one // `filterPrefix`: iterate only on the keys beginning with this prefix // `maxReturn`: iterate no more than `maxReturn` key/value pairs // `listFn`: the function called at each iteration func (ioctx *IOContext) ListOmapValues(oid string, startAfter string, filterPrefix string, maxReturn int64, listFn OmapListFunc) error { c_oid := C.CString(oid) c_start_after := C.CString(startAfter) c_filter_prefix := C.CString(filterPrefix) c_max_return := C.uint64_t(maxReturn) defer C.free(unsafe.Pointer(c_oid)) defer C.free(unsafe.Pointer(c_start_after)) defer C.free(unsafe.Pointer(c_filter_prefix)) op := C.rados_create_read_op() var c_iter C.rados_omap_iter_t var c_prval C.int C.rados_read_op_omap_get_vals( op, c_start_after, c_filter_prefix, c_max_return, &c_iter, &c_prval, ) ret := C.rados_read_op_operate(op, ioctx.ioctx, c_oid, 0) if int(c_prval) != 0 { return RadosError(int(c_prval)) } else if int(ret) != 0 { return GetRadosError(ret) } for { var c_key *C.char var c_val *C.char var c_len C.size_t ret = C.rados_omap_get_next(c_iter, &c_key, &c_val, &c_len) if int(ret) != 0 { return GetRadosError(ret) } if c_key == nil { break } listFn(C.GoString(c_key), C.GoBytes(unsafe.Pointer(c_val), C.int(c_len))) } C.rados_omap_get_end(c_iter) C.rados_release_read_op(op) return nil }
func (ro *ReadOperation) Operate(object *Object, flags ...LibradosOperation) (io.Reader, error) { oid := C.CString(object.name) defer freeString(oid) var f C.int = 0 for _, flag := range flags { f |= C.int(flag) } ret := C.rados_read_op_operate(ro.opContext, ro.ioContext, oid, f) if err := toRadosError(ret); err != nil { err.Message = fmt.Sprintf("Unable to perform read operations on object %s.", object.name) return nil, err } if err := toRadosError(ro.retVal); err != nil { err.Message = fmt.Sprintf("Unable to read from object %s.", object.name) return nil, err } if ro.bytesRead == 0 { err := toRadosError(-1) err.Message = fmt.Sprintf("Nothing read from object %s.", object.name) return nil, err } data := bufToReader(ro.buffer, C.int(ro.bytesRead)) return data, nil }
func (ioctx *IOContext) ReadTaggedFull(oid string, tagName string, data []byte, offset int) (n int, tag []byte, err error) { if len(data) == 0 { return 0, nil, nil } c_oid := C.CString(oid) c_tagName := C.CString(tagName) defer C.free(unsafe.Pointer(c_oid)) defer C.free(unsafe.Pointer(c_tagName)) var size C.size_t var rval_read C.int var rval_attr C.int var it C.rados_xattrs_iter_t op := C.rados_create_read_op() defer func() { C.rados_release_read_op(op) }() C.rados_read_op_read( op, (C.uint64_t)(offset), (C.size_t)(len(data)), (*C.char)(unsafe.Pointer(&data[0])), &size, &rval_read) C.rados_read_op_getxattrs( op, &it, &rval_attr) ret := C.rados_read_op_operate(op, ioctx.ioctx, c_oid, 0) if ret < 0 { return 0, nil, GetRadosError(ret) } if rval_read < 0 { return 0, nil, GetRadosError(rval_read) } if rval_attr < 0 { return 0, nil, GetRadosError(ret) } defer func() { C.rados_getxattrs_end(it) }() for { var c_name, c_val *C.char var c_len C.size_t defer C.free(unsafe.Pointer(c_name)) defer C.free(unsafe.Pointer(c_val)) ret := C.rados_getxattrs_next(it, &c_name, &c_val, &c_len) if ret < 0 { return int(size), nil, GetRadosError(ret) } // rados api returns a null name,val & 0-length upon // end of iteration if c_name == nil { return int(size), nil, GetRadosError(ret) } if tagName == C.GoString(c_name) { tag = C.GoBytes(unsafe.Pointer(c_val), (C.int)(c_len)) break } } return int(size), tag, nil }