use IsisDB module instead of OpenIsis -- this will fix various problems in
[webpac] / openisis / lstr.c
1 /*
2         openisis - an open implementation of the CDS/ISIS database
3         Version 0.8.x (patchlevel see file Version)
4         Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
5
6         This library is free software; you can redistribute it and/or
7         modify it under the terms of the GNU Lesser General Public
8         License as published by the Free Software Foundation; either
9         version 2.1 of the License, or (at your option) any later version.
10
11         This library is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14         Lesser General Public License for more details.
15
16         You should have received a copy of the GNU Lesser General Public
17         License along with this library; if not, write to the Free Software
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20         see README for more information
21 EOH */
22
23 /*
24         $Id: lstr.c,v 1.13 2003/04/08 00:20:53 kripke Exp $
25         implementation of record cooking.
26 */
27 #include <stdlib.h>
28
29 #include "lstr.h"
30 #include "luti.h"
31
32
33 /* ************************************************************
34         private types
35 */
36 /* ************************************************************
37         private data
38 */
39 static const char * nameMfc[] = {
40         "Mfc", "CTLM", "NMFN", "NMFB", "NMFP", "TYPE", "RCNT", "MFX1", "MFX2", "MFX3"
41 };
42
43 static int descMfc[] = {
44         LSTRSIZE( 9, 0, 0 ), /* sizes (fix, rep, occ) */
45         LSTR_AUTOLENGTHS,
46         LMBRINT,
47         LMBRINT,
48         LMBRINT,
49         LMBRSHORT,
50         LMBRSHORT,
51         LMBRINT,
52         LMBRINT,
53         LMBRINT,
54         LMBRINT
55 }; /* descMfc */
56
57
58 static const char * nameMfr[] = {
59         "Mfr", "MFN", "RECL", "BWB", "BWP", "BASE", "NVF", "STAT",
60         "TAG", "'POS", "LEN"
61 };
62 static int descMfr[] = {
63         LSTRSIZE( 7, 3, 0 ), /* sizes (fix, rep, occ) */
64         LSTR_AUTOLENGTHS,
65         LMBRINT,
66         LMBRSHORT,
67         LMBRINT,
68         LMBRSHORT,
69
70         LMBRSHORT,
71         LMBRSHORT,
72         LMBRSHORT,
73
74         LMBRSHORT,
75         LMBRSHORT,
76         LMBRSHORT
77 }; /* descMfr */
78
79 /* aligned version */
80 static int descMfrA[] = {
81         LSTRSIZE( 7, 3, 0 ), /* sizes (fix, rep, occ) */
82         LSTR_AUTOLENGTHS,
83         LMBRINT,
84         LMBRSHORT,
85         LSTRLOFF( LMBRINT, 8 ),
86         LMBRSHORT,
87
88         LMBRSHORT,
89         LMBRSHORT,
90         LMBRSHORT,
91
92         LMBRSHORT,
93         LMBRSHORT,
94         LMBRSHORT
95 }; /* descMfr */
96
97 static const char * nameXrf[] = {
98         "Xrf", "XPOS", "XREC"
99 };
100 static int descXrf[] = {
101         LSTRSIZE( 1, 1, 127 ), /* sizes (fix, rep, occ) */
102         LSTR_AUTOLENGTHS,
103         LMBRINT,
104         LMBRINT
105 }; /* descXrf */
106
107 static const char ** nameMst[LSTR_MST] = {
108         nameMfc, nameMfr, nameXrf
109 };
110
111 static int* descMst[LSTR_MST] = {
112         descMfc, /* MST head */
113         descMfr, /* MST record */
114         descXrf  /* XRF record */
115 };
116
117 static int* descMstA[LSTR_MST] = {
118         descMfc, /* MST head */
119         descMfrA, /* MST record */
120         descXrf  /* XRF record */
121 };
122
123
124 static const char * nameCnt[] = {
125         "Cnt", "TYPE", "ORDN", "ORDF", "N", "K", "LEV", "POSR", "NMAX", "FMAX", "ABNO"
126 };
127 static int descCnt[] = {
128         LSTRSIZE( 10, 0, 0 ), /* sizes (fix, rep, occ) */
129         LSTR_AUTOLENGTHS,
130         LMBRSHORT, /* TYPE */
131         LMBRSHORT, /* ORDN */
132         LMBRSHORT, /* ORDF */
133         LMBRSHORT, /* N */
134         LMBRSHORT, /* K */
135         LMBRSHORT, /* LEV */
136         LMBRINT,   /* POSR */
137         LMBRINT,   /* NMAX */
138         LMBRINT,   /* FMAX */
139         LMBRSHORT  /* ABNO */
140 }; /* descCnt */
141
142 static int descCntA[] = {
143         LSTRSIZE( 10, 0, 0 ), /* sizes (fix, rep, occ) */
144         0,28,44,
145         LMBRSHORT, /* TYPE */
146         LMBRSHORT, /* ORDN */
147         LMBRSHORT, /* ORDF */
148         LMBRSHORT, /* N */
149         LMBRSHORT, /* K */
150         LMBRSHORT, /* LEV */
151         LMBRINT,   /* POSR */
152         LMBRINT,   /* NMAX */
153         LMBRINT,   /* FMAX */
154         LMBRSHORT  /* ABNO */
155 }; /* descCntA */
156
157 static const char * nameN0[] = {
158         "N0", "POS", "OCK", "TYPE", "'KEY", "REF"
159 };
160 static int descN01[] = {
161         LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
162         LSTR_AUTOLENGTHS,
163         LMBRINT,   /* POS */
164         LMBRSHORT, /* OCK */
165         LMBRSHORT, /* TYPE */
166         10,        /* KEY */
167         LMBRINT    /* REF */
168 };
169
170 static int descN01A[] = {
171         LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
172         LSTR_AUTOLENGTHS,
173         LMBRINT,   /* POS */
174         LMBRSHORT, /* OCK */
175         LMBRSHORT, /* TYPE */
176         10,        /* KEY */
177         LSTRLOFF( LMBRINT, 12 )    /* REF */
178 };
179
180 static int descN02[] = {
181         LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
182         LSTR_AUTOLENGTHS,
183         LMBRINT,   /* POS */
184         LMBRSHORT, /* OCK */
185         LMBRSHORT, /* TYPE */
186         30,        /* KEY */
187         LMBRINT    /* REF */
188 };
189 static int descN02A[] = {
190         LSTRSIZE( 3, 2, 10 ), /* sizes (fix, rep, occ) */
191         LSTR_AUTOLENGTHS,
192         LMBRINT,   /* POS */
193         LMBRSHORT, /* OCK */
194         LMBRSHORT, /* TYPE */
195         30,        /* KEY */
196         LSTRLOFF( LMBRINT, 32 )    /* REF */
197 };
198
199 static const char * nameL0[] = {
200         "L0", "POS", "OCK", "TYPE", "PS", "'KEY", "INFB", "INFP"
201 };
202 static int descL01[] = {
203         LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
204         LSTR_AUTOLENGTHS,
205         LMBRINT,   /* POS */
206         LMBRSHORT, /* OCK */
207         LMBRSHORT, /* TYPE */
208         LMBRINT,   /* PS */
209         10,        /* KEY */
210         LMBRINT,   /* INFB */
211         LMBRINT    /* INFP */
212 };
213 static int descL01A[] = {
214         LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
215         LSTR_AUTOLENGTHS,
216         LMBRINT,   /* POS */
217         LMBRSHORT, /* OCK */
218         LMBRSHORT, /* TYPE */
219         LMBRINT,   /* PS */
220         10,        /* KEY */
221         LSTRLOFF( LMBRINT, 12 ),   /* INFB */
222         LMBRINT    /* INFP */
223 };
224
225
226 static int descL02[] = {
227         LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
228         LSTR_AUTOLENGTHS,
229         LMBRINT,   /* POS */
230         LMBRSHORT, /* OCK */
231         LMBRSHORT, /* TYPE */
232         LMBRINT,   /* PS */
233         30,        /* KEY */
234         LMBRINT,   /* INFB */
235         LMBRINT    /* INFP */
236 };
237 static int descL02A[] = {
238         LSTRSIZE( 4, 3, 10 ), /* sizes (fix, rep, occ) */
239         LSTR_AUTOLENGTHS,
240         LMBRINT,   /* POS */
241         LMBRSHORT, /* OCK */
242         LMBRSHORT, /* TYPE */
243         LMBRINT,   /* PS */
244         30,        /* KEY */
245         LSTRLOFF( LMBRINT, 32 ),   /* INFB */
246         LMBRINT    /* INFP */
247 };
248
249 static const char * nameIfp[] = {
250         "IfH", "NXTB", "NXTP", "TOTP", "SEGP", "SEGC", "MFN", "INFO"
251 };
252 static int descIfp[] = {
253 #ifdef CONVERT_POSTINGS
254         /*
255         to properly convert postings,
256         the repeated part needs to be a big-endian 64bit int
257
258         however, converting can't be done in a straightforward fashion anyway,
259         since posting segments have holes of one or two longs at block boundaries
260         */
261         LSTRSIZE( 5, 2, 1 ), /* sizes (fix, rep, occ) */
262         LSTR_AUTOLENGTHS,
263         LMBRINT,   /* */
264         LMBRINT,   /* */
265 #else
266         LSTRSIZE( 5, 0, 0 ), /* sizes (fix, rep, occ) */
267         LSTR_AUTOLENGTHS,
268 #endif
269         LMBRINT,   /* */
270         LMBRINT,   /* */
271         LMBRINT,   /* */
272         LMBRINT,   /* */
273         LMBRINT    /* */
274 };
275
276 static const char ** nameInv[LSTR_INV] = {
277         nameCnt,
278         nameN0,
279         nameL0,
280         nameN0,
281         nameL0,
282         nameIfp
283 };
284
285 static int* descInv[LSTR_INV] = {
286         descCnt, /* CNT record */
287         descN01, /* N01 record */
288         descL01, /* L01 record */
289         descN02, /* N02 record */
290         descL02, /* L02 record */
291         descIfp  /* Ifp record */
292 };
293
294 static int* descInvA[LSTR_INV] = {
295         descCntA, /* CNT record */
296         descN01A, /* N01 record */
297         descL01A, /* L01 record */
298         descN02A, /* N02 record */
299         descL02A, /* L02 record */
300         descIfp  /* Ifp record */
301 };
302
303
304 /* ************************************************************
305         private functions
306 */
307 /* ************************************************************
308         package data
309 */
310 const LstrSet lstrlib[LSET_SETS] = {
311         { /* Isis 1 MST */
312                 nameMst, { descMst, descMstA }
313         }, 
314         { /* Isis 1 INV */
315                 nameInv, { descInv, descInvA }
316         }, 
317 }; /* lstrlib */
318
319 /* ************************************************************
320         package functions
321 */
322 /* ************************************************************
323         public functions
324 */
325 int lstr_auto ( int *str ) {
326         static int pow2[] = { 1, 2, 4, 8 };
327         int ret = 0;
328         int fix,rep,occ,i;
329         int *xmbrs, txlen, tilen;
330         int nmbrs, off = 0, xlen[2] = {0,0}, blen[2] = {0,0}, x=0;
331         
332
333         if ( NULL == str ) {
334 #define DOALL( x ) \
335         for ( i=0; i<(int)(sizeof(x)/sizeof(x[0])); i++ ) \
336                 if ( NULL != x[i] ) ret |= lstr_auto( x[i] )
337                 DOALL( descMst );
338                 DOALL( descInv );
339                 DOALL( descMstA );
340                 DOALL( descInvA );
341                 return ret;
342         }
343
344         fix = LSTRFIX(*str);
345         rep = LSTRREP(*str);
346         occ = LSTROCC(*str);
347         xmbrs = str + LSTR_XMBR;
348         nmbrs = fix;
349
350         for ( x=0; ; x++ ) { /* fix and rep */
351                 for ( i=0; i<nmbrs; i++ ) {
352                         int xmbr = xmbrs[i];
353                         int len;
354                         if ( LONG2OFF( xmbr ) )
355                                 off = LONG2OFF( xmbr );
356                         else {
357                                 xmbrs[i] |= off << 16;
358                         }
359                         if ( LMBRISNUM(xmbr) )
360                                 len = pow2[ LMBRLD(xmbr) ];
361                         else {
362                                 len = LONG2LEN(xmbr);
363                                 blen[x] += len+1;
364                         }
365                         LOG_DBG( LOG_ALL, "x.i %d.%d off %3ld, xmbr %08x len %d",
366                                 x, i, off, xmbrs[i], len );
367                         off += len;
368                         if ( xlen[x] < off )
369                                 xlen[x] = off;
370                 }
371                 /* done with one part */
372                 if ( x || !rep ) /* was 2nd */
373                         break;
374                 xmbrs += fix;
375                 nmbrs  = rep;
376                 off    = 0;
377         }
378         /* got length's and buffer lengths of both parts */
379         LOG_DBG( LOG_ALL, "%08x %08x %d %d: xl %d %d bl %d %d",
380                 str[0], str[1], str[2], str[3],
381                 xlen[0], xlen[1], blen[0], blen[1] );
382         if ( !(short)(str[LSTR_XRLO] >> 16) )
383                 str[LSTR_XRLO] |= xlen[0] << 16;
384         else if ( xlen[0] > (short)(str[LSTR_XRLO] >> 16) )
385                 log_msg( LOG_WARN, "short xlen[0] %hd < %d",
386                         (short)(str[LSTR_XRLO] >> 16), xlen[0] );
387         if ( !(short)str[LSTR_XRLO] )
388                 str[LSTR_XRLO] |= 0xffff & xlen[1];
389         else if ( xlen[1] > (short)str[LSTR_XRLO] )
390                 log_msg( LOG_WARN, "short xlen[1] %hd < %d",
391                         (short)str[LSTR_XRLO], xlen[1] );
392         /* build totals applying occ */
393         txlen = (short)(str[LSTR_XRLO] >> 16)
394                 + (int)occ*(short)str[LSTR_XRLO];
395         if ( !str[LSTR_XLEN] )
396                 str[LSTR_XLEN] = txlen;
397         else if ( txlen > str[LSTR_XLEN] )
398                 log_msg( LOG_WARN, "short xlen %d < %d",
399                         str[LSTR_XLEN], txlen );
400         tilen = LSTRLEN(*str) + blen[0] + (int)occ*blen[1];
401         if ( !str[LSTR_ILEN] )
402                 str[LSTR_ILEN] = tilen;
403         else if ( tilen > str[LSTR_ILEN] )
404                 log_msg( LOG_WARN, "short ilen %d < %d",
405                         str[LSTR_ILEN], tilen );
406         LOG_DBG( LOG_ALL, "%08x xrlo %08x xl %d il %d",
407                 str[0], str[1], str[2], str[3] );
408         return ret;
409 }       /* lstr_auto */