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

Annotation of OpenXM/src/ox_math/ox.c, Revision 1.1.1.1

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
                      2: /* $OpenXM$ */
                      3: /* $Id: ox.c,v 1.5 1999/10/14 10:18:24 ohara Exp ohara $ */
                      4:
                      5: /*
                      6: 関数の名前付け規約(その2):
                      7: (1) receive_cmo 関数はCMOタグとデータ本体を受信する. この関数は CMOタグの
                      8: 値が事前に分からないときに使用する. 返り値として、cmo へのポインタを返す.
                      9: (2) receive_cmo_XXX 関数は, CMOタグを親の関数で受信してから呼び出される関
                     10: 数で、データ本体のみを受信し、cmo_XXX へのポインタを返す.  しかも、
                     11: 関数内部で new_cmo_XXX 関数を呼び出す.
                     12: (3) send_cmo 関数はCMOタグとデータ本体を送信する.
                     13: (4) send_cmo_XXX 関数はCMOタグを親の関数で送信してから呼び出される関数で、
                     14: データ本体のみを送信する.
                     15:
                     16: ----
                     17: (5) receive_ox_XXX 関数は存在しない(作らない).  receive_cmo を利用する.
                     18: (6) send_ox_XXX 関数は OX タグを含めて送信する.
                     19: (7) ox_XXX 関数は一連の送受信を含むより抽象的な操作を表現する.
                     20: ox_XXX 関数は、第一引数として、ox_file_t型の変数 sv をとる.
                     21:
                     22: (8) YYY_cmo 関数と YYY_cmo_XXX 関数の関係は次の通り:
                     23: まず YYY_cmo 関数で cmo のタグを処理し、タグを除いた残りの部分を
                     24: YYY_cmo_XXX 関数が処理する.  cmo の内部に cmo_ZZZ へのポインタが
                     25: あるときには、その種類によらずに YYY_cmo 関数を呼び出す.
                     26: */
                     27:
                     28: #include <stdio.h>
                     29: #include <stdlib.h>
                     30: #include <string.h>
                     31: #include <unistd.h>
                     32: #include <errno.h>
                     33: #include <fcntl.h>
                     34: #include <gmp.h>
                     35:
                     36: #include "mysocket.h"
                     37: #include "ox.h"
                     38: #include "parse.h"
                     39:
                     40: static int          cmolen_cmo_int32(cmo_int32* c);
                     41: static int          cmolen_cmo_list(cmo_list* c);
                     42: static int          cmolen_cmo_mathcap(cmo_mathcap* c);
                     43: static int          cmolen_cmo_null(cmo_null* c);
                     44: static int          cmolen_cmo_string(cmo_string* c);
                     45: static int          cmolen_cmo_zz(cmo_zz* c);
                     46:
                     47: static char*        dump_cmo_int32(char* array, cmo_int32* m);
                     48: static char*        dump_cmo_list(char* array, cmo_list* m);
                     49: static char*        dump_cmo_mathcap(char* array, cmo_mathcap* m);
                     50: static char*        dump_cmo_null(char* array, cmo_null* m);
                     51: static char*        dump_cmo_string(char* array, cmo_string* m);
                     52: static char*        dump_cmo_zz(char* array, cmo_zz* c);
                     53: static char*        dump_integer(char* array, int x);
                     54: static char*        dump_mpz(char* array, mpz_ptr mpz);
                     55:
                     56: static int          funcs(int cmo_type);
                     57:
                     58: static int          read_password(int fd, char* passwd);
                     59: static cmo_error*   receive_cmo_error(int fd);
                     60: static cmo_int32*   receive_cmo_int32(int fd);
                     61: static cmo_list*    receive_cmo_list(int fd);
                     62: static cmo_mathcap* receive_cmo_mathcap(int fd);
                     63: static cmo_null*    receive_cmo_null(int fd);
                     64: static cmo_string*  receive_cmo_string(int fd);
                     65: static cmo_zz*      receive_cmo_zz(int fd);
                     66: static void         receive_mpz(int fd, mpz_ptr mpz);
                     67:
                     68: static int          send_cmo_error(int fd, cmo_error* c);
                     69: static int          send_cmo_int32(int fd, cmo_int32* m);
                     70: static int          send_cmo_list(int fd, cmo_list* c);
                     71: static int          send_cmo_mathcap(int fd, cmo_mathcap* c);
                     72: static int          send_cmo_null(int fd, cmo_null* c);
                     73: static int          send_cmo_string(int fd, cmo_string* m);
                     74: static int          send_cmo_zz(int fd, cmo_zz* c);
                     75: static int          send_mpz(int fd, mpz_ptr mpz);
                     76:
                     77:
                     78: /* エラーハンドリングのため */
                     79: static int current_received_serial = 0;
                     80:
                     81: /* エラーを起こしたときはサーバは次のようにすればよい.  */
                     82: cmo_error* gen_error_object(int err_code)
                     83: {
                     84:     cmo_list* li = new_cmo_list();
                     85:     append_cmo_list(li, (cmo *)new_cmo_int32(current_received_serial));
                     86:     append_cmo_list(li, (cmo *)new_cmo_int32(err_code));
                     87:     /* 他の情報を加えるならココ */
                     88:     return new_cmo_error(li);
                     89: }
                     90:
                     91: /* add at Mon Sep  7 15:51:28 JST 1998 */
                     92: #define DEFAULT_SERIAL_NUMBER 0x0000ffff
                     93: #define receive_serial_number(x)   (receive_int32(x))
                     94:
                     95: /* 新しいシリアル番号を得る */
                     96: int next_serial()
                     97: {
                     98:     static int serial_number = DEFAULT_SERIAL_NUMBER;
                     99:     return serial_number++;
                    100: }
                    101:
                    102: /* int32 型のオブジェクトを送信する.  */
                    103: int send_int32(int fd, int int32)
                    104: {
                    105:     int32 = htonl(int32);
                    106:     return write(fd, &int32, sizeof(int));
                    107: }
                    108:
                    109: /* int32 型のオブジェクトを受信する.  */
                    110: int receive_int32(int fd)
                    111: {
                    112:     int tag;
                    113:     read(fd, &tag, sizeof(int));
                    114:     return ntohl(tag);
                    115: }
                    116:
                    117: /* (OX_tag, serial number) を受信する.  */
                    118: int receive_ox_tag(int fd)
                    119: {
                    120:     int serial;
                    121:     int tag = receive_int32(fd);
                    122:     current_received_serial = receive_serial_number(fd);
                    123:     return tag;
                    124: }
                    125:
                    126: /* (OX_tag, serial number) を送信する.   */
                    127: int send_ox_tag(int fd, int tag)
                    128: {
                    129:     send_int32(fd, tag);
                    130:     return send_int32(fd, next_serial());
                    131: }
                    132:
                    133:
                    134: /* CMO_LIST 関係の関数群 */
                    135: cell* new_cell(cmo* newcmo)
                    136: {
                    137:     cell* h = malloc(sizeof(cell));
                    138:     h->next = NULL;
                    139:     h->cmo  = newcmo;
                    140:     return h;
                    141: }
                    142:
                    143: static cell* *tailp(cmo_list* this) {
                    144:     cell **cp = &this->head;
                    145:     while (*cp != NULL) {
                    146:         cp = &((*cp)->next);
                    147:     }
                    148:     return cp;
                    149: }
                    150:
                    151: int length_cmo_list(cmo_list* this)
                    152: {
                    153:     return this->length;
                    154: }
                    155:
                    156: int append_cmo_list(cmo_list* this, cmo* newcmo)
                    157: {
                    158:     /* リストの最後尾のNULLを保持している変数へのポインタ */
                    159:     cell **cp = tailp(this);
                    160:     *cp = new_cell(newcmo);
                    161:     this->length++;
                    162:     return 0;
                    163: }
                    164:
                    165: /** receive_cmo_XXX 関数群 **/
                    166: static cmo_error* receive_cmo_error(int fd)
                    167: {
                    168:     cmo_list* li = (cmo_list *)receive_cmo(fd);
                    169:     return new_cmo_error(li);
                    170: }
                    171:
                    172: static cmo_int32* receive_cmo_int32(int fd)
                    173: {
                    174:     int i = receive_int32(fd);
                    175:     return new_cmo_int32(i);
                    176: }
                    177:
                    178: static cmo_list* receive_cmo_list(int fd)
                    179: {
                    180:     cmo* newcmo;
                    181:     cmo_list* c = new_cmo_list();
                    182:     int len = receive_int32(fd);
                    183:
                    184:     while (len>0) {
                    185:         newcmo = receive_cmo(fd);
                    186:         append_cmo_list(c, newcmo);
                    187:         len--;
                    188:     }
                    189:     return c;
                    190: }
                    191:
                    192: static cmo_mathcap* receive_cmo_mathcap(int fd)
                    193: {
                    194:     cmo_list* li = (cmo_list *)receive_cmo(fd);
                    195:     return new_cmo_mathcap(li);
                    196: }
                    197:
                    198: static cmo_null* receive_cmo_null(int fd)
                    199: {
                    200:     return new_cmo_null();
                    201: }
                    202:
                    203: static cmo_string* receive_cmo_string(int fd)
                    204: {
                    205:     int len = receive_int32(fd);
                    206:     char* s = malloc(len+1);
                    207:     memset(s, '\0', len+1);
                    208:     if (len > 0) {
                    209:         read(fd, s, len);
                    210:     }
                    211:     return new_cmo_string(s);
                    212: }
                    213:
                    214: static cmo_zz* receive_cmo_zz(int fd)
                    215: {
                    216:     cmo_zz* c = new_cmo_zz();
                    217:     receive_mpz(fd, c->mpz);
                    218:     return c;
                    219: }
                    220:
                    221: static void receive_mpz(int fd, mpz_ptr mpz)
                    222: {
                    223:     int i;
                    224:     int size  = receive_int32(fd);
                    225:     int len   = abs(size);
                    226:     resize_mpz(mpz, size);
                    227:
                    228:     for(i=0; i<len; i++) {
                    229:         mpz->_mp_d[i] = receive_int32(fd);
                    230:     }
                    231: }
                    232:
                    233: void resize_mpz(mpz_ptr mpz, int size)
                    234: {
                    235:     _mpz_realloc(mpz, abs(size));
                    236:     mpz->_mp_size = size;
                    237: }
                    238:
                    239: /** new_cmo_XXX 関数群 **/
                    240: cmo_error* new_cmo_error(cmo_list* li)
                    241: {
                    242:     cmo_error* c = malloc(sizeof(cmo_error));
                    243:     c->tag = CMO_ERROR2;
                    244:     c->li  = li;
                    245:     return c;
                    246: }
                    247:
                    248: cmo_int32* new_cmo_int32(int i)
                    249: {
                    250:     cmo_int32* c;
                    251:     c = malloc(sizeof(cmo_int32));
                    252:     c->tag     = CMO_INT32;
                    253:     c->i = i;
                    254:     return c;
                    255: }
                    256:
                    257: cmo_list* new_cmo_list()
                    258: {
                    259:     cmo_list* c = malloc(sizeof(cmo_list));
                    260:     c->tag    = CMO_LIST;
                    261:     c->length = 0;
                    262:     c->head   = NULL;
                    263:     return c;
                    264: }
                    265:
                    266: cmo_mathcap* new_cmo_mathcap(cmo_list* li)
                    267: {
                    268:     cmo_mathcap* c = malloc(sizeof(cmo_mathcap));
                    269:     c->tag = CMO_MATHCAP;
                    270:     c->li  = li;
                    271:     return c;
                    272: }
                    273:
                    274: cmo_null* new_cmo_null()
                    275: {
                    276:     cmo* m = malloc(sizeof(cmo));
                    277:     m->tag = CMO_NULL;
                    278:     return m;
                    279: }
                    280:
                    281: cmo_string* new_cmo_string(char* s)
                    282: {
                    283:     cmo_string* c = malloc(sizeof(cmo_string));
                    284:     c->tag = CMO_STRING;
                    285:     c->s   = s;
                    286:     return c;
                    287: }
                    288:
                    289: cmo_zz* new_cmo_zz()
                    290: {
                    291:     cmo_zz* c = malloc(sizeof(cmo_zz));
                    292:     c->tag  = CMO_ZZ;
                    293:     mpz_init(c->mpz);
                    294:     return c;
                    295: }
                    296:
                    297: cmo_zz* new_cmo_zz_noinit()
                    298: {
                    299:     cmo_zz* c = malloc(sizeof(cmo_zz));
                    300:     c->tag  = CMO_ZZ;
                    301:     return c;
                    302: }
                    303:
                    304: cmo_zz* new_cmo_zz_set_si(int i)
                    305: {
                    306:     cmo_zz* c = new_cmo_zz();
                    307:     mpz_set_si(c->mpz, i);
                    308:     return c;
                    309: }
                    310:
                    311: cmo_zz* new_cmo_zz_size(int size)
                    312: {
                    313:     cmo_zz* c = new_cmo_zz();
                    314:     resize_mpz(c->mpz, size);
                    315:     return c;
                    316: }
                    317:
                    318: /* receive_ox_tag() == OX_DATA の後に呼び出される */
                    319: /* 関数ポインタを使った方がきれいに書けるような気がする.  */
                    320: /* if (foo[tag] != NULL) foo[tag](fd); とか */
                    321:
                    322: cmo* receive_cmo(int fd)
                    323: {
                    324:     cmo* m;
                    325:     int tag;
                    326:     tag = receive_int32(fd);
                    327:
                    328:     switch(tag) {
                    329:     case CMO_NULL:
                    330:         m = receive_cmo_null(fd);
                    331:         break;
                    332:     case CMO_INT32:
                    333:         m = (cmo *)receive_cmo_int32(fd);
                    334:         break;
                    335:     case CMO_STRING:
                    336:         m = (cmo *)receive_cmo_string(fd);
                    337:         break;
                    338:     case CMO_ZZ:
                    339:         m = (cmo *)receive_cmo_zz(fd);
                    340:         break;
                    341:     case CMO_LIST:
                    342:         m = (cmo *)receive_cmo_list(fd);
                    343:         break;
                    344:     case CMO_MATHCAP:
                    345:         m = (cmo *)receive_cmo_mathcap(fd);
                    346:         break;
                    347:     case CMO_ERROR2:
                    348:         m = (cmo *)receive_cmo_error(fd);
                    349:         break;
                    350:     case CMO_DATUM:
                    351:     case CMO_QQ:
                    352:     case CMO_ZERO:
                    353:     case CMO_DMS:
                    354:     default:
                    355:         fprintf(stderr, "unknown cmo-type: tag = (%d)\n", m->tag);
                    356:     }
                    357:     return m;
                    358: }
                    359:
                    360: void send_ox_command(int fd, int sm_command)
                    361: {
                    362:     send_ox_tag(fd, OX_COMMAND);
                    363:     send_int32(fd, sm_command);
                    364: }
                    365:
                    366: int print_cmo(cmo* c)
                    367: {
                    368:     int tag = c->tag;
                    369:     fprintf(stderr, "local::tag = (%d): ", tag);
                    370:     switch(tag) {
                    371:     case CMO_LIST:
                    372:         print_cmo_list((cmo_list *)c);
                    373:         break;
                    374:     case CMO_INT32:
                    375:         print_cmo_int32((cmo_int32 *)c);
                    376:         break;
                    377:     case CMO_MATHCAP:
                    378:         print_cmo_mathcap((cmo_mathcap *)c);
                    379:         break;
                    380:     case CMO_STRING:
                    381:         print_cmo_string((cmo_string *)c);
                    382:         break;
                    383:     case CMO_NULL:
                    384:         fprintf(stderr, "\n");
                    385:         break;
                    386:     default:
                    387:         fprintf(stderr, "print_cmo() does not know how to print.\n");
                    388:     }
                    389: }
                    390:
                    391: int print_cmo_int32(cmo_int32* c)
                    392: {
                    393:     fprintf(stderr, "cmo_int32 = (%d)\n", c->i);
                    394: }
                    395:
                    396: int print_cmo_list(cmo_list* li)
                    397: {
                    398:     cell* cp = li->head;
                    399:     fprintf(stderr, "length = (%d)\nlist:\n", li->length);
                    400:     while(cp != NULL) {
                    401:         print_cmo(cp->cmo);
                    402:         cp=cp->next;
                    403:     }
                    404:     fprintf(stderr, "end of list\n");
                    405: }
                    406:
                    407: int print_cmo_mathcap(cmo_mathcap* c)
                    408: {
                    409:     fprintf(stderr, "\n");
                    410:     print_cmo((cmo *)c->li);
                    411: }
                    412:
                    413: int print_cmo_string(cmo_string* c)
                    414: {
                    415:     fprintf(stderr, "cmo_string = (%s)\n", c->s);
                    416: }
                    417:
                    418: /* ox_start() から呼び出す */
                    419: static int read_password(int fd, char* passwd)
                    420: {
                    421:     char buff[1024];
                    422:     int n;
                    423:     if ((n = read(fd, buff, 1024)) != strlen(passwd)) {
                    424:         fprintf(stderr, "Socket#%d: Login incorrect.\n", fd);
                    425:         fprintf(stderr, "password = (%s), received = (%s).\n", passwd, buff);
                    426:         fprintf(stderr, "         = (%d), received = (%d).\n", strlen(passwd), n);
                    427:     }
                    428:     fflush(stderr);
                    429: }
                    430:
                    431: void ox_close(ox_file_t sv)
                    432: {
                    433:     send_ox_command(sv->control, SM_control_kill);
                    434: #if DEBUG
                    435:     sleep(2); /* OpenXM server の終了を待つ. あまり意味はない. */
                    436:     fprintf(stderr, "I have closed an Open XM server.\n");
                    437: #endif
                    438: }
                    439:
                    440: void ox_executeStringByLocalParser(ox_file_t sv, char* s)
                    441: {
                    442:     /* 文字列ををスタックにプッシュ. */
                    443:     send_ox_cmo(sv->stream, (cmo *)new_cmo_string(s));
                    444:
                    445:     /* サーバに実行させる. */
                    446:     send_ox_command(sv->stream, SM_executeStringByLocalParser);
                    447: }
                    448:
                    449: /* ox_mathcap() をコールする.  */
                    450: cmo_mathcap* ox_mathcap(ox_file_t sv)
                    451: {
                    452:     send_ox_command(sv->stream, SM_mathcap);
                    453:     send_ox_command(sv->stream, SM_popCMO);
                    454:     receive_ox_tag(sv->stream);          /* OX_DATA */
                    455:     return (cmo_mathcap *)receive_cmo(sv->stream);
                    456: }
                    457:
                    458: char* ox_popString(ox_file_t sv, int fd)
                    459: {
                    460:     cmo_string* m = NULL;
                    461:
                    462:     send_ox_command(fd, SM_popString);
                    463:     receive_ox_tag(fd); /* OX_DATA */
                    464:     m = (cmo_string *)receive_cmo(fd);
                    465:     return m->s;
                    466: }
                    467:
                    468: cmo* ox_pop_cmo(ox_file_t sv, int fd)
                    469: {
                    470:     send_ox_command(fd, SM_popCMO);
                    471:     receive_ox_tag(fd); /* OX_DATA */
                    472:     return receive_cmo(fd);
                    473: }
                    474:
                    475: /*
                    476:    ox_start は クライアントが呼び出すための関数である.
                    477:    サーバでは使われない.  prog1 は コントロールサーバであり,
                    478:    -ox, -reverse, -data, -control, -pass, -host
                    479:    というオプションを理解することを仮定する. prog2 は計算サーバである.
                    480:    接続時には, sv->control を先にオープンする.
                    481: */
                    482:
                    483: ox_file_t ox_start(char* host, char* prog1, char* prog2)
                    484: {
                    485:     static char pass[] = "passwd";
                    486:     char ctl[16], dat[16];
                    487:     short portControl = 0; /* short であることに注意 */
                    488:     short portStream  = 0;
                    489:     ox_file_t sv = malloc(sizeof(__ox_file_struct));
                    490:
                    491:     sv->control = mysocketListen(host, &portControl);
                    492:     sv->stream  = mysocketListen(host, &portStream);
                    493:     sprintf(ctl, "%d", portControl);
                    494:     sprintf(dat, "%d", portStream);
                    495:
                    496:     if (fork() == 0) {
                    497:         dup2(2, 1);
                    498:         dup2(open(DEFAULT_LOGFILE, O_RDWR|O_CREAT|O_TRUNC, 0644), 2);
                    499:         execl(prog1, prog1, "-reverse", "-ox", prog2,
                    500:               "-data", dat, "-control", ctl, "-pass", pass,
                    501:               "-host", host, NULL);
                    502:     }
                    503:
                    504:     sv->control = mysocketAccept(sv->control);
                    505:     read_password(sv->control, pass);
                    506:     decideByteOrder(sv->control, sv->control, 0);
                    507:     usleep(10);
                    508:     sv->stream  = mysocketAccept(sv->stream);
                    509:     read_password(sv->stream, pass);
                    510:     decideByteOrder(sv->stream, sv->stream, 0);
                    511:
                    512:     return sv;
                    513: }
                    514:
                    515: void ox_reset(ox_file_t sv)
                    516: {
                    517:     send_ox_command(sv->control, SM_control_reset_connection);
                    518:
                    519:     receive_ox_tag(sv->control);      /* OX_DATA */
                    520:     receive_cmo(sv->control);         /* (CMO_INT32, 0) */
                    521:
                    522:     while(receive_ox_tag(sv->stream) != OX_SYNC_BALL) {
                    523:         receive_cmo(sv->stream); /* skipping a message. */
                    524:     }
                    525:
                    526:     send_ox_tag(sv->stream, OX_SYNC_BALL);
                    527: #if DEBUG
                    528:     fprintf(stderr, "I have reset an Open XM server.\n");
                    529: #endif
                    530: }
                    531:
                    532: /* 以下は parse.c で必要とする関数たち */
                    533: /* cmolen 関数は cmo の(送信時の)バイト長を返す */
                    534: /* cmolen_XXX 関数は tag を除いたバイト長を返す */
                    535:
                    536: static int cmolen_cmo_int32(cmo_int32* c)
                    537: {
                    538:     return sizeof(int);
                    539: }
                    540:
                    541: static int cmolen_cmo_list(cmo_list* c)
                    542: {
                    543:     int size = sizeof(c->head);
                    544:     cell* cp = c->head;
                    545:
                    546:     while(cp != NULL) {
                    547:         size += cmolen_cmo(cp->cmo);
                    548:         cp = cp->next;
                    549:     }
                    550:     return size;
                    551: }
                    552:
                    553: static int cmolen_cmo_mathcap(cmo_mathcap* c)
                    554: {
                    555:     return cmolen_cmo((cmo *)c->li);
                    556: }
                    557:
                    558: static int cmolen_cmo_null(cmo_null* c)
                    559: {
                    560:     return 0;
                    561: }
                    562:
                    563: static int cmolen_cmo_string(cmo_string* c)
                    564: {
                    565:     return sizeof(int)+strlen(c->s);
                    566: }
                    567:
                    568: static int cmolen_cmo_zz(cmo_zz* c)
                    569: {
                    570:     int len = abs(c->mpz->_mp_size);
                    571:     return sizeof(len) + len*sizeof(int);
                    572: }
                    573:
                    574: /* CMO がバイトエンコードされた場合のバイト列の長さを求める */
                    575: int cmolen_cmo(cmo* c)
                    576: {
                    577:     int size = sizeof(int);
                    578:
                    579:     switch(c->tag) {
                    580:     case CMO_NULL:
                    581:         size += cmolen_cmo_null(c);
                    582:         break;
                    583:     case CMO_INT32:
                    584:         size += cmolen_cmo_int32((cmo_int32 *)c);
                    585:         break;
                    586:     case CMO_STRING:
                    587:         size += cmolen_cmo_string((cmo_string *)c);
                    588:         break;
                    589:     case CMO_LIST:
                    590:         size += cmolen_cmo_list((cmo_list *)c);
                    591:         break;
                    592:     case CMO_ZZ:
                    593:         size += cmolen_cmo_zz((cmo_zz *)c);
                    594:         break;
                    595:     case CMO_MATHCAP:
                    596:         size += cmolen_cmo_mathcap((cmo_mathcap *)c);
                    597:         break;
                    598:     default:
                    599:     }
                    600:     return size;
                    601: }
                    602:
                    603: static char* dump_cmo_int32(char* array, cmo_int32* m)
                    604: {
                    605:     return dump_integer(array, m->i);
                    606: }
                    607:
                    608: static char* dump_cmo_list(char* array, cmo_list* m)
                    609: {
                    610:     cell* cp = m->head;
                    611:     int len = length_cmo_list(m);
                    612:     array = dump_integer(array, len);
                    613:
                    614:     while(cp != NULL) {
                    615:         array = dump_cmo(array, cp->cmo);
                    616:         cp = cp->next;
                    617:     }
                    618:     return array;
                    619: }
                    620:
                    621: static char* dump_cmo_mathcap(char* array, cmo_mathcap* c)
                    622: {
                    623:     return dump_cmo(array, (cmo *)c->li);
                    624: }
                    625:
                    626: static char* dump_cmo_null(char* array, cmo_null* m)
                    627: {
                    628:     return array;
                    629: }
                    630:
                    631: static char* dump_cmo_string(char* array, cmo_string* m)
                    632: {
                    633:     int len = strlen(m->s);
                    634:     array = dump_integer(array, len);
                    635:     memcpy(array, m->s, len);
                    636:     return array + len;
                    637: }
                    638:
                    639: static char* dump_cmo_zz(char* array, cmo_zz* c)
                    640: {
                    641:     return dump_mpz(array, c->mpz);
                    642: }
                    643:
                    644: /* タグを書き出してから、各関数を呼び出す */
                    645: char* dump_cmo(char* array, cmo* m)
                    646: {
                    647:     array = dump_integer(array, m->tag);
                    648:     switch(m->tag) {
                    649:     case CMO_NULL:
                    650:         return dump_cmo_null(array, m);
                    651:     case CMO_INT32:
                    652:         return dump_cmo_int32(array, (cmo_int32 *)m);
                    653:     case CMO_STRING:
                    654:         return dump_cmo_string(array, (cmo_string *)m);
                    655:     case CMO_LIST:
                    656:         return dump_cmo_list(array, (cmo_list *)m);
                    657:     case CMO_ZZ:
                    658:         return dump_cmo_zz(array, (cmo_zz *)m);
                    659:     case CMO_MATHCAP:
                    660:         return dump_cmo_mathcap(array, (cmo_mathcap *)m);
                    661:     default:
                    662:         return NULL;
                    663:     }
                    664: }
                    665:
                    666: static char* dump_integer(char* array, int x)
                    667: {
                    668:     int nx = htonl(x);
                    669:     memcpy(array, &nx, sizeof(int));
                    670:     return array + sizeof(int);
                    671: }
                    672:
                    673: static char* dump_mpz(char* array, mpz_ptr mpz)
                    674: {
                    675:     int i;
                    676:     int len = abs(mpz->_mp_size);
                    677:     array = dump_integer(array, mpz->_mp_size);
                    678:     for(i=0; i<len; i++) {
                    679:         array = dump_integer(array, mpz->_mp_d[i]);
                    680:     }
                    681:     return array;
                    682: }
                    683:
                    684:
                    685: int send_ox(ox_file_t s, ox *m)
                    686: {
                    687:     int tag = m->tag;
                    688:     int code;
                    689:     if (tag == OX_DATA) {
                    690:         send_ox_cmo(s->stream, ((ox_data *)m)->cmo);
                    691:     }else if (tag == OX_COMMAND) {
                    692:         code = ((ox_command *)m)->command;
                    693:         if (code >= 1024) {
                    694:             /* control command */
                    695:             send_ox_command(s->control, code);
                    696:         }else {
                    697:             send_ox_command(s->stream, code);
                    698:         }
                    699:     }else {
                    700:         /* CMO?? */
                    701:         send_ox_cmo(s->stream, (cmo *)m);
                    702:     }
                    703: }
                    704:
                    705: int send_ox_cmo(int fd, cmo* m)
                    706: {
                    707:     send_ox_tag(fd, OX_DATA);
                    708:     send_cmo(fd, m);
                    709: }
                    710:
                    711: int append_cell(cell* this, cell* cp);
                    712:
                    713: cell* next_cell(cell* this)
                    714: {
                    715:     return this->next;
                    716: }
                    717:
                    718: static int send_cmo_error(int fd, cmo_error* c)
                    719: {
                    720:     send_cmo(fd, (cmo *)c->li);
                    721:     return 0;
                    722: }
                    723:
                    724: static int send_cmo_int32(int fd, cmo_int32* m)
                    725: {
                    726:     send_int32(fd, m->i);
                    727: }
                    728:
                    729: static int send_cmo_list(int fd, cmo_list* c)
                    730: {
                    731:     cell* cp = c->head;
                    732:     int len = length_cmo_list(c);
                    733:     send_int32(fd, len);
                    734:
                    735:     while(cp != NULL) {
                    736:         send_cmo(fd, cp->cmo);
                    737:         cp = cp->next;
                    738:     }
                    739:     return 0;
                    740: }
                    741:
                    742: static int send_cmo_mathcap(int fd, cmo_mathcap* c)
                    743: {
                    744:     send_cmo(fd, (cmo *)c->li);
                    745:     return 0;
                    746: }
                    747:
                    748: static int send_cmo_null(int fd, cmo_null* c)
                    749: {
                    750:     return 0;
                    751: }
                    752:
                    753: static int send_cmo_string(int fd, cmo_string* m)
                    754: {
                    755:     int len = strlen(m->s);
                    756:     send_int32(fd, len);
                    757:     if (len > 0) {
                    758:         write(fd, m->s, len);
                    759:     }
                    760:     return 0;
                    761: }
                    762:
                    763: static int send_cmo_zz(int fd, cmo_zz* c)
                    764: {
                    765:     send_mpz(fd, c->mpz);
                    766: }
                    767:
                    768: /* CMOを送る.  OX_tag は送信済*/
                    769: int send_cmo(int fd, cmo* c)
                    770: {
                    771:     int tag = c->tag;
                    772:
                    773:     send_int32(fd, tag);
                    774:     switch(tag) {
                    775:     case CMO_NULL:
                    776:         send_cmo_null(fd, c);  /* 空の関数 */
                    777:         break;
                    778:     case CMO_INT32:
                    779:         send_cmo_int32(fd, (cmo_int32 *)c);
                    780:         break;
                    781:     case CMO_STRING:
                    782:         send_cmo_string(fd, (cmo_string *)c);
                    783:         break;
                    784:     case CMO_MATHCAP:
                    785:         send_cmo_mathcap(fd, (cmo_mathcap *)c);
                    786:         break;
                    787:     case CMO_LIST:
                    788:         send_cmo_list(fd, (cmo_list *)c);
                    789:         break;
                    790:     case CMO_ZZ:
                    791:         send_cmo_zz(fd, (cmo_zz *)c);
                    792:         break;
                    793:     case CMO_ERROR2:
                    794:         send_cmo_error(fd, (cmo_error *)c);
                    795:         break;
                    796:     default:
                    797:     }
                    798: }
                    799:
                    800: /* CMO_ZZ の例外の実装が不十分?? */
                    801: static int send_mpz(int fd, mpz_ptr mpz)
                    802: {
                    803:     int i;
                    804:     int len = abs(mpz->_mp_size);
                    805:     send_int32(fd, mpz->_mp_size);
                    806:     for(i=0; i<len; i++) {
                    807:         send_int32(fd, mpz->_mp_d[i]);
                    808:     }
                    809:     return 0;
                    810: }
                    811:
                    812: ox_data* new_ox_data(cmo* c)
                    813: {
                    814:     ox_data* m = malloc(sizeof(ox_data));
                    815:     m->tag = OX_DATA;
                    816:     m->cmo = c;
                    817:     return m;
                    818: }
                    819:
                    820: ox_command* new_ox_command(int sm_code)
                    821: {
                    822:     ox_command* m = malloc(sizeof(ox_command));
                    823:     m->tag = OX_COMMAND;
                    824:     m->command = sm_code;
                    825:     return m;
                    826: }
                    827:
                    828: char* dump_ox_data(char* array, ox_data* m)
                    829: {
                    830:     array = dump_integer(array, OX_DATA);
                    831:     array = dump_integer(array, -1);
                    832:     return dump_cmo(array, m->cmo);
                    833: }
                    834:
                    835: char* dump_ox_command(char* array, ox_command* m)
                    836: {
                    837:     array = dump_integer(array, OX_COMMAND);
                    838:     array = dump_integer(array, -1);
                    839:     return dump_integer(array, m->command);
                    840: }
                    841:
                    842: #define  MAX_TYPES  8
                    843: static int known_types[] = {
                    844:     -1,   /* gate keeper */
                    845:     CMO_NULL,
                    846:     CMO_INT32,
                    847:     CMO_STRING,
                    848:     CMO_MATHCAP,
                    849:     CMO_LIST,
                    850:     CMO_ZZ,
                    851:     CMO_ERROR2,
                    852: };
                    853:
                    854: #define VER_STR   "(CMO_LIST, 2, (CMO_LIST, (CMO_INT32, %d), (CMO_STRING, \"%s\")), (CMO_LIST, 7, (CMO_INT32, 1), (CMO_INT32, 2), (CMO_INT32, 4), (CMO_INT32, 5), (CMO_INT32, 17), (CMO_INT32, 20), (CMO_INT32, 2130706434)))\n"
                    855:
                    856: cmo* make_mathcap_object2(int version, char* id_string)
                    857: {
                    858:     cmo_list *li;
                    859:     char buff[4096];
                    860:
                    861:     setgetc(mygetc);
                    862:     sprintf(buff, VER_STR, version, id_string);
                    863:     setmode_mygetc(buff, 4096);
                    864:     li = parse();
                    865:     resetgetc();
                    866:
                    867:     return (cmo *)new_cmo_mathcap(li);
                    868: }
                    869:
                    870: cmo* make_mathcap_object(int version, char* id_string)
                    871: {
                    872:     cmo_list *li_ver, *li_cmo, *li;
                    873:
                    874:     int i;
                    875:     li_ver = new_cmo_list();
                    876:     append_cmo_list(li_ver, (cmo *)new_cmo_int32(version));
                    877:     append_cmo_list(li_ver, (cmo *)new_cmo_string(id_string));
                    878:
                    879:     li_cmo = new_cmo_list();
                    880:     for(i=0; i<MAX_TYPES; i++) {
                    881:         if (known_types[i] != -1) {
                    882:             append_cmo_list(li_cmo, (cmo *)new_cmo_int32(known_types[i]));
                    883:         }
                    884:     }
                    885:
                    886:     li = new_cmo_list();
                    887:     append_cmo_list(li, (cmo *)li_ver);
                    888:     append_cmo_list(li, (cmo *)li_cmo);
                    889:
                    890:     return (cmo *)new_cmo_mathcap(li);
                    891: }
                    892:
                    893: static int funcs(int cmo_type)
                    894: {
                    895:     int i;
                    896:     for(i=0; i<MAX_TYPES; i++) {
                    897:         if (known_types[i] == cmo_type) {
                    898:             return i;
                    899:         }
                    900:     }
                    901:     return 0;
                    902: }
                    903:
                    904: void setCmotypeDisable(int type)
                    905: {
                    906:     int i = funcs(type);
                    907:     known_types[i] = -1;
                    908: }
                    909: #if 0
                    910: cmo* (*received_funcs[])(int fd) = {
                    911:     NULL,  /* gate keeper */
                    912:     receive_cmo_null,
                    913:     receive_cmo_int32,
                    914:     receive_cmo_string,
                    915:     receive_cmo_mathcap,
                    916:     receive_cmo_list,
                    917:     receive_cmo_zz,
                    918:     receive_cmo_error
                    919: };
                    920:
                    921: cmo* receive_cmo2(int fd)
                    922: {
                    923:     int tag;
                    924:     cmo* (*foo)() = received_funcs[funcs(tag)];
                    925:     if (foo != NULL) {
                    926:         return foo(fd);
                    927:     }
                    928: }
                    929: #endif
                    930: /* ファイルディスクリプタ fd の通信路での integer の byte order を決定する */
                    931: /* 実際には order (0,1,or 0xFF)をみてはいない */
                    932: int decideByteOrder(int fd_read, int fd_write, int order)
                    933: {
                    934:     char zero = '\0';
                    935:     char dest;
                    936:     write(fd_write, &zero, 1);
                    937:     read(fd_read, &dest, 1);
                    938:     return 0;
                    939: }
                    940:
                    941: /* Server 側ではこちらを用いる */
                    942: int decideByteOrder2(int fd_read, int fd_write, int order)
                    943: {
                    944:     char zero = '\0';
                    945:     char dest;
                    946:     read(fd_read, &dest, 1);
                    947:     write(fd_write, &zero, 1);
                    948:     return 0;
                    949: }
                    950:
                    951: /* cmo と string の変換関数群 */
                    952:
                    953: cmo_zz *new_cmo_zz_set_string(char *s)
                    954: {
                    955:     cmo_zz* c = new_cmo_zz_noinit();
                    956:     mpz_init_set_str(c->mpz, s, 10);
                    957:     return c;
                    958: }
                    959:
                    960: char *CONVERT_ZZ_TO_CSTRING(cmo_zz *c)
                    961: {
                    962:     return mpz_get_str(NULL, 10, c->mpz);
                    963: }
                    964:
                    965: char *CONVERT_CMO_TO_CSTRING(cmo *m)
                    966: {
                    967:     switch(m->tag) {
                    968:     case CMO_ZZ:
                    969:         return CONVERT_ZZ_TO_CSTRING((cmo_zz *)m);
                    970:     case CMO_INT32:
                    971:         return CONVERT_INT_TO_CSTRING(((cmo_int32 *)m)->i);
                    972:     case CMO_STRING:
                    973:         return ((cmo_string *)m)->s;
                    974:     case CMO_NULL:
                    975:         return CONVERT_NULL_TO_CSTRING();
                    976:     default:
                    977:         fprintf(stderr, "sorry, not implemented CMO\n");
                    978:         /* まだ実装していません. */
                    979:         return NULL;
                    980:     }
                    981: }
                    982:
                    983: char *CONVERT_NULL_TO_CSTRING()
                    984: {
                    985:     static char* null_string = "";
                    986:     return null_string;
                    987: }
                    988:
                    989: char *CONVERT_INT_TO_CSTRING(int integer)
                    990: {
                    991:     char buff[1024];
                    992:     char *s;
                    993:
                    994:     sprintf(buff, "%d", integer);
                    995:     s = malloc(strlen(buff)+1);
                    996:     strcpy(s, buff);
                    997:
                    998:     return s;
                    999: }

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