IDZEBRA  2.2.7
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 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 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 
38 void 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 
63 void key_logdump(int logmask, const void *p)
64 {
65  key_logdump_txt(logmask, p, "");
66 }
67 
68 char *key_print_it (const void *p, char *buf)
69 {
70  strcpy(buf, "");
71  return buf;
72 }
73 
74 int 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 
97 zint 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 
104 zint 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 
111 int 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 
130 void *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 
138 void 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 
146 void 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 
155 void iscz1_stop (void *p)
156 {
157  xfree (p);
158 }
159 
160 /* small encoder that works with unsigneds of any length */
161 static 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 */
175 static 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 
190 void 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 
238 void 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
char * key_print_it(const void *p, char *buf)
Definition: it_key.c:68
static CODEC_INLINE zint iscz1_decode_int(unsigned char **src)
Definition: it_key.c:175
void * iscz1_start(void)
Definition: it_key.c:130
zint key_get_segment(const void *p)
Definition: it_key.c:104
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
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
Definition: it_key.h:30
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