[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     ! 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>