Example #1
0
// ReadBytes reads bytes from a data object at the specified position and length, returns []byte slice and error.
func (obj *DataObj) ReadBytes(pos int64, length int) ([]byte, error) {
	if er := obj.init(); er != nil {
		return nil, er
	}

	var (
		buffer    C.bytesBuf_t
		err       *C.char
		bytesRead C.int
	)

	if er := obj.LSeek(pos); er != nil {
		return nil, er
	}

	ccon := obj.con.GetCcon()
	defer obj.con.ReturnCcon(ccon)

	if status := C.gorods_read_dataobject(obj.chandle, C.rodsLong_t(length), &buffer, &bytesRead, ccon, &err); status != 0 {
		return nil, newError(Fatal, fmt.Sprintf("iRODS ReadBytes DataObject Failed: %v, %v", obj.path, C.GoString(err)))
	}

	buf := unsafe.Pointer(buffer.buf)
	defer C.free(buf)

	data := C.GoBytes(buf, bytesRead)

	return data, nil
}
Example #2
0
// ReadChunk reads the entire data object in chunks (size of chunk specified by size parameter), passing the data into a callback function for each chunk. Use this to read/write large files.
func (obj *DataObj) ReadChunk(size int64, callback func([]byte)) error {
	if er := obj.init(); er != nil {
		return er
	}

	var (
		buffer    C.bytesBuf_t
		err       *C.char
		bytesRead C.int
	)

	if er := obj.LSeek(0); er != nil {
		return er
	}

	for obj.offset < obj.size {

		ccon := obj.con.GetCcon()

		if status := C.gorods_read_dataobject(obj.chandle, C.rodsLong_t(size), &buffer, &bytesRead, ccon, &err); status != 0 {
			obj.con.ReturnCcon(ccon)
			return newError(Fatal, fmt.Sprintf("iRODS Read DataObject Failed: %v, %v", obj.path, C.GoString(err)))
		}

		obj.con.ReturnCcon(ccon)

		buf := unsafe.Pointer(buffer.buf)

		chunk := C.GoBytes(buf, bytesRead)

		C.free(buf)

		callback(chunk)

		if er := obj.LSeek(obj.offset + size); er != nil {
			return er
		}
	}

	if er := obj.LSeek(0); er != nil {
		return er
	}

	return obj.Close()
}