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

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>