예제 #1
0
파일: put.go 프로젝트: ready-steady/mat
// PutArray writes a multidimensional array into the file.
func (f *File) PutArray(name string, object interface{}, dimensions ...uint) error {
	value := reflect.ValueOf(object)
	length := uint(value.Len())

	switch len(dimensions) {
	case 0:
		dimensions = append(dimensions, length, 1)
	case 1:
		dimensions = append(dimensions, 1)
	}

	size := dimensions[0]
	for i := 1; i < len(dimensions); i++ {
		size *= dimensions[i]
	}

	if length != size {
		return errors.New("the dimensions do not match")
	}

	array, err := f.writeArray(value, dimensions...)
	if err != nil {
		return err
	}
	defer C.mxDestroyArray(array)

	return f.putVariable(name, array)
}
예제 #2
0
파일: put.go 프로젝트: ready-steady/mat
func (f *File) writeArray(value reflect.Value, dimensions ...uint) (*C.mxArray, error) {
	var kind reflect.Kind

	if value.Kind() == reflect.Slice {
		kind = value.Type().Elem().Kind()
	} else {
		kind = value.Kind()
	}

	classid, ok := kindClassMapping[kind]
	if !ok {
		return nil, errors.New("encountered an unsupported data type")
	}

	// NOTE: Do we need a proper conversion from uint to C.size_t?
	array := C.mxCreateNumericArray(C.size_t(len(dimensions)),
		(*C.size_t)(unsafe.Pointer(&dimensions[0])), classid, C.mxREAL)
	if array == nil {
		return nil, errors.New("cannot create an array")
	}

	parray := unsafe.Pointer(C.mxGetPr(array))
	if parray == nil {
		C.mxDestroyArray(array)
		return nil, errors.New("cannot create an array")
	}

	size, ok := classSizeMapping[classid]
	if !ok {
		return nil, errors.New("encountered an unsupported data type")
	}

	if value.Kind() == reflect.Slice {
		if err := writeSlice(value, parray, size); err != nil {
			C.mxDestroyArray(array)
			return nil, err
		}
	} else {
		if err := writeScalar(value, parray); err != nil {
			C.mxDestroyArray(array)
			return nil, err
		}
	}

	return array, nil
}
예제 #3
0
파일: put.go 프로젝트: ready-steady/mat
// Put writes an object into the file.
func (f *File) Put(name string, object interface{}) error {
	array, err := f.writeObject(reflect.ValueOf(object))
	if err != nil {
		return err
	}
	defer C.mxDestroyArray(array)

	return f.putVariable(name, array)
}
예제 #4
0
파일: put.go 프로젝트: ready-steady/mat
func (f *File) writeStruct(value reflect.Value) (*C.mxArray, error) {
	typo := value.Type()
	count := typo.NumField()
	names := make([]*C.char, 0, count)
	arrays := make([]*C.mxArray, 0, count)

	// NOTE: Should be called only when the function fails. If it succeeds, all
	// arrays will be disposed when the struct gets destroyed.
	cleanup := func() {
		for _, array := range arrays {
			C.mxDestroyArray(array)
		}
	}

	for i := 0; i < count; i++ {
		field := typo.Field(i)

		name := C.CString(field.Name)
		defer C.free(unsafe.Pointer(name))
		names = append(names, name)

		array, err := f.writeObject(value.Field(i))
		if err != nil {
			cleanup()
			return nil, err
		}
		arrays = append(arrays, array)
	}
	count = len(names)

	var pnames **C.char
	if count > 0 {
		pnames = (**C.char)(&names[0])
	}

	array := C.mxCreateStructMatrix(1, 1, C.int(count), pnames)
	if array == nil {
		cleanup()
		return nil, errors.New("cannot create a structure")
	}

	for i := 0; i < count; i++ {
		C.mxSetFieldByNumber(array, 0, C.int(i), arrays[i])
	}

	return array, nil
}
예제 #5
0
파일: get.go 프로젝트: ready-steady/mat
// Get reads an object from the file.
func (f *File) Get(name string, object interface{}) error {
	value := reflect.ValueOf(object)
	if value.Kind() != reflect.Ptr {
		return errors.New("expected a pointer")
	}

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	array := C.matGetVariable(f.mat, cname)
	if array == nil {
		return errors.New("cannot find the variable")
	}
	defer C.mxDestroyArray(array)

	return f.readObject(array, value)
}