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