Support new types for MD5 and SHA1 checksums (stored in binary, but with
[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_IDARRAY:
94       return data_read_ideof(dp, &kv->id, &kv->eof);
95     case REPOKEY_TYPE_DIRSTRARRAY:
96       dp = data_read_ideof(dp, &kv->id, &kv->eof);
97       kv->str = (const char *)dp;
98       return dp + strlen(kv->str) + 1;
99     case REPOKEY_TYPE_DIRNUMNUMARRAY:
100       dp = data_read_id(dp, &kv->id);
101       dp = data_read_id(dp, &kv->num);
102       return data_read_ideof(dp, &kv->num2, &kv->eof);
103     default:
104       return 0;
105     }
106 }
107
108 static inline unsigned char *
109 data_skip(unsigned char *dp, int type)
110 {
111   unsigned char x;
112   switch (type)
113     {
114     case REPOKEY_TYPE_VOID:
115     case REPOKEY_TYPE_CONSTANT:
116     case REPOKEY_TYPE_CONSTANTID:
117       return dp;
118     case REPOKEY_TYPE_ID:
119     case REPOKEY_TYPE_NUM:
120     case REPOKEY_TYPE_DIR:
121       while ((*dp & 0x80) != 0)
122         dp++;
123       return dp + 1;
124     case REPOKEY_TYPE_U32:
125       return dp + 4;
126     case REPOKEY_TYPE_MD5:
127       return dp + SIZEOF_MD5;
128     case REPOKEY_TYPE_SHA1:
129       return dp + SIZEOF_SHA1;
130     case REPOKEY_TYPE_IDARRAY:
131     case REPOKEY_TYPE_REL_IDARRAY:
132       while ((*dp & 0xc0) != 0)
133         dp++;
134       return dp + 1;
135     case REPOKEY_TYPE_STR:
136       while ((*dp) != 0)
137         dp++;
138       return dp + 1;
139     case REPOKEY_TYPE_DIRSTRARRAY:
140       for (;;)
141         {
142           while ((*dp & 0x80) != 0)
143             dp++;
144           x = *dp++;
145           while ((*dp) != 0)
146             dp++;
147           dp++;
148           if (!(x & 0x40))
149             return dp;
150         }
151     case REPOKEY_TYPE_DIRNUMNUMARRAY:
152       for (;;)
153         {
154           while ((*dp & 0x80) != 0)
155             dp++;
156           dp++;
157           while ((*dp & 0x80) != 0)
158             dp++;
159           dp++;
160           while ((*dp & 0x80) != 0)
161             dp++;
162           if (!(*dp & 0x40))
163             return dp + 1;
164           dp++;
165         }
166     default:
167       return 0;
168     }
169 }
170
171 static inline unsigned char *
172 data_skip_verify(unsigned char *dp, int type, int maxid, int maxdir)
173 {
174   Id id;
175   int eof;
176
177   switch (type)
178     {
179     case REPOKEY_TYPE_VOID:
180     case REPOKEY_TYPE_CONSTANT:
181     case REPOKEY_TYPE_CONSTANTID:
182       return dp;
183     case REPOKEY_TYPE_NUM:
184       while ((*dp & 0x80) != 0)
185         dp++;
186       return dp + 1;
187     case REPOKEY_TYPE_U32:
188       return dp + 4;
189     case REPOKEY_TYPE_MD5:
190       return dp + SIZEOF_MD5;
191     case REPOKEY_TYPE_SHA1:
192       return dp + SIZEOF_SHA1;
193     case REPOKEY_TYPE_ID:
194       dp = data_read_id(dp, &id);
195       if (id >= maxid)
196         return 0;
197       return dp;
198     case REPOKEY_TYPE_DIR:
199       dp = data_read_id(dp, &id);
200       if (id >= maxdir)
201         return 0;
202       return dp;
203     case REPOKEY_TYPE_IDARRAY:
204       for (;;)
205         {
206           dp = data_read_ideof(dp, &id, &eof);
207           if (id >= maxid)
208             return 0;
209           if (eof)
210             return dp;
211         }
212     case REPOKEY_TYPE_STR:
213       while ((*dp) != 0)
214         dp++;
215       return dp + 1;
216     case REPOKEY_TYPE_DIRSTRARRAY:
217       for (;;)
218         {
219           dp = data_read_ideof(dp, &id, &eof);
220           if (id >= maxdir)
221             return 0;
222           while ((*dp) != 0)
223             dp++;
224           dp++;
225           if (eof)
226             return dp;
227         }
228     case REPOKEY_TYPE_DIRNUMNUMARRAY:
229       for (;;)
230         {
231           dp = data_read_id(dp, &id);
232           if (id >= maxdir)
233             return 0;
234           while ((*dp & 0x80) != 0)
235             dp++;
236           dp++;
237           while ((*dp & 0x80) != 0)
238             dp++;
239           if (!(*dp & 0x40))
240             return dp + 1;
241           dp++;
242         }
243     default:
244       return 0;
245     }
246 }
247
248 #endif  /* SATSOLVER_REPOPACK */