1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 2003-2013 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Phong Vo <phongvo@gmail.com> *
18 * *
19 ***********************************************************************/
20 #include "vchdr.h"
21
22 /* Transforming rows by xor-ing.
23 **
24 ** Written by Kiem-Phong Vo
25 */
26
27 #define SIZE 2 /* #bytes coding a record size */
28 #define MAXSIZE (1 << 16) /* max record size */
29 #define GETSIZE(dt) (((dt)[0]<<8)+(dt)[1]) /* get AMA size */
30 #define PUTSIZE(dt,v) (((dt)[0] = (((v)>>8)&0377)), ((dt)[1] = ((v)&0377)) )
31
32 /* Fast string xor-ing. Assumption: sizeof(type) is a power-of-2 <= 8 */
33 #define ALIGN(ptr,type) (((unsigned char*)ptr - (unsigned char*)0) & (sizeof(type)-1) )
34 #define XOR(sx,s1,s2,sk,sn,algn,type) \
35 do { if((sk+algn+sizeof(type)) <= sn) \
36 { reg unsigned type *tx, *t1, *t2; \
37 if(algn > 0) for(algn = sk+sizeof(type)-algn; sk < algn; ++sk) \
38 *sx++ = *s1++ ^ *s2++; \
39 tx = (unsigned type*)sx; t1 = (unsigned type*)s1; t2 = (unsigned type*)s2; \
40 for(sn -= sizeof(type); sk <= sn; sk += sizeof(type)) \
41 *tx++ = *t1++ ^ *t2++; \
42 sn += sizeof(type); sx = (Vcchar_t*)tx; s1 = (Vcchar_t*)t1; s2 = (Vcchar_t*)t2; \
43 } \
44 for(; sk < sn; ++sk) \
45 *sx++ = *s1++ ^ *s2++; \
46 } while(0)
47
48 #if __STD_C
amadiff(Vcodex_t * vc,const Void_t * data,size_t size,Void_t ** out)49 static ssize_t amadiff(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
50 #else
51 static ssize_t amadiff(vc, data, size, out)
52 Vcodex_t* vc;
53 Void_t* data;
54 size_t size;
55 Void_t** out;
56 #endif
57 {
58 reg Vcchar_t *dt, *df, *pd;
59 ssize_t k, a, ncols, sz, hdsz;
60 Vcchar_t *enddt, *output;
61 Vcchar_t *rcdt[MAXSIZE];
62 Vcio_t io;
63 /**/DEBUG_DECLARE(int, i_align = 0)
64 /**/DEBUG_DECLARE(int, s_align = 0)
65
66 vc->undone = 0;
67 if(size == 0)
68 return 0;
69
70 ncols = vc->disc ? vc->disc->size : 0;
71 hdsz = vcsizeu(ncols);
72 sz = ((hdsz + sizeof(int)-1)/sizeof(int))*sizeof(int);
73 if(!(output = vcbuffer(vc, NIL(Vcchar_t*), size, sz)) )
74 return -1;
75
76 df = output; enddt = (dt = (Vcchar_t*)data) + size;
77 if(ncols > 0) /* fixed-length rows */
78 { if((sz = (size/ncols)*ncols) > 0)
79 { memcpy(df, dt, ncols);
80 pd = dt; df += ncols; dt += ncols;
81 if((sz -= ncols) > 0)
82 { k = 0;
83 if((a = ALIGN(df,int)) == ALIGN(dt,int) && a == ALIGN(pd,int) )
84 XOR(df, dt, pd, k, sz, a, int);
85 else if((a = ALIGN(df,short)) == ALIGN(dt,short) && a == ALIGN(pd,short) )
86 XOR(df, dt, pd, k, sz, a, short);
87 else for(; k < sz; ++k)
88 *df++ = *dt++ ^ *pd++;
89 }
90 }
91 }
92 else /* ama data */
93 { for(k = 0; k < MAXSIZE; ++k)
94 rcdt[k] = NIL(Vcchar_t*);
95 for(;;)
96 { if((dt+SIZE) > enddt)
97 break;
98 ncols = GETSIZE(dt);
99 if((dt+ncols) > enddt)
100 break;
101
102 pd = rcdt[ncols]; rcdt[ncols] = dt+SIZE;
103 if(!pd)
104 { for(k = 0; k < ncols; ++k) /* first record is kept clear */
105 *df++ = *dt++;
106 }
107 else
108 { for(k = 0; k < SIZE; ++k) /* record size is kept clear */
109 *df++ = *dt++;
110
111 /* xor-transforming the rest of the data */
112 if((a = ALIGN(df,int)) == ALIGN(dt,int) && a == ALIGN(pd,int))
113 XOR(df, dt, pd, k, ncols, a, int);
114 else if((a = ALIGN(df,short)) == ALIGN(dt,short) && a == ALIGN(pd,short) )
115 XOR(df, dt, pd, k, ncols, a, short);
116 else for(; k < ncols; ++k)
117 *df++ = *dt++ ^ *pd++;
118 }
119 }
120
121 ncols = 0;
122 }
123
124 vc->undone = enddt-dt;
125 if((sz = dt - (Vcchar_t*)data) == 0)
126 return 0;
127
128 dt = output;
129 if(vcrecode(vc, &output, &sz, hdsz, 0) < 0 )
130 return -1;
131 if(dt != output)
132 vcbuffer(vc, dt, -1, -1);
133
134 output -= hdsz; sz += hdsz;
135 vcioinit(&io, output, hdsz);
136 vcioputu(&io, ncols);
137
138 if(out)
139 *out = output;
140
141 return sz;
142 }
143
144 #if __STD_C
unamadiff(Vcodex_t * vc,const Void_t * data,size_t size,Void_t ** out)145 static ssize_t unamadiff(Vcodex_t* vc, const Void_t* data, size_t size, Void_t** out)
146 #else
147 static ssize_t unamadiff(vc, data, size, out)
148 Vcodex_t* vc;
149 Void_t* data;
150 size_t size;
151 Void_t** out;
152 #endif
153 {
154 Vcchar_t *dt, *df, *savdf, *pd, *enddt, *output;
155 ssize_t k, a, ncols, sz;
156 Vcchar_t *rcdt[MAXSIZE];
157 Vcio_t io;
158
159 vc->undone = 0;
160 if(size == 0)
161 return 0;
162
163 vcioinit(&io, data, size);
164 ncols = vciogetu(&io);
165
166 df = savdf = vcionext(&io);
167 sz = vciomore(&io);
168 if(vcrecode(vc, &df, &sz, 0, 0) < 0 )
169 return -1;
170
171 if(!(output = vcbuffer(vc, NIL(Vcchar_t*), sz, 0)) )
172 return -1;
173
174 /* undo the transform */
175 enddt = (dt = output) + sz;
176 if(ncols > 0)
177 { if(sz%ncols != 0)
178 return -1;
179 memcpy(dt, df, ncols);
180 for(pd = dt, df += ncols, dt += ncols; dt < enddt; )
181 *dt++ = *df++ ^ *pd++;
182 }
183 else
184 { for(k = 0; k < MAXSIZE; ++k)
185 rcdt[k] = NIL(Vcchar_t*);
186 for(;;)
187 { if((dt+SIZE) > enddt)
188 break;
189 ncols = GETSIZE(df);
190 if((dt+ncols) > enddt)
191 return -1;
192
193 pd = rcdt[ncols]; rcdt[ncols] = dt+SIZE;
194 if(!pd)
195 { for(k = 0; k < ncols; ++k)
196 *dt++ = *df++;
197 }
198 else
199 { for(k = 0; k < SIZE; ++k)
200 *dt++ = *df++;
201
202 /* xor-transforming the rest of the data */
203 if((a = ALIGN(df,int)) == ALIGN(dt,int) && a == ALIGN(pd,int))
204 XOR(dt, df, pd, k, ncols, a, int);
205 else if((a = ALIGN(df,short)) == ALIGN(dt,short) && a == ALIGN(pd,short) )
206 XOR(dt, df, pd, k, ncols, a, short);
207 else for(; k < ncols; ++k)
208 *dt++ = *df++ ^ *pd++;
209 }
210 }
211 }
212
213 vcbuffer(vc, savdf, -1, -1);
214
215 if(out)
216 *out = output;
217 return sz;
218 }
219
220 Vcmethod_t _Vcamadiff =
221 { amadiff,
222 unamadiff,
223 0,
224 "amadiff", "Xor-ing rows in an AMA table.",
225 "[-?\n@(#)$Id: vcodex-amadiff (AT&T Research) 2003-01-01 $\n]" USAGE_LICENSE,
226 0,
227 1024*1024,
228 0
229 };
230
231 VCLIB(Vcamadiff)
232