// fillString allocates memory for the return value that has to be freed func fillString(gostr string) (sapuc *C.SAP_UC, err error) { var rc C.RFC_RC var errorInfo C.RFC_ERROR_INFO var result_len C.uint sapuc_size := C.uint(len(gostr) + 1) sapuc = C.GoMallocU(sapuc_size) cStr := (*C.uchar)(unsafe.Pointer(C.CString(gostr))) defer C.free(unsafe.Pointer(cStr)) *sapuc = 0 rc = C.RfcUTF8ToSAPUC((*C.RFC_BYTE)(cStr), C.uint(len(gostr)), sapuc, &sapuc_size, &result_len, &errorInfo) if rc != C.RFC_OK { err = rfcError(errorInfo, "Could not fill the string \"%v\"", gostr) } return }
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) }