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