xdrfuns.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* xdrfuns.c Copyright (C) 1995 NAG Ltd */
  2. /*
  3. * Functions to support reading and writing of objects in XDR format.
  4. *
  5. * Version 1.0 September 1995
  6. *
  7. * Author: Mike Dewar
  8. *
  9. */
  10. /* Signature: 4695c817 27-Jan-1997 */
  11. #include <stdio.h>
  12. #ifdef AIX3
  13. #include <sys/select.h>
  14. #endif
  15. /*
  16. * What I really mean here is ifdef(UNIX), but we don't know that until
  17. * machine.h is included. To simplify matters I'll just check to see if
  18. * we are using the Watcom compiler. Including machine.h earlier causes
  19. * some problems on the RS6000.
  20. */
  21. #ifndef __WATCOMC__
  22. #include <rpc/rpc.h>
  23. #endif
  24. #include <stdarg.h>
  25. #include <ctype.h>
  26. /* These are defined by the rpc code on the alpha */
  27. #define int32 csl_int32
  28. #define int64 csl_int64
  29. #include "machine.h"
  30. #include "tags.h"
  31. #include "cslerror.h"
  32. #include "externs.h"
  33. #include "entries.h"
  34. #include "stream.h"
  35. #include "arith.h"
  36. #ifdef UNIX
  37. Lisp_Object LxdrOpen(Lisp_Object nil, Lisp_Object f, Lisp_Object d)
  38. {
  39. XDR xdrs;
  40. Lisp_Object lxdr;
  41. /*
  42. * First argument must be an open stream. Since CCL streams are all
  43. * bi-directional we get the intended direction from the second argument.
  44. */
  45. if (!is_stream(f)) return aerror("xdrOpen");
  46. xdrstdio_create(&xdrs,stream_file(f),(d == lisp_true)?XDR_ENCODE:XDR_DECODE);
  47. /* Copy the XDR structure into a string to avoid alignment problems. */
  48. lxdr = Lsmkvect(nil,fixnum_of_int(sizeof(XDR)));
  49. memcpy(&celt(lxdr,0),&xdrs,sizeof(XDR));
  50. return onevalue(lxdr);
  51. }
  52. #define XW(x,u) ( (!x) ? aerror1("Bad XDR write for: ",u) : u )
  53. Lisp_Object LxdrWrite(Lisp_Object nil, Lisp_Object lxdr,Lisp_Object u)
  54. {
  55. XDR xdrs;
  56. /* Copy the XDR structure out of a CCL string. */
  57. memcpy(&xdrs,&celt(lxdr,0),sizeof(XDR));
  58. /*
  59. * We include the bignum case since fixnums in CCL are 28 bits and we would
  60. * like to support 32 bit integers here.
  61. */
  62. if (is_fixnum(u) )
  63. { int32 temp = int_of_fixnum(u);
  64. return XW(xdr_int(&xdrs,&temp), u);
  65. }
  66. else if (is_float(u) )
  67. { double temp = float_of_number(u);
  68. return XW(xdr_double(&xdrs,&temp), u);
  69. }
  70. else if (is_numbers(u) && is_bignum(u) )
  71. { int32 temp=thirty_two_bits(u);
  72. return XW(xdr_int(&xdrs,&temp), u);
  73. }
  74. else if (is_vector(u) && type_of_header(vechdr(u)) == TYPE_STRING)
  75. { int32 len = length_of_header(vechdr(u))-4;
  76. char *temp=&celt(u,0);
  77. return XW(xdr_string(&xdrs,&temp,len),u);
  78. }
  79. else if (is_vector(u) )
  80. { int32 count, len = thirty_two_bits(Llength(nil,u));
  81. Lisp_Object v = elt(u,0);
  82. /*
  83. * Mimic the way that xdr_array works by writing the length of the
  84. * array first.
  85. */
  86. if (!xdr_int(&xdrs,&len)) aerror1("XDR Error writing length of:",u);
  87. /*
  88. * Although Common Lisp Vectors are not homogeneous, C vectors are,
  89. * so we will assume that u is homogeneous and only test the type
  90. * of the first element.
  91. */
  92. if (is_float(v) )
  93. { double temp;
  94. for (count=0 ; count < len ; ++count)
  95. { temp = float_of_number(elt(u,count));
  96. if (!xdr_double(&xdrs,&temp))
  97. aerror1("Bad XDR write for Double-Float vector element: ",v);
  98. }
  99. return(u);
  100. }
  101. else if (is_fixnum(v) || ( is_numbers(v) && is_bignum(v) ) )
  102. { int32 temp;
  103. for (count=0 ; count < len ; ++count)
  104. { temp = thirty_two_bits(elt(u,count));
  105. if (!xdr_int(&xdrs,&temp))
  106. aerror1("Bad XDR write for integer vector element: ",v);
  107. }
  108. return(u);
  109. }
  110. else
  111. aerror1("XDR cannot handle a vector containing:",v);
  112. }
  113. else
  114. aerror1("XDR cannot handle:",u);
  115. }
  116. /* This checks a 32 bit integer's value and returns it as either a fixnum
  117. or a bignum. */
  118. #define int2ccl(i) (i > -268435455 && i < 268435456) ? fixnum_of_int(i) : make_one_word_bignum(i)
  119. Lisp_Object LxdrRead(Lisp_Object nil, Lisp_Object lxdr,Lisp_Object u)
  120. {
  121. XDR xdrs;
  122. int temp;
  123. /* Copy the XDR structure out of a CCL string. */
  124. memcpy(&xdrs,&celt(lxdr,0),sizeof(XDR));
  125. if (is_fixnum(u) || (is_numbers(u) && is_bignum(u) ) )
  126. { int32 temp;
  127. if (!xdr_int(&xdrs,&temp)) aerror("Integer XDR read");
  128. return onevalue(int2ccl(temp));
  129. }
  130. else if (is_float(u) )
  131. { double temp;
  132. if (!xdr_double(&xdrs,&temp)) aerror("Double-Float XDR read");
  133. return onevalue(make_boxfloat(temp,TYPE_DOUBLE_FLOAT));
  134. }
  135. else if (is_vector(u) && type_of_header(vechdr(u)) == TYPE_STRING)
  136. { char *temp=NULL;
  137. /* Value for maximum length of a string is fairly arbitrary! */
  138. if (!xdr_string(&xdrs,&temp,16777216)) aerror("String XDR read");
  139. return onevalue(make_string(temp));
  140. }
  141. else if (is_vector(u) )
  142. { int32 count, len;
  143. Lisp_Object new, v = elt(u,0);
  144. /* xdr_array writes the length of the array first. */
  145. if (!xdr_int(&xdrs,&len)) aerror1("XDR Error reading length of:",u);
  146. /* Create the new vector */
  147. new = getvector(TAG_VECTOR, TYPE_SIMPLE_VEC, 4*len+4);
  148. /* vectors must pad to an even number of words */
  149. if ((len & 1) == 0) elt(new,len) = nil;
  150. /*
  151. * Although Common Lisp Vectors are not homogeneous, C vectors are,
  152. * so we will assume that u is homogeneous and only test the type
  153. * of the first element.
  154. */
  155. if (is_float(v) )
  156. { double temp;
  157. for (count=0 ; count < len ; ++count)
  158. { if (!xdr_double(&xdrs,&temp)) aerror("Double-Float vector XDR read");
  159. elt(new,count) = make_boxfloat(temp,TYPE_DOUBLE_FLOAT);
  160. }
  161. }
  162. else if ( is_fixnum(v) || ( is_numbers(v) && is_bignum(v) ))
  163. { int32 temp;
  164. for (count=0 ; count < len ; ++count)
  165. { if (!xdr_int(&xdrs,&temp)) aerror("Integer vector XDR read");
  166. elt(new,count) = int2ccl(temp);
  167. }
  168. }
  169. else
  170. aerror1("XDR cannot handle a vector containing:",v);
  171. return onevalue(new);
  172. }
  173. else
  174. aerror1("XDR cannot handle:",u);
  175. }
  176. #else /* UNIX */
  177. Lisp_Object LxdrOpen(Lisp_Object nil, Lisp_Object f, Lisp_Object d)
  178. {
  179. aerror("Attempt to call xdr-open on non-Unix platform");
  180. return nil;
  181. }
  182. Lisp_Object LxdrWrite(Lisp_Object nil, Lisp_Object lxdr, Lisp_Object u)
  183. {
  184. aerror("Attempt to call xdr-write on non-Unix platform");
  185. return nil;
  186. }
  187. Lisp_Object LxdrRead(Lisp_Object nil, Lisp_Object lxdr, Lisp_Object u)
  188. {
  189. aerror("Attempt to call xdr-read on non-Unix platform");
  190. return nil;
  191. }
  192. #endif /* UNIX */
  193. setup_type const xdr_setup[] =
  194. {
  195. {"xdr-open", too_few_2, LxdrOpen, wrong_no_2},
  196. {"xdr-write", too_few_2, LxdrWrite, wrong_no_2},
  197. {"xdr-read", too_few_2, LxdrRead, wrong_no_2},
  198. {NULL, 0, 0, 0}
  199. };