Ejemplo n.º 1
0
// function that lists all the xattrs for an object, since xattrs are
// a k-v pair, this function returns a map of k-v pairs on
// success, error code on failure
func (ioctx *IOContext) ListXattrs(oid string) (map[string][]byte, error) {
	c_oid := C.CString(oid)
	defer C.free(unsafe.Pointer(c_oid))

	var it C.rados_xattrs_iter_t

	ret := C.rados_getxattrs(ioctx.ioctx, c_oid, &it)
	if ret < 0 {
		return nil, GetRadosError(ret)
	}
	defer func() { C.rados_getxattrs_end(it) }()
	m := make(map[string][]byte)
	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 nil, GetRadosError(ret)
		}
		// rados api returns a null name,val & 0-length upon
		// end of iteration
		if c_name == nil {
			return m, nil // stop iteration
		}
		m[C.GoString(c_name)] = C.GoBytes(unsafe.Pointer(c_val), (C.int)(c_len))
	}
}
Ejemplo n.º 2
0
// Next returns the next extended attribute. This returns an error when there are no more attributes.
func (i *AttributeList) Next() (name string, value io.Reader, err error) {
	var n *C.char
	var v *C.char
	var length C.size_t
	ret := C.rados_getxattrs_next(i.iterator, &n, &v, &length)
	if errs := toRadosError(ret); errs != nil {
		errs.Message = "Unable to get next attribute"
		err = errs
	} else if length == 0 {
		errs := toRadosError(-1)
		errs.Message = "End of attribute list reached"
		err = errs
	} else {
		name = C.GoString(n)
		value = bufToReader(v, C.int(length))
	}
	return
}
Ejemplo n.º 3
0
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

}