Annotation of OpenXM/src/ruby/ox-taka.rb, Revision 1.4
1.1 takayama 1: # ox-taka.rb OpenXM client written by Ruby
2: # (takayama's version based on ogino's ox.rb)
3: #
1.4 ! takayama 4: # $OpenXM: OpenXM/src/ruby/ox-taka.rb,v 1.3 2000/07/28 07:45:28 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.3 takayama 166: oxserver = "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:
1.3 takayama 178: oxserver = oxhome+"bin/"+oxserver
1.4 ! takayama 179: srand()
1.1 takayama 180: @controlport = rand(20000)+1024
181: @dataport = @controlport+1
182: printf("Starting the server %s\n",oxserver)
183: $stdout.flush
1.4 ! takayama 184: Thread.start {
! 185: printf("Connection from %s, \n", host)
! 186: printf("Waiting a connection to controlport %d, \n", @controlport)
! 187: $stdout.flush
! 188: # @controlp = TCPserver.open(@controlport)
! 189: $ccccontrolp = TCPserver.open(@controlport)
! 190: }
! 191: printf("Waiting a connection to dataport %d, \n", @dataport)
! 192: $stdout.flush
! 193: @datap = TCPserver.open(@dataport)
! 194:
! 195: sleep 3 # Heuristic wait that TPCserver switches to accept mode.
! 196: printf(oxhome+"\n")
1.2 takayama 197: ox = oxhome+"bin/ox"
1.4 ! takayama 198: system("oxlog /usr/X11R6/bin/xterm -e "+ox+" -ox "+oxserver+" -control "+@controlport.to_s()+" -data "+@dataport.to_s()+" -reverse -pass a &");
1.1 takayama 199: if $? == nil
200: printf("failed to start the ox server.\n")
201: exit()
202: end
203: sleep 2
1.4 ! takayama 204: @controlp = $ccccontrolp
1.1 takayama 205: # rescue
206:
207:
208: # byte oder negotiation
209: @byteorder = decide_byte_order(byteorder)
210: end
211:
212: attr_accessor :controlp, :datap
213:
214: def decide_byte_order(b_or_l)
215: if b_or_l == 0
216: @controlp.read(1)
217: @datap.read(1)
218: @controlp.flush
219: @datap.flush
220: @controlp.write(0)
221: @datap.write(0)
222: return 0
223: end
224: end
225:
226: def send(data)
227: case data.tag
228: when OX_DATA
229: send_ox_tag(OX_DATA)
230: send_cmo(data.cmo)
231: when OX_COMMAND
232: send_ox_tag(OX_COMMAND);
233: send_int32(data.command);
234: end
235: end
236:
237: def send_ox_tag(tag)
238: send_int32(tag)
239: send_int32(@serial)
240: @serial += 1;
241: end
242:
243: def send_int32(n)
244: b = n.to_a.pack("N")
245: return datap.write(b)
246: end
247:
248: def send_cmo(data)
249: tag = data.tag
250: send_int32(tag)
251: case tag
252: when CMO_NULL
253: m = send_cmo_null
254: when CMO_INT32
255: m = send_cmo_int32(data)
256: when CMO_STRING
257: m = send_cmo_string(data)
258: when CMO_MATHCAP
259: m = send_cmo_mathcap(data)
260: when CMO_LIST
261: m = send_cmo_list(data)
262: end
263: return m
264: end
265:
266: def send_cmo_null
267: return 0
268: end
269:
270: def send_cmo_int32(cmo)
271: send_int32(cmo.i)
272: end
273:
274: def send_cmo_string(cmo)
275: send_int32(cmo.len)
276: datap.write(cmo.str)
277: end
278:
279: def receive
280: oxtag = receive_int32
1.2 takayama 281: # printf("oxtag = %d ",oxtag)
282: # $stdout.flush
1.1 takayama 283: seqNum = receive_int32
284: if oxtag = OX_DATA then
285: tag = receive_int32
286: else
287: printf("Cannot handle this OX tag %d\n",oxtag)
288: $stdout.flush
289: end
1.2 takayama 290: # printf("cmotag = %d ",tag)
291: # $stdout.flush
1.1 takayama 292: case tag
293: when CMO_NULL
294: m = receive_cmo_null
295: when CMO_INT32
296: m = receive_cmo_int32
297: when CMO_STRING
298: m = receive_cmo_string
299: when CMO_MATHCAP
300: m = receive_cmo_mathcap
301: when CMO_LIST
302: m = receive_cmo_list
303: # when CMO_MONOMIAL32
304: # m = receive_cmo_monomial32
305: # when CMO_ZZ
306: # m = receive_cmo_zz
307: # when CMO_ZERO
308: # m = receive_cmo_zero
309: # when CMO_DMS_GENERIC
310: # m = receive_cmo_dms_generic
311: # when CMO_RING_BY_NAME
312: # m = receive_cmo_ring_by_name
313: # when CMO_DISTRIBUTED_POLYNOMIAL
314: # m = receive_cmo_distributed_polynomial
315: # when CMO_ERROR2
316: # m = receive_cmo_error2
317: # when CMO_DATUM
318: # m = receive_cmo_datum
319: # when CMO_QQ
320: # m = receive_cmo_qq
321: else
322: printf("the CMO (%d) is not implemented.\n", tag)
323: $stdout.flush
324: end
325:
326: return m;
327: end
328:
329: def receive_int32
330: return datap.read(4).unpack("N").pop
331: end
332:
333: def receive_cmo_null
334: return CMONull.new
335: end
336:
337: def receive_cmo_int32
338: return CMOInt32.new(receive_int32)
339: end
340:
341: def receive_cmo_string
342: size = receive_int32
343: s = datap.read(size)
344: return(s)
345: end
346:
347: def rpc(s)
348: # when s is a string
349: self.send(OXData.new(CMOString.new(s)))
350: self.send(OXCommand.new(SM_executeStringByLocalParser))
351: self.send(OXCommand.new(SM_popString))
352: return(self.receive())
353: end
354: def submit(s)
355: # when s is a string
356: self.send(OXData.new(CMOString.new(s)))
357: self.send(OXCommand.new(SM_executeStringByLocalParser))
358: end
359:
360: # attr_accessor :send, :receive
361: end
362:
363: # Usage
364: # % ruby ox-taka.rb
365: #
366:
367: s = OXSession.new()
368:
369: s.submit(" [(oxWatch) 1] extension ");
1.2 takayama 370: ## sample
1.1 takayama 371: a = s.rpc(" 1 1 add ")
372: printf("%s\n",a)
373: $stdout.flush
1.2 takayama 374:
375: ## sample
376: ## 1 3 add
377: while 1
378: printf("\nruby-sm1>")
379: STDOUT.flush
380: input = gets
381: break if not input
382: str = input
383: str.chop!
384: eval("print(s.rpc(\""+str+"\"))")
385: end
386:
1.1 takayama 387:
388: while 1
389: print '> '
390: STDOUT.flush
391: input = gets
392: break if not input
393: str = input
394: str.chop!
395: eval(str)
396: end
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>