vistarpc4r 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,6 +1,16 @@
1
- = vistarpc4r
1
+ = VistaRPC4r
2
+ VistaRPC4r provides a Ruby interface to the Veterans Administration's almost opensource electronic health record called VistA.
3
+ The VistA architecture is old school client/server. The typical client is a Windows based GUI. The typical server is an Linux or Windows based server. The server is primarily written in MUMPS or M.
4
+ VistA provides an RPC-style interface to its core functions using TCP sockets and a custom message format
5
+ VistaRPC4r implements the socket layer and message format and provides methods which can initiate RPC requests and returns the RPC output.
6
+ The VistA server requires each connection to have a username/password authentication.
2
7
 
3
- Description goes here.
8
+ This gem has been tested with Medsphere's OpenVista server distribution.
9
+
10
+ Future topics for this document
11
+ * More detail on how to use
12
+ * Detailed examples
13
+ * links to more information
4
14
 
5
15
  == Contributing to vistarpc4r
6
16
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/examples/test.rb CHANGED
@@ -1,20 +1,20 @@
1
- require 'rpc_broker_connection'
1
+ require './../lib/vistarpc4r/rpc_response'
2
+ require './../lib/vistarpc4r/vista_rpc'
3
+ require './../lib/vistarpc4r/rpc_broker_connection'
2
4
 
3
5
  #broker = RPCBrokerConnection.new('192.168.1.20', 9270, 'sys.admin', 'vista!123')
4
- broker = RPCBrokerConnection.new('openvista.medsphere.org', 9201, 'PU1234', 'PU1234!!')
6
+ broker = VistaRPC4r::RPCBrokerConnection.new('openvista.medsphere.org', 9201, 'PU1234', 'PU1234!!')
5
7
 
6
8
  broker.connect
7
9
  broker.setContext('OR CPRS GUI CHART')
8
10
 
9
- wardsrpc = VistaRPC.new("ORQPT WARDS", RPCResponse::ARRAY)
10
- wardsresponse = broker.execute(wardsrpc)
11
- wardsresponse.value.each do |ward|
11
+ patient_ien = "4"
12
+ wardsarray = broker.call_a("ORQPT WARDS")
13
+ wardsarray.each do |ward|
12
14
  a = ward.split("^")
13
15
  puts "Ward:" + a[1]
14
- wardrpc = VistaRPC.new("ORQPT WARD PATIENTS", RPCResponse::ARRAY)
15
- wardrpc.params[0]=a[0] #ward ien
16
- wardresponse = broker.execute(wardrpc)
17
- wardresponse.value.each do |patient|
16
+ wardarray = broker.call_a("ORQPT WARD PATIENTS", [a[0]]) # ward ien
17
+ wardarray.each do |patient|
18
18
  b = patient.split("^")
19
19
  puts b[0] + ":" + b[1]
20
20
  end
@@ -22,63 +22,49 @@ end
22
22
 
23
23
  # Problem list
24
24
  puts "Problem list-------------------------------------"
25
- patientrpc = VistaRPC.new("ORQQPL LIST", RPCResponse::ARRAY)
26
- patientrpc.params[0]="4" #patient ien
27
- patientrpc.params[1]="A" #patient ien
28
- patientresponse = broker.execute(patientrpc)
29
- patientresponse.value.each do |d|
25
+ patientarray = broker.call_a("ORQQPL LIST", [patient_ien, "A"])
26
+ patientarray.each do |d|
30
27
  puts d
31
28
  end
32
29
 
33
30
  # Medications
34
31
  puts "Medications-------------------------------------"
35
- patientrpc = VistaRPC.new("ORWPS COVER", RPCResponse::ARRAY)
36
- patientrpc.params[0]="4" #patient ien
37
- patientresponse = broker.execute(patientrpc)
38
- patientresponse.value.each do |d|
32
+ patientarray = broker.call_a("ORWPS COVER", [patient_ien])
33
+ patientarray.each do |d|
39
34
  puts d
40
35
  end
41
36
 
42
37
  #Labs
43
38
  puts "Labs-------------------------------------"
44
- patientrpc = VistaRPC.new("ORWCV LAB", RPCResponse::ARRAY)
45
- patientrpc.params[0]="4" #patient ien
46
- patientresponse = broker.execute(patientrpc)
47
- patientresponse.value.each do |d|
39
+ patientarray = broker.call_a("ORWCV LAB", [patient_ien])
40
+ patientarray.each do |d|
48
41
  puts d
49
42
  end
50
43
 
51
44
  # Vitals
52
45
  puts "Vitals-------------------------------------"
53
- patientrpc = VistaRPC.new("ORQQVI VITALS", RPCResponse::ARRAY)
54
- patientrpc.params[0]="4" #patient ien
55
- patientresponse = broker.execute(patientrpc)
56
- patientresponse.value.each do |d|
46
+ patientarray = broker.call_a("ORQQVI VITALS", [patient_ien])
47
+ patientarray.each do |d|
57
48
  puts d
58
49
  end
59
50
 
60
51
  # Demo
61
52
  puts "Demographics-------------------------------------"
62
- patientrpc = VistaRPC.new("ORWPT PTINQ", RPCResponse::ARRAY)
63
- patientrpc.params[0]="4" #patient ien
64
- patientresponse = broker.execute(patientrpc)
65
- patientresponse.value.each do |d|
53
+ patientarray = broker.call_a("ORWPT PTINQ", [patient_ien])
54
+ patientarray.each do |d|
66
55
  puts d
67
56
  end
68
57
 
69
58
  #visits
70
59
  puts "Visits-------------------------------------"
71
- patientrpc = VistaRPC.new("ORWCV VST", RPCResponse::ARRAY)
72
- patientrpc.params[0]="4" #patient ien
73
- patientresponse = broker.execute(patientrpc)
74
- patientresponse.value.each do |d|
60
+ patientarray = broker.call_a("ORWCV VST", [patient_ien])
61
+ patientarray.each do |d|
75
62
  puts d
76
63
  end
77
64
 
78
65
  #providers
79
66
  puts "Providers---------------------------------"
80
- patientrpc = VistaRPC.new("ORQPT PROVIDERS", RPCResponse::ARRAY)
81
- patientresponse = broker.execute(patientrpc)
82
- patientresponse.value.each do |d|
67
+ patientarray = broker.call_a("ORQPT PROVIDERS")
68
+ patientarray.each do |d|
83
69
  puts d
84
70
  end
@@ -3,427 +3,476 @@ require 'socket'
3
3
  #require 'vista_rpc'
4
4
 
5
5
  module VistaRPC4r
6
- class RPCBrokerConnection
7
- # Header chunk types
8
- CHUNK_TYPE_HEADER = "1"
9
- CHUNK_TYPE_RPC = "2"
10
- CHUNK_TYPE_SECURITY = "3"
11
- CHUNK_TYPE_COMMAND = "4"
12
- CHUNK_TYPE_DATA = "5"
13
- XWB_HEADER = "[XWB]"
14
- # Header and protocol info
15
- VISTA_RPC_VERSION = "1"
16
- VISTA_RPC_TYPE_CMD = "0"
17
- VISTA_RPC_TYPE_RPC = "1"
18
- VISTA_RPC_LENV = 3
19
- VISTA_RPC_LENV_STR = "3"
20
- VISTA_RPC_RETURN_DATA = "0"
21
- VISTA_RPC_NO_RETURN_DATA = "1"
22
- END_MARKER = 4
23
- # Parameter types
24
- PARAM_LITERAL_MARKER = "0"
25
- PARAM_REFERENCE_MARKER = "1"
26
- PARAM_LIST_MARKER = "2"
27
- PARAM_GLOBAL_MARKER = "3"
28
- PARAM_EMPTY_MARKER = "4"
29
-
30
- def initialize(host, port, access, verify, debug=FALSE)
31
- @sentConnect = false
32
- @signedOn = false
33
- @host=host
34
- @port=port
35
- @access=access
36
- @verify=verify
37
- @debug=debug
38
- @token=nil
39
- @socket = nil
40
- @encryptedAV = nil
41
- @writeBuffer = String.new
42
- @duz = "0"
43
- @currentContext = nil
44
- end
45
-
46
- def connect
47
- retVal = true
48
- if isConnected()
49
- puts " already connected, closing first"
50
- close
6
+ class RPCBrokerConnection
7
+ # Header chunk types
8
+ CHUNK_TYPE_HEADER = "1"
9
+ CHUNK_TYPE_RPC = "2"
10
+ CHUNK_TYPE_SECURITY = "3"
11
+ CHUNK_TYPE_COMMAND = "4"
12
+ CHUNK_TYPE_DATA = "5"
13
+ XWB_HEADER = "[XWB]"
14
+ # Header and protocol info
15
+ VISTA_RPC_VERSION = "1"
16
+ VISTA_RPC_TYPE_CMD = "0"
17
+ VISTA_RPC_TYPE_RPC = "1"
18
+ VISTA_RPC_LENV = 3
19
+ VISTA_RPC_LENV_STR = "3"
20
+ VISTA_RPC_RETURN_DATA = "0"
21
+ VISTA_RPC_NO_RETURN_DATA = "1"
22
+ END_MARKER = 4
23
+ # Parameter types
24
+ PARAM_LITERAL_MARKER = "0"
25
+ PARAM_REFERENCE_MARKER = "1"
26
+ PARAM_LIST_MARKER = "2"
27
+ PARAM_GLOBAL_MARKER = "3"
28
+ PARAM_EMPTY_MARKER = "4"
29
+
30
+ public
31
+
32
+ def initialize(host, port, access, verify, debug=FALSE)
33
+ @sentConnect = false
34
+ @signedOn = false
35
+ @host=host
36
+ @port=port
37
+ @access=access
38
+ @verify=verify
39
+ @debug=debug
40
+ @token=nil
41
+ @socket = nil
42
+ @encryptedAV = nil
43
+ @writeBuffer = String.new
44
+ @duz = "0"
45
+ @currentContext = nil
51
46
  end
52
- @socket = TCPSocket.open(@host, @port) # Connect
53
- # socket.setTcpNoDelay(true)
54
- tcpConnect = VistaRPC.new("TCPConnect", RPCResponse::SINGLE_VALUE, true)
55
- tcpConnect.params[0]= @socket.addr[4] # local IP address
56
- tcpConnect.params[1]= "0" # callback port ?
57
- tcpConnect.params[2]= "OVID"
58
- connectResponse = execute(tcpConnect)
59
- if (connectResponse == nil || connectResponse.value == nil || connectResponse.value == "reject")
60
- puts "Handshake error"
47
+
48
+ def connect
49
+ retVal = true
50
+ if isConnected()
51
+ puts " already connected, closing first"
52
+ close
53
+ end
54
+ @socket = TCPSocket.open(@host, @port) # Connect
55
+ # socket.setTcpNoDelay(true)
56
+ tcpConnect = VistaRPC.new("TCPConnect", RPCResponse::SINGLE_VALUE, true)
57
+ tcpConnect.params[0]= @socket.addr[4] # local IP address
58
+ tcpConnect.params[1]= "0" # callback port ?
59
+ tcpConnect.params[2]= "OVID"
60
+ connectResponse = execute(tcpConnect)
61
+ if (connectResponse == nil || connectResponse.value == nil || connectResponse.value == "reject")
62
+ puts "Handshake error"
63
+ end
64
+ if (connectResponse.error_message != nil)
65
+ puts "RPC Error: " + connectResponse.error_message
66
+ end
67
+ @sentConnect = true
68
+
69
+ signOn()
70
+ retVal = logIn()
71
+ return retVal
61
72
  end
62
- if (connectResponse.error_message != nil)
63
- puts "RPC Error: " + connectResponse.error_message
73
+
74
+ def close()
75
+ if isConnected()
76
+ if @sentConnect
77
+ @sentConnect = false
78
+ bye = VistaRPC.new("#BYE#", RPCResponse::SINGLE_VALUE, true)
79
+ execute(bye)
80
+ @socket.close()
81
+ @socket = nil
82
+ end
83
+ end
64
84
  end
65
- @sentConnect = true
66
85
 
67
- signOn()
68
- retVal = logIn()
69
- return retVal
70
- end
71
-
72
- def signOn()
73
- signonResponse = execute(VistaRPC.new("XUS SIGNON SETUP", RPCResponse::ARRAY))
74
- if (signonResponse == nil || signonResponse.error_message != nil)
75
- puts "XUS SIGNON SETUP failed"
86
+ def isConnected()
87
+ return @socket != nil
76
88
  end
77
- @signedOn = true
78
- end
79
-
80
- def logIn()
81
- xusAvCode = VistaRPC.new("XUS AV CODE", RPCResponse::ARRAY)
82
- @duz = "0"
83
89
 
84
- if (@encryptedAV == nil)
85
- if (@token != nil)
86
- @encryptedAV = @token
87
- else
88
- @encryptedAV = xusAvCode.encrypt(@access + ";" + @verify)
90
+ def execute(rpc)
91
+ retVal = executeOnce(rpc)
92
+ if (retVal == nil && @signedOn)
93
+ #reconnect
94
+ if (rpc.name == "#BYE#")
95
+ # We're disconnecting anyway
96
+ return nil
97
+ end
98
+ # attempt to log back on
99
+ if (connect())
100
+ if (@currentContext != nil)
101
+ context = !currentContext
102
+ @currentContext = nil
103
+ setContext(context)
104
+ end
105
+ retVal = executeOnce(rpc)
106
+ end
89
107
  end
90
-
91
- end
92
- xusAvCode.params[0]= @encryptedAV
93
- response = execute(xusAvCode)
94
- if (response == nil)
95
- return false
108
+ if (retVal == nil)
109
+ puts "Lost connection to server"
110
+ end
111
+ return retVal
96
112
  end
97
- hasErrors = (response.error_message != nil)
98
- answer = response.value
99
- if (!hasErrors)
100
- if (answer.length == 0)
101
- hasErrors = true
102
- else
103
- hasErrors = answer[0]== "0"
113
+
114
+ # Call the RPC function
115
+ # rpcname = String containing name of RPC
116
+ # args = Array of arguments 0-based
117
+ # response type = one of the types in RPCResponse
118
+ # returns RPCResponse
119
+ def call(rpcname, responsetype, args=nil)
120
+ rpc = VistaRPC.new(rpcname, responsetype)
121
+ if !args.nil?
122
+ rpc.params = args
104
123
  end
124
+ rpcresponse = execute(rpc)
125
+ return rpcresponse
105
126
  end
106
- if (hasErrors)
107
- brokerInfo = extractBrokerErrorInfo(response)
108
- puts("Access denied: " + brokerInfo)
109
- else
110
- duz = answer[0]
127
+
128
+ # Call the RPC function expecting to receive a string or SINGLE_VALUE
129
+ # rpcname = String containing name of RPC
130
+ # args = Array of arguments 0-based
131
+ # returns String
132
+ def call_s(rpcname, args=nil)
133
+ rpc = VistaRPC.new(rpcname, RPCResponse::SINGLE_VALUE)
134
+ if !args.nil?
135
+ rpc.params = args
136
+ end
137
+ rpcresponse = execute(rpc)
138
+ return rpcresponse.value
111
139
  end
112
- return true
113
- end
114
140
 
115
-
116
- def extractBrokerErrorInfo(response)
117
- sb = String.new
118
- # if (response != nil && response.getArray() != nil)
119
- # response.getArray.each do |answer|
120
- # if (answer != nil && answer.length > 0 && !answer.matches("^(\\d+)$"))
121
- # if (sb.length() != 0) # sb is Stringbuilder
122
- # sb.append(" : ")
123
- # sb.append(answer)
124
- # end
125
- # end
126
- # end
127
- # end
128
- return sb
129
- end
130
-
131
- def close()
132
- if isConnected()
133
- if @sentConnect
134
- @sentConnect = false
135
- bye = VistaRPC.new("#BYE#", RPCResponse::SINGLE_VALUE, true)
136
- execute(bye)
137
- @socket.close()
138
- @socket = nil
141
+ # Call the RPC function expecting to receive a array of string ARRAY
142
+ # rpcname = String containing name of RPC
143
+ # args = Array of arguments 0-based
144
+ # returns Array
145
+ def call_a(rpcname, args=nil)
146
+ rpc = VistaRPC.new(rpcname, RPCResponse::ARRAY)
147
+ if !args.nil?
148
+ rpc.params = args
139
149
  end
150
+ rpcresponse = execute(rpc)
151
+ return rpcresponse.value
140
152
  end
141
- end
142
-
143
- def isConnected()
144
- return @socket != nil
145
- end
146
-
147
- # public String buildSubscript(String string) {
148
- # return /* "\r" + */ string
149
- # }
150
-
151
- def executeOnce(rpc)
152
- retVal = nil
153
- writeProtocol()
154
- writeCommand(rpc)
155
- writeParams(rpc)
156
- write(END_MARKER)
157
- if (flush())
158
- retVal = getResponse(rpc.type)
159
- if @debug
160
- puts "<Response> " + retVal.to_s + "</Response>"
153
+
154
+
155
+ def setContext(context)
156
+ if (context == @currentContext)
157
+ puts "context is already set to " + context + "..."
158
+ return
161
159
  end
160
+ if (@currentContext != nil)
161
+ puts "changing context from " + currentContext + " to " + context
162
+ end
163
+
164
+ puts "Setting context to: " + context
165
+ xwbCreateContext = VistaRPC.new("XWB CREATE CONTEXT", RPCResponse::SINGLE_VALUE)
166
+ encryptedContext = xwbCreateContext.encrypt(context)
167
+ xwbCreateContext.params[0] = encryptedContext
168
+ response = execute(xwbCreateContext)
169
+ if (response == nil || response.error_message != nil)
170
+ puts "XWB CREATE CONTEXT failed: " + response.error_message
171
+ end
172
+ @currentContext = context
162
173
  end
163
- return retVal
164
- end
165
-
166
- def write(data)
167
- @writeBuffer << data
168
- end
169
-
170
- def writeProtocol
171
- write(XWB_HEADER + VISTA_RPC_VERSION + VISTA_RPC_TYPE_RPC + VISTA_RPC_LENV_STR + VISTA_RPC_RETURN_DATA)
172
- end
173
-
174
- def writeCommand(rpc)
175
- if (rpc.isCommand)
176
- write(CHUNK_TYPE_COMMAND)
177
- else
178
- write(CHUNK_TYPE_RPC)
179
- writeSPack(VISTA_RPC_VERSION)
174
+
175
+
176
+ def getDUZ
177
+ return @duz
180
178
  end
181
- writeSPack(rpc.name)
182
- end
183
-
184
- def writeSPack(value)
185
- write(value.length) # integer
186
- write(value)
187
- end
188
-
189
- def writeLPack(string)
190
- len = sprintf("%03i", string.length) # 0-padded 3 place string of integer
191
- #Integer.toString(string.length())
192
- # while (len.length() < VISTA_RPC_LENV) {
193
- # len = "0" + len
194
- # }
195
- write(len) # "003"
196
- write(string)
197
- end
198
-
199
- def writeParams(rpc)
200
- write(CHUNK_TYPE_DATA)
201
-
202
- params = rpc.params # Hash integer => object
203
- if (!params.empty?)
204
- params.each do |param|
205
- if param.nil?
206
- writeEmptyParam()
207
- elsif param.class == String
208
- writeStringParam(param)
209
- elsif param.class == Array
210
- writeArrayParam(param)
211
- else
212
- writeEmptyParam()
213
- end
179
+
180
+
181
+
182
+ private
183
+
184
+ def signOn()
185
+ signonResponse = execute(VistaRPC.new("XUS SIGNON SETUP", RPCResponse::ARRAY))
186
+ if (signonResponse == nil || signonResponse.error_message != nil)
187
+ puts "XUS SIGNON SETUP failed"
214
188
  end
215
- else
216
- writeEmptyParam()
189
+ @signedOn = true
217
190
  end
218
- #No end marker. Chunk 5 is assumed to be the last.
219
- end
220
-
221
- def writeArrayParam(paramarray)
222
- write(PARAM_LIST_MARKER)
223
- size = paramarray.size
224
- index = 0
225
- paramarray.each do |v|
226
- writeLPack(v[0])
227
- writeLPack(v[1])
228
- index += 1
229
- if index !=size # looks like don't write a 't' after the last entry
230
- write("t")
191
+
192
+ def logIn()
193
+ xusAvCode = VistaRPC.new("XUS AV CODE", RPCResponse::ARRAY)
194
+ @duz = "0"
195
+
196
+ if (@encryptedAV == nil)
197
+ if (@token != nil)
198
+ @encryptedAV = @token
199
+ else
200
+ @encryptedAV = xusAvCode.encrypt(@access + ";" + @verify)
201
+ end
202
+
203
+ end
204
+ xusAvCode.params[0]= @encryptedAV
205
+ response = execute(xusAvCode)
206
+ if (response == nil)
207
+ return false
231
208
  end
209
+ hasErrors = (response.error_message != nil)
210
+ answer = response.value
211
+ if (!hasErrors)
212
+ if (answer.length == 0)
213
+ hasErrors = true
214
+ else
215
+ hasErrors = answer[0]== "0"
216
+ end
217
+ end
218
+ if (hasErrors)
219
+ brokerInfo = extractBrokerErrorInfo(response)
220
+ puts("Access denied: " + brokerInfo)
221
+ else
222
+ @duz = answer[0]
223
+ end
224
+ return true
232
225
  end
233
- write("f")
234
- end
235
-
236
- def writeStringParam(string)
237
- write(PARAM_LITERAL_MARKER)
238
- writeLPack(string)
239
- write("f")
240
- end
241
-
242
- def writeEmptyParam()
243
- write(PARAM_EMPTY_MARKER)
244
- write("f")
245
- end
246
-
247
- def flush()
248
- retVal = false
249
- if (isConnected() || connect())
250
- if @debug
251
- puts "<Request>" + @writeBuffer + "</Request>"
252
- end
253
- @socket.write(@writeBuffer)
254
- @socket.flush
255
- @writeBuffer = String.new
256
- retVal = true
226
+
227
+
228
+ def extractBrokerErrorInfo(response)
229
+ sb = String.new
230
+ # if (response != nil && response.getArray() != nil)
231
+ # response.getArray.each do |answer|
232
+ # if (answer != nil && answer.length > 0 && !answer.matches("^(\\d+)$"))
233
+ # if (sb.length() != 0) # sb is Stringbuilder
234
+ # sb.append(" : ")
235
+ # sb.append(answer)
236
+ # end
237
+ # end
238
+ # end
239
+ # end
240
+ return sb
257
241
  end
258
- return retVal
259
- end
242
+
260
243
 
261
- def getResponse(rpcType)
262
- hadError = Array.new # for passing around boolean by reference
263
- hadError[0]=false
264
- securityError = readSPack(hadError)
265
- #puts "<SecurityError>" + securityError + "</SecurityError>"
266
- if (hadError[0])
267
- return nil
268
- end
269
- if (securityError.empty?)
270
- securityError = nil
244
+ # public String buildSubscript(String string) {
245
+ # return /* "\r" + */ string
246
+ # }
247
+
248
+ def executeOnce(rpc)
249
+ retVal = nil
250
+ writeProtocol()
251
+ writeCommand(rpc)
252
+ writeParams(rpc)
253
+ write(END_MARKER)
254
+ if (flush())
255
+ retVal = getResponse(rpc.type)
256
+ if @debug
257
+ puts "<Response> " + retVal.to_s + "</Response>"
258
+ end
259
+ end
260
+ return retVal
271
261
  end
272
262
 
273
- otherError = readSPack(hadError)
274
- if (hadError[0])
275
- return nil
263
+ def write(data)
264
+ @writeBuffer << data
276
265
  end
277
- if (otherError.empty?)
278
- otherError = nil
266
+
267
+ def writeProtocol
268
+ write(XWB_HEADER + VISTA_RPC_VERSION + VISTA_RPC_TYPE_RPC + VISTA_RPC_LENV_STR + VISTA_RPC_RETURN_DATA)
279
269
  end
280
270
 
281
- retVal = nil
282
- if (rpcType == RPCResponse::SINGLE_VALUE or rpcType == RPCResponse::GLOBAL_INSTANCE)
283
- retVal = RPCResponse.new(readString(nil, hadError))
284
- if (hadError[0])
285
- return nil
286
- end
287
- elsif (rpcType == RPCResponse::GLOBAL_ARRAY or rpcType == RPCResponse::WORD_PROCESSING or rpcType == RPCResponse::ARRAY)
288
- retVal = RPCResponse.new(readArray(hadError))
289
- if (hadError[0])
290
- return nil
271
+ def writeCommand(rpc)
272
+ if (rpc.isCommand)
273
+ write(CHUNK_TYPE_COMMAND)
274
+ else
275
+ write(CHUNK_TYPE_RPC)
276
+ writeSPack(VISTA_RPC_VERSION)
291
277
  end
278
+ writeSPack(rpc.name)
292
279
  end
293
280
 
294
- if (retVal != nil && (otherError != nil || securityError != nil))
295
- if (otherError != nil && securityError != nil)
296
- retVal.error_message = otherError + "^" + securityError
297
- elsif (otherError != nil)
298
- retVal.error_message = otherError
299
- else
300
- retVal.error_message = securityError
301
- end
281
+ def writeSPack(value)
282
+ write(value.length) # integer
283
+ write(value)
302
284
  end
303
- return retVal
304
- end
305
-
306
- # returns array of string
307
- def readArray(hadError)
308
- if (hadError != nil)
309
- hadError[0] = false
285
+
286
+ def writeLPack(string)
287
+ len = sprintf("%03i", string.length) # 0-padded 3 place string of integer
288
+ #Integer.toString(string.length())
289
+ # while (len.length() < VISTA_RPC_LENV) {
290
+ # len = "0" + len
291
+ # }
292
+ write(len) # "003"
293
+ write(string)
310
294
  end
311
- arrayList = Array.new
312
- endMarker = Array.new
313
- endMarker[0] = false
314
- while true
315
- newString = readString(endMarker, hadError)
316
- if (newString == nil)
317
- if (hadError != nil)
318
- hadError[0] = true
295
+
296
+ def writeParams(rpc)
297
+ write(CHUNK_TYPE_DATA)
298
+
299
+ params = rpc.params # Hash integer => object
300
+ if (!params.empty?)
301
+ params.each do |param|
302
+ if param.nil?
303
+ writeEmptyParam()
304
+ elsif param.class == String
305
+ writeStringParam(param)
306
+ elsif param.class == Array
307
+ writeArrayParam(param)
308
+ else
309
+ writeEmptyParam()
310
+ end
319
311
  end
320
- break
312
+ else
313
+ writeEmptyParam()
321
314
  end
322
- if (endMarker[0])
323
- break
324
- end
325
- arrayList << newString
315
+ #No end marker. Chunk 5 is assumed to be the last.
326
316
  end
327
- return arrayList
328
- end
329
-
330
-
331
- # readString uses array argument so can pass values back
332
- def readString(endMarker, hadError) # returns...string!
333
- if (endMarker != nil)
334
- endMarker[0] = !isConnected()
317
+
318
+ def writeArrayParam(paramarray)
319
+ write(PARAM_LIST_MARKER)
320
+ size = paramarray.size
321
+ index = 0
322
+ paramarray.each do |v|
323
+ writeLPack(v[0])
324
+ writeLPack(v[1])
325
+ index += 1
326
+ if index !=size # looks like don't write a 't' after the last entry
327
+ write("t")
328
+ end
329
+ end
330
+ write("f")
335
331
  end
336
- if (hadError != nil)
337
- hadError[0] = !isConnected()
332
+
333
+ def writeStringParam(string)
334
+ write(PARAM_LITERAL_MARKER)
335
+ writeLPack(string)
336
+ write("f")
338
337
  end
339
- if (!isConnected())
340
- return nil
338
+
339
+ def writeEmptyParam()
340
+ write(PARAM_EMPTY_MARKER)
341
+ write("f")
341
342
  end
342
- buffer = String.new
343
- gotCR = false
344
- while true
345
- byte = @socket.readbyte # read one byte
346
- if (byte == END_MARKER)
347
- if (endMarker != nil)
348
- endMarker[0] = true
343
+
344
+ def flush()
345
+ retVal = false
346
+ if (isConnected() || connect())
347
+ if @debug
348
+ puts "<Request>" + @writeBuffer + "</Request>"
349
349
  end
350
- break
350
+ @socket.write(@writeBuffer)
351
+ @socket.flush
352
+ @writeBuffer = String.new
353
+ retVal = true
351
354
  end
352
- if (gotCR && byte == 10) # CR-LF
353
- break
355
+ return retVal
356
+ end
357
+
358
+ def getResponse(rpcType)
359
+ hadError = Array.new # for passing around boolean by reference
360
+ hadError[0]=false
361
+ securityError = readSPack(hadError)
362
+ #puts "<SecurityError>" + securityError + "</SecurityError>"
363
+ if (hadError[0])
364
+ return nil
354
365
  end
355
- if (byte == 13)
356
- gotCR = true
357
- else
358
- if (gotCR)
359
- buffer << 13 # we got a CR without a LF, so keep it in.
360
- gotCR = false
366
+ if (securityError.empty?)
367
+ securityError = nil
368
+ end
369
+
370
+ otherError = readSPack(hadError)
371
+ if (hadError[0])
372
+ return nil
373
+ end
374
+ if (otherError.empty?)
375
+ otherError = nil
376
+ end
377
+
378
+ retVal = nil
379
+ if (rpcType == RPCResponse::SINGLE_VALUE or rpcType == RPCResponse::GLOBAL_INSTANCE)
380
+ retVal = RPCResponse.new(readString(nil, hadError))
381
+ if (hadError[0])
382
+ return nil
383
+ end
384
+ elsif (rpcType == RPCResponse::GLOBAL_ARRAY or rpcType == RPCResponse::WORD_PROCESSING or rpcType == RPCResponse::ARRAY)
385
+ retVal = RPCResponse.new(readArray(hadError))
386
+ if (hadError[0])
387
+ return nil
361
388
  end
362
- buffer << byte
363
389
  end
390
+
391
+ if (retVal != nil && (otherError != nil || securityError != nil))
392
+ if (otherError != nil && securityError != nil)
393
+ retVal.error_message = otherError + "^" + securityError
394
+ elsif (otherError != nil)
395
+ retVal.error_message = otherError
396
+ else
397
+ retVal.error_message = securityError
398
+ end
399
+ end
400
+ return retVal
364
401
  end
365
-
366
- retVal = buffer
367
- return retVal
368
- end
369
-
370
- def readSPack(hadError)
371
- if (hadError != nil)
372
- hadError[0] = false
402
+
403
+ # returns array of string
404
+ def readArray(hadError)
405
+ if (hadError != nil)
406
+ hadError[0] = false
407
+ end
408
+ arrayList = Array.new
409
+ endMarker = Array.new
410
+ endMarker[0] = false
411
+ while true
412
+ newString = readString(endMarker, hadError)
413
+ if (newString == nil)
414
+ if (hadError != nil)
415
+ hadError[0] = true
416
+ end
417
+ break
418
+ end
419
+ if (endMarker[0])
420
+ break
421
+ end
422
+ arrayList << newString
423
+ end
424
+ return arrayList
373
425
  end
374
- len = @socket.readbyte # read one byte into a fixnum
375
- data = String.new
376
- data = @socket.read(len)
377
- return data
378
- end
379
-
380
- def execute(rpc)
381
- retVal = executeOnce(rpc)
382
- if (retVal == nil && @signedOn)
383
- #reconnect
384
- if (rpc.name == "#BYE#")
385
- # We're disconnecting anyway
426
+
427
+
428
+ # readString uses array argument so can pass values back
429
+ def readString(endMarker, hadError) # returns...string!
430
+ if (endMarker != nil)
431
+ endMarker[0] = !isConnected()
432
+ end
433
+ if (hadError != nil)
434
+ hadError[0] = !isConnected()
435
+ end
436
+ if (!isConnected())
386
437
  return nil
387
438
  end
388
- # attempt to log back on
389
- if (connect())
390
- if (@currentContext != nil)
391
- context = !currentContext
392
- @currentContext = nil
393
- setContext(context)
439
+ buffer = String.new
440
+ gotCR = false
441
+ while true
442
+ byte = @socket.readbyte # read one byte
443
+ if (byte == END_MARKER)
444
+ if (endMarker != nil)
445
+ endMarker[0] = true
446
+ end
447
+ break
448
+ end
449
+ if (gotCR && byte == 10) # CR-LF
450
+ break
451
+ end
452
+ if (byte == 13)
453
+ gotCR = true
454
+ else
455
+ if (gotCR)
456
+ buffer << 13 # we got a CR without a LF, so keep it in.
457
+ gotCR = false
458
+ end
459
+ buffer << byte
394
460
  end
395
- retVal = executeOnce(rpc)
396
461
  end
397
- end
398
- if (retVal == nil)
399
- puts "Lost connection to server"
400
- end
401
- return retVal
402
- end
403
-
404
- def setContext(context)
405
- if (context == @currentContext)
406
- puts "context is already set to " + context + "..."
407
- return
408
- end
409
- if (@currentContext != nil)
410
- puts "changing context from " + currentContext + " to " + context
462
+
463
+ retVal = buffer
464
+ return retVal
411
465
  end
412
466
 
413
- puts "Setting context to: " + context
414
- xwbCreateContext = VistaRPC.new("XWB CREATE CONTEXT", RPCResponse::SINGLE_VALUE)
415
- encryptedContext = xwbCreateContext.encrypt(context)
416
- xwbCreateContext.params[0] = encryptedContext
417
- response = execute(xwbCreateContext)
418
- if (response == nil || response.error_message != nil)
419
- puts "XWB CREATE CONTEXT failed: " + response.error_message
467
+ def readSPack(hadError)
468
+ if (hadError != nil)
469
+ hadError[0] = false
470
+ end
471
+ len = @socket.readbyte # read one byte into a fixnum
472
+ data = String.new
473
+ data = @socket.read(len)
474
+ return data
420
475
  end
421
- @currentContext = context
422
- end
423
-
424
- def getDUZ
425
- return duz
476
+
426
477
  end
427
-
428
- end
429
478
  end
@@ -1,46 +1,55 @@
1
1
  module VistaRPC4r
2
- class RPCResponse
3
- attr_accessor :type, :value, :error_message
4
-
5
- SINGLE_VALUE = 1
6
- GLOBAL_INSTANCE = 2
7
- ARRAY = 3
8
- GLOBAL_ARRAY=4
9
- WORD_PROCESSING=5
10
-
11
- def initialize(value=nil, type=nil)
12
- if value.nil?
13
- @type = SINGLE_VALUE
14
- @value = nil
15
- elsif value.class == String
16
- @value = value
17
- @type = SINGLE_VALUE
18
- elsif value.class == Array
19
- @value = value
20
- @type = ARRAY
21
- elsif !type.nil?
2
+
3
+ # Response object from RPC call
4
+ # type = one of the constant types
5
+ # value = String or Array of Strings representing the actual response
6
+ class RPCResponse
7
+ attr_accessor :type, :value, :error_message
8
+
9
+ # Single string response
10
+ SINGLE_VALUE = 1
11
+ # Not sure, but is usually a string response
12
+ GLOBAL_INSTANCE = 2
13
+ # Array of string response
14
+ ARRAY = 3
15
+ # Array of string response
16
+ GLOBAL_ARRAY=4
17
+ # Array of string response
18
+ WORD_PROCESSING=5
19
+
20
+ def initialize(value=nil, type=nil)
21
+ if value.nil?
22
+ @type = SINGLE_VALUE
23
+ @value = nil
24
+ elsif value.class == String
25
+ @value = value
26
+ @type = SINGLE_VALUE
27
+ elsif value.class == Array
22
28
  @value = value
23
- @type = type
29
+ @type = ARRAY
30
+ elsif !type.nil?
31
+ @value = value
32
+ @type = type
33
+ end
34
+ @error_message = nil
24
35
  end
25
- @error_message = nil
26
- end
27
-
28
- def to_s
29
- sb = String.new
30
- if !@error_message.nil?
31
- sb << "ERROR: "
32
- sb << @error_message
33
- elsif @value.nil?
34
- sb << "No value or error"
35
- elsif @value.class == Array
36
- sb = "ARRAY:" + value.join("|")
37
- elsif @value.class == String
38
- sb = "STRING:" + value.to_s
39
- else
40
- sb << "Unknown value type"
36
+
37
+ def to_s
38
+ sb = String.new
39
+ if !@error_message.nil?
40
+ sb << "ERROR: "
41
+ sb << @error_message
42
+ elsif @value.nil?
43
+ sb << "No value or error"
44
+ elsif @value.class == Array
45
+ sb = "ARRAY:" + value.join("|")
46
+ elsif @value.class == String
47
+ sb = "STRING:" + value.to_s
48
+ else
49
+ sb << "Unknown value type"
50
+ end
51
+ return sb
41
52
  end
42
- return sb
43
53
  end
44
- end
45
54
 
46
55
  end
@@ -1,36 +1,42 @@
1
1
  # the 'Request' of the RPC request/response. Stores the command or api call, and arguments
2
2
  module VistaRPC4r
3
- class VistaRPC
4
- attr_accessor :name, :type, :isCommand, :params
5
3
 
4
+ # Request object for the RPC call. It contains:
5
+ # name = string containing name of the RPC
6
+ # type = The response type from RPCResponse
7
+ # param = Array of parameters - This is 0-based. Delphi and Ovid code refer to 1-based
8
+ # isCommand = Is this a command, usually false
9
+ class VistaRPC
10
+ attr_accessor :name, :type, :isCommand, :params
11
+
6
12
  def initialize(name, type=RPCResponse::SINGLE_VALUE, isCommand=false)
7
13
  @name=name # string
8
14
  @type=type # response type
9
15
  @params=Array.new # params = new TreeMap<Integer, Object>();
10
16
  @isCommand=isCommand # boolean
11
17
  @cipher = [
12
- "wkEo-ZJt!dG)49K{nX1BS$vH<&:Myf*>Ae0jQW=;|#PsO`'%+rmb[gpqN,l6/hFC@DcUa ]z~R}\"V\\iIxu?872.(TYL5_3",
13
- "rKv`R;M/9BqAF%&tSs#Vh)dO1DZP> *fX'u[.4lY=-mg_ci802N7LTG<]!CWo:3?{+,5Q}(@jaExn$~p\\IyHwzU\"|k6Jeb",
14
- "\\pV(ZJk\"WQmCn!Y,y@1d+~8s?[lNMxgHEt=uw|X:qSLjAI*}6zoF{T3#;ca)/h5%`P4$r]G'9e2if_>UDKb7<v0&- RBO.",
15
- "depjt3g4W)qD0V~NJar\\B \"?OYhcu[<Ms%Z`RIL_6:]AX-zG.#}$@vk7/5x&*m;(yb2Fn+l'PwUof1K{9,|EQi>H=CT8S!",
16
- "NZW:1}K$byP;jk)7'`x90B|cq@iSsEnu,(l-hf.&Y_?J#R]+voQXU8mrV[!p4tg~OMez CAaGFD6H53%L/dT2<*>\"{\\wI=",
17
- "vCiJ<oZ9|phXVNn)m K`t/SI%]A5qOWe\\&?;jT~M!fz1l>[D_0xR32c*4.P\"G{r7}E8wUgyudF+6-:B=$(sY,LkbHa#'@Q",
18
- "hvMX,'4Ty;[a8/{6l~F_V\"}qLI\\!@x(D7bRmUH]W15J%N0BYPkrs&9:$)Zj>u|zwQ=ieC-oGA.#?tfdcO3gp`S+En K2*<",
19
- "jd!W5[];4'<C$/&x|rZ(k{>?ghBzIFN}fAK\"#`p_TqtD*1E37XGVs@0nmSe+Y6Qyo-aUu%i8c=H2vJ\\) R:MLb.9,wlO~P",
20
- "2ThtjEM+!=xXb)7,ZV{*ci3\"8@_l-HS69L>]\\AUF/Q%:qD?1~m(yvO0e'<#o$p4dnIzKP|`NrkaGg.ufCRB[; sJYwW}5&",
21
- "vB\\5/zl-9y:Pj|=(R'7QJI *&CTX\"p0]_3.idcuOefVU#omwNZ`$Fs?L+1Sk<,b)hM4A6[Y%aDrg@~KqEW8t>H};n!2xG{",
22
- "sFz0Bo@_HfnK>LR}qWXV+D6`Y28=4Cm~G/7-5A\\b9!a#rP.l&M$hc3ijQk;),TvUd<[:I\"u1'NZSOw]*gxtE{eJp|y (?%",
23
- "M@,D}|LJyGO8`$*ZqH .j>c~h<d=fimszv[#-53F!+a;NC'6T91IV?(0x&/{B)w\"]Q\\YUWprk4:ol%g2nE7teRKbAPuS_X",
24
- ".mjY#_0*H<B=Q+FML6]s;r2:e8R}[ic&KA 1w{)vV5d,$u\"~xD/Pg?IyfthO@CzWp%!`N4Z'3-(o|J9XUE7k\\TlqSb>anG",
25
- "xVa1']_GU<X`|\\NgM?LS9{\"jT%s$}y[nvtlefB2RKJW~(/cIDCPow4,>#zm+:5b@06O3Ap8=*7ZFY!H-uEQk; .q)i&rhd",
26
- "I]Jz7AG@QX.\"%3Lq>METUo{Pp_ |a6<0dYVSv8:b)~W9NK`(r'4fs&wim\\kReC2hg=HOj$1B*/nxt,;c#y+![?lFuZ-5D}",
27
- "Rr(Ge6F Hx>q$m&C%M~Tn,:\"o'tX/*yP.{lZ!YkiVhuw_<KE5a[;}W0gjsz3]@7cI2\\QN?f#4p|vb1OUBD9)=-LJA+d`S8",
28
- "I~k>y|m};d)-7DZ\"Fe/Y<B:xwojR,Vh]O0Sc[`$sg8GXE!1&Qrzp._W%TNK(=J 3i*2abuHA4C'?Mv\\Pq{n#56LftUl@9+",
29
- "~A*>9 WidFN,1KsmwQ)GJM{I4:C%}#Ep(?HB/r;t.&U8o|l['Lg\"2hRDyZ5`nbf]qjc0!zS-TkYO<_=76a\\X@$Pe3+xVvu",
30
- "yYgjf\"5VdHc#uA,W1i+v'6|@pr{n;DJ!8(btPGaQM.LT3oe?NB/&9>Z`-}02*%x<7lsqz4OS ~E$\\R]KI[:UwC_=h)kXmF",
31
- "5:iar.{YU7mBZR@-K|2 \"+~`M%8sq4JhPo<_X\\Sg3WC;Tuxz,fvEQ1p9=w}FAI&j/keD0c?)LN6OHV]lGy'$*>nd[(tb!#" ]
18
+ "wkEo-ZJt!dG)49K{nX1BS$vH<&:Myf*>Ae0jQW=;|#PsO`'%+rmb[gpqN,l6/hFC@DcUa ]z~R}\"V\\iIxu?872.(TYL5_3",
19
+ "rKv`R;M/9BqAF%&tSs#Vh)dO1DZP> *fX'u[.4lY=-mg_ci802N7LTG<]!CWo:3?{+,5Q}(@jaExn$~p\\IyHwzU\"|k6Jeb",
20
+ "\\pV(ZJk\"WQmCn!Y,y@1d+~8s?[lNMxgHEt=uw|X:qSLjAI*}6zoF{T3#;ca)/h5%`P4$r]G'9e2if_>UDKb7<v0&- RBO.",
21
+ "depjt3g4W)qD0V~NJar\\B \"?OYhcu[<Ms%Z`RIL_6:]AX-zG.#}$@vk7/5x&*m;(yb2Fn+l'PwUof1K{9,|EQi>H=CT8S!",
22
+ "NZW:1}K$byP;jk)7'`x90B|cq@iSsEnu,(l-hf.&Y_?J#R]+voQXU8mrV[!p4tg~OMez CAaGFD6H53%L/dT2<*>\"{\\wI=",
23
+ "vCiJ<oZ9|phXVNn)m K`t/SI%]A5qOWe\\&?;jT~M!fz1l>[D_0xR32c*4.P\"G{r7}E8wUgyudF+6-:B=$(sY,LkbHa#'@Q",
24
+ "hvMX,'4Ty;[a8/{6l~F_V\"}qLI\\!@x(D7bRmUH]W15J%N0BYPkrs&9:$)Zj>u|zwQ=ieC-oGA.#?tfdcO3gp`S+En K2*<",
25
+ "jd!W5[];4'<C$/&x|rZ(k{>?ghBzIFN}fAK\"#`p_TqtD*1E37XGVs@0nmSe+Y6Qyo-aUu%i8c=H2vJ\\) R:MLb.9,wlO~P",
26
+ "2ThtjEM+!=xXb)7,ZV{*ci3\"8@_l-HS69L>]\\AUF/Q%:qD?1~m(yvO0e'<#o$p4dnIzKP|`NrkaGg.ufCRB[; sJYwW}5&",
27
+ "vB\\5/zl-9y:Pj|=(R'7QJI *&CTX\"p0]_3.idcuOefVU#omwNZ`$Fs?L+1Sk<,b)hM4A6[Y%aDrg@~KqEW8t>H};n!2xG{",
28
+ "sFz0Bo@_HfnK>LR}qWXV+D6`Y28=4Cm~G/7-5A\\b9!a#rP.l&M$hc3ijQk;),TvUd<[:I\"u1'NZSOw]*gxtE{eJp|y (?%",
29
+ "M@,D}|LJyGO8`$*ZqH .j>c~h<d=fimszv[#-53F!+a;NC'6T91IV?(0x&/{B)w\"]Q\\YUWprk4:ol%g2nE7teRKbAPuS_X",
30
+ ".mjY#_0*H<B=Q+FML6]s;r2:e8R}[ic&KA 1w{)vV5d,$u\"~xD/Pg?IyfthO@CzWp%!`N4Z'3-(o|J9XUE7k\\TlqSb>anG",
31
+ "xVa1']_GU<X`|\\NgM?LS9{\"jT%s$}y[nvtlefB2RKJW~(/cIDCPow4,>#zm+:5b@06O3Ap8=*7ZFY!H-uEQk; .q)i&rhd",
32
+ "I]Jz7AG@QX.\"%3Lq>METUo{Pp_ |a6<0dYVSv8:b)~W9NK`(r'4fs&wim\\kReC2hg=HOj$1B*/nxt,;c#y+![?lFuZ-5D}",
33
+ "Rr(Ge6F Hx>q$m&C%M~Tn,:\"o'tX/*yP.{lZ!YkiVhuw_<KE5a[;}W0gjsz3]@7cI2\\QN?f#4p|vb1OUBD9)=-LJA+d`S8",
34
+ "I~k>y|m};d)-7DZ\"Fe/Y<B:xwojR,Vh]O0Sc[`$sg8GXE!1&Qrzp._W%TNK(=J 3i*2abuHA4C'?Mv\\Pq{n#56LftUl@9+",
35
+ "~A*>9 WidFN,1KsmwQ)GJM{I4:C%}#Ep(?HB/r;t.&U8o|l['Lg\"2hRDyZ5`nbf]qjc0!zS-TkYO<_=76a\\X@$Pe3+xVvu",
36
+ "yYgjf\"5VdHc#uA,W1i+v'6|@pr{n;DJ!8(btPGaQM.LT3oe?NB/&9>Z`-}02*%x<7lsqz4OS ~E$\\R]KI[:UwC_=h)kXmF",
37
+ "5:iar.{YU7mBZR@-K|2 \"+~`M%8sq4JhPo<_X\\Sg3WC;Tuxz,fvEQ1p9=w}FAI&j/keD0c?)LN6OHV]lGy'$*>nd[(tb!#" ]
32
38
  end
33
-
39
+
34
40
  def encrypt(orig_string)
35
41
  ra = rand(19)
36
42
  rb = rand(19)
@@ -41,7 +47,7 @@ class VistaRPC
41
47
  cb = @cipher[rb]
42
48
  len = orig_string.length
43
49
  pos = 0;
44
-
50
+
45
51
  buffer = String.new
46
52
  buffer << ra+32
47
53
  for i in 0..(len-1)
@@ -56,44 +62,44 @@ class VistaRPC
56
62
  buffer << rb + 32
57
63
  return buffer
58
64
  end
59
-
65
+
60
66
  def to_s
61
67
  sb = String.new
62
68
  sb << @name + ":"
63
69
  sb << @params.to_s
64
70
  return sb
65
71
  end
66
-
67
- # @Override
72
+
73
+ # @Override
68
74
  # public boolean equals(Object obj) {
69
- # if (obj == null) {
70
- # return false;
71
- # }
72
- # if (getClass() != obj.getClass()) {
73
- # return false;
74
- # }
75
+ # if (obj == null) {
76
+ # return false;
77
+ # }
78
+ # if (getClass() != obj.getClass()) {
79
+ # return false;
80
+ # }
75
81
  # final VistaRPC other = (VistaRPC) obj;
76
- # if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
77
- # return false;
78
- # }
79
- # if (this.type != other.type) {
80
- # return false;
81
- # }
82
- # if (this.params != other.params && (this.params == null || !this.params.equals(other.params))) {
82
+ # if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
83
+ # return false;
84
+ # }
85
+ # if (this.type != other.type) {
83
86
  # return false;
87
+ # }
88
+ # if (this.params != other.params && (this.params == null || !this.params.equals(other.params))) {
89
+ # return false;
84
90
  # }
85
- # return true;
86
- # }
87
-
88
- # @Override
89
- # public int hashCode() {
91
+ # return true;
92
+ # }
93
+
94
+ # @Override
95
+ # public int hashCode() {
90
96
  # int hash = 3;
91
- # hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
92
- # hash = 29 * hash + (this.type != null ? this.type.hashCode() : 0);
93
- # hash = 29 * hash + (this.params != null ? this.params.hashCode() : 0);
94
- # return hash;
95
- # }
97
+ # hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
98
+ # hash = 29 * hash + (this.type != null ? this.type.hashCode() : 0);
99
+ # hash = 29 * hash + (this.params != null ? this.params.hashCode() : 0);
100
+ # return hash;
101
+ # }
96
102
 
97
-
98
- end
103
+
104
+ end
99
105
  end
data/vistarpc4r.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{vistarpc4r}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mike Cham"]
12
- s.date = %q{2011-05-26}
12
+ s.date = %q{2011-05-27}
13
13
  s.description = %q{more}
14
14
  s.email = %q{mike@blenderhouse.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vistarpc4r
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mike Cham
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-26 00:00:00 -04:00
18
+ date: 2011-05-27 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency