示例#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
}
示例#2
0
// Put reads the entire file from localPath and adds it the collection, using the options specified.
func (col *Collection) Put(localPath string, opts DataObjOptions) (*DataObj, error) {

	var (
		errMsg   *C.char
		force    int
		resource *C.char
	)

	if opts.Force {
		force = 1
	} else {
		force = 0
	}

	if opts.Resource != nil {
		switch opts.Resource.(type) {
		case string:
			resource = C.CString(opts.Resource.(string))
		case *Resource:
			r := opts.Resource.(*Resource)
			resource = C.CString(r.Name())
		default:
			return nil, newError(Fatal, fmt.Sprintf("Wrong variable type passed in Resource field"))
		}
	} else {
		resource = C.CString("")
	}

	if opts.Name == "" {
		opts.Name = filepath.Base(localPath)
	}

	path := C.CString(col.path + "/" + opts.Name)
	cLocalPath := C.CString(localPath)

	defer C.free(unsafe.Pointer(path))
	defer C.free(unsafe.Pointer(resource))
	defer C.free(unsafe.Pointer(cLocalPath))

	ccon := col.con.GetCcon()

	if status := C.gorods_put_dataobject(cLocalPath, path, C.rodsLong_t(opts.Size), C.int(opts.Mode), C.int(force), resource, ccon, &errMsg); status != 0 {
		col.con.ReturnCcon(ccon)
		return nil, newError(Fatal, fmt.Sprintf("iRODS Put DataObject Failed: %v, Does the file already exist?", C.GoString(errMsg)))
	}
	col.con.ReturnCcon(ccon)

	if err := col.Refresh(); err != nil {
		return nil, err
	}

	if do, err := getDataObj(C.GoString(path), col.con); err != nil {
		return nil, err
	} else {
		return do, nil
	}

}
示例#3
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()
}
示例#4
0
// LSeek sets the read/write offset pointer of a data object, returns error
func (obj *DataObj) LSeek(offset int64) error {
	if er := obj.init(); er != nil {
		return er
	}

	var (
		err *C.char
	)

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

	if status := C.gorods_lseek_dataobject(obj.chandle, C.rodsLong_t(offset), ccon, &err); status != 0 {
		return newError(Fatal, fmt.Sprintf("iRODS LSeek DataObject Failed: %v, %v", obj.path, C.GoString(err)))
	}

	obj.offset = offset

	return nil
}
示例#5
0
// Backup is similar to Replicate. In backup mode, if a good copy already exists in this resource group or resource, don't make another one.
func (obj *DataObj) Backup(targetResource interface{}, opts DataObjOptions) error {

	var (
		err         *C.char
		resourceStr string
	)

	switch targetResource.(type) {
	case string:
		resourceStr = targetResource.(string)
	case *Resource:
		resourceStr = (targetResource.(*Resource)).Name()
	default:
		return newError(Fatal, fmt.Sprintf("Unknown type passed as targetResource"))

	}

	cPath := C.CString(obj.Path())
	cResource := C.CString(resourceStr)
	defer C.free(unsafe.Pointer(cPath))
	defer C.free(unsafe.Pointer(cResource))

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

	if status := C.gorods_repl_dataobject(ccon, cPath, cResource, C.int(1), C.int(opts.Mode), C.rodsLong_t(opts.Size), &err); status != 0 {
		return newError(Fatal, fmt.Sprintf("iRODS Backup Failed: %v, %v", obj.path, C.GoString(err)))
	}

	return nil
}