func wrapVariable(cType C.RFCTYPE, container C.RFC_FUNCTION_HANDLE, cName *C.SAP_UC, cLen C.uint, typeDesc C.RFC_TYPE_DESC_HANDLE, strip bool) (result interface{}, 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 charValue *C.RFC_CHAR var stringValue *C.SAP_UC var numValue *C.RFC_NUM var byteValue *C.SAP_RAW var floatValue C.RFC_FLOAT var intValue C.RFC_INT var int1Value C.RFC_INT1 var int2Value C.RFC_INT2 var dateValue *C.RFC_CHAR var timeValue *C.RFC_CHAR var resultLen, strLen C.uint switch cType { case C.RFCTYPE_STRUCTURE: rc = C.RfcGetStructure(container, cName, &structure, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting structure") } return wrapStructure(typeDesc, structure, strip) case C.RFCTYPE_TABLE: rc = C.RfcGetTable(container, cName, &table, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting table") } return wrapTable(typeDesc, table, strip) case C.RFCTYPE_CHAR: charValue = (*C.RFC_CHAR)(C.GoMallocU(cLen)) defer C.free(unsafe.Pointer(charValue)) rc = C.RfcGetChars(container, cName, charValue, cLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting chars") } return nWrapString((*C.SAP_UC)(charValue), C.int(cLen), strip) case C.RFCTYPE_STRING: rc = C.RfcGetStringLength(container, cName, &strLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting string length") } stringValue = (*C.SAP_UC)(C.GoMallocU(strLen + 1)) defer C.free(unsafe.Pointer(stringValue)) rc = C.RfcGetString(container, cName, stringValue, strLen+1, &resultLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting string") } return wrapString(stringValue, strip) case C.RFCTYPE_NUM: numValue = (*C.RFC_NUM)(C.GoMallocU(cLen)) defer C.free(unsafe.Pointer(numValue)) rc = C.RfcGetNum(container, cName, numValue, cLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting num") } return nWrapString((*C.SAP_UC)(numValue), C.int(cLen), strip) case C.RFCTYPE_BYTE: byteValue = (*C.SAP_RAW)(C.malloc(C.size_t(cLen))) defer C.free(unsafe.Pointer(byteValue)) rc = C.RfcGetBytes(container, cName, byteValue, cLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting bytes") } return (*[1 << 30]byte)(unsafe.Pointer(byteValue))[:cLen:cLen], err case C.RFCTYPE_XSTRING: rc = C.RfcGetStringLength(container, cName, &strLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting xstring length") } byteValue = (*C.SAP_RAW)(C.malloc(C.size_t(strLen + 1))) defer C.free(unsafe.Pointer(byteValue)) *byteValue = 0 rc = C.RfcGetXString(container, cName, byteValue, strLen, &resultLen, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting xstring") } return (*[1 << 30]byte)(unsafe.Pointer(byteValue))[:resultLen:resultLen], err case C.RFCTYPE_BCD: // An upper bound for the length of the _string representation_ // of the BCD is given by (2*cLen)-1 (each digit is encoded in 4bit, // the first 4 bit are reserved for the sign) // Furthermore, a sign char, a decimal separator char may be present // => (2*cLen)+1 strLen = 2*cLen + 1 stringValue = C.GoMallocU(strLen + 1) defer C.free(unsafe.Pointer(stringValue)) rc = C.RfcGetString(container, cName, stringValue, strLen+1, &resultLen, &errorInfo) /*if rc == 23: # Buffer too small, use returned requried result length print("Warning: Buffer for BCD (cLen={}, buffer={}) too small: " "trying with {}".format(cLen, strLen, resultLen)) free(stringValue) strLen = resultLen stringValue = mallocU(strLen+1) rc = RfcGetString(container, cName, stringValue, strLen+1, &resultLen, &errorInfo)*/ if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting BCD") } return wrapString(stringValue, strip) //return Decimal(wrapString(stringValue)) case C.RFCTYPE_FLOAT: rc = C.RfcGetFloat(container, cName, &floatValue, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting float") } return float64(floatValue), err case C.RFCTYPE_INT: rc = C.RfcGetInt(container, cName, &intValue, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting int") } return int(intValue), err case C.RFCTYPE_INT1: rc = C.RfcGetInt1(container, cName, &int1Value, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting int1") } return int(int1Value), err case C.RFCTYPE_INT2: rc = C.RfcGetInt2(container, cName, &int2Value, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting int2") } return int(int2Value), err case C.RFCTYPE_DATE: dateValue = (*C.RFC_CHAR)(C.malloc(8)) defer C.free(unsafe.Pointer(dateValue)) rc = C.RfcGetDate(container, cName, dateValue, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting date") } var value string value, err = nWrapString((*C.SAP_UC)(dateValue), 8, false) if value == "00000000" || ' ' == value[1] || err != nil { return } goDate, _ := time.Parse("20060102", value) return goDate, err case C.RFCTYPE_TIME: timeValue = (*C.RFC_CHAR)(C.malloc(6)) defer C.free(unsafe.Pointer(timeValue)) rc = C.RfcGetTime(container, cName, timeValue, &errorInfo) if rc != C.RFC_OK { return result, rfcError(errorInfo, "Failed getting time") } var value string value, err = nWrapString((*C.SAP_UC)(timeValue), 6, false) if err != nil { return } goTime, _ := time.Parse("150405", value) return goTime, err } return result, rfcError(errorInfo, "Unknown RFC type %d when wrapping variable", cType) }
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 }