1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>zstr.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> </center>
<hr><h1>zstr.cpp</h1><div class="fragment"><pre>00001 <font class="comment">/******************************************************************************</font>
00002 <font class="comment"> * zstr.cpp - code for class 'zStr'- a module that reads compressed text</font>
00003 <font class="comment"> * files and provides lookup and parsing functions based on</font>
00004 <font class="comment"> * class StrKey</font>
00005 <font class="comment"> */</font>
00006
00007 <font class="preprocessor">#include <stdio.h></font>
00008 <font class="preprocessor">#include <fcntl.h></font>
00009 <font class="preprocessor">#include <errno.h></font>
00010
00011 <font class="preprocessor">#ifndef __GNUC__</font>
00012 <font class="preprocessor"></font><font class="preprocessor">#include <io.h></font>
00013 <font class="preprocessor">#else</font>
00014 <font class="preprocessor"></font><font class="preprocessor">#include <unistd.h></font>
00015 <font class="preprocessor">#endif</font>
00016 <font class="preprocessor"></font>
00017 <font class="preprocessor">#include <string.h></font>
00018 <font class="preprocessor">#include <stdlib.h></font>
00019 <font class="preprocessor">#include <utilfuns.h></font>
00020 <font class="preprocessor">#include <zstr.h></font>
00021 <font class="preprocessor">#include <swcomprs.h></font>
00022
00023 <font class="preprocessor">#include <sysdata.h></font>
00024 <font class="preprocessor">#include <entriesblk.h></font>
00025
00026 <font class="comment">/******************************************************************************</font>
00027 <font class="comment"> * zStr Statics</font>
00028 <font class="comment"> */</font>
00029
00030 <font class="keywordtype">int</font> zStr::instance = 0;
00031 <font class="keyword">const</font> <font class="keywordtype">int</font> zStr::IDXENTRYSIZE = 8;
00032 <font class="keyword">const</font> <font class="keywordtype">int</font> zStr::ZDXENTRYSIZE = 8;
00033
00034
00035 <font class="comment">/******************************************************************************</font>
00036 <font class="comment"> * zStr Constructor - Initializes data for instance of zStr</font>
00037 <font class="comment"> *</font>
00038 <font class="comment"> * ENT: ipath - path of the directory where data and index files are located.</font>
00039 <font class="comment"> */</font>
00040
00041 zStr::zStr(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath, <font class="keywordtype">int</font> fileMode, <font class="keywordtype">long</font> blockCount, SWCompress *icomp) {
00042 <font class="keywordtype">char</font> buf[127];
00043
00044 nl = <font class="charliteral">'\n'</font>;
00045 lastoff = -1;
00046 path = 0;
00047 stdstr(&path, ipath);
00048
00049 compressor = (icomp) ? icomp : <font class="keyword">new</font> SWCompress();
00050 this->blockCount = blockCount;
00051 <font class="preprocessor">#ifndef O_BINARY // O_BINARY is needed in Borland C++ 4.53</font>
00052 <font class="preprocessor"></font><font class="preprocessor">#define O_BINARY 0 // If it hasn't been defined than we probably</font>
00053 <font class="preprocessor"></font><font class="preprocessor">#endif // don't need it.</font>
00054 <font class="preprocessor"></font>
00055 <font class="keywordflow">if</font> (fileMode == -1) { <font class="comment">// try read/write if possible</font>
00056 fileMode = O_RDWR;
00057 }
00058
00059 sprintf(buf, <font class="stringliteral">"%s.idx"</font>, path);
00060 idxfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, <font class="keyword">true</font>);
00061
00062 sprintf(buf, <font class="stringliteral">"%s.dat"</font>, path);
00063 datfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, <font class="keyword">true</font>);
00064
00065 sprintf(buf, <font class="stringliteral">"%s.zdx"</font>, path);
00066 zdxfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, <font class="keyword">true</font>);
00067
00068 sprintf(buf, <font class="stringliteral">"%s.zdt"</font>, path);
00069 zdtfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, <font class="keyword">true</font>);
00070
00071 <font class="keywordflow">if</font> (datfd <= 0) {
00072 sprintf(buf, <font class="stringliteral">"Error: %d"</font>, errno);
00073 perror(buf);
00074 }
00075
00076 cacheBlock = 0;
00077 cacheBlockIndex = -1;
00078 cacheDirty = <font class="keyword">false</font>;
00079
00080 <a class="code" href="class_verse_key.html#r3">instance</a>++;
00081 }
00082
00083
00084 <font class="comment">/******************************************************************************</font>
00085 <font class="comment"> * zStr Destructor - Cleans up instance of zStr</font>
00086 <font class="comment"> */</font>
00087
00088 zStr::~zStr() {
00089
00090 flushCache();
00091
00092 <font class="keywordflow">if</font> (path)
00093 <font class="keyword">delete</font> [] path;
00094
00095 --<a class="code" href="class_verse_key.html#r3">instance</a>;
00096
00097 FileMgr::systemFileMgr.close(idxfd);
00098 FileMgr::systemFileMgr.close(datfd);
00099 FileMgr::systemFileMgr.close(zdxfd);
00100 FileMgr::systemFileMgr.close(zdtfd);
00101
00102
00103 <font class="keywordflow">if</font> (compressor)
00104 <font class="keyword">delete</font> compressor;
00105
00106 }
00107
00108
00109 <font class="comment">/******************************************************************************</font>
00110 <font class="comment"> * zStr::getidxbufdat - Gets the index string at the given dat offset</font>
00111 <font class="comment"> * NOTE: buf is calloc'd, or if not null, realloc'd and must</font>
00112 <font class="comment"> * be free'd by calling function</font>
00113 <font class="comment"> *</font>
00114 <font class="comment"> * ENT: ioffset - offset in dat file to lookup</font>
00115 <font class="comment"> * buf - address of pointer to allocate for storage of string</font>
00116 <font class="comment"> */</font>
00117
00118 <font class="keywordtype">void</font> zStr::getKeyFromDatOffset(<font class="keywordtype">long</font> ioffset, <font class="keywordtype">char</font> **buf) {
00119 <font class="keywordtype">int</font> size;
00120 <font class="keywordtype">char</font> ch;
00121 <font class="keywordflow">if</font> (datfd > 0) {
00122 lseek(datfd->getFd(), ioffset, SEEK_SET);
00123 <font class="keywordflow">for</font> (size = 0; read(datfd->getFd(), &ch, 1) == 1; size++) {
00124 <font class="keywordflow">if</font> ((ch == <font class="charliteral">'\\'</font>) || (ch == 10) || (ch == 13))
00125 <font class="keywordflow">break</font>;
00126 }
00127 *buf = (*buf) ? (<font class="keywordtype">char</font> *)realloc(*buf, size + 1) : (char *)malloc(size + 1);
00128 <font class="keywordflow">if</font> (size) {
00129 lseek(datfd->getFd(), ioffset, SEEK_SET);
00130 read(datfd->getFd(), *buf, size);
00131 }
00132 (*buf)[size] = 0;
00133 <font class="keywordflow">for</font> (size--; size > 0; size--)
00134 (*buf)[size] = SW_toupper((*buf)[size]);
00135 }
00136 <font class="keywordflow">else</font> {
00137 *buf = (*buf) ? (<font class="keywordtype">char</font> *)realloc(*buf, 1) : (char *)malloc(1);
00138 **buf = 0;
00139 }
00140 }
00141
00142
00143 <font class="comment">/******************************************************************************</font>
00144 <font class="comment"> * zStr::getidxbuf - Gets the index string at the given idx offset</font>
00145 <font class="comment"> * NOTE: buf is calloc'd, or if not null, realloc'd</font>
00146 <font class="comment"> * and must be freed by calling function</font>
00147 <font class="comment"> *</font>
00148 <font class="comment"> * ENT: ioffset - offset in idx file to lookup</font>
00149 <font class="comment"> * buf - address of pointer to allocate for storage of string</font>
00150 <font class="comment"> */</font>
00151
00152 <font class="keywordtype">void</font> zStr::getKeyFromIdxOffset(<font class="keywordtype">long</font> ioffset, <font class="keywordtype">char</font> **buf) {
00153 __u32 offset;
00154
00155 <font class="keywordflow">if</font> (idxfd > 0) {
00156 lseek(idxfd->getFd(), ioffset, SEEK_SET);
00157 read(idxfd->getFd(), &offset, <font class="keyword">sizeof</font>(__u32));
00158 offset = swordtoarch32(offset);
00159 getKeyFromDatOffset(offset, buf);
00160 }
00161 }
00162
00163
00164 <font class="comment">/******************************************************************************</font>
00165 <font class="comment"> * zStr::findoffset - Finds the offset of the key string from the indexes</font>
00166 <font class="comment"> *</font>
00167 <font class="comment"> * ENT: key - key string to lookup</font>
00168 <font class="comment"> * offset - address to store the starting offset</font>
00169 <font class="comment"> * size - address to store the size of the entry</font>
00170 <font class="comment"> * away - number of entries before of after to jump</font>
00171 <font class="comment"> * (default = 0)</font>
00172 <font class="comment"> *</font>
00173 <font class="comment"> * RET: error status</font>
00174 <font class="comment"> */</font>
00175
00176 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> zStr::findKeyIndex(<font class="keyword">const</font> <font class="keywordtype">char</font> *ikey, <font class="keywordtype">long</font> *idxoff, <font class="keywordtype">long</font> away) {
00177 <font class="keywordtype">char</font> *trybuf = 0, *key = 0, quitflag = 0;
00178 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> retval = 0;
00179 __s32 headoff, tailoff, tryoff = 0, maxoff = 0;
00180 __u32 start, size;
00181
00182 <font class="keywordflow">if</font> (idxfd->getFd() >= 0) {
00183 tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - IDXENTRYSIZE;
00184 <font class="keywordflow">if</font> (*ikey) {
00185 headoff = 0;
00186 stdstr(&key, ikey);
00187 toupperstr(key);
00188
00189 <font class="keywordflow">while</font> (headoff < tailoff) {
00190 tryoff = (lastoff == -1) ? headoff + (((((tailoff / IDXENTRYSIZE) - (headoff / IDXENTRYSIZE))) / 2) * IDXENTRYSIZE) : lastoff;
00191 lastoff = -1;
00192
00193 getKeyFromIdxOffset(tryoff, &trybuf);
00194
00195 <font class="keywordflow">if</font> (!*trybuf && tryoff) { <font class="comment">// In case of extra entry at end of idx (not first entry)</font>
00196 tryoff += (tryoff > (maxoff / 2))?-IDXENTRYSIZE:IDXENTRYSIZE;
00197 retval = -1;
00198 <font class="keywordflow">break</font>;
00199 }
00200
00201 <font class="keywordtype">int</font> diff = strcmp(key, trybuf);
00202 <font class="keywordflow">if</font> (!diff)
00203 <font class="keywordflow">break</font>;
00204
00205 <font class="keywordflow">if</font> (diff < 0)
00206 tailoff = (tryoff == headoff) ? headoff : tryoff;
00207 <font class="keywordflow">else</font> headoff = tryoff;
00208 <font class="keywordflow">if</font> (tailoff == headoff + IDXENTRYSIZE) {
00209 <font class="keywordflow">if</font> (quitflag++)
00210 headoff = tailoff;
00211 }
00212 }
00213 <font class="keywordflow">if</font> (headoff >= tailoff)
00214 tryoff = headoff;
00215 <font class="keywordflow">if</font> (trybuf)
00216 free(trybuf);
00217 <font class="keyword">delete</font> [] key;
00218 }
00219 <font class="keywordflow">else</font> { tryoff = 0; }
00220
00221 lseek(idxfd->getFd(), tryoff, SEEK_SET);
00222
00223 start = size = 0;
00224 retval = (read(idxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32))==<font class="keyword">sizeof</font>(__u32)) ? retval : -1;
00225 retval = (read(idxfd->getFd(), &size, <font class="keyword">sizeof</font>(__u32))==<font class="keyword">sizeof</font>(__u32)) ? retval : -1;
00226 start = swordtoarch32(start);
00227 size = swordtoarch32(size);
00228
00229 <font class="keywordflow">if</font> (idxoff)
00230 *idxoff = tryoff;
00231
00232 <font class="keywordflow">while</font> (away) {
00233 __u32 laststart = start;
00234 __u32 lastsize = size;
00235 __s32 lasttry = tryoff;
00236 tryoff += (away > 0) ? IDXENTRYSIZE : -IDXENTRYSIZE;
00237
00238 <font class="keywordtype">bool</font> bad = <font class="keyword">false</font>;
00239 <font class="keywordflow">if</font> (((long)(tryoff + (away*IDXENTRYSIZE)) < -IDXENTRYSIZE) || (tryoff + (away*IDXENTRYSIZE) > (maxoff+IDXENTRYSIZE)))
00240 bad = <font class="keyword">true</font>;
00241 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (lseek(idxfd->getFd(), tryoff, SEEK_SET) < 0)
00242 bad = <font class="keyword">true</font>;
00243 <font class="keywordflow">if</font> (bad) {
00244 retval = -1;
00245 start = laststart;
00246 size = lastsize;
00247 tryoff = lasttry;
00248 <font class="keywordflow">if</font> (idxoff)
00249 *idxoff = tryoff;
00250 <font class="keywordflow">break</font>;
00251 }
00252 read(idxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32));
00253 read(idxfd->getFd(), &size, <font class="keyword">sizeof</font>(__u32));
00254 start = swordtoarch32(start);
00255 size = swordtoarch32(size);
00256
00257 <font class="keywordflow">if</font> (idxoff)
00258 *idxoff = tryoff;
00259
00260
00261 <font class="keywordflow">if</font> (((laststart != start) || (lastsize != size)) && (start >= 0) && (size))
00262 away += (away < 0) ? 1 : -1;
00263 }
00264
00265 lastoff = tryoff;
00266 }
00267 <font class="keywordflow">else</font> {
00268 <font class="keywordflow">if</font> (idxoff)
00269 *idxoff = 0;
00270 retval = -1;
00271 }
00272 <font class="keywordflow">return</font> retval;
00273 }
00274
00275
00276 <font class="comment">/******************************************************************************</font>
00277 <font class="comment"> * zStr::preptext - Prepares the text before returning it to external</font>
00278 <font class="comment"> * objects</font>
00279 <font class="comment"> *</font>
00280 <font class="comment"> * ENT: buf - buffer where text is stored and where to store the prep'd</font>
00281 <font class="comment"> * text.</font>
00282 <font class="comment"> */</font>
00283
00284 <font class="keywordtype">void</font> zStr::prepText(<font class="keywordtype">char</font> *buf) {
00285 <font class="keywordtype">char</font> *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0;
00286
00287 <font class="keywordflow">for</font> (to = from = buf; *from; from++) {
00288 <font class="keywordflow">switch</font> (*from) {
00289 <font class="keywordflow">case</font> 10:
00290 <font class="keywordflow">if</font> (!realdata)
00291 <font class="keywordflow">continue</font>;
00292 space = (cr) ? 0 : 1;
00293 cr = 0;
00294 nlcnt++;
00295 <font class="keywordflow">if</font> (nlcnt > 1) {
00296 <font class="comment">// *to++ = nl;</font>
00297 *to++ = nl;
00298 <font class="comment">// nlcnt = 0;</font>
00299 }
00300 <font class="keywordflow">continue</font>;
00301 <font class="keywordflow">case</font> 13:
00302 <font class="keywordflow">if</font> (!realdata)
00303 <font class="keywordflow">continue</font>;
00304 *to++ = nl;
00305 space = 0;
00306 cr = 1;
00307 <font class="keywordflow">continue</font>;
00308 }
00309 realdata = 1;
00310 nlcnt = 0;
00311 <font class="keywordflow">if</font> (space) {
00312 space = 0;
00313 <font class="keywordflow">if</font> (*from != <font class="charliteral">' '</font>) {
00314 *to++ = <font class="charliteral">' '</font>;
00315 from--;
00316 <font class="keywordflow">continue</font>;
00317 }
00318 }
00319 *to++ = *from;
00320 }
00321 *to = 0;
00322
00323 <font class="keywordflow">while</font> (to > (buf+1)) { <font class="comment">// remove trailing excess</font>
00324 to--;
00325 <font class="keywordflow">if</font> ((*to == 10) || (*to == <font class="charliteral">' '</font>))
00326 *to = 0;
00327 <font class="keywordflow">else</font> <font class="keywordflow">break</font>;
00328 }
00329 }
00330
00331
00332 <font class="comment">/******************************************************************************</font>
00333 <font class="comment"> * zStr::gettext - gets text at a given offset</font>
00334 <font class="comment"> *</font>
00335 <font class="comment"> * ENT:</font>
00336 <font class="comment"> * offset - idxoffset where the key is located.</font>
00337 <font class="comment"> * buf - buffer to store text</font>
00338 <font class="comment"> * idxbuf - buffer to store index key</font>
00339 <font class="comment"> * NOTE: buffer will be alloc'd / realloc'd and </font>
00340 <font class="comment"> * should be free'd by the client</font>
00341 <font class="comment"> *</font>
00342 <font class="comment"> */</font>
00343
00344 <font class="keywordtype">void</font> zStr::getText(<font class="keywordtype">long</font> offset, <font class="keywordtype">char</font> **idxbuf, <font class="keywordtype">char</font> **buf) {
00345 <font class="keywordtype">char</font> *ch;
00346 <font class="keywordtype">char</font> *idxbuflocal = 0;
00347 getKeyFromIdxOffset(offset, &idxbuflocal);
00348 __u32 start;
00349 __u32 size;
00350
00351 <font class="keywordflow">do</font> {
00352 lseek(idxfd->getFd(), offset, SEEK_SET);
00353 read(idxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32));
00354 read(idxfd->getFd(), &size, <font class="keyword">sizeof</font>(__u32));
00355 start = swordtoarch32(start);
00356 size = swordtoarch32(size);
00357
00358 *buf = (*buf) ? (<font class="keywordtype">char</font> *)realloc(*buf, size + 1) : (char *)malloc(size + 1);
00359 *idxbuf = (*idxbuf) ? (<font class="keywordtype">char</font> *)realloc(*idxbuf, size + 1) : (char *)malloc(size + 1);
00360 memset(*buf, 0, size + 1);
00361 memset(*idxbuf, 0, size + 1);
00362 lseek(datfd->getFd(), start, SEEK_SET);
00363 read(datfd->getFd(), *buf, (int)(size));
00364
00365 <font class="keywordflow">for</font> (ch = *buf; *ch; ch++) { <font class="comment">// skip over index string</font>
00366 <font class="keywordflow">if</font> (*ch == 10) {
00367 ch++;
00368 <font class="keywordflow">break</font>;
00369 }
00370 }
00371 memmove(*buf, ch, size - (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>)(ch-*buf));
00372
00373 <font class="comment">// resolve link</font>
00374 <font class="keywordflow">if</font> (!strncmp(*buf, <font class="stringliteral">"@LINK"</font>, 5)) {
00375 <font class="keywordflow">for</font> (ch = *buf; *ch; ch++) { <font class="comment">// null before nl</font>
00376 <font class="keywordflow">if</font> (*ch == 10) {
00377 *ch = 0;
00378 <font class="keywordflow">break</font>;
00379 }
00380 }
00381 findKeyIndex(*buf + IDXENTRYSIZE, &offset);
00382 }
00383 <font class="keywordflow">else</font> <font class="keywordflow">break</font>;
00384 }
00385 <font class="keywordflow">while</font> (true); <font class="comment">// while we're resolving links</font>
00386
00387 <font class="keywordflow">if</font> (idxbuflocal) {
00388 __u32 localsize = strlen(idxbuflocal);
00389 localsize = (localsize < (size - 1)) ? localsize : (size - 1);
00390 strncpy(*idxbuf, idxbuflocal, localsize);
00391 (*idxbuf)[localsize] = 0;
00392 free(idxbuflocal);
00393 }
00394 __u32 block = 0;
00395 __u32 entry = 0;
00396 memmove(&block, *buf, <font class="keyword">sizeof</font>(__u32));
00397 memmove(&entry, *buf + <font class="keyword">sizeof</font>(__u32), <font class="keyword">sizeof</font>(__u32));
00398 block = swordtoarch32(block);
00399 entry = swordtoarch32(entry);
00400 getCompressedText(block, entry, buf);
00401 }
00402
00403
00404 <font class="comment">/******************************************************************************</font>
00405 <font class="comment"> * zStr::getCompressedText - Get text entry from a compressed index / zdata</font>
00406 <font class="comment"> * file.</font>
00407 <font class="comment"> */</font>
00408
00409 <font class="keywordtype">void</font> zStr::getCompressedText(<font class="keywordtype">long</font> block, <font class="keywordtype">long</font> entry, <font class="keywordtype">char</font> **buf) {
00410
00411 __u32 size = 0;
00412
00413 <font class="keywordflow">if</font> (cacheBlockIndex != block) {
00414 __u32 start = 0;
00415
00416 lseek(zdxfd->getFd(), block * ZDXENTRYSIZE, SEEK_SET);
00417 read(zdxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32));
00418 read(zdxfd->getFd(), &size, <font class="keyword">sizeof</font>(__u32));
00419 start = swordtoarch32(start);
00420 size = swordtoarch32(size);
00421
00422 *buf = (*buf) ? (<font class="keywordtype">char</font> *)realloc(*buf, size + 1) : (char *)malloc(size + 1);
00423
00424 lseek(zdtfd->getFd(), start, SEEK_SET);
00425 read(zdtfd->getFd(), *buf, size);
00426
00427 flushCache();
00428
00429 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> len = size;
00430 compressor->zBuf(&len, *buf);
00431 <font class="keywordtype">char</font> * rawBuf = compressor->Buf(0, &len);
00432 cacheBlock = <font class="keyword">new</font> EntriesBlock(rawBuf, len);
00433 cacheBlockIndex = block;
00434 }
00435 size = cacheBlock->getEntrySize(entry);
00436 *buf = (*buf) ? (<font class="keywordtype">char</font> *)realloc(*buf, size + 1) : (char *)malloc(size + 1);
00437 strcpy(*buf, cacheBlock->getEntry(entry));
00438 }
00439
00440
00441 <font class="comment">/******************************************************************************</font>
00442 <font class="comment"> * zLD::settext - Sets text for current offset</font>
00443 <font class="comment"> *</font>
00444 <font class="comment"> * ENT: key - key for this entry</font>
00445 <font class="comment"> * buf - buffer to store</font>
00446 <font class="comment"> * len - length of buffer (0 - null terminated)</font>
00447 <font class="comment"> */</font>
00448
00449 <font class="keywordtype">void</font> zStr::setText(<font class="keyword">const</font> <font class="keywordtype">char</font> *ikey, <font class="keyword">const</font> <font class="keywordtype">char</font> *buf, <font class="keywordtype">long</font> len) {
00450
00451 __u32 start, outstart;
00452 __u32 size, outsize;
00453 __s32 endoff;
00454 <font class="keywordtype">long</font> idxoff = 0;
00455 __s32 shiftSize;
00456 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> nl[] = {13, 10};
00457 <font class="keywordtype">char</font> *tmpbuf = 0;
00458 <font class="keywordtype">char</font> *key = 0;
00459 <font class="keywordtype">char</font> *dbKey = 0;
00460 <font class="keywordtype">char</font> *idxBytes = 0;
00461 <font class="keywordtype">char</font> *outbuf = 0;
00462 <font class="keywordtype">char</font> *ch = 0;
00463
00464 stdstr(&key, ikey);
00465 toupperstr(key);
00466
00467 <font class="keywordtype">char</font> notFound = findKeyIndex(ikey, &idxoff, 0);
00468 <font class="keywordflow">if</font> (!notFound) {
00469 getKeyFromIdxOffset(idxoff, &dbKey);
00470 <font class="keywordtype">int</font> diff = strcmp(key, dbKey);
00471 <font class="keywordflow">if</font> (diff < 0) {
00472 }
00473 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (diff > 0) {
00474 idxoff += IDXENTRYSIZE;
00475 }
00476 <font class="keywordflow">else</font> <font class="keywordflow">if</font> ((!diff) && (len || strlen(buf) <font class="comment">/*we're not deleting*/</font>)) { <font class="comment">// got absolute entry</font>
00477 <font class="keywordflow">do</font> {
00478 lseek(idxfd->getFd(), idxoff, SEEK_SET);
00479 read(idxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32));
00480 read(idxfd->getFd(), &size, <font class="keyword">sizeof</font>(__u32));
00481 start = swordtoarch32(start);
00482 size = swordtoarch32(size);
00483
00484 tmpbuf = <font class="keyword">new</font> <font class="keywordtype">char</font> [ size + 2 ];
00485 memset(tmpbuf, 0, size + 2);
00486 lseek(datfd->getFd(), start, SEEK_SET);
00487 read(datfd->getFd(), tmpbuf, size);
00488
00489 <font class="keywordflow">for</font> (ch = tmpbuf; *ch; ch++) { <font class="comment">// skip over index string</font>
00490 <font class="keywordflow">if</font> (*ch == 10) {
00491 ch++;
00492 <font class="keywordflow">break</font>;
00493 }
00494 }
00495 memmove(tmpbuf, ch, size - (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>)(ch-tmpbuf));
00496
00497 <font class="comment">// resolve link</font>
00498 <font class="keywordflow">if</font> (!strncmp(tmpbuf, <font class="stringliteral">"@LINK"</font>, 5) && (len ? len : strlen(buf))) {
00499 <font class="keywordflow">for</font> (ch = tmpbuf; *ch; ch++) { <font class="comment">// null before nl</font>
00500 <font class="keywordflow">if</font> (*ch == 10) {
00501 *ch = 0;
00502 <font class="keywordflow">break</font>;
00503 }
00504 }
00505 findKeyIndex(tmpbuf + IDXENTRYSIZE, &idxoff);
00506 <font class="keyword">delete</font> [] tmpbuf;
00507 }
00508 <font class="keywordflow">else</font> <font class="keywordflow">break</font>;
00509 }
00510 <font class="keywordflow">while</font> (true); <font class="comment">// while we're resolving links</font>
00511 }
00512 }
00513
00514 endoff = lseek(idxfd->getFd(), 0, SEEK_END);
00515
00516 shiftSize = endoff - idxoff;
00517
00518 <font class="keywordflow">if</font> (shiftSize > 0) {
00519 idxBytes = <font class="keyword">new</font> <font class="keywordtype">char</font> [ shiftSize ];
00520 lseek(idxfd->getFd(), idxoff, SEEK_SET);
00521 read(idxfd->getFd(), idxBytes, shiftSize);
00522 }
00523
00524 outbuf = <font class="keyword">new</font> <font class="keywordtype">char</font> [ (len ? len : strlen(buf)) + strlen(key) + 5 ];
00525 sprintf(outbuf, <font class="stringliteral">"%s%c%c"</font>, key, 13, 10);
00526 size = strlen(outbuf);
00527 <font class="keywordflow">if</font> (len ? len : strlen(buf)) { <font class="comment">// NOT a link</font>
00528 <font class="keywordflow">if</font> (!cacheBlock) {
00529 flushCache();
00530 cacheBlock = <font class="keyword">new</font> EntriesBlock();
00531 cacheBlockIndex = (lseek(zdxfd->getFd(), 0, SEEK_END) / ZDXENTRYSIZE);
00532 }
00533 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (cacheBlock->getCount() >= blockCount) {
00534 flushCache();
00535 cacheBlock = <font class="keyword">new</font> EntriesBlock();
00536 cacheBlockIndex = (lseek(zdxfd->getFd(), 0, SEEK_END) / ZDXENTRYSIZE);
00537 }
00538 __u32 entry = cacheBlock->addEntry(buf);
00539 cacheDirty = <font class="keyword">true</font>;
00540 outstart = archtosword32(cacheBlockIndex);
00541 outsize = archtosword32(entry);
00542 memcpy (outbuf + size, &outstart, <font class="keyword">sizeof</font>(__u32));
00543 memcpy (outbuf + size + <font class="keyword">sizeof</font>(__u32), &outsize, <font class="keyword">sizeof</font>(__u32));
00544 size += (<font class="keyword">sizeof</font>(__u32) * 2);
00545 }
00546 <font class="keywordflow">else</font> { <font class="comment">// link</font>
00547 memcpy(outbuf + size, buf, len ? len : strlen(buf));
00548 size += (len ? len : strlen(buf));
00549 }
00550
00551 start = lseek(datfd->getFd(), 0, SEEK_END);
00552
00553 outstart = archtosword32(start);
00554 outsize = archtosword32(size);
00555
00556 lseek(idxfd->getFd(), idxoff, SEEK_SET);
00557 <font class="keywordflow">if</font> (len ? len : strlen(buf)) {
00558 lseek(datfd->getFd(), start, SEEK_SET);
00559 write(datfd->getFd(), outbuf, size);
00560
00561 <font class="comment">// add a new line to make data file easier to read in an editor</font>
00562 write(datfd->getFd(), &nl, 2);
00563
00564 write(idxfd->getFd(), &outstart, <font class="keyword">sizeof</font>(__u32));
00565 write(idxfd->getFd(), &outsize, <font class="keyword">sizeof</font>(__u32));
00566 <font class="keywordflow">if</font> (idxBytes) {
00567 write(idxfd->getFd(), idxBytes, shiftSize);
00568 }
00569 }
00570 <font class="keywordflow">else</font> { <font class="comment">// delete entry</font>
00571 <font class="keywordflow">if</font> (idxBytes) {
00572 write(idxfd->getFd(), idxBytes+IDXENTRYSIZE, shiftSize-IDXENTRYSIZE);
00573 lseek(idxfd->getFd(), -1, SEEK_CUR); <font class="comment">// last valid byte</font>
00574 FileMgr::systemFileMgr.trunc(idxfd); <font class="comment">// truncate index</font>
00575 }
00576 }
00577
00578 <font class="keywordflow">if</font> (idxBytes)
00579 <font class="keyword">delete</font> [] idxBytes;
00580 <font class="keyword">delete</font> [] key;
00581 <font class="keyword">delete</font> [] outbuf;
00582 free(dbKey);
00583 }
00584
00585
00586 <font class="comment">/******************************************************************************</font>
00587 <font class="comment"> * zLD::linkentry - links one entry to another</font>
00588 <font class="comment"> *</font>
00589 <font class="comment"> * ENT: testmt - testament to find (0 - Bible/module introduction)</font>
00590 <font class="comment"> * destidxoff - dest offset into .vss</font>
00591 <font class="comment"> * srcidxoff - source offset into .vss</font>
00592 <font class="comment"> */</font>
00593
00594 <font class="keywordtype">void</font> zStr::linkEntry(<font class="keyword">const</font> <font class="keywordtype">char</font> *destkey, <font class="keyword">const</font> <font class="keywordtype">char</font> *srckey) {
00595 <font class="keywordtype">char</font> *text = <font class="keyword">new</font> <font class="keywordtype">char</font> [ strlen(destkey) + 7 ];
00596 sprintf(text, <font class="stringliteral">"@LINK %s"</font>, destkey);
00597 <a class="code" href="class_verse_key.html#a13">setText</a>(srckey, text);
00598 <font class="keyword">delete</font> [] text;
00599 }
00600
00601
00602 <font class="keywordtype">void</font> zStr::flushCache() {
00603 <font class="keywordflow">if</font> (cacheBlock) {
00604 <font class="keywordflow">if</font> (cacheDirty) {
00605 __u32 start = 0;
00606 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> size = 0;
00607 __u32 outstart = 0, outsize = 0;
00608
00609 <font class="keyword">const</font> <font class="keywordtype">char</font> *rawBuf = cacheBlock->getRawData(&size);
00610 compressor->Buf(rawBuf, &size);
00611 compressor->zBuf(&size);
00612
00613 <font class="keywordtype">long</font> zdxSize = lseek(zdxfd->getFd(), 0, SEEK_END);
00614 <font class="keywordtype">long</font> zdtSize = lseek(zdtfd->getFd(), 0, SEEK_END);
00615
00616 <font class="keywordflow">if</font> ((cacheBlockIndex * ZDXENTRYSIZE) > (zdxSize - ZDXENTRYSIZE)) { <font class="comment">// New Block</font>
00617 start = zdtSize;
00618 }
00619 <font class="keywordflow">else</font> {
00620 lseek(zdxfd->getFd(), cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET);
00621 read(zdxfd->getFd(), &start, <font class="keyword">sizeof</font>(__u32));
00622 read(zdxfd->getFd(), &outsize, <font class="keyword">sizeof</font>(__u32));
00623 start = swordtoarch32(start);
00624 outsize = swordtoarch32(outsize);
00625 <font class="keywordflow">if</font> (start + outsize >= zdtSize) { <font class="comment">// last entry, just overwrite</font>
00626 <font class="comment">// start is already set</font>
00627 }
00628 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (size < outsize) { <font class="comment">// middle entry, but smaller, that's fine and let's preserve bigger size</font>
00629 size = outsize;
00630 }
00631 <font class="keywordflow">else</font> { <font class="comment">// middle and bigger-- we have serious problems, for now let's put it at the end = lots of wasted space</font>
00632 start = zdtSize;
00633 }
00634 }
00635
00636
00637
00638 outstart = archtosword32(start);
00639 outsize = archtosword32((__u32)size);
00640
00641 lseek(zdxfd->getFd(), cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET);
00642 lseek(zdtfd->getFd(), start, SEEK_SET);
00643 rawBuf = compressor->zBuf(&size);
00644 write(zdtfd->getFd(), rawBuf, size);
00645
00646 <font class="comment">// add a new line to make data file easier to read in an editor</font>
00647 write(zdtfd->getFd(), &nl, 2);
00648
00649 write(zdxfd->getFd(), &outstart, <font class="keyword">sizeof</font>(__u32));
00650 write(zdxfd->getFd(), &outsize, <font class="keyword">sizeof</font>(__u32));
00651
00652 <font class="keyword">delete</font> cacheBlock;
00653 }
00654 }
00655 cacheBlockIndex = -1;
00656 cacheBlock = 0;
00657 cacheDirty = <font class="keyword">false</font>;
00658 }
00659
00660
00661 <font class="comment">/******************************************************************************</font>
00662 <font class="comment"> * zLD::CreateModule - Creates new module files</font>
00663 <font class="comment"> *</font>
00664 <font class="comment"> * ENT: path - directory to store module files</font>
00665 <font class="comment"> * RET: error status</font>
00666 <font class="comment"> */</font>
00667
00668 <font class="keywordtype">signed</font> <font class="keywordtype">char</font> zStr::createModule(<font class="keyword">const</font> <font class="keywordtype">char</font> *ipath) {
00669 <font class="keywordtype">char</font> *path = 0;
00670 <font class="keywordtype">char</font> *buf = <font class="keyword">new</font> <font class="keywordtype">char</font> [ strlen (ipath) + 20 ];
00671 FileDesc *fd, *fd2;
00672
00673 stdstr(&path, ipath);
00674
00675 <font class="keywordflow">if</font> ((path[strlen(path)-1] == <font class="charliteral">'/'</font>) || (path[strlen(path)-1] == <font class="charliteral">'\\'</font>))
00676 path[strlen(path)-1] = 0;
00677
00678 sprintf(buf, <font class="stringliteral">"%s.dat"</font>, path);
00679 unlink(buf);
00680 fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00681 fd->getFd();
00682 FileMgr::systemFileMgr.close(fd);
00683
00684 sprintf(buf, <font class="stringliteral">"%s.idx"</font>, path);
00685 unlink(buf);
00686 fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00687 fd2->getFd();
00688 FileMgr::systemFileMgr.close(fd2);
00689
00690 sprintf(buf, <font class="stringliteral">"%s.zdt"</font>, path);
00691 unlink(buf);
00692 fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00693 fd2->getFd();
00694 FileMgr::systemFileMgr.close(fd2);
00695
00696 sprintf(buf, <font class="stringliteral">"%s.zdx"</font>, path);
00697 unlink(buf);
00698 fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00699 fd2->getFd();
00700 FileMgr::systemFileMgr.close(fd2);
00701
00702 <font class="keyword">delete</font> [] path;
00703
00704 <font class="keywordflow">return</font> 0;
00705 }
</pre></div><hr><address align="right"><small>Generated on Thu Jun 20 22:13:01 2002 for The Sword Project by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>
|