func nWrapString(uc *C.SAP_UC, length C.int, strip bool) (result string, err error) { var rc C.RFC_RC var errorInfo C.RFC_ERROR_INFO if length == -1 { length = C.int(C.GoStrlenU((*C.SAP_UTF16)(uc))) } if length == 0 { return "", err } utf8Size := C.uint(length*3) + 1 utf8str := (*C.char)(unsafe.Pointer(C.malloc((C.size_t)(utf8Size)))) defer C.free(unsafe.Pointer(utf8str)) // _todo: Memory access error on Windows only, when trying to free RFCCHAR1 of RFCTABLE in function call test *utf8str = 0 resultLen := C.uint(0) rc = C.RfcSAPUCToUTF8(uc, (C.uint)(length), (*C.RFC_BYTE)(utf8str), &utf8Size, &resultLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed wrapping a C string") } result = C.GoStringN(utf8str, length) if strip { result = strings.Trim(result, "\x00 ") return } return }
func fillVariable(cType C.RFCTYPE, container C.RFC_FUNCTION_HANDLE, cName *C.SAP_UC, value interface{}, typeDesc C.RFC_TYPE_DESC_HANDLE) (err error) { var rc C.RFC_RC var errorInfo C.RFC_ERROR_INFO var structure C.RFC_STRUCTURE_HANDLE var table C.RFC_TABLE_HANDLE var cValue *C.SAP_UC var bValue *C.SAP_RAW defer C.free(unsafe.Pointer(cValue)) defer C.free(unsafe.Pointer(bValue)) switch cType { case C.RFCTYPE_STRUCTURE: rc = C.RfcGetStructure(container, cName, &structure, &errorInfo) if rc != C.RFC_OK { return rfcError(errorInfo, "Could not get structure") } err = fillStructure(typeDesc, structure, value) case C.RFCTYPE_TABLE: rc = C.RfcGetTable(container, cName, &table, &errorInfo) if rc != C.RFC_OK { return rfcError(errorInfo, "Could not get table") } err = fillTable(typeDesc, table, value) case C.RFCTYPE_CHAR: cValue, err = fillString(reflect.ValueOf(value).String()) rc = C.RfcSetChars(container, cName, (*C.RFC_CHAR)(cValue), C.uint(C.GoStrlenU((*C.SAP_UTF16)(cValue))), &errorInfo) case C.RFCTYPE_BYTE: bValue = fillBytes(reflect.ValueOf(value).Bytes()) rc = C.RfcSetBytes(container, cName, bValue, C.uint(len(reflect.ValueOf(value).Bytes())), &errorInfo) case C.RFCTYPE_XSTRING: bValue = fillBytes(reflect.ValueOf(value).Bytes()) rc = C.RfcSetXString(container, cName, bValue, C.uint(len(reflect.ValueOf(value).Bytes())), &errorInfo) case C.RFCTYPE_STRING: cValue, err = fillString(reflect.ValueOf(value).String()) rc = C.RfcSetString(container, cName, cValue, C.uint(C.GoStrlenU((*C.SAP_UTF16)(cValue))), &errorInfo) case C.RFCTYPE_NUM: cValue, err = fillString(reflect.ValueOf(value).String()) rc = C.RfcSetNum(container, cName, (*C.RFC_NUM)(cValue), C.uint(C.GoStrlenU((*C.SAP_UTF16)(cValue))), &errorInfo) case C.RFCTYPE_BCD: // support for float missing cValue, err = fillString(reflect.ValueOf(value).String()) rc = C.RfcSetString(container, cName, cValue, C.uint(C.GoStrlenU((*C.SAP_UTF16)(cValue))), &errorInfo) case C.RFCTYPE_FLOAT: rc = C.RfcSetFloat(container, cName, C.RFC_FLOAT(reflect.ValueOf(value).Float()), &errorInfo) case C.RFCTYPE_INT, C.RFCTYPE_INT1, C.RFCTYPE_INT2: rc = C.RfcSetInt(container, cName, C.RFC_INT(reflect.ValueOf(value).Int()), &errorInfo) case C.RFCTYPE_DATE: cValue, err = fillString(value.(time.Time).Format("20060102")) rc = C.RfcSetDate(container, cName, (*C.RFC_CHAR)(cValue), &errorInfo) case C.RFCTYPE_TIME: cValue, err = fillString(value.(time.Time).Format("150405")) rc = C.RfcSetTime(container, cName, (*C.RFC_CHAR)(cValue), &errorInfo) default: var goName string goName, err = wrapString(cName, true) return rfcError(errorInfo, "Unknown RFC type %v when filling %v", cType, goName) } if rc != C.RFC_OK { var goName string goName, err = wrapString(cName, true) err = rfcError(errorInfo, "Could not fill %v of type %v", goName, cType) } return }