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