Imported Upstream version 0.7.20
[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;
17   unsigned char c;
18   if (!(dp[0] & 0x80))
19     {
20       *idp = dp[0];
21       return dp + 1;
22     }
23   if (!(dp[1] & 0x80))
24     {
25       *idp = dp[0] << 7 ^ dp[1] ^ 0x4000;
26       return dp + 2;
27     }
28   if (!(dp[2] & 0x80))
29     {
30       *idp = dp[0] << 14 ^ dp[1] << 7 ^ dp[2] ^ 0x204000;
31       return dp + 3;
32     }
33   if (!(dp[3] & 0x80))
34     {
35       *idp = dp[0] << 21 ^ dp[1] << 14 ^ dp[2] << 7 ^ dp[3] ^ 0x10204000;
36       return dp + 4;
37     }
38   x = dp[0] << 28 ^ dp[1] << 21 ^ dp[2] << 14 ^ dp[3] << 7 ^ dp[4] ^ 0x10204000;
39   if (!(dp[4] & 0x80))
40     {
41       *idp = x;
42       return dp + 5;
43     }
44   x ^= 80;
45   dp += 5;
46   for (;;)
47     {
48       c = *dp++;
49       if (!(c & 0x80))
50         {
51           *idp = (x << 7) ^ c;
52           return dp;
53         }
54       x = (x << 7) ^ (c ^ 128);
55     }
56 }
57
58 static inline unsigned char *
59 data_read_num64(unsigned char *dp, unsigned int *low, unsigned int *high)
60 {
61   unsigned long long int x;
62   unsigned char c;
63
64   *high = 0;
65   if (!(dp[0] & 0x80))
66     {
67       *low = dp[0];
68       return dp + 1;
69     }
70   if (!(dp[1] & 0x80))
71     {
72       *low = dp[0] << 7 ^ dp[1] ^ 0x4000;
73       return dp + 2;
74     }
75   if (!(dp[2] & 0x80))
76     {
77       *low = dp[0] << 14 ^ dp[1] << 7 ^ dp[2] ^ 0x204000;
78       return dp + 3;
79     }
80   if (!(dp[3] & 0x80))
81     {
82       *low = dp[0] << 21 ^ dp[1] << 14 ^ dp[2] << 7 ^ dp[3] ^ 0x10204000;
83       return dp + 4;
84     }
85   if (!(dp[4] & 0x80))
86     {
87       *low = dp[0] << 28 ^ dp[1] << 21 ^ dp[2] << 14 ^ dp[3] << 7 ^ dp[4] ^ 0x10204000;
88       *high = (dp[0] ^ 0x80) >> 4;
89       return dp + 5;
90     }
91   x = (unsigned long long)(dp[0] ^ 0x80) << 28 ^ (unsigned int)(dp[1] << 21 ^ dp[2] << 14 ^ dp[3] << 7 ^ dp[4] ^ 0x10204080);
92   dp += 5;
93   for (;;)
94     {
95       c = *dp++;
96       if (!(c & 0x80))
97         {
98           x = (x << 7) ^ c;
99           *low = x;
100           *high = x >> 32;
101           return dp;
102         }
103       x = (x << 7) ^ (c ^ 128);
104     }
105 }
106
107 static inline unsigned char *
108 data_read_ideof(unsigned char *dp, Id *idp, int *eof)
109 {
110   Id x = 0;
111   unsigned char c;
112   for (;;)
113     {
114       c = *dp++;
115       if (!(c & 0x80))
116         {
117           if (c & 0x40)
118             {
119               c ^= 0x40;
120               *eof = 0;
121             }
122           else
123             *eof = 1;
124           *idp = (x << 6) ^ c;
125           return dp;
126         }
127       x = (x << 7) ^ c ^ 128;
128     }
129 }
130
131 static inline unsigned char *
132 data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
133 {
134   kv->eof = 1;
135   if (!dp)
136     return 0;
137   switch (key->type)
138     {
139     case REPOKEY_TYPE_VOID:
140     case REPOKEY_TYPE_DELETED:
141       return dp;
142     case REPOKEY_TYPE_CONSTANT:
143       kv->num2 = 0;
144       kv->num = key->size;
145       return dp;
146     case REPOKEY_TYPE_CONSTANTID:
147       kv->id = key->size;
148       return dp;
149     case REPOKEY_TYPE_STR:
150       kv->str = (const char *)dp;
151       return dp + strlen(kv->str) + 1;
152     case REPOKEY_TYPE_ID:
153     case REPOKEY_TYPE_DIR:
154       return data_read_id(dp, &kv->id);
155     case REPOKEY_TYPE_NUM:
156       return data_read_num64(dp, &kv->num, &kv->num2);
157     case REPOKEY_TYPE_MD5:
158       kv->num = 0;      /* not stringified yet */
159       kv->str = (const char *)dp;
160       return dp + SIZEOF_MD5;
161     case REPOKEY_TYPE_SHA1:
162       kv->num = 0;      /* not stringified yet */
163       kv->str = (const char *)dp;
164       return dp + SIZEOF_SHA1;
165     case REPOKEY_TYPE_SHA224:
166       kv->num = 0;      /* not stringified yet */
167       kv->str = (const char *)dp;
168       return dp + SIZEOF_SHA224;
169     case REPOKEY_TYPE_SHA256:
170       kv->num = 0;      /* not stringified yet */
171       kv->str = (const char *)dp;
172       return dp + SIZEOF_SHA256;
173     case REPOKEY_TYPE_SHA384:
174       kv->num = 0;      /* not stringified yet */
175       kv->str = (const char *)dp;
176       return dp + SIZEOF_SHA384;
177     case REPOKEY_TYPE_SHA512:
178       kv->num = 0;      /* not stringified yet */
179       kv->str = (const char *)dp;
180       return dp + SIZEOF_SHA512;
181     case REPOKEY_TYPE_BINARY:
182       dp = data_read_id(dp, (Id *)&kv->num);
183       kv->str = (const char *)dp;
184       return dp + kv->num;
185     case REPOKEY_TYPE_IDARRAY:
186       return data_read_ideof(dp, &kv->id, &kv->eof);
187     case REPOKEY_TYPE_DIRSTRARRAY:
188       dp = data_read_ideof(dp, &kv->id, &kv->eof);
189       kv->num = 0;      /* not stringified yet */
190       kv->str = (const char *)dp;
191       return dp + strlen(kv->str) + 1;
192     case REPOKEY_TYPE_DIRNUMNUMARRAY:
193       dp = data_read_id(dp, &kv->id);
194       dp = data_read_id(dp, (Id *)&kv->num);
195       return data_read_ideof(dp, (Id *)&kv->num2, &kv->eof);
196     case REPOKEY_TYPE_FIXARRAY:
197     case REPOKEY_TYPE_FLEXARRAY:
198       if (!kv->entry)
199         {
200           dp = data_read_id(dp, (Id *)&kv->num);        /* number of elements */
201           if (!kv->num)
202             return 0;           /* illegal */
203         }
204       if (!kv->entry || key->type == REPOKEY_TYPE_FLEXARRAY)
205         dp = data_read_id(dp, &kv->id); /* schema */
206       kv->str = (const char *)dp;
207       return dp;
208     default:
209       return 0;
210     }
211 }
212
213 static inline unsigned char *
214 data_skip(unsigned char *dp, int type)
215 {
216   unsigned char x;
217   switch (type)
218     {
219     case REPOKEY_TYPE_VOID:
220     case REPOKEY_TYPE_CONSTANT:
221     case REPOKEY_TYPE_CONSTANTID:
222     case REPOKEY_TYPE_DELETED:
223       return dp;
224     case REPOKEY_TYPE_ID:
225     case REPOKEY_TYPE_NUM:
226     case REPOKEY_TYPE_DIR:
227       while ((*dp & 0x80) != 0)
228         dp++;
229       return dp + 1;
230     case REPOKEY_TYPE_MD5:
231       return dp + SIZEOF_MD5;
232     case REPOKEY_TYPE_SHA1:
233       return dp + SIZEOF_SHA1;
234     case REPOKEY_TYPE_SHA224:
235       return dp + SIZEOF_SHA224;
236     case REPOKEY_TYPE_SHA256:
237       return dp + SIZEOF_SHA256;
238     case REPOKEY_TYPE_SHA384:
239       return dp + SIZEOF_SHA384;
240     case REPOKEY_TYPE_SHA512:
241       return dp + SIZEOF_SHA512;
242     case REPOKEY_TYPE_IDARRAY:
243     case REPOKEY_TYPE_REL_IDARRAY:
244       while ((*dp & 0xc0) != 0)
245         dp++;
246       return dp + 1;
247     case REPOKEY_TYPE_STR:
248       while ((*dp) != 0)
249         dp++;
250       return dp + 1;
251     case REPOKEY_TYPE_BINARY:
252       {
253         unsigned int len;
254         dp = data_read_id(dp, (Id *)&len);
255         return dp + len;
256       }
257     case REPOKEY_TYPE_DIRSTRARRAY:
258       for (;;)
259         {
260           while ((*dp & 0x80) != 0)
261             dp++;
262           x = *dp++;
263           while ((*dp) != 0)
264             dp++;
265           dp++;
266           if (!(x & 0x40))
267             return dp;
268         }
269     case REPOKEY_TYPE_DIRNUMNUMARRAY:
270       for (;;)
271         {
272           while ((*dp & 0x80) != 0)
273             dp++;
274           dp++;
275           while ((*dp & 0x80) != 0)
276             dp++;
277           dp++;
278           while ((*dp & 0x80) != 0)
279             dp++;
280           if (!(*dp & 0x40))
281             return dp + 1;
282           dp++;
283         }
284     default:
285       return 0;
286     }
287 }
288
289 #endif  /* LIBSOLV_REPOPACK */