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