Ejemplo n.º 1
0
// 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
}
Ejemplo n.º 2
0
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)
}