Beispiel #1
0
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
}
Beispiel #2
0
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
}