(De-)Serialize structured types. Dataiterator and repo_search support
[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 SATSOLVER_REPOPACK_H
11 #define SATSOLVER_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_ideof(unsigned char *dp, Id *idp, int *eof)
32 {
33   Id x = 0;
34   unsigned char c;
35   for (;;)
36     {
37       c = *dp++;
38       if (!(c & 0x80))
39         {
40           if (c & 0x40)
41             {
42               c ^= 0x40;
43               *eof = 0;
44             }
45           else
46             *eof = 1;
47           *idp = (x << 6) ^ c;
48           return dp;
49         }
50       x = (x << 7) ^ c ^ 128;
51     }
52 }
53
54 static inline unsigned char *
55 data_read_u32(unsigned char *dp, unsigned int *nump)
56 {
57   *nump = (dp[0] << 24) | (dp[1] << 16) | (dp[2] << 8) | dp[3];
58   return dp + 4;
59 }
60
61 static inline unsigned char *
62 data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key)
63 {
64   kv->eof = 1;
65   if (!dp)
66     return 0;
67   switch (key->type)
68     {
69     case REPOKEY_TYPE_VOID:
70       return dp;
71     case REPOKEY_TYPE_CONSTANT:
72       kv->num = key->size;
73       return dp;
74     case REPOKEY_TYPE_CONSTANTID:
75       kv->id = key->size;
76       return dp;
77     case REPOKEY_TYPE_STR:
78       kv->str = (const char *)dp;
79       return dp + strlen(kv->str) + 1;
80     case REPOKEY_TYPE_ID:
81     case REPOKEY_TYPE_DIR:
82       return data_read_id(dp, &kv->id);
83     case REPOKEY_TYPE_NUM:
84       return data_read_id(dp, &kv->num);
85     case REPOKEY_TYPE_U32:
86       return data_read_u32(dp, (unsigned int *)&kv->num);
87     case REPOKEY_TYPE_MD5:
88       kv->str = (const char *)dp;
89       return dp + SIZEOF_MD5;
90     case REPOKEY_TYPE_SHA1:
91       kv->str = (const char *)dp;
92       return dp + SIZEOF_SHA1;
93     case REPOKEY_TYPE_SHA256:
94       kv->str = (const char *)dp;
95       return dp + SIZEOF_SHA256;
96     case REPOKEY_TYPE_IDARRAY:
97       return data_read_ideof(dp, &kv->id, &kv->eof);
98     case REPOKEY_TYPE_DIRSTRARRAY:
99       dp = data_read_ideof(dp, &kv->id, &kv->eof);
100       kv->str = (const char *)dp;
101       return dp + strlen(kv->str) + 1;
102     case REPOKEY_TYPE_DIRNUMNUMARRAY:
103       dp = data_read_id(dp, &kv->id);
104       dp = data_read_id(dp, &kv->num);
105       return data_read_ideof(dp, &kv->num2, &kv->eof);
106     case REPOKEY_TYPE_COUNTED:
107       dp = data_read_id(dp, &kv->num);
108       return data_read_id(dp, &kv->id);
109     default:
110       return 0;
111     }
112 }
113
114 static inline unsigned char *
115 data_skip(unsigned char *dp, int type)
116 {
117   unsigned char x;
118   switch (type)
119     {
120     case REPOKEY_TYPE_VOID:
121     case REPOKEY_TYPE_CONSTANT:
122     case REPOKEY_TYPE_CONSTANTID:
123       return dp;
124     case REPOKEY_TYPE_ID:
125     case REPOKEY_TYPE_NUM:
126     case REPOKEY_TYPE_DIR:
127       while ((*dp & 0x80) != 0)
128         dp++;
129       return dp + 1;
130     case REPOKEY_TYPE_U32:
131       return dp + 4;
132     case REPOKEY_TYPE_MD5:
133       return dp + SIZEOF_MD5;
134     case REPOKEY_TYPE_SHA1:
135       return dp + SIZEOF_SHA1;
136     case REPOKEY_TYPE_SHA256:
137       return dp + SIZEOF_SHA256;
138     case REPOKEY_TYPE_IDARRAY:
139     case REPOKEY_TYPE_REL_IDARRAY:
140       while ((*dp & 0xc0) != 0)
141         dp++;
142       return dp + 1;
143     case REPOKEY_TYPE_STR:
144       while ((*dp) != 0)
145         dp++;
146       return dp + 1;
147     case REPOKEY_TYPE_DIRSTRARRAY:
148       for (;;)
149         {
150           while ((*dp & 0x80) != 0)
151             dp++;
152           x = *dp++;
153           while ((*dp) != 0)
154             dp++;
155           dp++;
156           if (!(x & 0x40))
157             return dp;
158         }
159     case REPOKEY_TYPE_DIRNUMNUMARRAY:
160       for (;;)
161         {
162           while ((*dp & 0x80) != 0)
163             dp++;
164           dp++;
165           while ((*dp & 0x80) != 0)
166             dp++;
167           dp++;
168           while ((*dp & 0x80) != 0)
169             dp++;
170           if (!(*dp & 0x40))
171             return dp + 1;
172           dp++;
173         }
174     case REPOKEY_TYPE_COUNTED:
175       while ((*dp & 0x80) != 0)
176         dp++;
177       dp++;
178       while ((*dp & 0x80) != 0)
179         dp++;
180       return dp + 1;
181     default:
182       return 0;
183     }
184 }
185
186 static inline unsigned char *
187 data_skip_verify(unsigned char *dp, int type, int maxid, int maxdir)
188 {
189   Id id;
190   int eof;
191
192   switch (type)
193     {
194     case REPOKEY_TYPE_VOID:
195     case REPOKEY_TYPE_CONSTANT:
196     case REPOKEY_TYPE_CONSTANTID:
197       return dp;
198     case REPOKEY_TYPE_NUM:
199       while ((*dp & 0x80) != 0)
200         dp++;
201       return dp + 1;
202     case REPOKEY_TYPE_U32:
203       return dp + 4;
204     case REPOKEY_TYPE_MD5:
205       return dp + SIZEOF_MD5;
206     case REPOKEY_TYPE_SHA1:
207       return dp + SIZEOF_SHA1;
208     case REPOKEY_TYPE_SHA256:
209       return dp + SIZEOF_SHA256;
210     case REPOKEY_TYPE_ID:
211       dp = data_read_id(dp, &id);
212       if (id >= maxid)
213         return 0;
214       return dp;
215     case REPOKEY_TYPE_DIR:
216       dp = data_read_id(dp, &id);
217       if (id >= maxdir)
218         return 0;
219       return dp;
220     case REPOKEY_TYPE_IDARRAY:
221       for (;;)
222         {
223           dp = data_read_ideof(dp, &id, &eof);
224           if (id >= maxid)
225             return 0;
226           if (eof)
227             return dp;
228         }
229     case REPOKEY_TYPE_STR:
230       while ((*dp) != 0)
231         dp++;
232       return dp + 1;
233     case REPOKEY_TYPE_DIRSTRARRAY:
234       for (;;)
235         {
236           dp = data_read_ideof(dp, &id, &eof);
237           if (id >= maxdir)
238             return 0;
239           while ((*dp) != 0)
240             dp++;
241           dp++;
242           if (eof)
243             return dp;
244         }
245     case REPOKEY_TYPE_DIRNUMNUMARRAY:
246       for (;;)
247         {
248           dp = data_read_id(dp, &id);
249           if (id >= maxdir)
250             return 0;
251           while ((*dp & 0x80) != 0)
252             dp++;
253           dp++;
254           while ((*dp & 0x80) != 0)
255             dp++;
256           if (!(*dp & 0x40))
257             return dp + 1;
258           dp++;
259         }
260     case REPOKEY_TYPE_COUNTED:
261       while ((*dp & 0x80) != 0)
262         dp++;
263       dp++;
264       while ((*dp & 0x80) != 0)
265         dp++;
266       return dp + 1;
267     default:
268       return 0;
269     }
270 }
271
272 unsigned char * data_skip_recursive(Repodata *data, unsigned char *dp,
273                                     Repokey *key);
274
275 #endif  /* SATSOLVER_REPOPACK */