- advance num64 support. For now, we store the high 32 bits in kv->num2 to stay somew...
[platform/upstream/libsolv.git] / src / repopack.h
1 /*
2  * Copyright (c) 2007, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 /* pack/unpack functions for key data */
9
10 #ifndef LIBSOLV_REPOPACK_H
11 #define LIBSOLV_REPOPACK_H
12
13 static inline unsigned char *
14 data_read_id(unsigned char *dp, Id *idp)
15 {
16   Id x = 0;
17   unsigned char c;
18   for (;;)
19     {
20       c = *dp++;
21       if (!(c & 0x80))
22         {
23           *idp = (x << 7) ^ c;
24           return dp;
25         }
26       x = (x << 7) ^ (c ^ 128);
27     }
28 }
29
30 static inline unsigned char *
31 data_read_num64(unsigned char *dp, unsigned int *low, unsigned int *high)
32 {
33   unsigned int x = 0;
34   unsigned long long int xx;
35   unsigned char c;
36   int n;
37
38   *high = 0;
39   for (n = 4; n-- > 0;)
40     {
41       c = *dp++;
42       if (!(c & 0x80))
43         {
44           *low = (x << 7) ^ c;
45           return dp;
46         }
47       x = (x << 7) ^ (c ^ 128);
48     }
49   xx = x;
50   for (;;)
51     {
52       c = *dp++;
53       if (!(c & 0x80))
54         {
55           xx = (xx << 7) ^ c;
56           *low = xx;
57           *high = xx >> 32;
58           return dp;
59         }
60       xx = (xx << 7) ^ (c ^ 128);
61     }
62 }
63
64 static inline unsigned char *
65 data_read_ideof(unsigned char *dp, Id *idp, int *eof)
66 {
67   Id x = 0;
68   unsigned char c;
69   for (;;)
70     {
71       c = *dp++;
72       if (!(c & 0x80))
73         {
74           if (c & 0x40)
75             {
76               c ^= 0x40;
77               *eof = 0;
78             }
79           else
80             *eof = 1;
81           *idp = (x << 6) ^ c;
82           return dp;
83         }
84       x = (x << 7) ^ c ^ 128;
85     }
86 }
87
88 static inline unsigned char *
89 data_read_u32(unsigned char *dp, unsigned int *nump)
90 {
91   *nump = (dp[0] << 24) | (dp[1] << 16) | (dp[2] << 8) | dp[3];
92   return dp + 4;
93 }
94
95 static inline unsigned char *
96 data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
97 {
98   kv->eof = 1;
99   if (!dp)
100     return 0;
101   switch (key->type)
102     {
103     case REPOKEY_TYPE_VOID:
104       return dp;
105     case REPOKEY_TYPE_CONSTANT:
106       kv->num2 = 0;
107       kv->num = key->size;
108       return dp;
109     case REPOKEY_TYPE_CONSTANTID:
110       kv->id = key->size;
111       return dp;
112     case REPOKEY_TYPE_STR:
113       kv->str = (const char *)dp;
114       return dp + strlen(kv->str) + 1;
115     case REPOKEY_TYPE_ID:
116     case REPOKEY_TYPE_DIR:
117       return data_read_id(dp, &kv->id);
118     case REPOKEY_TYPE_NUM:
119       return data_read_num64(dp, &kv->num, &kv->num2);
120     case REPOKEY_TYPE_U32:
121       kv->num2 = 0;
122       return data_read_u32(dp, &kv->num);
123     case REPOKEY_TYPE_MD5:
124       kv->str = (const char *)dp;
125       return dp + SIZEOF_MD5;
126     case REPOKEY_TYPE_SHA1:
127       kv->str = (const char *)dp;
128       return dp + SIZEOF_SHA1;
129     case REPOKEY_TYPE_SHA256:
130       kv->str = (const char *)dp;
131       return dp + SIZEOF_SHA256;
132     case REPOKEY_TYPE_BINARY:
133       dp = data_read_id(dp, (Id *)&kv->num);
134       kv->str = (const char *)dp;
135       return dp + kv->num;
136     case REPOKEY_TYPE_IDARRAY:
137       return data_read_ideof(dp, &kv->id, &kv->eof);
138     case REPOKEY_TYPE_DIRSTRARRAY:
139       dp = data_read_ideof(dp, &kv->id, &kv->eof);
140       kv->str = (const char *)dp;
141       return dp + strlen(kv->str) + 1;
142     case REPOKEY_TYPE_DIRNUMNUMARRAY:
143       dp = data_read_id(dp, &kv->id);
144       dp = data_read_id(dp, (Id *)&kv->num);
145       return data_read_ideof(dp, (Id *)&kv->num2, &kv->eof);
146     case REPOKEY_TYPE_FIXARRAY:
147       dp = data_read_id(dp, (Id *)&kv->num);
148       return data_read_id(dp, &kv->id);
149     case REPOKEY_TYPE_FLEXARRAY:
150       return data_read_id(dp, (Id *)&kv->num);
151     default:
152       return 0;
153     }
154 }
155
156 static inline unsigned char *
157 data_skip(unsigned char *dp, int type)
158 {
159   unsigned char x;
160   switch (type)
161     {
162     case REPOKEY_TYPE_VOID:
163     case REPOKEY_TYPE_CONSTANT:
164     case REPOKEY_TYPE_CONSTANTID:
165     case REPOKEY_TYPE_DELETED:
166       return dp;
167     case REPOKEY_TYPE_ID:
168     case REPOKEY_TYPE_NUM:
169     case REPOKEY_TYPE_DIR:
170       while ((*dp & 0x80) != 0)
171         dp++;
172       return dp + 1;
173     case REPOKEY_TYPE_U32:
174       return dp + 4;
175     case REPOKEY_TYPE_MD5:
176       return dp + SIZEOF_MD5;
177     case REPOKEY_TYPE_SHA1:
178       return dp + SIZEOF_SHA1;
179     case REPOKEY_TYPE_SHA256:
180       return dp + SIZEOF_SHA256;
181     case REPOKEY_TYPE_IDARRAY:
182     case REPOKEY_TYPE_REL_IDARRAY:
183       while ((*dp & 0xc0) != 0)
184         dp++;
185       return dp + 1;
186     case REPOKEY_TYPE_STR:
187       while ((*dp) != 0)
188         dp++;
189       return dp + 1;
190     case REPOKEY_TYPE_BINARY:
191       {
192         unsigned int len;
193         dp = data_read_id(dp, (Id *)&len);
194         return dp + len;
195       }
196     case REPOKEY_TYPE_DIRSTRARRAY:
197       for (;;)
198         {
199           while ((*dp & 0x80) != 0)
200             dp++;
201           x = *dp++;
202           while ((*dp) != 0)
203             dp++;
204           dp++;
205           if (!(x & 0x40))
206             return dp;
207         }
208     case REPOKEY_TYPE_DIRNUMNUMARRAY:
209       for (;;)
210         {
211           while ((*dp & 0x80) != 0)
212             dp++;
213           dp++;
214           while ((*dp & 0x80) != 0)
215             dp++;
216           dp++;
217           while ((*dp & 0x80) != 0)
218             dp++;
219           if (!(*dp & 0x40))
220             return dp + 1;
221           dp++;
222         }
223     default:
224       return 0;
225     }
226 }
227
228 static inline unsigned char *
229 data_skip_verify(unsigned char *dp, int type, int maxid, int maxdir)
230 {
231   Id id;
232   int eof;
233
234   switch (type)
235     {
236     case REPOKEY_TYPE_VOID:
237     case REPOKEY_TYPE_CONSTANT:
238     case REPOKEY_TYPE_CONSTANTID:
239     case REPOKEY_TYPE_DELETED:
240       return dp;
241     case REPOKEY_TYPE_NUM:
242       while ((*dp & 0x80) != 0)
243         dp++;
244       return dp + 1;
245     case REPOKEY_TYPE_U32:
246       return dp + 4;
247     case REPOKEY_TYPE_MD5:
248       return dp + SIZEOF_MD5;
249     case REPOKEY_TYPE_SHA1:
250       return dp + SIZEOF_SHA1;
251     case REPOKEY_TYPE_SHA256:
252       return dp + SIZEOF_SHA256;
253     case REPOKEY_TYPE_ID:
254       dp = data_read_id(dp, &id);
255       if (id >= maxid)
256         return 0;
257       return dp;
258     case REPOKEY_TYPE_DIR:
259       dp = data_read_id(dp, &id);
260       if (id >= maxdir)
261         return 0;
262       return dp;
263     case REPOKEY_TYPE_IDARRAY:
264       for (;;)
265         {
266           dp = data_read_ideof(dp, &id, &eof);
267           if (id >= maxid)
268             return 0;
269           if (eof)
270             return dp;
271         }
272     case REPOKEY_TYPE_STR:
273       while ((*dp) != 0)
274         dp++;
275       return dp + 1;
276     case REPOKEY_TYPE_BINARY:
277       {
278         unsigned int len;
279         dp = data_read_id(dp, (Id *)&len);
280         return dp + len;
281       }
282     case REPOKEY_TYPE_DIRSTRARRAY:
283       for (;;)
284         {
285           dp = data_read_ideof(dp, &id, &eof);
286           if (id >= maxdir)
287             return 0;
288           while ((*dp) != 0)
289             dp++;
290           dp++;
291           if (eof)
292             return dp;
293         }
294     case REPOKEY_TYPE_DIRNUMNUMARRAY:
295       for (;;)
296         {
297           dp = data_read_id(dp, &id);
298           if (id >= maxdir)
299             return 0;
300           while ((*dp & 0x80) != 0)
301             dp++;
302           dp++;
303           while ((*dp & 0x80) != 0)
304             dp++;
305           if (!(*dp & 0x40))
306             return dp + 1;
307           dp++;
308         }
309     default:
310       return 0;
311     }
312 }
313
314 #endif  /* LIBSOLV_REPOPACK */