- add SOLVER_NOAUTOSET to disable automatic SET deduction
[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_BINARY:
97       dp = data_read_id(dp, &kv->num);
98       kv->str = (const char *)dp;
99       return dp + kv->num;
100     case REPOKEY_TYPE_IDARRAY:
101       return data_read_ideof(dp, &kv->id, &kv->eof);
102     case REPOKEY_TYPE_DIRSTRARRAY:
103       dp = data_read_ideof(dp, &kv->id, &kv->eof);
104       kv->str = (const char *)dp;
105       return dp + strlen(kv->str) + 1;
106     case REPOKEY_TYPE_DIRNUMNUMARRAY:
107       dp = data_read_id(dp, &kv->id);
108       dp = data_read_id(dp, &kv->num);
109       return data_read_ideof(dp, &kv->num2, &kv->eof);
110     case REPOKEY_TYPE_FIXARRAY:
111       dp = data_read_id(dp, &kv->num);
112       return data_read_id(dp, &kv->id);
113     case REPOKEY_TYPE_FLEXARRAY:
114       return data_read_id(dp, &kv->num);
115     default:
116       return 0;
117     }
118 }
119
120 static inline unsigned char *
121 data_skip(unsigned char *dp, int type)
122 {
123   unsigned char x;
124   switch (type)
125     {
126     case REPOKEY_TYPE_VOID:
127     case REPOKEY_TYPE_CONSTANT:
128     case REPOKEY_TYPE_CONSTANTID:
129       return dp;
130     case REPOKEY_TYPE_ID:
131     case REPOKEY_TYPE_NUM:
132     case REPOKEY_TYPE_DIR:
133       while ((*dp & 0x80) != 0)
134         dp++;
135       return dp + 1;
136     case REPOKEY_TYPE_U32:
137       return dp + 4;
138     case REPOKEY_TYPE_MD5:
139       return dp + SIZEOF_MD5;
140     case REPOKEY_TYPE_SHA1:
141       return dp + SIZEOF_SHA1;
142     case REPOKEY_TYPE_SHA256:
143       return dp + SIZEOF_SHA256;
144     case REPOKEY_TYPE_IDARRAY:
145     case REPOKEY_TYPE_REL_IDARRAY:
146       while ((*dp & 0xc0) != 0)
147         dp++;
148       return dp + 1;
149     case REPOKEY_TYPE_STR:
150       while ((*dp) != 0)
151         dp++;
152       return dp + 1;
153     case REPOKEY_TYPE_BINARY:
154       {
155         Id len;
156         dp = data_read_id(dp, &len);
157         return dp + len;
158       }
159     case REPOKEY_TYPE_DIRSTRARRAY:
160       for (;;)
161         {
162           while ((*dp & 0x80) != 0)
163             dp++;
164           x = *dp++;
165           while ((*dp) != 0)
166             dp++;
167           dp++;
168           if (!(x & 0x40))
169             return dp;
170         }
171     case REPOKEY_TYPE_DIRNUMNUMARRAY:
172       for (;;)
173         {
174           while ((*dp & 0x80) != 0)
175             dp++;
176           dp++;
177           while ((*dp & 0x80) != 0)
178             dp++;
179           dp++;
180           while ((*dp & 0x80) != 0)
181             dp++;
182           if (!(*dp & 0x40))
183             return dp + 1;
184           dp++;
185         }
186     default:
187       return 0;
188     }
189 }
190
191 static inline unsigned char *
192 data_skip_verify(unsigned char *dp, int type, int maxid, int maxdir)
193 {
194   Id id;
195   int eof;
196
197   switch (type)
198     {
199     case REPOKEY_TYPE_VOID:
200     case REPOKEY_TYPE_CONSTANT:
201     case REPOKEY_TYPE_CONSTANTID:
202       return dp;
203     case REPOKEY_TYPE_NUM:
204       while ((*dp & 0x80) != 0)
205         dp++;
206       return dp + 1;
207     case REPOKEY_TYPE_U32:
208       return dp + 4;
209     case REPOKEY_TYPE_MD5:
210       return dp + SIZEOF_MD5;
211     case REPOKEY_TYPE_SHA1:
212       return dp + SIZEOF_SHA1;
213     case REPOKEY_TYPE_SHA256:
214       return dp + SIZEOF_SHA256;
215     case REPOKEY_TYPE_ID:
216       dp = data_read_id(dp, &id);
217       if (id >= maxid)
218         return 0;
219       return dp;
220     case REPOKEY_TYPE_DIR:
221       dp = data_read_id(dp, &id);
222       if (id >= maxdir)
223         return 0;
224       return dp;
225     case REPOKEY_TYPE_IDARRAY:
226       for (;;)
227         {
228           dp = data_read_ideof(dp, &id, &eof);
229           if (id >= maxid)
230             return 0;
231           if (eof)
232             return dp;
233         }
234     case REPOKEY_TYPE_STR:
235       while ((*dp) != 0)
236         dp++;
237       return dp + 1;
238     case REPOKEY_TYPE_DIRSTRARRAY:
239       for (;;)
240         {
241           dp = data_read_ideof(dp, &id, &eof);
242           if (id >= maxdir)
243             return 0;
244           while ((*dp) != 0)
245             dp++;
246           dp++;
247           if (eof)
248             return dp;
249         }
250     case REPOKEY_TYPE_DIRNUMNUMARRAY:
251       for (;;)
252         {
253           dp = data_read_id(dp, &id);
254           if (id >= maxdir)
255             return 0;
256           while ((*dp & 0x80) != 0)
257             dp++;
258           dp++;
259           while ((*dp & 0x80) != 0)
260             dp++;
261           if (!(*dp & 0x40))
262             return dp + 1;
263           dp++;
264         }
265     default:
266       return 0;
267     }
268 }
269
270 unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key);
271
272 #endif  /* SATSOLVER_REPOPACK */