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