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