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>