示例#1
0
func doFinish(call rpc.ClientCall, numResults int) (C.SwiftByteArrayArray, error) {
	// Have all the results be decoded into *vdl.Value.
	resultPtrs := make([]interface{}, numResults)
	for i := 0; i < numResults; i++ {
		value := new(vdl.Value)
		resultPtrs[i] = &value
	}
	if err := call.Finish(resultPtrs...); err != nil {
		// Invocation error.
		return EmptySwiftByteArrayArray(), err
	}

	// VOM-encode the results. Note in the future we'll want a pathway where we can get the original VOM results
	// from finish so we don't end up wasting CPU & memory here.

	// Prepare the byte array array that can be accessed from Swift via C.malloc
	vomResultsMemory := C.malloc(C.size_t(numResults * int(C.sizeofSwiftByteArray)))
	// Make that malloc'd memory available as a slice to Go.
	vomResultsPtrsHdr := reflect.SliceHeader{
		Data: uintptr(vomResultsMemory),
		Len:  numResults,
		Cap:  numResults,
	}
	vomResults := *(*[]C.SwiftByteArray)(unsafe.Pointer(&vomResultsPtrsHdr))
	// Create the C Struct to return that encapsulates our byte array array
	var cVomResults C.SwiftByteArrayArray
	cVomResults.length = C._GoUint64(numResults)
	cVomResults.data = (*C.SwiftByteArray)(vomResultsMemory)

	// For each result, VOM encode into a byte array that we stick into the returned struct
	for i, resultPtr := range resultPtrs {
		// Remove the pointer from the result.  Simply *resultPtr doesn't work
		// as resultPtr is of type interface{}.
		result := interface{}(sutil.DerefOrDie(resultPtr))
		var vomResult []byte
		var err error
		if vomResult, err = vom.Encode(result); err != nil {
			return EmptySwiftByteArrayArray(), err
		}
		cVomResultCopy := C.malloc(C.size_t(len(vomResult)))
		C.memcpy(cVomResultCopy, unsafe.Pointer(&vomResult[0]), C.size_t(len(vomResult)))
		var cVomResult C.SwiftByteArray
		cVomResult.length = C._GoUint64(len(vomResult))
		cVomResult.data = cVomResultCopy
		vomResults[i] = cVomResult
	}
	return cVomResults, nil
}
示例#2
0
文件: util.go 项目: vanadium/go.swift
func EmptySwiftByteArrayArray() C.SwiftByteArrayArray {
	var empty C.SwiftByteArrayArray
	empty.length = 0
	empty.data = nil
	return empty
}