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