IDZEBRA 2.2.8
it_key.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdlib.h>
24#include <string.h>
25#include <stdio.h>
26#include <assert.h>
27
28#include <yaz/xmalloc.h>
29#include <yaz/snprintf.h>
30#include <it_key.h>
31
32#ifdef __GNUC__
33#define CODEC_INLINE inline
34#else
35#define CODEC_INLINE
36#endif
37
38void key_logdump_txt(int logmask, const void *p, const char *txt)
39{
40 struct it_key key;
41 if (!txt)
42 txt = "(none)";
43 if (p)
44 {
45 char formstr[IT_KEY_LEVEL_MAX * 24];
46 int i;
47
48 memcpy(&key, p, sizeof(key));
49 assert(key.len > 0 && key.len <= IT_KEY_LEVEL_MAX);
50 *formstr = '\0';
51 for (i = 0; i<key.len; i++)
52 {
53 if (i)
54 strcat(formstr, ".");
55 yaz_snprintf(formstr + strlen(formstr), 23, ZINT_FORMAT, key.mem[i]);
56 }
57 yaz_log(logmask, "%s %s", formstr, txt);
58 }
59 else
60 yaz_log(logmask, " (no key) %s",txt);
61}
62
63void key_logdump(int logmask, const void *p)
64{
65 key_logdump_txt(logmask, p, "");
66}
67
68char *key_print_it (const void *p, char *buf)
69{
70 strcpy(buf, "");
71 return buf;
72}
73
74int key_compare (const void *p1, const void *p2)
75{
76 struct it_key i1, i2;
77 int i, l;
78 memcpy (&i1, p1, sizeof(i1));
79 memcpy (&i2, p2, sizeof(i2));
80 l = i1.len;
81 if (i2.len > l)
82 l = i2.len;
83 assert (l <= IT_KEY_LEVEL_MAX && l > 0);
84 for (i = 0; i < l; i++)
85 {
86 if (i1.mem[i] != i2.mem[i])
87 {
88 if (i1.mem[i] > i2.mem[i])
89 return l-i;
90 else
91 return i-l;
92 }
93 }
94 return 0;
95}
96
97zint key_get_seq(const void *p)
98{
99 struct it_key k;
100 memcpy (&k, p, sizeof(k));
101 return k.mem[k.len-1];
102}
103
104zint key_get_segment(const void *p)
105{
106 struct it_key k;
107 memcpy (&k, p, sizeof(k));
108 return k.mem[k.len-2];
109}
110
111int key_qsort_compare (const void *p1, const void *p2)
112{
113 int r;
114 size_t l;
115 char *cp1 = *(char **) p1;
116 char *cp2 = *(char **) p2;
117
118 if ((r = strcmp (cp1, cp2)))
119 return r;
120 l = strlen(cp1)+1;
121 if ((r = key_compare (cp1+l+1, cp2+l+1)))
122 return r;
123 return cp1[l] - cp2[l];
124}
125
127 struct it_key key;
128};
129
130void *iscz1_start (void)
131{
132 struct iscz1_code_info *p = (struct iscz1_code_info *)
133 xmalloc (sizeof(*p));
134 iscz1_reset(p);
135 return p;
136}
137
138void key_init(struct it_key *key)
139{
140 int i;
141 key->len = 0;
142 for (i = 0; i < IT_KEY_LEVEL_MAX; i++)
143 key->mem[i] = 0;
144}
145
146void iscz1_reset (void *vp)
147{
148 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
149 int i;
150 p->key.len = 0;
151 for (i = 0; i < IT_KEY_LEVEL_MAX; i++)
152 p->key.mem[i] = 0;
153}
154
155void iscz1_stop (void *p)
156{
157 xfree (p);
158}
159
160/* small encoder that works with unsigneds of any length */
161static CODEC_INLINE void iscz1_encode_int (zint d, char **dst)
162{
163 unsigned char *bp = (unsigned char*) *dst;
164
165 while (d > 127)
166 {
167 *bp++ = (unsigned) (128 | (d & 127));
168 d = d >> 7;
169 }
170 *bp++ = (unsigned) d;
171 *dst = (char *) bp;
172}
173
174/* small decoder that works with unsigneds of any length */
175static CODEC_INLINE zint iscz1_decode_int (unsigned char **src)
176{
177 zint d = 0;
178 unsigned char c;
179 unsigned r = 0;
180
181 while (((c = *(*src)++) & 128))
182 {
183 d += ((zint) (c&127) << r);
184 r += 7;
185 }
186 d += ((zint) c << r);
187 return d;
188}
189
190void iscz1_encode (void *vp, char **dst, const char **src)
191{
192 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
193 struct it_key tkey;
194 zint d;
195 int i;
196
197 /* 1
198 3, 2, 9, 12
199 3, 2, 10, 2
200 4, 1
201
202 if diff is 0, then there is more ...
203 if diff is non-zero, then _may_ be more
204 */
205 memcpy (&tkey, *src, sizeof(struct it_key));
206
207 /* deal with leader + delta encoding .. */
208 d = 0;
209 assert(tkey.len > 0 && tkey.len <= IT_KEY_LEVEL_MAX);
210 for (i = 0; i < tkey.len; i++)
211 {
212 d = tkey.mem[i] - p->key.mem[i];
213 if (d || i == tkey.len-1)
214 { /* all have been equal until now, now make delta .. */
215 p->key.mem[i] = tkey.mem[i];
216 if (d > 0)
217 {
218 iscz1_encode_int (i + (tkey.len << 3) + 64, dst);
219 i++;
220 iscz1_encode_int (d, dst);
221 }
222 else
223 {
224 iscz1_encode_int (i + (tkey.len << 3), dst);
225 }
226 break;
227 }
228 }
229 /* rest uses absolute encoding ... */
230 for (; i < tkey.len; i++)
231 {
232 iscz1_encode_int (tkey.mem[i], dst);
233 p->key.mem[i] = tkey.mem[i];
234 }
235 (*src) += sizeof(struct it_key);
236}
237
238void iscz1_decode (void *vp, char **dst, const char **src)
239{
240 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
241 int i;
242
243 int leader = (int) iscz1_decode_int ((unsigned char **) src);
244 i = leader & 7;
245 if (leader & 64)
246 p->key.mem[i] += iscz1_decode_int ((unsigned char **) src);
247 else
248 p->key.mem[i] = iscz1_decode_int ((unsigned char **) src);
249 p->key.len = (leader >> 3) & 7;
250 while (++i < p->key.len)
251 p->key.mem[i] = iscz1_decode_int ((unsigned char **) src);
252 memcpy (*dst, &p->key, sizeof(struct it_key));
253 (*dst) += sizeof(struct it_key);
254}
255
256/*
257 * Local variables:
258 * c-basic-offset: 4
259 * c-file-style: "Stroustrup"
260 * indent-tabs-mode: nil
261 * End:
262 * vim: shiftwidth=4 tabstop=8 expandtab
263 */
264
static CODEC_INLINE void iscz1_encode_int(zint d, char **dst)
Definition it_key.c:161
static CODEC_INLINE zint iscz1_decode_int(unsigned char **src)
Definition it_key.c:175
zint key_get_segment(const void *p)
Definition it_key.c:104
void * iscz1_start(void)
Definition it_key.c:130
void iscz1_decode(void *vp, char **dst, const char **src)
Definition it_key.c:238
void iscz1_encode(void *vp, char **dst, const char **src)
Definition it_key.c:190
int key_qsort_compare(const void *p1, const void *p2)
Definition it_key.c:111
#define CODEC_INLINE
Definition it_key.c:35
int key_compare(const void *p1, const void *p2)
Definition it_key.c:74
char * key_print_it(const void *p, char *buf)
Definition it_key.c:68
void key_logdump_txt(int logmask, const void *p, const char *txt)
Definition it_key.c:38
void iscz1_reset(void *vp)
Definition it_key.c:146
void key_logdump(int logmask, const void *p)
Definition it_key.c:63
void key_init(struct it_key *key)
Definition it_key.c:138
zint key_get_seq(const void *p)
Definition it_key.c:97
void iscz1_stop(void *p)
Definition it_key.c:155
#define IT_KEY_LEVEL_MAX
Definition it_key.h:29
struct it_key key
Definition it_key.c:127
int len
Definition it_key.h:31
zint mem[IT_KEY_LEVEL_MAX]
Definition it_key.h:32
long zint
Zebra integer.
Definition util.h:66
#define ZINT_FORMAT
Definition util.h:72