nwrfc 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.rdoc +124 -120
- data/Rakefile +8 -8
- data/lib/nwrfc.rb +390 -389
- data/lib/nwrfc/datacontainer.rb +337 -337
- data/lib/nwrfc/nwerror.rb +39 -24
- data/lib/nwrfc/nwrfclib.rb +436 -436
- data/lib/nwrfc/server.rb +45 -45
- metadata +37 -59
data/lib/nwrfc/nwerror.rb
CHANGED
@@ -1,25 +1,40 @@
|
|
1
|
-
module NWRFC
|
2
|
-
|
3
|
-
class NWError < Exception
|
4
|
-
|
5
|
-
attr_reader :code, :group, :message, :class, :type, :number
|
6
|
-
|
7
|
-
# Instantiate Error object with a handle to an FFI::MemoryPointer
|
8
|
-
# to an NWRFCLib::RFCError object. The error object is analyzed so that
|
9
|
-
# when the caller intercepts it with Rescue, all the error details are
|
10
|
-
# available
|
11
|
-
def initialize(error)
|
12
|
-
@code = NWRFCLib::RFC_RC[error[:code]]
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
module NWRFC
|
2
|
+
|
3
|
+
class NWError < Exception
|
4
|
+
|
5
|
+
attr_reader :code, :group, :message, :class, :type, :number
|
6
|
+
|
7
|
+
# Instantiate Error object with a handle to an FFI::MemoryPointer
|
8
|
+
# to an NWRFCLib::RFCError object. The error object is analyzed so that
|
9
|
+
# when the caller intercepts it with Rescue, all the error details are
|
10
|
+
# available
|
11
|
+
def initialize(error)
|
12
|
+
@code = NWRFCLib::RFC_RC[error[:code]]
|
13
|
+
# In the event that the called function raised an exception, we must create a more specific
|
14
|
+
# error
|
15
|
+
raise(NWABAPException, error[:key].get_str) if @code == :RFC_ABAP_EXCEPTION
|
16
|
+
@group = NWRFCLib::RFC_ERROR_GROUP[error[:group]]
|
17
|
+
@message = error[:message].get_str
|
18
|
+
@type = error[:abapMsgType].get_str
|
19
|
+
@number = error[:abapMsgNumber].get_str
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#{@message} (code #{@code}, group #{@group}, type #{@type}, number #{@number})"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class NWABAPException < NWError
|
29
|
+
attr_reader :exception
|
30
|
+
def initialize(exception)
|
31
|
+
@exception = exception
|
32
|
+
end
|
33
|
+
|
34
|
+
def inspect
|
35
|
+
"Function exception #{exception}"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
25
40
|
end
|
data/lib/nwrfc/nwrfclib.rb
CHANGED
@@ -1,436 +1,436 @@
|
|
1
|
-
# Author:: Martin Ceronio martin.ceronio@infosize.co.za
|
2
|
-
# Copyright:: Copyright (c) 2012 Martin Ceronio
|
3
|
-
# License:: MIT and/or Creative Commons Attribution-ShareAlike
|
4
|
-
# SAP, Netweaver, RFC and other names referred to in this code
|
5
|
-
# are, or may be registered trademarks and the property of SAP, AG
|
6
|
-
# No ownership over any of these is asserted by Martin Ceronio
|
7
|
-
|
8
|
-
require 'rubygems'
|
9
|
-
require 'ffi'
|
10
|
-
require 'iconv'
|
11
|
-
|
12
|
-
RUBY_VERSION_18 = RUBY_VERSION[0..2] == "1.8"
|
13
|
-
|
14
|
-
# Provide an alias for FFI::MemoryPointer#read_int to `read_uint` in 1.8
|
15
|
-
# See http://stackoverflow.com/questions/9035661/ruby-ffi-memorypointer-read-int-present-in-1-9-but-not-1-8
|
16
|
-
# Probably not good to interpret an unsigned int as an int, but we don't expect to use it for big values
|
17
|
-
# that could result in sign conversion
|
18
|
-
# FIXME - This must go! Replace with calls to get_* defined in FFI::MemoryPointer
|
19
|
-
if RUBY_VERSION_18
|
20
|
-
FFI::MemoryPointer.class_eval{ alias :read_uint :read_int}
|
21
|
-
end
|
22
|
-
|
23
|
-
# Enhancement to FFI::Pointer to be able to read a double-null terminated string,
|
24
|
-
# which would be returned e.g. by RfcGetVersion() in the SDK
|
25
|
-
# See http://stackoverflow.com/questions/9293307/ruby-ffi-ruby-1-8-reading-utf-16le-encoded-strings
|
26
|
-
module FFI
|
27
|
-
class Pointer
|
28
|
-
|
29
|
-
# Enhancement to FFI::Pointer to be able to read a double-null terminated string,
|
30
|
-
# which would be returned e.g. by RfcGetVersion() in the SDK
|
31
|
-
# See http://stackoverflow.com/questions/9293307/ruby-ffi-ruby-1-8-reading-utf-16le-encoded-strings
|
32
|
-
# It should be safe to call this on a Pointer within the context of the NW RFC SDK library,
|
33
|
-
# because all strings are supposed to be UTF-16LE encoded and double-null terminated
|
34
|
-
def read_string_dn(max=0)
|
35
|
-
cont_nullcount = 0
|
36
|
-
offset = 0
|
37
|
-
until cont_nullcount == 2
|
38
|
-
byte = get_bytes(offset,1)
|
39
|
-
cont_nullcount += 1 if byte == "\000"
|
40
|
-
cont_nullcount = 0 if byte != "\000"
|
41
|
-
offset += 1
|
42
|
-
end
|
43
|
-
get_bytes(0,offset+1)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Enhancement to the String class to put string values into double-null
|
49
|
-
# terminated UTF16 little endian encoded strings as required by the NW RFC
|
50
|
-
# SDK function, which should work on Linux and Windows (and maybe other
|
51
|
-
# architectures, though the plan is not to support them)
|
52
|
-
#String.class_eval{define_method(:cU){ Iconv.conv("UTF-16LE", "UTF8", self+"\0") }}
|
53
|
-
class String
|
54
|
-
|
55
|
-
# Convert string from UTF-8 to doudble-null terminated UTF-16LE string
|
56
|
-
def cU
|
57
|
-
NWRFCLib::Cutf8_to_utf16le.iconv(self+"\0")
|
58
|
-
end
|
59
|
-
|
60
|
-
# Convert string from UTF-16LE to UTF-8 and trim trailing whitespace
|
61
|
-
def uC
|
62
|
-
NWRFCLib::Cutf16le_to_utf8.iconv(self).strip
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
# Enhancement to FFI::StructLayout::CharArray to add a get_str method that changes the
|
68
|
-
# string value of the character array by enforcing encoding of UTF-16LE (as used in NW RFC SDK)
|
69
|
-
# and strips off blanks at the end to return a readable String
|
70
|
-
class FFI::StructLayout::CharArray
|
71
|
-
def get_str
|
72
|
-
NWRFCLib::Cutf16le_to_utf8.iconv(self.to_ptr.read_string(self.size)).strip
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Library wrapper around NW RFC SDK shared library using RUBY-FFI
|
77
|
-
module NWRFCLib
|
78
|
-
|
79
|
-
Cutf8_to_utf16le = Iconv.new("UTF-16LE", "UTF-8")
|
80
|
-
Cutf16le_to_utf8 = Iconv.new("UTF-8", "UTF-16LE")
|
81
|
-
|
82
|
-
extend FFI::Library
|
83
|
-
ffi_lib 'sapnwrfc'
|
84
|
-
|
85
|
-
# Multiplier for providing correct byte size for String passed to RFC library
|
86
|
-
#@todo Make platform-dependent size based on RUBY_PLATFORM
|
87
|
-
B_SIZE = 2
|
88
|
-
|
89
|
-
RFC_RC = enum(
|
90
|
-
:RFC_OK,
|
91
|
-
:RFC_COMMUNICATION_FAILURE,
|
92
|
-
:RFC_LOGON_FAILURE,
|
93
|
-
:RFC_ABAP_RUNTIME_FAILURE,
|
94
|
-
:RFC_ABAP_MESSAGE,
|
95
|
-
:RFC_ABAP_EXCEPTION,
|
96
|
-
:RFC_CLOSED,
|
97
|
-
:RFC_CANCELED,
|
98
|
-
:RFC_TIMEOUT,
|
99
|
-
:RFC_MEMORY_INSUFFICIENT,
|
100
|
-
:RFC_VERSION_MISMATCH,
|
101
|
-
:RFC_INVALID_PROTOCOL,
|
102
|
-
:RFC_SERIALIZATION_FAILURE,
|
103
|
-
:RFC_INVALID_HANDLE,
|
104
|
-
:RFC_RETRY,
|
105
|
-
:RFC_EXTERNAL_FAILURE,
|
106
|
-
:RFC_EXECUTED,
|
107
|
-
:RFC_NOT_FOUND,
|
108
|
-
:RFC_NOT_SUPPORTED,
|
109
|
-
:RFC_ILLEGAL_STATE,
|
110
|
-
:RFC_INVALID_PARAMETER,
|
111
|
-
:RFC_CODEPAGE_CONVERSION_FAILURE,
|
112
|
-
:RFC_CONVERSION_FAILURE,
|
113
|
-
:RFC_BUFFER_TOO_SMALL,
|
114
|
-
:RFC_TABLE_MOVE_BOF,
|
115
|
-
:RFC_TABLE_MOVE_EOF,
|
116
|
-
:RFC_UNKNOWN_ERROR
|
117
|
-
)
|
118
|
-
|
119
|
-
RFC_ERROR_GROUP = enum(
|
120
|
-
:OK,
|
121
|
-
:ABAP_APPLICATION_FAILURE,
|
122
|
-
:ABAP_RUNTIME_FAILURE,
|
123
|
-
:LOGON_FAILURE,
|
124
|
-
:COMMUNICATION_FAILURE,
|
125
|
-
:EXTERNAL_RUNTIME_FAILURE,
|
126
|
-
:EXTERNAL_APPLICATION_FAILURE
|
127
|
-
)
|
128
|
-
|
129
|
-
RFC_DIRECTION = enum(
|
130
|
-
:RFC_IMPORT, 1,
|
131
|
-
:RFC_EXPORT, 2,
|
132
|
-
:RFC_CHANGING, 3,
|
133
|
-
:RFC_TABLES, 7
|
134
|
-
)
|
135
|
-
|
136
|
-
RFC_TYPE = enum(
|
137
|
-
:RFCTYPE_CHAR , 0,
|
138
|
-
:RFCTYPE_DATE , 1,
|
139
|
-
:RFCTYPE_BCD , 2,
|
140
|
-
:RFCTYPE_TIME , 3,
|
141
|
-
:RFCTYPE_BYTE , 4,
|
142
|
-
:RFCTYPE_TABLE , 5,
|
143
|
-
:RFCTYPE_NUM , 6,
|
144
|
-
:RFCTYPE_FLOAT , 7,
|
145
|
-
:RFCTYPE_INT , 8,
|
146
|
-
:RFCTYPE_INT2 , 9,
|
147
|
-
:RFCTYPE_INT1 , 10,
|
148
|
-
:RFCTYPE_NULL , 14,
|
149
|
-
:RFCTYPE_ABAPOBJECT, 16,
|
150
|
-
:RFCTYPE_STRUCTURE , 17,
|
151
|
-
:RFCTYPE_DECF16 , 23,
|
152
|
-
:RFCTYPE_DECF34 , 24,
|
153
|
-
:RFCTYPE_XMLDATA , 28,
|
154
|
-
:RFCTYPE_STRING , 29,
|
155
|
-
:RFCTYPE_XSTRING , 30,
|
156
|
-
:RFCTYPE_BOX, 31,
|
157
|
-
:RFCTYPE_GENERIC_BOX, 32,
|
158
|
-
:_RFCTYPE_max_value
|
159
|
-
)
|
160
|
-
|
161
|
-
# Connection parameter wrapper (struct RFC_CONNECTION_PARAMETER in sapnwrfc.h)
|
162
|
-
class RFCConnParam < FFI::Struct
|
163
|
-
layout :name, :pointer,
|
164
|
-
:value, :pointer
|
165
|
-
end
|
166
|
-
|
167
|
-
# Connection Details (struct RFC_ATTRIBUTES in sapnwrfc.h)
|
168
|
-
class RFCConnection < FFI::Struct
|
169
|
-
layout :dest, [:char, (64+1)*B_SIZE],
|
170
|
-
:host, [:char, (100+1)*B_SIZE],
|
171
|
-
:partnerHost, [:char, (100+1)*B_SIZE],
|
172
|
-
:sysNumber, [:char, (2+1)*B_SIZE],
|
173
|
-
:sysId, [:char, (8+1)*B_SIZE],
|
174
|
-
:client, [:char, (3+1)*B_SIZE],
|
175
|
-
:user, [:char, (12+1)*B_SIZE],
|
176
|
-
:language, [:char, (2+1)*B_SIZE],
|
177
|
-
:trace, [:char, (1+1)*B_SIZE],
|
178
|
-
:isoLanguage, [:char, (2+1)*B_SIZE],
|
179
|
-
:codepage, [:char, (4+1)*B_SIZE],
|
180
|
-
:partnerCodepage, [:char, (4+1)*B_SIZE],
|
181
|
-
:rfcRole, [:char, (1+1)*B_SIZE],
|
182
|
-
:type, [:char, (1+1)*B_SIZE],
|
183
|
-
:partnerType, [:char, (1+1)*B_SIZE],
|
184
|
-
:rel, [:char, (4+1)*B_SIZE],
|
185
|
-
:partnerRel, [:char, (4+1)*B_SIZE],
|
186
|
-
:kernelRel, [:char, (4+1)*B_SIZE],
|
187
|
-
:cpicConvId, [:char, (8+1)*B_SIZE],
|
188
|
-
:progName, [:char, (128+1)*B_SIZE],
|
189
|
-
:reserved, [:char, (86+1)*B_SIZE]
|
190
|
-
end
|
191
|
-
|
192
|
-
# Error info wrapper (struct RFC_ERROR_INFO in sapnwrfc.h)
|
193
|
-
class RFCError < FFI::Struct
|
194
|
-
layout :code, :int,
|
195
|
-
:group, :int,
|
196
|
-
:key, [:char, (128)*B_SIZE],
|
197
|
-
:message, [:char, (512)*B_SIZE],
|
198
|
-
:abapMsgClass, [:char, (20+1)*B_SIZE],
|
199
|
-
:abapMsgType, [:char, (1+1)*B_SIZE],
|
200
|
-
:abapMsgNumber, [:char, (3+1)*B_SIZE],
|
201
|
-
:abapMsgV1, [:char, (50+1)*B_SIZE],
|
202
|
-
:abapMsgV2, [:char, (50+1)*B_SIZE],
|
203
|
-
:abapMsgV3, [:char, (50+1)*B_SIZE],
|
204
|
-
:abapMsgV4, [:char, (50+1)*B_SIZE]
|
205
|
-
end
|
206
|
-
|
207
|
-
# Function Parameter Description (struct RFC_PARAMETER_DESC in sapnwrfc.h)
|
208
|
-
class RFCFuncParam < FFI::Struct
|
209
|
-
layout :name, [:char, (30+1)*B_SIZE],
|
210
|
-
:type, :int, #enum RFCTYPE
|
211
|
-
:direction, :int, #enum RFC_DIRECTION
|
212
|
-
:nucLength, :uint,
|
213
|
-
:ucLength, :uint,
|
214
|
-
:decimals, :uint,
|
215
|
-
:typeDescHandle, :pointer, #RFC_TYPE_DESC_HANDLE
|
216
|
-
:defaultValue, [:char, (30+1)*B_SIZE], #RFC_PARAMETER_DEFVALUE
|
217
|
-
:parameterText, [:char, (79+1)*B_SIZE], #RFC_PARAMETER_TEXT
|
218
|
-
:optional, :uchar, #RFC_BYTE
|
219
|
-
:extendedDescription, :pointer
|
220
|
-
end
|
221
|
-
|
222
|
-
class RFCFieldDesc < FFI::Struct
|
223
|
-
layout :name, [:char, (30+1)*B_SIZE],
|
224
|
-
:type, :int, #enum RFCTYPE
|
225
|
-
:nucLength, :uint,
|
226
|
-
:nucOffset, :uint,
|
227
|
-
:ucLength, :uint,
|
228
|
-
:ucOffset, :uint,
|
229
|
-
:decimals, :uint,
|
230
|
-
:typeDescHandle, :pointer, #RFC_TYPE_DESC_HANDLE
|
231
|
-
:extendedDescription, :pointer
|
232
|
-
end
|
233
|
-
|
234
|
-
class RFCDataContainer < FFI::Struct
|
235
|
-
layout :handle, :pointer
|
236
|
-
end
|
237
|
-
|
238
|
-
# typedef :RFCDataContainer, RFCStructureHandle
|
239
|
-
# typedef :RFCDataContainer, RFCTableHandle
|
240
|
-
|
241
|
-
class RFC_FUNCTION_DESC_HANDLE < FFI::Struct
|
242
|
-
layout :handle, :pointer
|
243
|
-
end
|
244
|
-
|
245
|
-
class RFC_TYPE_DESC_HANDLE < FFI::Struct
|
246
|
-
layout :handle, :pointer
|
247
|
-
end
|
248
|
-
|
249
|
-
class DATA_CONTAINER_HANDLE < FFI::Struct
|
250
|
-
layout :handle, :pointer
|
251
|
-
end
|
252
|
-
|
253
|
-
class RFC_DECF16 < FFI::Union
|
254
|
-
layout :bytes, [:uchar, 8],
|
255
|
-
:align, :double
|
256
|
-
end
|
257
|
-
|
258
|
-
# class SAP_MAX_ALIGN_T < FFI::Union
|
259
|
-
# layout :align1, :long,
|
260
|
-
# :align2, :double,
|
261
|
-
# :align3, :pointer,
|
262
|
-
# :align4,
|
263
|
-
# end
|
264
|
-
|
265
|
-
# class RFC_DECF34 < FFI::Union
|
266
|
-
# layout :bytes, [:uchar, 16],
|
267
|
-
# :align, 16
|
268
|
-
# end
|
269
|
-
|
270
|
-
#############################################################################################################
|
271
|
-
# ATTACH FUNCTIONS
|
272
|
-
# The functions here were obtained by parsing content from the doxygen files from the documentation
|
273
|
-
# accompanying the NW RFC SDK, and were tweaked here and there afterward. Most of them are actually not
|
274
|
-
# yet used in our NWRFC library, so calling them may not work. For best results, consult sapnwrfc.h from
|
275
|
-
# the SDK
|
276
|
-
#############################################################################################################
|
277
|
-
# Callback for function server (function implementation)
|
278
|
-
callback :funcimpl, [:pointer, :pointer, :pointer], :int
|
279
|
-
|
280
|
-
# Function mappings
|
281
|
-
[
|
282
|
-
[:add_exception, :RfcAddException, [:pointer, :pointer, :pointer], :int],
|
283
|
-
[:add_function_desc, :RfcAddFunctionDesc, [:pointer, :pointer, :pointer], :int],
|
284
|
-
[:add_parameter, :RfcAddParameter, [:pointer, :pointer, :pointer], :int],
|
285
|
-
[:add_type_desc, :RfcAddTypeDesc, [:pointer, :pointer, :pointer], :int],
|
286
|
-
[:add_type_field, :RfcAddTypeField, [:pointer, :pointer, :pointer], :int],
|
287
|
-
# @method append_new_row(table_handle, error_handle)
|
288
|
-
# @returns FFI::Pointer pointer to structure of new row
|
289
|
-
# calls RfcAppendNewRow()
|
290
|
-
[:append_new_row, :RfcAppendNewRow, [:pointer, :pointer], :pointer],
|
291
|
-
# @method append_row(table_handle, structure, error_handle)
|
292
|
-
# @returns Integer RC
|
293
|
-
# calls RfcAppendRow()
|
294
|
-
[:append_row, :RfcAppendRow, [:pointer, :pointer, :pointer], :int],
|
295
|
-
[:clone_structure, :RfcCloneStructure, [:pointer, :pointer], :pointer],
|
296
|
-
[:clone_table, :RfcCloneTable, [:pointer, :pointer], :pointer],
|
297
|
-
[:close_connection, :RfcCloseConnection, [:pointer, :pointer], :int],
|
298
|
-
[:confirm_transaction, :RfcConfirmTransaction, [:pointer, :pointer], :int],
|
299
|
-
[:create_function, :RfcCreateFunction, [:pointer, :pointer], :pointer],
|
300
|
-
[:create_function_desc, :RfcCreateFunctionDesc, [:pointer, :pointer], :pointer],
|
301
|
-
[:create_structure, :RfcCreateStructure, [:pointer, :pointer], :pointer],
|
302
|
-
[:create_table, :RfcCreateTable, [:pointer, :pointer], :pointer],
|
303
|
-
[:create_transaction, :RfcCreateTransaction, [:pointer, :pointer, :pointer, :pointer], :pointer],
|
304
|
-
[:create_type_desc, :RfcCreateTypeDesc, [:pointer, :pointer], :pointer],
|
305
|
-
[:delete_all_rows, :RfcDeleteAllRows, [:pointer, :pointer], :int],
|
306
|
-
[:delete_current_row, :RfcDeleteCurrentRow, [:pointer, :pointer], :int],
|
307
|
-
[:describe_function, :RfcDescribeFunction, [:pointer, :pointer], :pointer],
|
308
|
-
[:describe_type, :RfcDescribeType, [:pointer, :pointer], :pointer],
|
309
|
-
[:destroy_function, :RfcDestroyFunction, [:pointer, :pointer], :int],
|
310
|
-
[:destroy_function_desc, :RfcDestroyFunctionDesc, [:pointer, :pointer], :int],
|
311
|
-
[:destroy_structure, :RfcDestroyStructure, [:pointer, :pointer], :int],
|
312
|
-
[:destroy_table, :RfcDestroyTable, [:pointer, :pointer], :int],
|
313
|
-
[:destroy_transaction, :RfcDestroyTransaction, [:pointer, :pointer], :int],
|
314
|
-
[:destroy_type_desc, :RfcDestroyTypeDesc, [:pointer, :pointer], :int],
|
315
|
-
[:enable_basxml, :RfcEnableBASXML, [:pointer, :pointer], :int],
|
316
|
-
[:get_bytes, :RfcGetBytes, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
317
|
-
[:get_cached_function_desc, :RfcGetCachedFunctionDesc, [:pointer, :pointer, :pointer], :pointer],
|
318
|
-
[:get_cached_type_desc, :RfcGetCachedTypeDesc, [:pointer, :pointer, :pointer], :pointer],
|
319
|
-
[:get_chars, :RfcGetChars, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
320
|
-
[:get_connection_attributes, :RfcGetConnectionAttributes, [:pointer, :pointer, :pointer], :int],
|
321
|
-
[:get_current_row, :RfcGetCurrentRow, [:pointer, :pointer], :pointer],
|
322
|
-
[:get_date, :RfcGetDate, [:pointer, :pointer, :pointer, :pointer], :int],
|
323
|
-
[:get_dec_f16, :RfcGetDecF16, [:pointer, :pointer, :pointer, :pointer], :int],
|
324
|
-
[:get_dec_f34, :RfcGetDecF34, [:pointer, :pointer, :pointer, :pointer], :int],
|
325
|
-
[:get_direction_as_string, :RfcGetDirectionAsString, [:pointer], :pointer],
|
326
|
-
[:get_exception_count, :RfcGetExceptionCount, [:pointer, :pointer, :pointer], :int],
|
327
|
-
[:get_exception_desc_by_index, :RfcGetExceptionDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
328
|
-
[:get_exception_desc_by_name, :RfcGetExceptionDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
329
|
-
[:get_field_count, :RfcGetFieldCount, [:pointer, :pointer, :pointer], :int],
|
330
|
-
[:get_field_desc_by_index, :RfcGetFieldDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
331
|
-
[:get_field_desc_by_name, :RfcGetFieldDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
332
|
-
[:get_float, :RfcGetFloat, [:pointer, :pointer, :pointer, :pointer], :int],
|
333
|
-
[:get_function_desc, :RfcGetFunctionDesc, [:pointer, :pointer, :pointer], :pointer],
|
334
|
-
[:get_function_name, :RfcGetFunctionName, [:pointer, :pointer, :pointer], :int],
|
335
|
-
[:get_int, :RfcGetInt, [:pointer, :pointer, :pointer, :pointer], :int],
|
336
|
-
[:get_int1, :RfcGetInt1, [:pointer, :pointer, :pointer, :pointer], :int],
|
337
|
-
[:get_int2, :RfcGetInt2, [:pointer, :pointer, :pointer, :pointer], :int],
|
338
|
-
[:get_num, :RfcGetNum, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
339
|
-
[:get_parameter_count, :RfcGetParameterCount, [:pointer, :pointer, :pointer], :int],
|
340
|
-
[:get_parameter_desc_by_index, :RfcGetParameterDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
341
|
-
[:get_parameter_desc_by_name, :RfcGetParameterDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
342
|
-
[:get_partner_snc_key, :RfcGetPartnerSNCKey, [:pointer, :pointer, :pointer, :pointer], :int],
|
343
|
-
[:get_partner_snc_name, :RfcGetPartnerSNCName, [:pointer, :pointer, :uint, :pointer], :int],
|
344
|
-
[:get_partner_sso_ticket, :RfcGetPartnerSSOTicket, [:pointer, :pointer, :pointer, :pointer], :int],
|
345
|
-
[:get_rc_as_string, :RfcGetRcAsString, [:pointer], :pointer],
|
346
|
-
[:get_row_count, :RfcGetRowCount, [:pointer, :pointer, :pointer], :int],
|
347
|
-
[:get_string, :RfcGetString, [:pointer, :pointer, :pointer, :uint, :pointer, :pointer], :int],
|
348
|
-
[:get_string_length, :RfcGetStringLength, [:pointer, :pointer, :pointer, :pointer], :int],
|
349
|
-
[:get_structure, :RfcGetStructure, [:pointer, :pointer, :pointer, :pointer], :int],
|
350
|
-
[:get_table, :RfcGetTable, [:pointer, :pointer, :pointer, :pointer], :int],
|
351
|
-
[:get_time, :RfcGetTime, [:pointer, :pointer, :pointer, :pointer], :int],
|
352
|
-
[:get_transaction_id, :RfcGetTransactionID, [:pointer, :pointer, :pointer], :int],
|
353
|
-
[:get_type_as_string, :RfcGetTypeAsString, [:pointer], :pointer],
|
354
|
-
[:get_type_desc, :RfcGetTypeDesc, [:pointer, :pointer, :pointer], :pointer],
|
355
|
-
[:get_type_length, :RfcGetTypeLength, [:pointer, :pointer, :pointer, :pointer], :int],
|
356
|
-
[:get_type_name, :RfcGetTypeName, [:pointer, :pointer, :pointer], :int],
|
357
|
-
[:get_version, :RfcGetVersion, [:pointer, :pointer, :pointer], :pointer],
|
358
|
-
[:get_x_string, :RfcGetXString, [:pointer, :pointer, :pointer, :uint, :pointer, :pointer], :int],
|
359
|
-
[:init, :RfcInit, [:pointer], :int],
|
360
|
-
[:insert_new_row, :RfcInsertNewRow, [:pointer, :pointer], :pointer],
|
361
|
-
[:insert_row, :RfcInsertRow, [:pointer, :pointer, :pointer], :int],
|
362
|
-
[:install_generic_server_function, :RfcInstallGenericServerFunction, [:pointer, :pointer, :pointer], :int],
|
363
|
-
[:install_server_function, :RfcInstallServerFunction, [:pointer, :pointer, :funcimpl, :pointer], :int],
|
364
|
-
[:install_transaction_handlers, :RfcInstallTransactionHandlers, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int],
|
365
|
-
[:invoke, :RfcInvoke, [:pointer, :pointer, :pointer], :int],
|
366
|
-
[:invoke_in_transaction, :RfcInvokeInTransaction, [:pointer, :pointer, :pointer], :int],
|
367
|
-
[:is_basxml_supported, :RfcIsBASXMLSupported, [:pointer, :pointer, :pointer], :int],
|
368
|
-
#[:is_connection_handle_valid, :RfcIsConnectionHandleValid, [:pointer, :pointer, :pointer], :int],
|
369
|
-
[:is_parameter_active, :RfcIsParameterActive, [:pointer, :pointer, :pointer, :pointer], :int],
|
370
|
-
[:listen_and_dispatch, :RfcListenAndDispatch, [:pointer, :int, :pointer], :int],
|
371
|
-
[:move_to, :RfcMoveTo, [:pointer, :uint, :pointer], :int],
|
372
|
-
[:move_to_first_row, :RfcMoveToFirstRow, [:pointer, :pointer], :int],
|
373
|
-
[:move_to_last_row, :RfcMoveToLastRow, [:pointer, :pointer], :int],
|
374
|
-
[:move_to_next_row, :RfcMoveToNextRow, [:pointer, :pointer], :int],
|
375
|
-
[:move_to_previous_row, :RfcMoveToPreviousRow, [:pointer, :pointer], :int],
|
376
|
-
[:open_connection, :RfcOpenConnection, [:pointer, :uint, :pointer], :pointer],
|
377
|
-
[:ping, :RfcPing, [:pointer, :pointer], :int],
|
378
|
-
[:register_server, :RfcRegisterServer, [:pointer, :uint, :pointer], :pointer],
|
379
|
-
[:reload_ini_file, :RfcReloadIniFile, [:pointer], :int],
|
380
|
-
# [:remove_function_desc, :RfcRemoveFunctionDesc, [:pointer, :pointer, :pointer], :int],
|
381
|
-
# [:remove_type_desc, :RfcRemoveTypeDesc, [:pointer, :pointer, :pointer], :int],
|
382
|
-
[:reset_server_context, :RfcResetServerContext, [:pointer, :pointer], :int],
|
383
|
-
[:sapuc_to_utf8, :RfcSAPUCToUTF8, [:pointer, :uint, :pointer, :pointer, :pointer, :pointer], :int],
|
384
|
-
[:set_bytes, :RfcSetBytes, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
385
|
-
[:set_chars, :RfcSetChars, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
386
|
-
[:set_date, :RfcSetDate, [:pointer, :pointer, :pointer, :pointer], :int],
|
387
|
-
#[:set_dec_f16, :RfcSetDecF16, [:pointer, :pointer, :pointer, :pointer], :int],
|
388
|
-
[:set_dec_f16, :RfcSetDecF16, [:pointer, :pointer, RFC_DECF16.by_value, :pointer], :int],
|
389
|
-
[:set_dec_f34, :RfcSetDecF34, [:pointer, :pointer, :pointer, :pointer], :int],
|
390
|
-
[:set_float, :RfcSetFloat, [:pointer, :pointer, :double, :pointer], :int],
|
391
|
-
[:set_ini_path, :RfcSetIniPath, [:pointer, :pointer], :int],
|
392
|
-
[:set_int, :RfcSetInt, [:pointer, :pointer, :long, :pointer], :int],
|
393
|
-
[:set_int1, :RfcSetInt1, [:pointer, :pointer, :uint8, :pointer], :int],
|
394
|
-
[:set_int2, :RfcSetInt2, [:pointer, :pointer, :short, :pointer], :int],
|
395
|
-
[:set_num, :RfcSetNum, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
396
|
-
[:set_parameter_active, :RfcSetParameterActive, [:pointer, :pointer, :int, :pointer], :int],
|
397
|
-
[:set_string, :RfcSetString, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
398
|
-
[:set_structure, :RfcSetStructure, [:pointer, :pointer, :pointer, :pointer], :int],
|
399
|
-
[:set_table, :RfcSetTable, [:pointer, :pointer, :pointer, :pointer], :int],
|
400
|
-
[:set_time, :RfcSetTime, [:pointer, :pointer, :pointer, :pointer], :int],
|
401
|
-
#[:set_trace_dir, :RfcSetTraceDir, [:pointer, :pointer], :int],
|
402
|
-
#[:set_trace_encoding, :RfcSetTraceEncoding, [:pointer, :pointer], :int],
|
403
|
-
#[:set_trace_level, :RfcSetTraceLevel, [:pointer, :pointer, :uint, :pointer], :int],
|
404
|
-
[:set_type_length, :RfcSetTypeLength, [:pointer, :uint, :uint, :pointer], :int],
|
405
|
-
[:set_x_string, :RfcSetXString, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
406
|
-
[:snc_key_to_name, :RfcSNCKeyToName, [:pointer, :pointer, :uint, :pointer, :uint, :pointer], :int],
|
407
|
-
[:snc_name_to_key, :RfcSNCNameToKey, [:pointer, :pointer, :pointer, :pointer, :pointer], :int],
|
408
|
-
[:start_server, :RfcStartServer, [:int, :pointer, :pointer, :uint, :pointer], :pointer],
|
409
|
-
[:submit_transaction, :RfcSubmitTransaction, [:pointer, :pointer], :int],
|
410
|
-
[:utf8_to_sapuc, :RfcUTF8ToSAPUC, [:pointer, :uint, :pointer, :pointer, :pointer, :pointer], :int]
|
411
|
-
].each{|funcsig|
|
412
|
-
attach_function(funcsig[0], funcsig[1], funcsig[2], funcsig[3])
|
413
|
-
}
|
414
|
-
|
415
|
-
# Take Hash of connection parameters and returns FFI pointer to an array
|
416
|
-
# for passing to connection
|
417
|
-
# ---
|
418
|
-
# TODO - Ideally, this method should live in nwrfc.rb
|
419
|
-
def NWRFCLib.make_conn_params(params) #https://github.com/ffi/ffi/wiki/Structs
|
420
|
-
par = FFI::MemoryPointer.new(RFCConnParam, params.length)
|
421
|
-
pars = params.length.times.collect do |i|
|
422
|
-
RFCConnParam.new(par + i * RFCConnParam.size)
|
423
|
-
end
|
424
|
-
#TODO Optimize this method
|
425
|
-
tpar = params.to_a
|
426
|
-
params.length.times do |n|
|
427
|
-
# str = (tpar[n][0].to_s + "\0").encode("UTF-16LE")
|
428
|
-
pars[n][:name] = FFI::MemoryPointer.from_string(tpar[n][0].to_s.cU)
|
429
|
-
# str = (tpar[n][1].to_s + "\0").encode("UTF-16LE")
|
430
|
-
# str = str.encode("UTF-16LE")
|
431
|
-
pars[n][:value] = FFI::MemoryPointer.from_string(tpar[n][1].to_s.cU)
|
432
|
-
end
|
433
|
-
par
|
434
|
-
end
|
435
|
-
|
436
|
-
end
|
1
|
+
# Author:: Martin Ceronio martin.ceronio@infosize.co.za
|
2
|
+
# Copyright:: Copyright (c) 2012 Martin Ceronio
|
3
|
+
# License:: MIT and/or Creative Commons Attribution-ShareAlike
|
4
|
+
# SAP, Netweaver, RFC and other names referred to in this code
|
5
|
+
# are, or may be registered trademarks and the property of SAP, AG
|
6
|
+
# No ownership over any of these is asserted by Martin Ceronio
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'ffi'
|
10
|
+
require 'iconv'
|
11
|
+
|
12
|
+
RUBY_VERSION_18 = RUBY_VERSION[0..2] == "1.8"
|
13
|
+
|
14
|
+
# Provide an alias for FFI::MemoryPointer#read_int to `read_uint` in 1.8
|
15
|
+
# See http://stackoverflow.com/questions/9035661/ruby-ffi-memorypointer-read-int-present-in-1-9-but-not-1-8
|
16
|
+
# Probably not good to interpret an unsigned int as an int, but we don't expect to use it for big values
|
17
|
+
# that could result in sign conversion
|
18
|
+
# FIXME - This must go! Replace with calls to get_* defined in FFI::MemoryPointer
|
19
|
+
if RUBY_VERSION_18
|
20
|
+
FFI::MemoryPointer.class_eval{ alias :read_uint :read_int}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Enhancement to FFI::Pointer to be able to read a double-null terminated string,
|
24
|
+
# which would be returned e.g. by RfcGetVersion() in the SDK
|
25
|
+
# See http://stackoverflow.com/questions/9293307/ruby-ffi-ruby-1-8-reading-utf-16le-encoded-strings
|
26
|
+
module FFI
|
27
|
+
class Pointer
|
28
|
+
|
29
|
+
# Enhancement to FFI::Pointer to be able to read a double-null terminated string,
|
30
|
+
# which would be returned e.g. by RfcGetVersion() in the SDK
|
31
|
+
# See http://stackoverflow.com/questions/9293307/ruby-ffi-ruby-1-8-reading-utf-16le-encoded-strings
|
32
|
+
# It should be safe to call this on a Pointer within the context of the NW RFC SDK library,
|
33
|
+
# because all strings are supposed to be UTF-16LE encoded and double-null terminated
|
34
|
+
def read_string_dn(max=0)
|
35
|
+
cont_nullcount = 0
|
36
|
+
offset = 0
|
37
|
+
until cont_nullcount == 2
|
38
|
+
byte = get_bytes(offset,1)
|
39
|
+
cont_nullcount += 1 if byte == "\000"
|
40
|
+
cont_nullcount = 0 if byte != "\000"
|
41
|
+
offset += 1
|
42
|
+
end
|
43
|
+
get_bytes(0,offset+1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Enhancement to the String class to put string values into double-null
|
49
|
+
# terminated UTF16 little endian encoded strings as required by the NW RFC
|
50
|
+
# SDK function, which should work on Linux and Windows (and maybe other
|
51
|
+
# architectures, though the plan is not to support them)
|
52
|
+
#String.class_eval{define_method(:cU){ Iconv.conv("UTF-16LE", "UTF8", self+"\0") }}
|
53
|
+
class String
|
54
|
+
|
55
|
+
# Convert string from UTF-8 to doudble-null terminated UTF-16LE string
|
56
|
+
def cU
|
57
|
+
NWRFCLib::Cutf8_to_utf16le.iconv(self+"\0")
|
58
|
+
end
|
59
|
+
|
60
|
+
# Convert string from UTF-16LE to UTF-8 and trim trailing whitespace
|
61
|
+
def uC
|
62
|
+
NWRFCLib::Cutf16le_to_utf8.iconv(self).strip
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
# Enhancement to FFI::StructLayout::CharArray to add a get_str method that changes the
|
68
|
+
# string value of the character array by enforcing encoding of UTF-16LE (as used in NW RFC SDK)
|
69
|
+
# and strips off blanks at the end to return a readable String
|
70
|
+
class FFI::StructLayout::CharArray
|
71
|
+
def get_str
|
72
|
+
NWRFCLib::Cutf16le_to_utf8.iconv(self.to_ptr.read_string(self.size)).strip
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Library wrapper around NW RFC SDK shared library using RUBY-FFI
|
77
|
+
module NWRFCLib
|
78
|
+
|
79
|
+
Cutf8_to_utf16le = Iconv.new("UTF-16LE", "UTF-8")
|
80
|
+
Cutf16le_to_utf8 = Iconv.new("UTF-8", "UTF-16LE")
|
81
|
+
|
82
|
+
extend FFI::Library
|
83
|
+
ffi_lib 'sapnwrfc'
|
84
|
+
|
85
|
+
# Multiplier for providing correct byte size for String passed to RFC library
|
86
|
+
#@todo Make platform-dependent size based on RUBY_PLATFORM
|
87
|
+
B_SIZE = 2
|
88
|
+
|
89
|
+
RFC_RC = enum(
|
90
|
+
:RFC_OK,
|
91
|
+
:RFC_COMMUNICATION_FAILURE,
|
92
|
+
:RFC_LOGON_FAILURE,
|
93
|
+
:RFC_ABAP_RUNTIME_FAILURE,
|
94
|
+
:RFC_ABAP_MESSAGE,
|
95
|
+
:RFC_ABAP_EXCEPTION,
|
96
|
+
:RFC_CLOSED,
|
97
|
+
:RFC_CANCELED,
|
98
|
+
:RFC_TIMEOUT,
|
99
|
+
:RFC_MEMORY_INSUFFICIENT,
|
100
|
+
:RFC_VERSION_MISMATCH,
|
101
|
+
:RFC_INVALID_PROTOCOL,
|
102
|
+
:RFC_SERIALIZATION_FAILURE,
|
103
|
+
:RFC_INVALID_HANDLE,
|
104
|
+
:RFC_RETRY,
|
105
|
+
:RFC_EXTERNAL_FAILURE,
|
106
|
+
:RFC_EXECUTED,
|
107
|
+
:RFC_NOT_FOUND,
|
108
|
+
:RFC_NOT_SUPPORTED,
|
109
|
+
:RFC_ILLEGAL_STATE,
|
110
|
+
:RFC_INVALID_PARAMETER,
|
111
|
+
:RFC_CODEPAGE_CONVERSION_FAILURE,
|
112
|
+
:RFC_CONVERSION_FAILURE,
|
113
|
+
:RFC_BUFFER_TOO_SMALL,
|
114
|
+
:RFC_TABLE_MOVE_BOF,
|
115
|
+
:RFC_TABLE_MOVE_EOF,
|
116
|
+
:RFC_UNKNOWN_ERROR
|
117
|
+
)
|
118
|
+
|
119
|
+
RFC_ERROR_GROUP = enum(
|
120
|
+
:OK,
|
121
|
+
:ABAP_APPLICATION_FAILURE,
|
122
|
+
:ABAP_RUNTIME_FAILURE,
|
123
|
+
:LOGON_FAILURE,
|
124
|
+
:COMMUNICATION_FAILURE,
|
125
|
+
:EXTERNAL_RUNTIME_FAILURE,
|
126
|
+
:EXTERNAL_APPLICATION_FAILURE
|
127
|
+
)
|
128
|
+
|
129
|
+
RFC_DIRECTION = enum(
|
130
|
+
:RFC_IMPORT, 1,
|
131
|
+
:RFC_EXPORT, 2,
|
132
|
+
:RFC_CHANGING, 3,
|
133
|
+
:RFC_TABLES, 7
|
134
|
+
)
|
135
|
+
|
136
|
+
RFC_TYPE = enum(
|
137
|
+
:RFCTYPE_CHAR , 0,
|
138
|
+
:RFCTYPE_DATE , 1,
|
139
|
+
:RFCTYPE_BCD , 2,
|
140
|
+
:RFCTYPE_TIME , 3,
|
141
|
+
:RFCTYPE_BYTE , 4,
|
142
|
+
:RFCTYPE_TABLE , 5,
|
143
|
+
:RFCTYPE_NUM , 6,
|
144
|
+
:RFCTYPE_FLOAT , 7,
|
145
|
+
:RFCTYPE_INT , 8,
|
146
|
+
:RFCTYPE_INT2 , 9,
|
147
|
+
:RFCTYPE_INT1 , 10,
|
148
|
+
:RFCTYPE_NULL , 14,
|
149
|
+
:RFCTYPE_ABAPOBJECT, 16,
|
150
|
+
:RFCTYPE_STRUCTURE , 17,
|
151
|
+
:RFCTYPE_DECF16 , 23,
|
152
|
+
:RFCTYPE_DECF34 , 24,
|
153
|
+
:RFCTYPE_XMLDATA , 28,
|
154
|
+
:RFCTYPE_STRING , 29,
|
155
|
+
:RFCTYPE_XSTRING , 30,
|
156
|
+
:RFCTYPE_BOX, 31,
|
157
|
+
:RFCTYPE_GENERIC_BOX, 32,
|
158
|
+
:_RFCTYPE_max_value
|
159
|
+
)
|
160
|
+
|
161
|
+
# Connection parameter wrapper (struct RFC_CONNECTION_PARAMETER in sapnwrfc.h)
|
162
|
+
class RFCConnParam < FFI::Struct
|
163
|
+
layout :name, :pointer,
|
164
|
+
:value, :pointer
|
165
|
+
end
|
166
|
+
|
167
|
+
# Connection Details (struct RFC_ATTRIBUTES in sapnwrfc.h)
|
168
|
+
class RFCConnection < FFI::Struct
|
169
|
+
layout :dest, [:char, (64+1)*B_SIZE],
|
170
|
+
:host, [:char, (100+1)*B_SIZE],
|
171
|
+
:partnerHost, [:char, (100+1)*B_SIZE],
|
172
|
+
:sysNumber, [:char, (2+1)*B_SIZE],
|
173
|
+
:sysId, [:char, (8+1)*B_SIZE],
|
174
|
+
:client, [:char, (3+1)*B_SIZE],
|
175
|
+
:user, [:char, (12+1)*B_SIZE],
|
176
|
+
:language, [:char, (2+1)*B_SIZE],
|
177
|
+
:trace, [:char, (1+1)*B_SIZE],
|
178
|
+
:isoLanguage, [:char, (2+1)*B_SIZE],
|
179
|
+
:codepage, [:char, (4+1)*B_SIZE],
|
180
|
+
:partnerCodepage, [:char, (4+1)*B_SIZE],
|
181
|
+
:rfcRole, [:char, (1+1)*B_SIZE],
|
182
|
+
:type, [:char, (1+1)*B_SIZE],
|
183
|
+
:partnerType, [:char, (1+1)*B_SIZE],
|
184
|
+
:rel, [:char, (4+1)*B_SIZE],
|
185
|
+
:partnerRel, [:char, (4+1)*B_SIZE],
|
186
|
+
:kernelRel, [:char, (4+1)*B_SIZE],
|
187
|
+
:cpicConvId, [:char, (8+1)*B_SIZE],
|
188
|
+
:progName, [:char, (128+1)*B_SIZE],
|
189
|
+
:reserved, [:char, (86+1)*B_SIZE]
|
190
|
+
end
|
191
|
+
|
192
|
+
# Error info wrapper (struct RFC_ERROR_INFO in sapnwrfc.h)
|
193
|
+
class RFCError < FFI::Struct
|
194
|
+
layout :code, :int,
|
195
|
+
:group, :int,
|
196
|
+
:key, [:char, (128)*B_SIZE],
|
197
|
+
:message, [:char, (512)*B_SIZE],
|
198
|
+
:abapMsgClass, [:char, (20+1)*B_SIZE],
|
199
|
+
:abapMsgType, [:char, (1+1)*B_SIZE],
|
200
|
+
:abapMsgNumber, [:char, (3+1)*B_SIZE],
|
201
|
+
:abapMsgV1, [:char, (50+1)*B_SIZE],
|
202
|
+
:abapMsgV2, [:char, (50+1)*B_SIZE],
|
203
|
+
:abapMsgV3, [:char, (50+1)*B_SIZE],
|
204
|
+
:abapMsgV4, [:char, (50+1)*B_SIZE]
|
205
|
+
end
|
206
|
+
|
207
|
+
# Function Parameter Description (struct RFC_PARAMETER_DESC in sapnwrfc.h)
|
208
|
+
class RFCFuncParam < FFI::Struct
|
209
|
+
layout :name, [:char, (30+1)*B_SIZE],
|
210
|
+
:type, :int, #enum RFCTYPE
|
211
|
+
:direction, :int, #enum RFC_DIRECTION
|
212
|
+
:nucLength, :uint,
|
213
|
+
:ucLength, :uint,
|
214
|
+
:decimals, :uint,
|
215
|
+
:typeDescHandle, :pointer, #RFC_TYPE_DESC_HANDLE
|
216
|
+
:defaultValue, [:char, (30+1)*B_SIZE], #RFC_PARAMETER_DEFVALUE
|
217
|
+
:parameterText, [:char, (79+1)*B_SIZE], #RFC_PARAMETER_TEXT
|
218
|
+
:optional, :uchar, #RFC_BYTE
|
219
|
+
:extendedDescription, :pointer
|
220
|
+
end
|
221
|
+
|
222
|
+
class RFCFieldDesc < FFI::Struct
|
223
|
+
layout :name, [:char, (30+1)*B_SIZE],
|
224
|
+
:type, :int, #enum RFCTYPE
|
225
|
+
:nucLength, :uint,
|
226
|
+
:nucOffset, :uint,
|
227
|
+
:ucLength, :uint,
|
228
|
+
:ucOffset, :uint,
|
229
|
+
:decimals, :uint,
|
230
|
+
:typeDescHandle, :pointer, #RFC_TYPE_DESC_HANDLE
|
231
|
+
:extendedDescription, :pointer
|
232
|
+
end
|
233
|
+
|
234
|
+
class RFCDataContainer < FFI::Struct
|
235
|
+
layout :handle, :pointer
|
236
|
+
end
|
237
|
+
|
238
|
+
# typedef :RFCDataContainer, RFCStructureHandle
|
239
|
+
# typedef :RFCDataContainer, RFCTableHandle
|
240
|
+
|
241
|
+
class RFC_FUNCTION_DESC_HANDLE < FFI::Struct
|
242
|
+
layout :handle, :pointer
|
243
|
+
end
|
244
|
+
|
245
|
+
class RFC_TYPE_DESC_HANDLE < FFI::Struct
|
246
|
+
layout :handle, :pointer
|
247
|
+
end
|
248
|
+
|
249
|
+
class DATA_CONTAINER_HANDLE < FFI::Struct
|
250
|
+
layout :handle, :pointer
|
251
|
+
end
|
252
|
+
|
253
|
+
class RFC_DECF16 < FFI::Union
|
254
|
+
layout :bytes, [:uchar, 8],
|
255
|
+
:align, :double
|
256
|
+
end
|
257
|
+
|
258
|
+
# class SAP_MAX_ALIGN_T < FFI::Union
|
259
|
+
# layout :align1, :long,
|
260
|
+
# :align2, :double,
|
261
|
+
# :align3, :pointer,
|
262
|
+
# :align4,
|
263
|
+
# end
|
264
|
+
|
265
|
+
# class RFC_DECF34 < FFI::Union
|
266
|
+
# layout :bytes, [:uchar, 16],
|
267
|
+
# :align, 16
|
268
|
+
# end
|
269
|
+
|
270
|
+
#############################################################################################################
|
271
|
+
# ATTACH FUNCTIONS
|
272
|
+
# The functions here were obtained by parsing content from the doxygen files from the documentation
|
273
|
+
# accompanying the NW RFC SDK, and were tweaked here and there afterward. Most of them are actually not
|
274
|
+
# yet used in our NWRFC library, so calling them may not work. For best results, consult sapnwrfc.h from
|
275
|
+
# the SDK
|
276
|
+
#############################################################################################################
|
277
|
+
# Callback for function server (function implementation)
|
278
|
+
callback :funcimpl, [:pointer, :pointer, :pointer], :int
|
279
|
+
|
280
|
+
# Function mappings
|
281
|
+
[
|
282
|
+
[:add_exception, :RfcAddException, [:pointer, :pointer, :pointer], :int],
|
283
|
+
[:add_function_desc, :RfcAddFunctionDesc, [:pointer, :pointer, :pointer], :int],
|
284
|
+
[:add_parameter, :RfcAddParameter, [:pointer, :pointer, :pointer], :int],
|
285
|
+
[:add_type_desc, :RfcAddTypeDesc, [:pointer, :pointer, :pointer], :int],
|
286
|
+
[:add_type_field, :RfcAddTypeField, [:pointer, :pointer, :pointer], :int],
|
287
|
+
# @method append_new_row(table_handle, error_handle)
|
288
|
+
# @returns FFI::Pointer pointer to structure of new row
|
289
|
+
# calls RfcAppendNewRow()
|
290
|
+
[:append_new_row, :RfcAppendNewRow, [:pointer, :pointer], :pointer],
|
291
|
+
# @method append_row(table_handle, structure, error_handle)
|
292
|
+
# @returns Integer RC
|
293
|
+
# calls RfcAppendRow()
|
294
|
+
[:append_row, :RfcAppendRow, [:pointer, :pointer, :pointer], :int],
|
295
|
+
[:clone_structure, :RfcCloneStructure, [:pointer, :pointer], :pointer],
|
296
|
+
[:clone_table, :RfcCloneTable, [:pointer, :pointer], :pointer],
|
297
|
+
[:close_connection, :RfcCloseConnection, [:pointer, :pointer], :int],
|
298
|
+
[:confirm_transaction, :RfcConfirmTransaction, [:pointer, :pointer], :int],
|
299
|
+
[:create_function, :RfcCreateFunction, [:pointer, :pointer], :pointer],
|
300
|
+
[:create_function_desc, :RfcCreateFunctionDesc, [:pointer, :pointer], :pointer],
|
301
|
+
[:create_structure, :RfcCreateStructure, [:pointer, :pointer], :pointer],
|
302
|
+
[:create_table, :RfcCreateTable, [:pointer, :pointer], :pointer],
|
303
|
+
[:create_transaction, :RfcCreateTransaction, [:pointer, :pointer, :pointer, :pointer], :pointer],
|
304
|
+
[:create_type_desc, :RfcCreateTypeDesc, [:pointer, :pointer], :pointer],
|
305
|
+
[:delete_all_rows, :RfcDeleteAllRows, [:pointer, :pointer], :int],
|
306
|
+
[:delete_current_row, :RfcDeleteCurrentRow, [:pointer, :pointer], :int],
|
307
|
+
[:describe_function, :RfcDescribeFunction, [:pointer, :pointer], :pointer],
|
308
|
+
[:describe_type, :RfcDescribeType, [:pointer, :pointer], :pointer],
|
309
|
+
[:destroy_function, :RfcDestroyFunction, [:pointer, :pointer], :int],
|
310
|
+
[:destroy_function_desc, :RfcDestroyFunctionDesc, [:pointer, :pointer], :int],
|
311
|
+
[:destroy_structure, :RfcDestroyStructure, [:pointer, :pointer], :int],
|
312
|
+
[:destroy_table, :RfcDestroyTable, [:pointer, :pointer], :int],
|
313
|
+
[:destroy_transaction, :RfcDestroyTransaction, [:pointer, :pointer], :int],
|
314
|
+
[:destroy_type_desc, :RfcDestroyTypeDesc, [:pointer, :pointer], :int],
|
315
|
+
[:enable_basxml, :RfcEnableBASXML, [:pointer, :pointer], :int],
|
316
|
+
[:get_bytes, :RfcGetBytes, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
317
|
+
[:get_cached_function_desc, :RfcGetCachedFunctionDesc, [:pointer, :pointer, :pointer], :pointer],
|
318
|
+
[:get_cached_type_desc, :RfcGetCachedTypeDesc, [:pointer, :pointer, :pointer], :pointer],
|
319
|
+
[:get_chars, :RfcGetChars, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
320
|
+
[:get_connection_attributes, :RfcGetConnectionAttributes, [:pointer, :pointer, :pointer], :int],
|
321
|
+
[:get_current_row, :RfcGetCurrentRow, [:pointer, :pointer], :pointer],
|
322
|
+
[:get_date, :RfcGetDate, [:pointer, :pointer, :pointer, :pointer], :int],
|
323
|
+
[:get_dec_f16, :RfcGetDecF16, [:pointer, :pointer, :pointer, :pointer], :int],
|
324
|
+
[:get_dec_f34, :RfcGetDecF34, [:pointer, :pointer, :pointer, :pointer], :int],
|
325
|
+
[:get_direction_as_string, :RfcGetDirectionAsString, [:pointer], :pointer],
|
326
|
+
[:get_exception_count, :RfcGetExceptionCount, [:pointer, :pointer, :pointer], :int],
|
327
|
+
[:get_exception_desc_by_index, :RfcGetExceptionDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
328
|
+
[:get_exception_desc_by_name, :RfcGetExceptionDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
329
|
+
[:get_field_count, :RfcGetFieldCount, [:pointer, :pointer, :pointer], :int],
|
330
|
+
[:get_field_desc_by_index, :RfcGetFieldDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
331
|
+
[:get_field_desc_by_name, :RfcGetFieldDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
332
|
+
[:get_float, :RfcGetFloat, [:pointer, :pointer, :pointer, :pointer], :int],
|
333
|
+
[:get_function_desc, :RfcGetFunctionDesc, [:pointer, :pointer, :pointer], :pointer],
|
334
|
+
[:get_function_name, :RfcGetFunctionName, [:pointer, :pointer, :pointer], :int],
|
335
|
+
[:get_int, :RfcGetInt, [:pointer, :pointer, :pointer, :pointer], :int],
|
336
|
+
[:get_int1, :RfcGetInt1, [:pointer, :pointer, :pointer, :pointer], :int],
|
337
|
+
[:get_int2, :RfcGetInt2, [:pointer, :pointer, :pointer, :pointer], :int],
|
338
|
+
[:get_num, :RfcGetNum, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
339
|
+
[:get_parameter_count, :RfcGetParameterCount, [:pointer, :pointer, :pointer], :int],
|
340
|
+
[:get_parameter_desc_by_index, :RfcGetParameterDescByIndex, [:pointer, :uint, :pointer, :pointer], :int],
|
341
|
+
[:get_parameter_desc_by_name, :RfcGetParameterDescByName, [:pointer, :pointer, :pointer, :pointer], :int],
|
342
|
+
[:get_partner_snc_key, :RfcGetPartnerSNCKey, [:pointer, :pointer, :pointer, :pointer], :int],
|
343
|
+
[:get_partner_snc_name, :RfcGetPartnerSNCName, [:pointer, :pointer, :uint, :pointer], :int],
|
344
|
+
[:get_partner_sso_ticket, :RfcGetPartnerSSOTicket, [:pointer, :pointer, :pointer, :pointer], :int],
|
345
|
+
[:get_rc_as_string, :RfcGetRcAsString, [:pointer], :pointer],
|
346
|
+
[:get_row_count, :RfcGetRowCount, [:pointer, :pointer, :pointer], :int],
|
347
|
+
[:get_string, :RfcGetString, [:pointer, :pointer, :pointer, :uint, :pointer, :pointer], :int],
|
348
|
+
[:get_string_length, :RfcGetStringLength, [:pointer, :pointer, :pointer, :pointer], :int],
|
349
|
+
[:get_structure, :RfcGetStructure, [:pointer, :pointer, :pointer, :pointer], :int],
|
350
|
+
[:get_table, :RfcGetTable, [:pointer, :pointer, :pointer, :pointer], :int],
|
351
|
+
[:get_time, :RfcGetTime, [:pointer, :pointer, :pointer, :pointer], :int],
|
352
|
+
[:get_transaction_id, :RfcGetTransactionID, [:pointer, :pointer, :pointer], :int],
|
353
|
+
[:get_type_as_string, :RfcGetTypeAsString, [:pointer], :pointer],
|
354
|
+
[:get_type_desc, :RfcGetTypeDesc, [:pointer, :pointer, :pointer], :pointer],
|
355
|
+
[:get_type_length, :RfcGetTypeLength, [:pointer, :pointer, :pointer, :pointer], :int],
|
356
|
+
[:get_type_name, :RfcGetTypeName, [:pointer, :pointer, :pointer], :int],
|
357
|
+
[:get_version, :RfcGetVersion, [:pointer, :pointer, :pointer], :pointer],
|
358
|
+
[:get_x_string, :RfcGetXString, [:pointer, :pointer, :pointer, :uint, :pointer, :pointer], :int],
|
359
|
+
[:init, :RfcInit, [:pointer], :int],
|
360
|
+
[:insert_new_row, :RfcInsertNewRow, [:pointer, :pointer], :pointer],
|
361
|
+
[:insert_row, :RfcInsertRow, [:pointer, :pointer, :pointer], :int],
|
362
|
+
[:install_generic_server_function, :RfcInstallGenericServerFunction, [:pointer, :pointer, :pointer], :int],
|
363
|
+
[:install_server_function, :RfcInstallServerFunction, [:pointer, :pointer, :funcimpl, :pointer], :int],
|
364
|
+
[:install_transaction_handlers, :RfcInstallTransactionHandlers, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int],
|
365
|
+
[:invoke, :RfcInvoke, [:pointer, :pointer, :pointer], :int],
|
366
|
+
[:invoke_in_transaction, :RfcInvokeInTransaction, [:pointer, :pointer, :pointer], :int],
|
367
|
+
[:is_basxml_supported, :RfcIsBASXMLSupported, [:pointer, :pointer, :pointer], :int],
|
368
|
+
#[:is_connection_handle_valid, :RfcIsConnectionHandleValid, [:pointer, :pointer, :pointer], :int],
|
369
|
+
[:is_parameter_active, :RfcIsParameterActive, [:pointer, :pointer, :pointer, :pointer], :int],
|
370
|
+
[:listen_and_dispatch, :RfcListenAndDispatch, [:pointer, :int, :pointer], :int],
|
371
|
+
[:move_to, :RfcMoveTo, [:pointer, :uint, :pointer], :int],
|
372
|
+
[:move_to_first_row, :RfcMoveToFirstRow, [:pointer, :pointer], :int],
|
373
|
+
[:move_to_last_row, :RfcMoveToLastRow, [:pointer, :pointer], :int],
|
374
|
+
[:move_to_next_row, :RfcMoveToNextRow, [:pointer, :pointer], :int],
|
375
|
+
[:move_to_previous_row, :RfcMoveToPreviousRow, [:pointer, :pointer], :int],
|
376
|
+
[:open_connection, :RfcOpenConnection, [:pointer, :uint, :pointer], :pointer],
|
377
|
+
[:ping, :RfcPing, [:pointer, :pointer], :int],
|
378
|
+
[:register_server, :RfcRegisterServer, [:pointer, :uint, :pointer], :pointer],
|
379
|
+
[:reload_ini_file, :RfcReloadIniFile, [:pointer], :int],
|
380
|
+
# [:remove_function_desc, :RfcRemoveFunctionDesc, [:pointer, :pointer, :pointer], :int],
|
381
|
+
# [:remove_type_desc, :RfcRemoveTypeDesc, [:pointer, :pointer, :pointer], :int],
|
382
|
+
[:reset_server_context, :RfcResetServerContext, [:pointer, :pointer], :int],
|
383
|
+
[:sapuc_to_utf8, :RfcSAPUCToUTF8, [:pointer, :uint, :pointer, :pointer, :pointer, :pointer], :int],
|
384
|
+
[:set_bytes, :RfcSetBytes, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
385
|
+
[:set_chars, :RfcSetChars, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
386
|
+
[:set_date, :RfcSetDate, [:pointer, :pointer, :pointer, :pointer], :int],
|
387
|
+
#[:set_dec_f16, :RfcSetDecF16, [:pointer, :pointer, :pointer, :pointer], :int],
|
388
|
+
[:set_dec_f16, :RfcSetDecF16, [:pointer, :pointer, RFC_DECF16.by_value, :pointer], :int],
|
389
|
+
[:set_dec_f34, :RfcSetDecF34, [:pointer, :pointer, :pointer, :pointer], :int],
|
390
|
+
[:set_float, :RfcSetFloat, [:pointer, :pointer, :double, :pointer], :int],
|
391
|
+
[:set_ini_path, :RfcSetIniPath, [:pointer, :pointer], :int],
|
392
|
+
[:set_int, :RfcSetInt, [:pointer, :pointer, :long, :pointer], :int],
|
393
|
+
[:set_int1, :RfcSetInt1, [:pointer, :pointer, :uint8, :pointer], :int],
|
394
|
+
[:set_int2, :RfcSetInt2, [:pointer, :pointer, :short, :pointer], :int],
|
395
|
+
[:set_num, :RfcSetNum, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
396
|
+
[:set_parameter_active, :RfcSetParameterActive, [:pointer, :pointer, :int, :pointer], :int],
|
397
|
+
[:set_string, :RfcSetString, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
398
|
+
[:set_structure, :RfcSetStructure, [:pointer, :pointer, :pointer, :pointer], :int],
|
399
|
+
[:set_table, :RfcSetTable, [:pointer, :pointer, :pointer, :pointer], :int],
|
400
|
+
[:set_time, :RfcSetTime, [:pointer, :pointer, :pointer, :pointer], :int],
|
401
|
+
#[:set_trace_dir, :RfcSetTraceDir, [:pointer, :pointer], :int],
|
402
|
+
#[:set_trace_encoding, :RfcSetTraceEncoding, [:pointer, :pointer], :int],
|
403
|
+
#[:set_trace_level, :RfcSetTraceLevel, [:pointer, :pointer, :uint, :pointer], :int],
|
404
|
+
[:set_type_length, :RfcSetTypeLength, [:pointer, :uint, :uint, :pointer], :int],
|
405
|
+
[:set_x_string, :RfcSetXString, [:pointer, :pointer, :pointer, :uint, :pointer], :int],
|
406
|
+
[:snc_key_to_name, :RfcSNCKeyToName, [:pointer, :pointer, :uint, :pointer, :uint, :pointer], :int],
|
407
|
+
[:snc_name_to_key, :RfcSNCNameToKey, [:pointer, :pointer, :pointer, :pointer, :pointer], :int],
|
408
|
+
[:start_server, :RfcStartServer, [:int, :pointer, :pointer, :uint, :pointer], :pointer],
|
409
|
+
[:submit_transaction, :RfcSubmitTransaction, [:pointer, :pointer], :int],
|
410
|
+
[:utf8_to_sapuc, :RfcUTF8ToSAPUC, [:pointer, :uint, :pointer, :pointer, :pointer, :pointer], :int]
|
411
|
+
].each{|funcsig|
|
412
|
+
attach_function(funcsig[0], funcsig[1], funcsig[2], funcsig[3], :blocking => true)
|
413
|
+
}
|
414
|
+
|
415
|
+
# Take Hash of connection parameters and returns FFI pointer to an array
|
416
|
+
# for passing to connection
|
417
|
+
# ---
|
418
|
+
# TODO - Ideally, this method should live in nwrfc.rb
|
419
|
+
def NWRFCLib.make_conn_params(params) #https://github.com/ffi/ffi/wiki/Structs
|
420
|
+
par = FFI::MemoryPointer.new(RFCConnParam, params.length)
|
421
|
+
pars = params.length.times.collect do |i|
|
422
|
+
RFCConnParam.new(par + i * RFCConnParam.size)
|
423
|
+
end
|
424
|
+
#TODO Optimize this method
|
425
|
+
tpar = params.to_a
|
426
|
+
params.length.times do |n|
|
427
|
+
# str = (tpar[n][0].to_s + "\0").encode("UTF-16LE")
|
428
|
+
pars[n][:name] = FFI::MemoryPointer.from_string(tpar[n][0].to_s.cU)
|
429
|
+
# str = (tpar[n][1].to_s + "\0").encode("UTF-16LE")
|
430
|
+
# str = str.encode("UTF-16LE")
|
431
|
+
pars[n][:value] = FFI::MemoryPointer.from_string(tpar[n][1].to_s.cU)
|
432
|
+
end
|
433
|
+
par
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|