Annotation of OpenXM/src/ox_toolkit/ox.c, Revision 1.49
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.49 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.48 2016/06/30 01:14:00 ohara Exp $ */
1.1 ohara 3:
1.8 ohara 4: /*
5: This module includes functions for sending/receiveng CMO's.
1.1 ohara 6: */
7:
8: #include <stdio.h>
9: #include <stdlib.h>
1.20 ohara 10: #include <stdarg.h>
1.1 ohara 11: #include <string.h>
1.45 ohara 12: #include <fcntl.h>
13: #include <time.h>
1.46 ohara 14: #include <limits.h>
1.45 ohara 15: #if !defined(_MSC_VER)
1.1 ohara 16: #include <unistd.h>
1.5 ohara 17: #include <sys/file.h>
1.45 ohara 18: #endif
1.1 ohara 19:
1.38 noro 20: #include <mpfr.h>
21: /* XXX : defined in mpfr-impl.h */
22: #define MPFR_PREC(x) ((x)->_mpfr_prec)
23: #define MPFR_EXP(x) ((x)->_mpfr_exp)
24: #define MPFR_MANT(x) ((x)->_mpfr_d)
1.46 ohara 25: #define RAT_CEIL(nm,dn) (((nm)+(dn)-1)/((dn)))
26: #define MPFR_LIMB_SIZE_REAL(x) (RAT_CEIL(MPFR_PREC((x)),sizeof(mp_limb_t)*CHAR_BIT) * (sizeof(mp_limb_t)/sizeof(int)) )
27: #define MPFR_LIMB_SIZE_BODY(x) (RAT_CEIL(MPFR_PREC((x)),sizeof(unsigned int)*CHAR_BIT))
1.38 noro 28:
29: #if SIZEOF_LONG==4
30: typedef long long L64;
31: typedef unsigned long long UL64;
32: #else
33: typedef long L64;
34: typedef unsigned long UL64;
35: #endif
36:
1.1 ohara 37: #include "mysocket.h"
1.12 ohara 38: #include "ox_toolkit.h"
1.1 ohara 39: #include "parse.h"
40:
1.20 ohara 41: static FILE *ox_stderr = NULL;
42:
1.17 ohara 43: /* sorting by the value of CMO_xxx. (for debugging) */
1.13 ohara 44: static cmo_null* receive_cmo_null(OXFILE *oxfp);
45: static cmo_int32* receive_cmo_int32(OXFILE *oxfp);
46: static cmo_string* receive_cmo_string(OXFILE *oxfp);
47: static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp);
48: static cmo_list* receive_cmo_list(OXFILE *oxfp);
49: static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp);
50: static cmo_zero* receive_cmo_zero(OXFILE *oxfp);
51: static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp);
52: static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp);
53: static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp);
1.26 ohara 54: static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp);
55: static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp);
1.32 ohara 56: static cmo_double* receive_cmo_double(OXFILE *oxfp);
1.13 ohara 57: static cmo_error2* receive_cmo_error2(OXFILE *oxfp);
58:
59: static int send_cmo_null(OXFILE *oxfp, cmo_null* c);
60: static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m);
61: static int send_cmo_string(OXFILE *oxfp, cmo_string* m);
62: static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c);
63: static int send_cmo_list(OXFILE *oxfp, cmo_list* c);
64: static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c);
1.32 ohara 65: static int send_cmo_double(OXFILE *oxfp, cmo_double* c);
1.22 ohara 66: static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c);
67: static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c);
1.26 ohara 68: static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c);
69: static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c);
1.22 ohara 70:
71: static cmo_zz* receive_cmo_zz(OXFILE *oxfp);
72: static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz);
1.13 ohara 73: static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c);
74: static int send_mpz(OXFILE *oxfp, mpz_ptr mpz);
1.46 ohara 75: static cmo_bf* receive_cmo_bf(OXFILE *oxfp);
1.38 noro 76: static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
1.46 ohara 77: static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c);
1.38 noro 78: static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
1.3 ohara 79:
1.8 ohara 80: /* hook functions. (yet not implemented) */
1.2 ohara 81: static hook_t hook_before_send_cmo = NULL;
82: static hook_t hook_after_send_cmo = NULL;
83:
84: int add_hook_before_send_cmo(hook_t func)
85: {
1.13 ohara 86: hook_before_send_cmo = func;
87: return 0;
1.2 ohara 88: }
89:
90: int add_hook_after_send_cmo(hook_t func)
91: {
1.13 ohara 92: hook_after_send_cmo = func;
93: return 0;
1.2 ohara 94: }
95:
1.13 ohara 96: static cmo *call_hook_before_send_cmo(OXFILE *oxfp, cmo *c)
1.2 ohara 97: {
1.13 ohara 98: if (hook_before_send_cmo != NULL) {
99: return hook_before_send_cmo(oxfp, c);
100: }
101: return c;
1.2 ohara 102: }
103:
1.13 ohara 104: static cmo *call_hook_after_send_cmo(OXFILE *oxfp, cmo *c)
1.2 ohara 105: {
1.13 ohara 106: if (hook_after_send_cmo != NULL) {
107: return hook_after_send_cmo(oxfp, c);
108: }
109: return c;
1.2 ohara 110: }
1.1 ohara 111:
1.7 ohara 112: /* Handling an error. */
1.1 ohara 113: static int current_received_serial = 0;
114:
1.7 ohara 115: /* If an error object be needed, then a server call the following function. */
1.1 ohara 116: cmo_error2* make_error_object(int err_code, cmo *ob)
117: {
118: cmo_list* li = new_cmo_list();
1.13 ohara 119: list_append(li, (cmo *)new_cmo_int32(current_received_serial));
120: list_append(li, (cmo *)new_cmo_int32(err_code));
121: list_append(li, ob);
1.1 ohara 122: return new_cmo_error2((cmo *)li);
123: }
124:
1.7 ohara 125: /* getting a next serial number. */
1.13 ohara 126: int next_serial(OXFILE *oxfp)
1.1 ohara 127: {
1.13 ohara 128: return oxfp->serial_number++;
1.1 ohara 129: }
130:
1.7 ohara 131: /* sending an object of int32 type. (not equal to cmo_int32 type) */
1.13 ohara 132: int send_int32(OXFILE *oxfp, int int32)
1.1 ohara 133: {
1.13 ohara 134: return oxfp->send_int32(oxfp, int32);
1.1 ohara 135: }
136:
1.13 ohara 137: /* receiving an object of int32 type. (not equal to cmo_int32 type) */
138: int receive_int32(OXFILE *oxfp)
1.1 ohara 139: {
1.13 ohara 140: return oxfp->receive_int32(oxfp);
1.1 ohara 141: }
142:
1.32 ohara 143: /* sending an object of int32 type. (not equal to cmo_int32 type) */
144: int send_double(OXFILE *oxfp, double d)
145: {
146: return oxfp->send_double(oxfp, d);
147: }
148:
149: /* receiving an object of int32 type. (not equal to cmo_int32 type) */
150: double receive_double(OXFILE *oxfp)
151: {
152: return oxfp->receive_double(oxfp);
153: }
154:
1.13 ohara 155: /* receiving an (OX_tag, serial number) */
156: int receive_ox_tag(OXFILE *oxfp)
1.1 ohara 157: {
1.13 ohara 158: int tag = receive_int32(oxfp);
1.16 ohara 159: oxfp->received_serial_number = receive_int32(oxfp);
1.13 ohara 160: return tag;
1.1 ohara 161: }
162:
1.13 ohara 163: /* sending an (OX_tag, serial number) */
164: int send_ox_tag(OXFILE *oxfp, int tag)
1.3 ohara 165: {
1.13 ohara 166: send_int32(oxfp, tag);
167: return send_int32(oxfp, next_serial(oxfp));
1.1 ohara 168: }
169:
1.7 ohara 170: /* functions named receive_cmo_*. */
1.13 ohara 171: static cmo_null* receive_cmo_null(OXFILE *oxfp)
1.1 ohara 172: {
173: return new_cmo_null();
174: }
175:
1.13 ohara 176: static cmo_int32* receive_cmo_int32(OXFILE *oxfp)
1.1 ohara 177: {
1.13 ohara 178: int i = receive_int32(oxfp);
1.1 ohara 179: return new_cmo_int32(i);
180: }
181:
1.13 ohara 182: static cmo_string* receive_cmo_string(OXFILE *oxfp)
1.1 ohara 183: {
1.49 ! ohara 184: int i,n;
1.13 ohara 185: int len = receive_int32(oxfp);
1.25 ohara 186: char* s = MALLOC(len+1);
1.1 ohara 187: memset(s, '\0', len+1);
1.49 ! ohara 188: for(i=0; i<len; i+=n) {
! 189: n=oxf_read(s+i, 1, len-i, oxfp);
1.1 ohara 190: }
191: return new_cmo_string(s);
192: }
193:
1.13 ohara 194: static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp)
1.1 ohara 195: {
1.13 ohara 196: cmo* ob = receive_cmo(oxfp);
1.1 ohara 197: return new_cmo_mathcap(ob);
198: }
199:
1.13 ohara 200: static cmo_list* receive_cmo_list(OXFILE *oxfp)
1.1 ohara 201: {
202: cmo* ob;
203: cmo_list* c = new_cmo_list();
1.13 ohara 204: int len = receive_int32(oxfp);
1.1 ohara 205:
206: while (len>0) {
1.13 ohara 207: ob = receive_cmo(oxfp);
208: list_append(c, ob);
1.1 ohara 209: len--;
210: }
211: return c;
212: }
213:
1.13 ohara 214: static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp)
1.1 ohara 215: {
216: int i;
1.13 ohara 217: int len = receive_int32(oxfp);
1.1 ohara 218: cmo_monomial32* c = new_cmo_monomial32(len);
219:
220: for(i=0; i<len; i++) {
1.13 ohara 221: c->exps[i] = receive_int32(oxfp);
1.1 ohara 222: }
1.13 ohara 223: c->coef = receive_cmo(oxfp);
1.1 ohara 224: return c;
225: }
226:
1.13 ohara 227: static cmo_zz* receive_cmo_zz(OXFILE *oxfp)
1.1 ohara 228: {
229: cmo_zz* c = new_cmo_zz();
1.13 ohara 230: receive_mpz(oxfp, c->mpz);
1.1 ohara 231: return c;
232: }
233:
1.33 ohara 234: static cmo_qq* receive_cmo_qq(OXFILE *oxfp)
235: {
1.34 ohara 236: mpz_t num, den;
237: mpz_init(num);
238: mpz_init(den);
239: receive_mpz(oxfp, num);
240: receive_mpz(oxfp, den);
241: return new_cmo_qq_set_mpz(num, den);
1.33 ohara 242: }
243:
1.38 noro 244: static cmo_bf* receive_cmo_bf(OXFILE *oxfp)
245: {
246: mpfr_t num;
247: mpfr_init(num);
248: receive_mpfr(oxfp, num);
249: return new_cmo_bf_set_mpfr(num);
250: }
251:
1.44 noro 252: static cmo_complex* receive_cmo_complex(OXFILE *oxfp)
253: {
254: cmo *re, *im;
255:
256: re = receive_cmo(oxfp);
257: im = receive_cmo(oxfp);
258: return new_cmo_complex_set_re_im(re,im);
259: }
260:
261:
1.13 ohara 262: static cmo_zero* receive_cmo_zero(OXFILE *oxfp)
1.1 ohara 263: {
264: return new_cmo_zero();
265: }
266:
1.13 ohara 267: static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp)
1.1 ohara 268: {
269: return new_cmo_dms_generic();
270: }
271:
1.13 ohara 272: static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp)
1.1 ohara 273: {
1.13 ohara 274: cmo* ob = receive_cmo(oxfp);
275: /* We need to check semantics but yet ... */
1.1 ohara 276: return new_cmo_ring_by_name(ob);
277: }
278:
1.26 ohara 279: static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp)
280: {
1.27 ohara 281: cmo_list* ringdef = (cmo_list *)receive_cmo(oxfp);
282: cmo* coef = receive_cmo(oxfp);
1.26 ohara 283: return new_cmo_recursive_polynomial(ringdef, coef);
284: }
285:
1.13 ohara 286: static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp)
1.1 ohara 287: {
288: cmo* ob;
289: cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();
1.13 ohara 290: int len = receive_int32(oxfp);
291: c->ringdef = receive_cmo(oxfp);
1.1 ohara 292:
293: while (len>0) {
1.13 ohara 294: ob = receive_cmo(oxfp);
295: list_append((cmo_list *)c, ob);
1.1 ohara 296: len--;
297: }
298: return c;
299: }
300:
1.26 ohara 301: static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp)
302: {
303: cmo* coef;
304: cmo_polynomial_in_one_variable* c;
305: int len = receive_int32(oxfp);
306: int var = receive_int32(oxfp);
307: int exp;
308: c = new_cmo_polynomial_in_one_variable(var);
309: while (len>0) {
310: exp = receive_int32(oxfp);
311: coef = receive_cmo(oxfp);
1.27 ohara 312: list_append_monomial((cmo_list *)c, coef, exp);
1.26 ohara 313: len--;
314: }
315: return c;
316: }
317:
1.32 ohara 318: static cmo_double* receive_cmo_double(OXFILE *oxfp)
319: {
320: double d = receive_double(oxfp);
321: return new_cmo_double(d);
322: }
323:
1.29 ohara 324: static cmo_indeterminate* receive_cmo_indeterminate(OXFILE *oxfp)
325: {
326: cmo* ob = receive_cmo(oxfp);
327: return new_cmo_indeterminate(ob);
328: }
329:
1.28 ohara 330: static cmo_tree* receive_cmo_tree(OXFILE *oxfp)
331: {
332: cmo_string* name = (cmo_string *)receive_cmo(oxfp);
333: cmo_list* attrib = (cmo_list *)receive_cmo(oxfp);
334: cmo_list* leaves = (cmo_list *)receive_cmo(oxfp);
335: return new_cmo_tree(name, attrib, leaves);
336: }
337:
338: static cmo_lambda* receive_cmo_lambda(OXFILE *oxfp)
339: {
340: cmo_list* args = (cmo_list *)receive_cmo(oxfp);
341: cmo_tree* body = (cmo_tree *)receive_cmo(oxfp);
342: return new_cmo_lambda(args, body);
343: }
344:
1.13 ohara 345: static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
1.1 ohara 346: {
1.13 ohara 347: cmo* ob = receive_cmo(oxfp);
1.1 ohara 348: return new_cmo_error2(ob);
349: }
350:
1.17 ohara 351: /* receive_cmo() is called after receive_ox_tag(). */
1.13 ohara 352: cmo* receive_cmo(OXFILE *oxfp)
1.1 ohara 353: {
1.24 ohara 354: int tag = receive_int32(oxfp);
355: return receive_cmo_tag(oxfp, tag);
356: }
357:
358: cmo *receive_cmo_tag(OXFILE *oxfp, int tag)
359: {
1.1 ohara 360: cmo* m;
361: switch(tag) {
362: case CMO_NULL:
1.13 ohara 363: m = receive_cmo_null(oxfp);
1.1 ohara 364: break;
365: case CMO_INT32:
1.13 ohara 366: m = (cmo *)receive_cmo_int32(oxfp);
1.1 ohara 367: break;
368: case CMO_STRING:
1.13 ohara 369: m = (cmo *)receive_cmo_string(oxfp);
1.1 ohara 370: break;
371: case CMO_MATHCAP:
1.13 ohara 372: m = (cmo *)receive_cmo_mathcap(oxfp);
1.1 ohara 373: break;
374: case CMO_LIST:
1.13 ohara 375: m = (cmo *)receive_cmo_list(oxfp);
1.1 ohara 376: break;
377: case CMO_MONOMIAL32:
1.13 ohara 378: m = (cmo *)receive_cmo_monomial32(oxfp);
1.1 ohara 379: break;
380: case CMO_ZZ:
1.13 ohara 381: m = (cmo *)receive_cmo_zz(oxfp);
1.1 ohara 382: break;
1.33 ohara 383: case CMO_QQ:
384: m = (cmo *)receive_cmo_qq(oxfp);
385: break;
1.47 ohara 386: case CMO_BIGFLOAT32:
1.38 noro 387: m = (cmo *)receive_cmo_bf(oxfp);
388: break;
1.44 noro 389: case CMO_COMPLEX:
390: m = (cmo *)receive_cmo_complex(oxfp);
391: break;
1.1 ohara 392: case CMO_ZERO:
1.13 ohara 393: m = (cmo *)receive_cmo_zero(oxfp);
1.1 ohara 394: break;
395: case CMO_DMS_GENERIC:
1.13 ohara 396: m = (cmo *)receive_cmo_dms_generic(oxfp);
1.1 ohara 397: break;
398: case CMO_RING_BY_NAME:
1.13 ohara 399: m = (cmo *)receive_cmo_ring_by_name(oxfp);
1.1 ohara 400: break;
401: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 402: m = (cmo *)receive_cmo_distributed_polynomial(oxfp);
1.1 ohara 403: break;
1.26 ohara 404: case CMO_RECURSIVE_POLYNOMIAL:
405: m = (cmo *)receive_cmo_recursive_polynomial(oxfp);
406: break;
407: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
408: m = (cmo *)receive_cmo_polynomial_in_one_variable(oxfp);
1.29 ohara 409: break;
1.32 ohara 410: case CMO_64BIT_MACHINE_DOUBLE:
411: case CMO_IEEE_DOUBLE_FLOAT:
412: m = (cmo *)receive_cmo_double(oxfp);
413: break;
1.29 ohara 414: case CMO_INDETERMINATE:
415: m = (cmo *)receive_cmo_indeterminate(oxfp);
1.28 ohara 416: break;
417: case CMO_TREE:
418: m = (cmo *)receive_cmo_tree(oxfp);
419: break;
420: case CMO_LAMBDA:
421: m = (cmo *)receive_cmo_lambda(oxfp);
422: break;
1.1 ohara 423: case CMO_ERROR2:
1.13 ohara 424: m = (cmo *)receive_cmo_error2(oxfp);
1.1 ohara 425: break;
426: case CMO_DATUM:
427: default:
1.13 ohara 428: m = NULL;
1.20 ohara 429: ox_printf("the CMO (%d) is not implemented.\n", tag);
1.1 ohara 430: }
431: return m;
432: }
433:
1.13 ohara 434: static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 435: {
436: int i;
1.36 iwane 437: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
1.13 ohara 438: int size = receive_int32(oxfp);
1.1 ohara 439: int len = abs(size);
1.36 iwane 440: int *ptr;
441: if (n == 1) {
442: resize_mpz(mpz, size);
1.37 iwane 443: } else if (size >= 0) {
444: resize_mpz(mpz, (size+1) / n);
1.36 iwane 445: } else {
1.37 iwane 446: resize_mpz(mpz, (size-1) / n);
1.36 iwane 447: }
448:
449: ptr = (int *)mpz->_mp_d;
450: for(i=0; i<len; i++) {
451: ptr[i] = receive_int32(oxfp);
452: }
1.1 ohara 453: }
454:
1.13 ohara 455: void send_ox_command(OXFILE *oxfp, int sm_command)
1.1 ohara 456: {
1.13 ohara 457: send_ox_tag(oxfp, OX_COMMAND);
458: send_int32(oxfp, sm_command);
459: oxf_flush(oxfp);
1.1 ohara 460: }
461:
1.13 ohara 462: void ox_close(OXFILE *sv)
1.1 ohara 463: {
1.13 ohara 464: send_ox_command(oxf_control(sv), SM_control_kill);
1.7 ohara 465: sleep(2);
1.13 ohara 466: /* We wait thar an OpenXM server terminates. */
1.20 ohara 467: ox_printf("I have closed the connection to an Open XM server.\n");
1.1 ohara 468: }
469:
1.13 ohara 470: void ox_shutdown(OXFILE *sv)
1.3 ohara 471: {
1.13 ohara 472: /* We need to use SM_shutdown but yet ... */
473: ox_close(sv);
1.3 ohara 474: }
475:
1.13 ohara 476: void ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[])
1.3 ohara 477: {
1.13 ohara 478: int i = argc;
479: while(i-- > 0) {
480: send_ox_cmo(sv, argv[i]);
481: }
482: send_ox_cmo(sv, (cmo *)new_cmo_int32(argc));
483: send_ox_cmo(sv, (cmo *)new_cmo_string(function));
484: send_ox_command(sv, SM_executeFunction);
1.3 ohara 485: }
486:
1.13 ohara 487: void ox_execute_string(OXFILE *sv, char* s)
1.3 ohara 488: {
1.13 ohara 489: send_ox_cmo(sv, (cmo *)new_cmo_string(s));
490: send_ox_command(sv, SM_executeStringByLocalParser);
1.3 ohara 491: }
492:
1.13 ohara 493: void ox_push_cmd(OXFILE *sv, int sm_code)
1.1 ohara 494: {
1.13 ohara 495: send_ox_command(sv, sm_code);
1.1 ohara 496: }
497:
1.13 ohara 498: cmo_mathcap* ox_mathcap(OXFILE *sv)
1.1 ohara 499: {
1.13 ohara 500: send_ox_command(sv, SM_mathcap);
501: send_ox_command(sv, SM_popCMO);
502: receive_ox_tag(sv); /* OX_DATA */
503: return (cmo_mathcap *)receive_cmo(sv);
1.1 ohara 504: }
505:
1.13 ohara 506: char* ox_popString(OXFILE *sv)
1.1 ohara 507: {
508: cmo_string* m = NULL;
509:
1.13 ohara 510: send_ox_command(sv, SM_popString);
511: receive_ox_tag(sv); /* OX_DATA */
512: m = (cmo_string *)receive_cmo(sv);
1.1 ohara 513: return m->s;
514: }
515:
1.13 ohara 516: void ox_pops(OXFILE *sv, int num)
1.3 ohara 517: {
1.13 ohara 518: send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
519: send_ox_command(sv, SM_pops);
1.3 ohara 520: }
521:
1.13 ohara 522: cmo* ox_pop_cmo(OXFILE *sv)
1.3 ohara 523: {
1.13 ohara 524: send_ox_command(sv, SM_popCMO);
525: receive_ox_tag(sv); /* OX_DATA */
526: return receive_cmo(sv);
1.3 ohara 527: }
528:
1.13 ohara 529: void ox_push_cmo(OXFILE *sv, cmo *c)
1.3 ohara 530: {
1.13 ohara 531: send_ox_cmo(sv, c);
1.3 ohara 532: }
533:
1.7 ohara 534: /* a dummy function for flushing a connection. */
1.13 ohara 535: int ox_flush(OXFILE *sv)
1.5 ohara 536: {
1.13 ohara 537: return 1;
1.5 ohara 538: }
539:
1.13 ohara 540: void ox_reset(OXFILE *sv)
1.1 ohara 541: {
1.13 ohara 542: send_ox_command(oxf_control(sv), SM_control_reset_connection);
1.31 iwane 543: while(receive_ox_tag(sv) != OX_SYNC_BALL) {
544: receive_cmo(sv); /* skipping a message. */
1.1 ohara 545: }
546:
1.13 ohara 547: send_ox_tag(sv, OX_SYNC_BALL);
1.20 ohara 548: ox_printf("I have reset an Open XM server.\n");
1.1 ohara 549: }
550:
1.13 ohara 551: void send_ox(OXFILE *oxfp, ox *m)
1.1 ohara 552: {
553: switch(m->tag) {
1.13 ohara 554: case OX_DATA:
555: send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
1.1 ohara 556: break;
1.13 ohara 557: case OX_COMMAND:
558: send_ox_command(oxfp, ((ox_command *)m)->command);
1.1 ohara 559: break;
560: default:
561: /* CMO?? */
1.13 ohara 562: send_ox_cmo(oxfp, (cmo *)m);
1.1 ohara 563: }
564: }
565:
1.13 ohara 566: void send_ox_cmo(OXFILE *oxfp, cmo* m)
1.1 ohara 567: {
1.13 ohara 568: send_ox_tag(oxfp, OX_DATA);
569: send_cmo(oxfp, m);
570: oxf_flush(oxfp);
1.1 ohara 571: }
572:
1.8 ohara 573: /* send_cmo_* functions */
1.13 ohara 574: static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
1.1 ohara 575: {
576: return 0;
577: }
578:
1.13 ohara 579: static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
1.1 ohara 580: {
1.13 ohara 581: return send_int32(oxfp, m->i);
1.1 ohara 582: }
583:
1.13 ohara 584: static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
1.1 ohara 585: {
586: int len = (m->s != NULL)? strlen(m->s): 0;
1.13 ohara 587: send_int32(oxfp, len);
1.1 ohara 588: if (len > 0) {
1.13 ohara 589: oxf_write(m->s, 1, len, oxfp);
1.1 ohara 590: }
591: return 0;
592: }
593:
1.13 ohara 594: static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
1.1 ohara 595: {
1.13 ohara 596: send_cmo(oxfp, c->ob);
1.1 ohara 597: return 0;
598: }
599:
1.13 ohara 600: static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
1.1 ohara 601: {
1.13 ohara 602: cell* el = list_first(c);
603: int len = list_length(c);
604: send_int32(oxfp, len);
605:
606: while(!list_endof(c, el)) {
607: send_cmo(oxfp, el->cmo);
608: el = list_next(el);
1.1 ohara 609: }
610: return 0;
611: }
612:
1.13 ohara 613: static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
1.1 ohara 614: {
1.13 ohara 615: cell* el = list_first((cmo_list *)c);
616: int len = list_length((cmo_list *)c);
617: send_int32(oxfp, len);
618: send_cmo(oxfp, c->ringdef);
619: while(!list_endof((cmo_list *)c, el)) {
620: send_cmo(oxfp, el->cmo);
621: el = list_next(el);
1.1 ohara 622: }
623: return 0;
624: }
625:
1.26 ohara 626: static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c)
627: {
1.27 ohara 628: cell* el = list_first((cmo_list *)c);
629: int len = list_length((cmo_list *)c);
1.26 ohara 630: send_int32(oxfp, len);
631: send_int32(oxfp, c->var);
632:
1.27 ohara 633: while(!list_endof((cmo_list *)c, el)) {
634: send_int32(oxfp, el->exp);
1.26 ohara 635: send_cmo(oxfp, el->cmo);
636: el = list_next(el);
637: }
638: return 0;
639: }
640:
1.32 ohara 641: static int send_cmo_double(OXFILE *oxfp, cmo_double* c)
642: {
643: return send_double(oxfp, c->d);
644: }
645:
1.13 ohara 646: static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
1.1 ohara 647: {
648: int i;
649: int len = c->length;
1.13 ohara 650: send_int32(oxfp, len);
1.1 ohara 651: for(i=0; i<len; i++) {
1.13 ohara 652: send_int32(oxfp, c->exps[i]);
1.1 ohara 653: }
1.13 ohara 654: send_cmo(oxfp, c->coef);
1.1 ohara 655: return 0;
656: }
657:
1.13 ohara 658: static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
1.1 ohara 659: {
1.13 ohara 660: send_mpz(oxfp, c->mpz);
1.1 ohara 661: return 0;
662: }
663:
1.33 ohara 664: static int send_cmo_qq(OXFILE *oxfp, cmo_qq* c)
665: {
1.34 ohara 666: send_mpz(oxfp, mpq_numref(c->mpq));
667: send_mpz(oxfp, mpq_denref(c->mpq));
1.33 ohara 668: return 0;
669: }
670:
1.38 noro 671: static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c)
672: {
673: send_mpfr(oxfp, c->mpfr);
674: return 0;
675: }
676:
1.44 noro 677: static int send_cmo_complex(OXFILE *oxfp, cmo_complex* c)
678: {
679: send_cmo(oxfp, c->re);
680: send_cmo(oxfp, c->im);
681: return 0;
682: }
683:
1.26 ohara 684: static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c)
685: {
1.27 ohara 686: send_cmo(oxfp, (cmo *)c->ringdef);
1.26 ohara 687: send_cmo(oxfp, c->coef);
688: return 0;
689: }
690:
1.28 ohara 691: static int send_cmo_tree(OXFILE *oxfp, cmo_tree *c)
692: {
693: send_cmo(oxfp, (cmo *)c->name);
694: send_cmo(oxfp, (cmo *)c->attributes);
695: send_cmo(oxfp, (cmo *)c->leaves);
696: return 0;
697: }
698:
699: static int send_cmo_lambda(OXFILE *oxfp, cmo_lambda *c)
700: {
701: send_cmo(oxfp, (cmo *)c->args);
702: send_cmo(oxfp, (cmo *)c->body);
703: return 0;
704: }
705:
1.13 ohara 706: static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c)
1.1 ohara 707: {
1.13 ohara 708: send_cmo(oxfp, c->ob);
1.1 ohara 709: return 0;
710: }
711:
1.8 ohara 712: /* sending a CMO. (Remarks: OX_tag is already sent.) */
1.13 ohara 713: void send_cmo(OXFILE *oxfp, cmo* c)
1.1 ohara 714: {
715: int tag = c->tag;
716:
1.13 ohara 717: c = call_hook_before_send_cmo(oxfp, c);
1.2 ohara 718:
1.13 ohara 719: send_int32(oxfp, tag);
1.1 ohara 720: switch(tag) {
721: case CMO_NULL:
722: case CMO_ZERO:
723: case CMO_DMS_GENERIC:
1.13 ohara 724: send_cmo_null(oxfp, c); /* empty function. */
1.1 ohara 725: break;
726: case CMO_INT32:
1.13 ohara 727: send_cmo_int32(oxfp, (cmo_int32 *)c);
1.1 ohara 728: break;
729: case CMO_STRING:
1.13 ohara 730: send_cmo_string(oxfp, (cmo_string *)c);
1.1 ohara 731: break;
732: case CMO_MATHCAP:
733: case CMO_ERROR2:
734: case CMO_RING_BY_NAME:
735: case CMO_INDETERMINATE:
1.13 ohara 736: send_cmo_mathcap(oxfp, (cmo_mathcap *)c);
1.1 ohara 737: break;
738: case CMO_LIST:
1.13 ohara 739: send_cmo_list(oxfp, (cmo_list *)c);
1.1 ohara 740: break;
741: case CMO_MONOMIAL32:
1.13 ohara 742: send_cmo_monomial32(oxfp, (cmo_monomial32 *)c);
1.1 ohara 743: break;
744: case CMO_ZZ:
1.13 ohara 745: send_cmo_zz(oxfp, (cmo_zz *)c);
1.33 ohara 746: break;
747: case CMO_QQ:
748: send_cmo_qq(oxfp, (cmo_qq *)c);
1.1 ohara 749: break;
1.47 ohara 750: case CMO_BIGFLOAT32:
1.38 noro 751: send_cmo_bf(oxfp, (cmo_bf *)c);
752: break;
1.44 noro 753: case CMO_COMPLEX:
754: send_cmo_complex(oxfp, (cmo_complex *)c);
755: break;
1.1 ohara 756: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 757: send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c);
1.26 ohara 758: break;
759: case CMO_RECURSIVE_POLYNOMIAL:
760: send_cmo_recursive_polynomial(oxfp, (cmo_recursive_polynomial *)c);
761: break;
762: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
763: send_cmo_polynomial_in_one_variable(oxfp, (cmo_polynomial_in_one_variable *)c);
1.28 ohara 764: break;
1.32 ohara 765: case CMO_64BIT_MACHINE_DOUBLE:
766: case CMO_IEEE_DOUBLE_FLOAT:
767: send_cmo_double(oxfp, (cmo_double *)c);
768: break;
1.28 ohara 769: case CMO_TREE:
770: send_cmo_tree(oxfp, (cmo_tree *)c);
771: break;
772: case CMO_LAMBDA:
773: send_cmo_lambda(oxfp, (cmo_lambda *)c);
1.1 ohara 774: break;
775: default:
1.13 ohara 776: call_hook_after_send_cmo(oxfp, c);
1.1 ohara 777: }
778: }
779:
1.13 ohara 780: static int send_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 781: {
782: int i;
1.35 iwane 783: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
784: int len = abs(mpz->_mp_size) * n;
785: int *ptr = (int *)mpz->_mp_d;
1.37 iwane 786: int size;
787: if (len > 0 && ptr[len-1] == 0) {
788: len--;
789: }
790: size = mpz->_mp_size < 0 ? -len : len;
791: send_int32(oxfp, size);
1.1 ohara 792: for(i=0; i<len; i++) {
1.35 iwane 793: send_int32(oxfp, ptr[i]);
1.1 ohara 794: }
795: return 0;
796: }
797:
1.41 noro 798: int send_int64(OXFILE *oxfp,UL64 a)
1.38 noro 799: {
1.41 noro 800: return oxfp->send_double(oxfp,((double *)&a)[0]);
1.38 noro 801: }
802:
803: UL64 receive_int64(OXFILE *oxfp)
804: {
1.41 noro 805: double d = receive_double(oxfp);
1.46 ohara 806: return ((UL64 *)&d)[0];
1.38 noro 807: }
808:
809: static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
810: {
1.46 ohara 811: int sgn,prec,exp,len_r,len,i;
812: unsigned int *ptr;
813:
814: prec = receive_int32(oxfp);
815: sgn = receive_int32(oxfp);
816: exp = receive_int32(oxfp);
817: len = receive_int32(oxfp);
818: mpfr_init2(mpfr,prec); /* initialized by NaN */
819: MPFR_SIGN(mpfr) = sgn;
820: MPFR_EXP(mpfr) = exp;
821: *(MPFR_MANT(mpfr))=0; /* initialized by 0 */
822: ptr = (unsigned int *)MPFR_MANT(mpfr);
823: len_r = MPFR_LIMB_SIZE_REAL(mpfr);
824: for(i=(len_r-len); i<len_r; i++) {
825: ptr[i] = receive_int32(oxfp);
826: }
1.38 noro 827: }
828:
829: static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
830: {
1.46 ohara 831: int i,len_r,len;
832: unsigned int *ptr;
1.38 noro 833:
1.46 ohara 834: send_int32(oxfp, MPFR_PREC(mpfr));
835: send_int32(oxfp, MPFR_SIGN(mpfr));
836: send_int32(oxfp, MPFR_EXP(mpfr));
837: len_r = MPFR_LIMB_SIZE_REAL(mpfr);
838: len = MPFR_LIMB_SIZE_BODY(mpfr);
839: ptr = (unsigned int *)MPFR_MANT(mpfr);
840: send_int32(oxfp, len);
841: for(i=(len_r-len); i<len_r; i++) {
842: send_int32(oxfp, ptr[i]);
843: }
1.38 noro 844: return 0;
845: }
846:
1.1 ohara 847: ox_data* new_ox_data(cmo* c)
848: {
1.25 ohara 849: ox_data* m = MALLOC(sizeof(ox_data));
1.1 ohara 850: m->tag = OX_DATA;
851: m->cmo = c;
852: return m;
853: }
854:
855: ox_command* new_ox_command(int sm_code)
856: {
1.25 ohara 857: ox_command* m = MALLOC(sizeof(ox_command));
1.1 ohara 858: m->tag = OX_COMMAND;
859: m->command = sm_code;
860: return m;
861: }
862:
863: ox_sync_ball* new_ox_sync_ball()
864: {
1.25 ohara 865: ox_sync_ball *m = MALLOC(sizeof(ox_sync_ball));
1.1 ohara 866: m->tag = OX_SYNC_BALL;
867: return m;
1.19 ohara 868: }
869:
870: int ox_stderr_init(FILE *fp)
871: {
1.21 ohara 872: ox_stderr = fp;
873: if (ox_stderr != NULL) {
874: setbuf(ox_stderr, NULL);
875: }
1.27 ohara 876: return 0;
1.20 ohara 877: }
878:
879: int ox_printf(char *format, ...)
880: {
1.21 ohara 881: if (ox_stderr != NULL) {
882: va_list ap;
883: va_start(ap, format);
884: vfprintf(ox_stderr, format, ap);
885: }
1.27 ohara 886: return 0;
1.1 ohara 887: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>