[BACK]Return to ox.rb CVS log [TXT][DIR] Up to [local] / OpenXM / src / ruby

Annotation of OpenXM/src/ruby/ox.rb, Revision 1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>