Annotation of OpenXM/src/ruby/ox-taka.rb, Revision 1.2
1.1 takayama 1: # ox-taka.rb OpenXM client written by Ruby
2: # (takayama's version based on ogino's ox.rb)
3: #
1.2 ! takayama 4: # $OpenXM: OpenXM/src/ruby/ox-taka.rb,v 1.1 2000/07/28 06:02:20 takayama Exp $
1.1 takayama 5: #
6: require 'socket'
7: include Socket::Constants
8:
9: # define for CMO constants
10:
11: # Moved from oxtag.h
12: LARGEID = 0x7f000000
13: CMO_PRIVATE = 0x7fff0000
14: CMO_ERROR = (LARGEID+1)
15: CMO_ERROR2 = (LARGEID+2)
16: CMO_NULL = 1
17: CMO_INT32 = 2
18: CMO_DATUM = 3
19: CMO_STRING = 4
20: CMO_MATHCAP = 5
21:
22: CMO_START_SIGNATURE = 0x7fabcd03
23: CMO_LOCAL_OBJECT = 0x7fcdef03
24: CMO_LOCAL_OBJECT_ASIR = (CMO_LOCAL_OBJECT+0)
25: CMO_LOCAL_OBJECT_SM1 = (CMO_LOCAL_OBJECT+1)
26: # for OpenMathematica
27: MLO_FUNCTION = (CMO_LOCAL_OBJECT+2)
28:
29: OX_LOCAL_OBJECT = 0x7fcdef30
30: OX_LOCAL_OBJECT_ASIR = (OX_LOCAL_OBJECT+0)
31: OX_LOCAL_OBJECT_SM1 = (OX_LOCAL_OBJECT+1)
32: OX_LOCAL_OBJECT_MATH = (OX_LOCAL_OBJECT+2)
33:
34: CMO_ARRAY = 16
35: CMO_LIST = 17
36: CMO_ATOM = 18
37: CMO_MONOMIAL32 = 19
38: CMO_ZZ = 20
39: CMO_QQ = 21
40: CMO_ZERO = 22
41: # CMO_DMS = 23
42: CMO_DMS_GENERIC = 24
43: CMO_DMS_OF_N_VARIABLES = 25
44: CMO_RING_BY_NAME = 26
45: CMO_RECURSIVE_POLYNOMIAL = 27
46: CMO_LIST_R = 28
47:
48: CMO_INT32COEFF = 30
49: CMO_DISTRIBUTED_POLYNOMIAL = 31
50: # CMO_ZZ_OLD = 32
51: CMO_POLYNOMIAL_IN_ONE_VARIABLE = 33
52: CMO_RATIONAL = 34
53:
54: CMO_64BIT_MACHINE_DOUBLE = 40
55: CMO_ARRAY_OF_64BIT_MACHINE_DOUBLE = 41
56: CMO_128BIT_MACHINE_DOUBLE = 42
57: CMO_ARRAY_OF_128BIT_MACHINE_DOUBLE = 43
58:
59: CMO_BIGFLOAT = 50
60: CMO_IEEE_DOUBLE_FLOAT = 51
61:
62: CMO_INDETERMINATE = 60
63: CMO_TREE = 61
64: CMO_LAMBDA = 62 # for function definition
65:
66:
67: OX_COMMAND = 513
68: OX_DATA = 514
69: OX_SYNC_BALL = 515 # ball to interrupt
70:
71: # level 2 stack machine with programming facility.
72: OX_START_OF_FUNCTION_BLOCK = 518
73: OX_END_OF_FUNCTION_BLOCK = 519
74: OX_ADDRESS = 520
75:
76: OX_DATA_WITH_SIZE = 521
77: OX_DATA_ASIR_BINARY_EXPRESSION = 522 # This number should be changed
78: OX_DATA_OPENMATH_XML = 523
79: OX_DATA_OPENMATH_BINARY = 524
80: OX_DATA_MP = 525
81:
82: # OX BYTE command
83: OX_BYTE_NETWORK_BYTE_ORDER = 0
84: OX_BYTE_LITTLE_ENDIAN = 1
85: OX_BYTE_BIG_ENDIAN = 0xff
86:
87: # ox_function_id.h
88: SM_popSerializedLocalObject = 258
89: SM_popCMO = 262
90: SM_popString = 263 # result ==> string and send the string by CMO
91:
92: SM_mathcap = 264
93: SM_pops = 265
94: SM_setName = 266
95: SM_evalName = 267
96: SM_executeStringByLocalParser = 268
97: SM_executeFunction = 269
98: SM_beginBlock = 270
99: SM_endBlock = 271
100: SM_shutdown = 272
101: SM_setMathCap = 273
102: SM_executeStringByLocalParserInBatchMode = 274
103: SM_getsp = 275
104: SM_dupErrors = 276
105:
106: SM_DUMMY_sendcmo = 280
107: SM_sync_ball = 281
108:
109: SM_control_kill = 1024
110: SM_control_reset_connection = 1030
111: SM_control_to_debug_mode = 1025
112: SM_control_exit_debug_mode = 1026
113: SM_control_ping = 1027
114: SM_control_start_watch_thread = 1028
115: SM_control_stop_watch_thread = 1029
116:
117: # end of CMO constants
118:
119: class CMO
120: def set_tag(tag)
121: @tag = tag
122: end
123: attr_accessor :tag
124: end
125: class CMONull < CMO
126: def initialize
127: set_tag(CMO_NULL)
128: end
129: end
130: class CMOInt32 < CMO
131: def initialize(i)
132: set_tag(CMO_INT32)
133: @i = i
134: end
135: attr_accessor :i
136: end
137: class CMOString < CMO
138: def initialize(str)
139: set_tag(CMO_STRING)
140: @str = str
141: @len = str.length
142: end
143: attr_accessor :len, :str
144: end
145:
146: class OX < CMO
147: end
148:
149: class OXCommand < OX
150: def initialize(command)
151: set_tag(OX_COMMAND)
152: @command = command
153: end
154: attr_accessor :command
155: end
156: class OXData < OX
157: def initialize(cmo)
158: set_tag(OX_DATA)
159: @cmo = cmo
160: end
161: attr_accessor :cmo
162: end
163:
164: class OXSession
165: def initialize(
1.2 ! takayama 166: oxserver = "/usr/local/OpenXM/bin/ox_sm1",
1.1 takayama 167: host = "localhost",
168: byteorder = 0
169: )
170: @serial = 0
171:
172: if ENV.include?("OpenXM_HOME")
173: oxhome = ENV["OpenXM_HOME"]+"/"
174: else
175: oxhome = "/usr/local/OpenXM/"
176: end
177:
178: @controlport = rand(20000)+1024
179: @dataport = @controlport+1
180: printf(oxhome+"\n")
181: printf("Starting the server %s\n",oxserver)
182: $stdout.flush
1.2 ! takayama 183: ox = oxhome+"bin/ox"
! 184: system("oxlog /usr/X11R6/bin/xterm -e "+ox+" -ox "+oxserver+" -control "+@controlport.to_s()+" -data "+@dataport.to_s()+" &");
1.1 takayama 185: if $? == nil
186: printf("failed to start the ox server.\n")
187: exit()
188: end
189: sleep 3
190: printf("Connecting to %s, \n", host)
191: printf("Trying to connect to controlport %d, \n", @controlport)
192: $stdout.flush
193: @controlp = TCPSocket.new(host, @controlport)
194: sleep 2
195: printf("Trying to connect to dataport %d, \n", @dataport)
196: $stdout.flush
197: @datap = TCPSocket.new(host, @dataport)
198: sleep 2
199: # rescue
200:
201:
202: # byte oder negotiation
203: @byteorder = decide_byte_order(byteorder)
204: end
205:
206: attr_accessor :controlp, :datap
207:
208: def decide_byte_order(b_or_l)
209: if b_or_l == 0
210: @controlp.read(1)
211: @datap.read(1)
212: @controlp.flush
213: @datap.flush
214: @controlp.write(0)
215: @datap.write(0)
216: return 0
217: end
218: end
219:
220: def send(data)
221: case data.tag
222: when OX_DATA
223: send_ox_tag(OX_DATA)
224: send_cmo(data.cmo)
225: when OX_COMMAND
226: send_ox_tag(OX_COMMAND);
227: send_int32(data.command);
228: end
229: end
230:
231: def send_ox_tag(tag)
232: send_int32(tag)
233: send_int32(@serial)
234: @serial += 1;
235: end
236:
237: def send_int32(n)
238: b = n.to_a.pack("N")
239: return datap.write(b)
240: end
241:
242: def send_cmo(data)
243: tag = data.tag
244: send_int32(tag)
245: case tag
246: when CMO_NULL
247: m = send_cmo_null
248: when CMO_INT32
249: m = send_cmo_int32(data)
250: when CMO_STRING
251: m = send_cmo_string(data)
252: when CMO_MATHCAP
253: m = send_cmo_mathcap(data)
254: when CMO_LIST
255: m = send_cmo_list(data)
256: end
257: return m
258: end
259:
260: def send_cmo_null
261: return 0
262: end
263:
264: def send_cmo_int32(cmo)
265: send_int32(cmo.i)
266: end
267:
268: def send_cmo_string(cmo)
269: send_int32(cmo.len)
270: datap.write(cmo.str)
271: end
272:
273: def receive
274: oxtag = receive_int32
1.2 ! takayama 275: # printf("oxtag = %d ",oxtag)
! 276: # $stdout.flush
1.1 takayama 277: seqNum = receive_int32
278: if oxtag = OX_DATA then
279: tag = receive_int32
280: else
281: printf("Cannot handle this OX tag %d\n",oxtag)
282: $stdout.flush
283: end
1.2 ! takayama 284: # printf("cmotag = %d ",tag)
! 285: # $stdout.flush
1.1 takayama 286: case tag
287: when CMO_NULL
288: m = receive_cmo_null
289: when CMO_INT32
290: m = receive_cmo_int32
291: when CMO_STRING
292: m = receive_cmo_string
293: when CMO_MATHCAP
294: m = receive_cmo_mathcap
295: when CMO_LIST
296: m = receive_cmo_list
297: # when CMO_MONOMIAL32
298: # m = receive_cmo_monomial32
299: # when CMO_ZZ
300: # m = receive_cmo_zz
301: # when CMO_ZERO
302: # m = receive_cmo_zero
303: # when CMO_DMS_GENERIC
304: # m = receive_cmo_dms_generic
305: # when CMO_RING_BY_NAME
306: # m = receive_cmo_ring_by_name
307: # when CMO_DISTRIBUTED_POLYNOMIAL
308: # m = receive_cmo_distributed_polynomial
309: # when CMO_ERROR2
310: # m = receive_cmo_error2
311: # when CMO_DATUM
312: # m = receive_cmo_datum
313: # when CMO_QQ
314: # m = receive_cmo_qq
315: else
316: printf("the CMO (%d) is not implemented.\n", tag)
317: $stdout.flush
318: end
319:
320: return m;
321: end
322:
323: def receive_int32
324: return datap.read(4).unpack("N").pop
325: end
326:
327: def receive_cmo_null
328: return CMONull.new
329: end
330:
331: def receive_cmo_int32
332: return CMOInt32.new(receive_int32)
333: end
334:
335: def receive_cmo_string
336: size = receive_int32
337: s = datap.read(size)
338: return(s)
339: end
340:
341: def rpc(s)
342: # when s is a string
343: self.send(OXData.new(CMOString.new(s)))
344: self.send(OXCommand.new(SM_executeStringByLocalParser))
345: self.send(OXCommand.new(SM_popString))
346: return(self.receive())
347: end
348: def submit(s)
349: # when s is a string
350: self.send(OXData.new(CMOString.new(s)))
351: self.send(OXCommand.new(SM_executeStringByLocalParser))
352: end
353:
354: # attr_accessor :send, :receive
355: end
356:
357: # Usage
358: # % ruby ox-taka.rb
359: #
360:
361: s = OXSession.new()
362:
363: s.submit(" [(oxWatch) 1] extension ");
1.2 ! takayama 364: ## sample
1.1 takayama 365: a = s.rpc(" 1 1 add ")
366: printf("%s\n",a)
367: $stdout.flush
1.2 ! takayama 368:
! 369: ## sample
! 370: ## 1 3 add
! 371: while 1
! 372: printf("\nruby-sm1>")
! 373: STDOUT.flush
! 374: input = gets
! 375: break if not input
! 376: str = input
! 377: str.chop!
! 378: eval("print(s.rpc(\""+str+"\"))")
! 379: end
! 380:
1.1 takayama 381:
382: while 1
383: print '> '
384: STDOUT.flush
385: input = gets
386: break if not input
387: str = input
388: str.chop!
389: eval(str)
390: end
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>