- use correct defaults for rpm5, put tmpspace in extra struct
[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     case REPOKEY_TYPE_DELETED:
130       return dp;
131     case REPOKEY_TYPE_ID:
132     case REPOKEY_TYPE_NUM:
133     case REPOKEY_TYPE_DIR:
134       while ((*dp & 0x80) != 0)
135         dp++;
136       return dp + 1;
137     case REPOKEY_TYPE_U32:
138       return dp + 4;
139     case REPOKEY_TYPE_MD5:
140       return dp + SIZEOF_MD5;
141     case REPOKEY_TYPE_SHA1:
142       return dp + SIZEOF_SHA1;
143     case REPOKEY_TYPE_SHA256:
144       return dp + SIZEOF_SHA256;
145     case REPOKEY_TYPE_IDARRAY:
146     case REPOKEY_TYPE_REL_IDARRAY:
147       while ((*dp & 0xc0) != 0)
148         dp++;
149       return dp + 1;
150     case REPOKEY_TYPE_STR:
151       while ((*dp) != 0)
152         dp++;
153       return dp + 1;
154     case REPOKEY_TYPE_BINARY:
155       {
156         Id len;
157         dp = data_read_id(dp, &len);
158         return dp + len;
159       }
160     case REPOKEY_TYPE_DIRSTRARRAY:
161       for (;;)
162         {
163           while ((*dp & 0x80) != 0)
164             dp++;
165           x = *dp++;
166           while ((*dp) != 0)
167             dp++;
168           dp++;
169           if (!(x & 0x40))
170             return dp;
171         }
172     case REPOKEY_TYPE_DIRNUMNUMARRAY:
173       for (;;)
174         {
175           while ((*dp & 0x80) != 0)
176             dp++;
177           dp++;
178           while ((*dp & 0x80) != 0)
179             dp++;
180           dp++;
181           while ((*dp & 0x80) != 0)
182             dp++;
183           if (!(*dp & 0x40))
184             return dp + 1;
185           dp++;
186         }
187     default:
188       return 0;
189     }
190 }
191
192 static inline unsigned char *
193 data_skip_verify(unsigned char *dp, int type, int maxid, int maxdir)
194 {
195   Id id;
196   int eof;
197
198   switch (type)
199     {
200     case REPOKEY_TYPE_VOID:
201     case REPOKEY_TYPE_CONSTANT:
202     case REPOKEY_TYPE_CONSTANTID:
203     case REPOKEY_TYPE_DELETED:
204       return dp;
205     case REPOKEY_TYPE_NUM:
206       while ((*dp & 0x80) != 0)
207         dp++;
208       return dp + 1;
209     case REPOKEY_TYPE_U32:
210       return dp + 4;
211     case REPOKEY_TYPE_MD5:
212       return dp + SIZEOF_MD5;
213     case REPOKEY_TYPE_SHA1:
214       return dp + SIZEOF_SHA1;
215     case REPOKEY_TYPE_SHA256:
216       return dp + SIZEOF_SHA256;
217     case REPOKEY_TYPE_ID:
218       dp = data_read_id(dp, &id);
219       if (id >= maxid)
220         return 0;
221       return dp;
222     case REPOKEY_TYPE_DIR:
223       dp = data_read_id(dp, &id);
224       if (id >= maxdir)
225         return 0;
226       return dp;
227     case REPOKEY_TYPE_IDARRAY:
228       for (;;)
229         {
230           dp = data_read_ideof(dp, &id, &eof);
231           if (id >= maxid)
232             return 0;
233           if (eof)
234             return dp;
235         }
236     case REPOKEY_TYPE_STR:
237       while ((*dp) != 0)
238         dp++;
239       return dp + 1;
240     case REPOKEY_TYPE_DIRSTRARRAY:
241       for (;;)
242         {
243           dp = data_read_ideof(dp, &id, &eof);
244           if (id >= maxdir)
245             return 0;
246           while ((*dp) != 0)
247             dp++;
248           dp++;
249           if (eof)
250             return dp;
251         }
252     case REPOKEY_TYPE_DIRNUMNUMARRAY:
253       for (;;)
254         {
255           dp = data_read_id(dp, &id);
256           if (id >= maxdir)
257             return 0;
258           while ((*dp & 0x80) != 0)
259             dp++;
260           dp++;
261           while ((*dp & 0x80) != 0)
262             dp++;
263           if (!(*dp & 0x40))
264             return dp + 1;
265           dp++;
266         }
267     default:
268       return 0;
269     }
270 }
271
272 unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key);
273
274 #endif  /* SATSOLVER_REPOPACK */