1 |
dpavlin |
237 |
/* |
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 */ |