1 /* Notes */ /*{{{C}}}*//*{{{*/
2 /*
3 
4 xdr_enum() is unusable, because enum_t may have a different size than
5 an enum.  The construction
6 
7   int_value=*enum_value;
8   result=xdr_int(xdrs,&int_value);
9   *enum_value=int_value;
10   return result;
11 
12 solves the problem and works for both encoding and decoding.
13 Unfortunately, I could not yet find such a solution for a variable sized
14 array terminated by a special element.
15 
16 */
17 /*}}}*/
18 /* #includes */ /*{{{*/
19 #ifdef DMALLOC
20 #include "dmalloc.h"
21 #endif
22 
23 #include <assert.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #include "sheet.h"
29 #include "xdr.h"
30 /*}}}*/
31 
32 /* xdr_token */ /*{{{*/
xdr_token(XDR * xdrs,Token * t)33 static bool_t xdr_token(XDR *xdrs, Token *t)
34 {
35   int x,result;
36 
37   if (xdrs->x_op==XDR_DECODE) (void)memset(t,0,sizeof(Token));
38   x=t->type;
39   if (t->type==OPERATOR) x|=t->u.op<<8;
40   result=xdr_int(xdrs,&x);
41   if ((x&0xff)==OPERATOR) t->u.op=(x>>8)&0xff;
42   t->type=x&0xff;
43   if (result==0) return result;
44   switch (t->type)
45   {
46     /* EMPTY */ /*{{{*/
47     case EMPTY:
48     {
49       return 1;
50     }
51     /*}}}*/
52     /* STRING */ /*{{{*/
53     case STRING:
54     {
55       return xdr_wrapstring(xdrs,&(t->u.string));
56     }
57     /*}}}*/
58     /* FLOAT */ /*{{{*/
59     case FLOAT:
60     {
61       return xdr_double(xdrs,&(t->u.flt));
62     }
63     /*}}}*/
64     /* INT */ /*{{{*/
65     case INT:
66     {
67       return xdr_long(xdrs,&(t->u.integer));
68     }
69     /*}}}*/
70     /* OPERATOR */ /*{{{*/
71     case OPERATOR:
72     {
73       return 1; /* since op is encoded in type */
74     }
75     /*}}}*/
76     /* LIDENT */ /*{{{*/
77     case LIDENT:
78     {
79       return xdr_wrapstring(xdrs,&(t->u.lident));
80     }
81     /*}}}*/
82     /* FIDENT */ /*{{{*/
83     case FIDENT:
84     {
85       return xdr_int(xdrs,&(t->u.fident));
86     }
87     /*}}}*/
88     /* LOCATION */ /*{{{*/
89     case LOCATION:
90     {
91       return (xdr_int(xdrs,&(t->u.location[0])) && xdr_int(xdrs,&(t->u.location[1])) && xdr_int(xdrs,&(t->u.location[2])));
92     }
93     /*}}}*/
94     /* EEK */ /*{{{*/
95     case EEK:
96     {
97       return xdr_wrapstring(xdrs,&(t->u.err));
98     }
99     /*}}}*/
100     /* default -- should not happen */ /*{{{*/
101     default: assert(0);
102     /*}}}*/
103   }
104   return 0;
105 }
106 /*}}}*/
107 /* xdr_tokenptr */ /*{{{*/
xdr_tokenptr(XDR * xdrs,Token ** t)108 static bool_t xdr_tokenptr(XDR *xdrs, Token **t)
109 {
110   return xdr_pointer(xdrs,(char**)t,sizeof(Token),(xdrproc_t)xdr_token);
111 }
112 /*}}}*/
113 /* xdr_tokenptrvec */ /*{{{*/
xdr_tokenptrvec(XDR * xdrs,Token *** t)114 static bool_t xdr_tokenptrvec(XDR *xdrs, Token ***t)
115 {
116   unsigned int len;
117   int result;
118 
119   assert(t!=(Token***)0);
120   if (xdrs->x_op!=XDR_DECODE)
121   {
122     Token **run;
123 
124     if (*t==(Token**)0) len=0;
125     else for (len=1,run=*t; *run!=(Token*)0; ++len,++run);
126   }
127   result=xdr_array(xdrs,(char**)t,&len,65536,sizeof(Token*),(xdrproc_t)xdr_tokenptr);
128   if (len==0) *t=(Token**)0;
129   return result;
130 }
131 /*}}}*/
132 /* xdr_mystring */ /*{{{*/
xdr_mystring(XDR * xdrs,char ** str)133 static bool_t xdr_mystring(XDR *xdrs, char **str)
134 {
135   static struct xdr_discrim arms[3]=
136   {
137     { 0, (xdrproc_t)xdr_void },
138     { 1, (xdrproc_t)xdr_wrapstring },
139     { -1, (xdrproc_t)0 }
140   };
141   enum_t x;
142   int res;
143 
144   x=(*str!=(char*)0);
145   res=xdr_union(xdrs, &x, (char*)str, arms, (xdrproc_t)0);
146   if (!x) *str=(char*)0;
147   return res;
148 }
149 /*}}}*/
150 
151 /* Notes */ /*{{{*/
152 /*
153 
154 The saved sheet consists of three xdr_int()s which specify x, y and z
155 position of the cell saved with xdr_cell().  Perhaps xdr_cell could be
156 given those as parameters, which would be more correct concerning the
157 purpose of the xdr_functions.  Then again, reading the position may
158 fail (eof), whereas after the position has been read, xdr_cell() must
159 not fail when loading a sheet.
160 
161 */
162 /*}}}*/
163 /* xdr_cell */ /*{{{*/
xdr_cell(XDR * xdrs,Cell * cell)164 bool_t xdr_cell(XDR *xdrs, Cell *cell)
165 {
166   int result,x;
167 
168   assert(cell!=(Cell*)0);
169   if (!(xdr_tokenptrvec(xdrs, &(cell->contents)) && xdr_tokenptrvec(xdrs, &(cell->ccontents)) /* && xdr_token(xdrs, &(cell->value)) */ )) return 0;
170   if (xdr_mystring(xdrs, &(cell->label))==0) return 0;
171   x=cell->adjust;
172   result=xdr_int(xdrs, &x);
173   cell->adjust=x;
174   if (result==0) return 0;
175   if (xdr_int(xdrs, &(cell->precision))==0) return 0;
176   x=(cell->updated&1)|((cell->shadowed&1)<<1)|((cell->scientific&1)<<2)|((cell->locked&1)<<3)|((cell->transparent&1)<<4)|((cell->ignored&1)<<5)|((cell->bold&1)<<6)|((cell->underline&1)<<7);
177   result=xdr_int(xdrs, &x);
178   cell->updated=((x&(1))!=0);
179   cell->shadowed=((x&(1<<1))!=0);
180   cell->scientific=((x&(1<<2))!=0);
181   cell->locked=((x&(1<<3))!=0);
182   cell->transparent=((x&(1<<4))!=0);
183   cell->ignored=((x&(1<<5))!=0);
184   cell->bold=((x&(1<<6))!=0);
185   cell->underline=((x&(1<<7))!=0);
186   return result;
187 }
188 /*}}}*/
189 /* xdr_column */ /*{{{*/
xdr_column(XDR * xdrs,int * x,int * z,int * width)190 bool_t xdr_column(XDR *xdrs, int *x, int *z, int *width)
191 {
192   return (xdr_int(xdrs, x) && xdr_int(xdrs, z) && xdr_int(xdrs, width));
193 }
194 /*}}}*/
195 /* xdr_magic */ /*{{{*/
196 #define MAGIC0 (('#'<<24)|('!'<<16)|('t'<<8)|'e')
197 #define MAGIC1 (('a'<<24)|('p'<<16)|('o'<<8)|'t')
198 #define MAGIC2 (('\n'<<24)|('x'<<16)|('d'<<8)|'r')
199 
xdr_magic(XDR * xdrs)200 bool_t xdr_magic(XDR *xdrs)
201 {
202   long m0,m1,m2;
203 
204   m0=MAGIC0;
205   m1=MAGIC1;
206   m2=MAGIC2;
207   return (xdr_long(xdrs,&m0) && m0==MAGIC0 && xdr_long(xdrs,&m1) && m1==MAGIC1 && xdr_long(xdrs,&m2) && m2==MAGIC2);
208 }
209 /*}}}*/
210