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 */ |