1
/******************************************************************************
2
* zverse.h - code for class 'zVerse'- a module that reads raw text
3
* files: ot and nt using indexs ??.bks ??.cps ??.vss
4
* and provides lookup and parsing functions based on
5
* class VerseKey for compressed modules
34
/******************************************************************************
38
int zVerse::instance = 0;
40
const char zVerse::uniqueIndexID[] = {'X', 'r', 'v', 'c', 'b'};
42
/******************************************************************************
43
* zVerse Constructor - Initializes data for instance of zVerse
45
* ENT: ipath - path of the directory where data and index files are located.
46
* be sure to include the trailing separator (e.g. '/' or '\')
47
* (e.g. 'modules/texts/rawtext/webster/')
48
* fileMode - open mode for the files (O_RDONLY, etc.)
49
* blockType - verse, chapter, book, etc.
52
zVerse::zVerse(const char *ipath, int fileMode, int blockType, SWCompress *icomp)
64
if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
65
path[strlen(path)-1] = 0;
67
compressor = (icomp) ? icomp : new SWCompress();
69
if (fileMode == -1) { // try read/write if possible
73
sprintf(buf, "%s/ot.%czs", path, uniqueIndexID[blockType]);
74
idxfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
76
sprintf(buf, "%s/nt.%czs", path, uniqueIndexID[blockType]);
77
idxfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
79
sprintf(buf, "%s/ot.%czz", path, uniqueIndexID[blockType]);
80
textfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
82
sprintf(buf, "%s/nt.%czz", path, uniqueIndexID[blockType]);
83
textfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
85
sprintf(buf, "%s/ot.%czv", path, uniqueIndexID[blockType]);
86
compfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
88
sprintf(buf, "%s/nt.%czv", path, uniqueIndexID[blockType]);
89
compfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
95
/******************************************************************************
96
* zVerse Destructor - Cleans up instance of zVerse
116
for (loop1 = 0; loop1 < 2; loop1++) {
117
FileMgr::systemFileMgr.close(idxfp[loop1]);
118
FileMgr::systemFileMgr.close(textfp[loop1]);
119
FileMgr::systemFileMgr.close(compfp[loop1]);
124
/******************************************************************************
125
* zVerse::findoffset - Finds the offset of the key verse from the indexes
129
* ENT: testmt - testament to find (0 - Bible/module introduction)
130
* book - book to find (0 - testament introduction)
131
* chapter - chapter to find (0 - book introduction)
132
* verse - verse to find (0 - chapter introduction)
133
* start - address to store the starting offset
134
* size - address to store the size of the entry
137
void zVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size)
139
// set start to offset in
142
unsigned long ulBuffNum=0; // buffer number
143
unsigned long ulVerseStart=0; // verse offset within buffer
144
unsigned short usVerseSize=0; // verse size
145
unsigned long ulCompOffset=0; // compressed buffer start
146
unsigned long ulCompSize=0; // buffer size compressed
147
unsigned long ulUnCompSize=0; // buffer size uncompressed
148
char *pcCompText=NULL; // compressed text
151
//printf ("Finding offset %ld\n", idxoff);
154
testmt = ((idxfp[0]) ? 1:2);
157
// assert we have and valid file descriptor
158
if (compfp[testmt-1]->getFd() < 1)
161
long newOffset = lseek(compfp[testmt-1]->getFd(), idxoff, SEEK_SET);
162
if (newOffset == idxoff) {
163
if (read(compfp[testmt-1]->getFd(), &ulBuffNum, 4) != 4) {
164
printf ("Error reading ulBuffNum\n");
170
ulBuffNum = swordtoarch32(ulBuffNum);
172
if (read(compfp[testmt-1]->getFd(), &ulVerseStart, 4) < 2)
174
printf ("Error reading ulVerseStart\n");
177
if (read(compfp[testmt-1]->getFd(), &usVerseSize, 2) < 2)
179
printf ("Error reading usVerseSize\n");
183
*start = swordtoarch32(ulVerseStart);
184
*size = swordtoarch16(usVerseSize);
187
if (((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf)) {
188
// have the text buffered
192
//printf ("Got buffer number{%ld} versestart{%ld} versesize{%d}\n", ulBuffNum, ulVerseStart, usVerseSize);
195
if (lseek(idxfp[testmt-1]->getFd(), ulBuffNum*12, SEEK_SET)!=(long) ulBuffNum*12)
197
printf ("Error seeking compressed file index\n");
200
if (read(idxfp[testmt-1]->getFd(), &ulCompOffset, 4)<4)
202
printf ("Error reading ulCompOffset\n");
205
if (read(idxfp[testmt-1]->getFd(), &ulCompSize, 4)<4)
207
printf ("Error reading ulCompSize\n");
210
if (read(idxfp[testmt-1]->getFd(), &ulUnCompSize, 4)<4)
212
printf ("Error reading ulUnCompSize\n");
216
ulCompOffset = swordtoarch32(ulCompOffset);
217
ulCompSize = swordtoarch32(ulCompSize);
218
ulUnCompSize = swordtoarch32(ulUnCompSize);
220
if (lseek(textfp[testmt-1]->getFd(), ulCompOffset, SEEK_SET)!=(long)ulCompOffset)
222
printf ("Error: could not seek to right place in compressed text\n");
226
pcCompText.setSize(ulCompSize+5);
228
if (read(textfp[testmt-1]->getFd(), pcCompText.getRawData(), ulCompSize)<(long)ulCompSize) {
229
printf ("Error reading compressed text\n");
232
pcCompText.setSize(ulCompSize);
233
rawZFilter(pcCompText, 0); // 0 = decipher
235
compressor->zBuf(&ulCompSize, pcCompText.getRawData());
242
unsigned long len = 0;
243
compressor->Buf(0, &len);
244
cacheBuf = (char *)calloc(len + 1, 1);
245
memcpy(cacheBuf, compressor->Buf(), len);
247
cacheTestament = testmt;
248
cacheBufIdx = ulBuffNum;
253
/******************************************************************************
254
* zVerse::zreadtext - gets text at a given offset
256
* ENT: testmt - testament file to search in (0 - Old; 1 - New)
257
* start - starting offset where the text is located in the file
258
* size - size of text entry + 1 (null)
259
* buf - buffer to store text
263
void zVerse::zReadText(char testmt, long start, unsigned short size, SWBuf &inBuf) {
265
inBuf.setFillByte(0);
266
inBuf.setSize(size+1);
269
strncpy(inBuf.getRawData(), &(cacheBuf[start]), size);
271
inBuf.setSize(strlen(inBuf.c_str()));
275
/******************************************************************************
276
* zVerse::settext - Sets text for current offset
278
* ENT: testmt - testament to find (0 - Bible/module introduction)
279
* idxoff - offset into .vss
280
* buf - buffer to store
281
* len - length of buffer (0 - null terminated)
284
void zVerse::doSetText(char testmt, long idxoff, const char *buf, long len) {
286
len = (len < 0) ? strlen(buf) : len;
288
testmt = ((idxfp[0]) ? 1:2);
289
if ((!dirtyCache) || (cacheBufIdx < 0)) {
290
cacheBufIdx = lseek(idxfp[testmt-1]->getFd(), 0, SEEK_END) / 12;
291
cacheTestament = testmt;
294
cacheBuf = (char *)calloc(len + 1, 1);
296
else cacheBuf = (char *)((cacheBuf)?realloc(cacheBuf, strlen(cacheBuf)+(len + 1)):calloc((len + 1), 1));
300
unsigned long start, outstart;
301
unsigned long outBufIdx = cacheBufIdx;
303
unsigned short outsize;
306
size = outsize = len;
308
start = strlen(cacheBuf);
311
start = outBufIdx = 0;
313
outBufIdx = archtosword32(outBufIdx);
314
outstart = archtosword32(start);
315
outsize = archtosword16(size);
317
lseek(compfp[testmt-1]->getFd(), idxoff, SEEK_SET);
318
write(compfp[testmt-1]->getFd(), &outBufIdx, 4);
319
write(compfp[testmt-1]->getFd(), &outstart, 4);
320
write(compfp[testmt-1]->getFd(), &outsize, 2);
321
strcat(cacheBuf, buf);
325
void zVerse::flushCache() {
327
unsigned long idxoff;
328
unsigned long start, outstart;
329
unsigned long size, outsize;
330
unsigned long zsize, outzsize;
332
idxoff = cacheBufIdx * 12;
334
size = outsize = zsize = outzsize = strlen(cacheBuf);
337
// delete compressor;
338
// compressor = new LZSSCompress();
340
compressor->Buf(cacheBuf);
341
compressor->zBuf(&zsize);
345
buf.setSize(zsize + 5);
346
memcpy(buf.getRawData(), compressor->zBuf(&zsize), zsize);
348
rawZFilter(buf, 1); // 1 = encipher
350
start = outstart = lseek(textfp[cacheTestament-1]->getFd(), 0, SEEK_END);
352
outstart = archtosword32(start);
353
outsize = archtosword32(size);
354
outzsize = archtosword32(zsize);
356
write(textfp[cacheTestament-1]->getFd(), buf, zsize);
358
lseek(idxfp[cacheTestament-1]->getFd(), idxoff, SEEK_SET);
359
write(idxfp[cacheTestament-1]->getFd(), &outstart, 4);
360
write(idxfp[cacheTestament-1]->getFd(), &outzsize, 4);
361
write(idxfp[cacheTestament-1]->getFd(), &outsize, 4);
370
/******************************************************************************
371
* RawVerse::linkentry - links one entry to another
373
* ENT: testmt - testament to find (0 - Bible/module introduction)
374
* destidxoff - dest offset into .vss
375
* srcidxoff - source offset into .vss
378
void zVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
387
testmt = ((idxfp[1]) ? 1:2);
390
lseek(compfp[testmt-1]->getFd(), srcidxoff, SEEK_SET);
391
read(compfp[testmt-1]->getFd(), &bufidx, 4);
392
read(compfp[testmt-1]->getFd(), &start, 4);
393
read(compfp[testmt-1]->getFd(), &size, 2);
396
lseek(compfp[testmt-1]->getFd(), destidxoff, SEEK_SET);
397
write(compfp[testmt-1]->getFd(), &bufidx, 4);
398
write(compfp[testmt-1]->getFd(), &start, 4);
399
write(compfp[testmt-1]->getFd(), &size, 2);
403
/******************************************************************************
404
* RawVerse::CreateModule - Creates new module files
406
* ENT: path - directory to store module files
410
char zVerse::createModule(const char *ipath, int blockBound)
413
char *buf = new char [ strlen (ipath) + 20 ];
416
stdstr(&path, ipath);
418
if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
419
path[strlen(path)-1] = 0;
421
sprintf(buf, "%s/ot.%czs", path, uniqueIndexID[blockBound]);
423
fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
425
FileMgr::systemFileMgr.close(fd);
427
sprintf(buf, "%s/nt.%czs", path, uniqueIndexID[blockBound]);
429
fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
431
FileMgr::systemFileMgr.close(fd);
433
sprintf(buf, "%s/ot.%czz", path, uniqueIndexID[blockBound]);
435
fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
437
FileMgr::systemFileMgr.close(fd);
439
sprintf(buf, "%s/nt.%czz", path, uniqueIndexID[blockBound]);
441
fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
443
FileMgr::systemFileMgr.close(fd);
445
sprintf(buf, "%s/ot.%czv", path, uniqueIndexID[blockBound]);
447
fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
450
sprintf(buf, "%s/nt.%czv", path, uniqueIndexID[blockBound]);
452
fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
459
for (vk = TOP; !vk.Error(); vk++) {
460
write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &offset, 4); //compBufIdxOffset
461
write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &offset, 4);
462
write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &size, 2);
465
FileMgr::systemFileMgr.close(fd);
466
FileMgr::systemFileMgr.close(fd2);
472
VerseKey mykey("Rev 22:21");
479
/******************************************************************************
480
* zVerse::preptext - Prepares the text before returning it to external
483
* ENT: buf - buffer where text is stored and where to store the prep'd
487
void zVerse::prepText(SWBuf &buf) {
488
unsigned int to, from;
489
char space = 0, cr = 0, realdata = 0, nlcnt = 0;
490
char *rawBuf = buf.getRawData();
491
for (to = from = 0; rawBuf[from]; from++) {
492
switch (rawBuf[from]) {
496
space = (cr) ? 0 : 1;
519
if (rawBuf[from] != ' ') {
525
rawBuf[to++] = rawBuf[from];
529
while (to > 1) { // remove trailing excess
531
if ((rawBuf[to] == 10) || (rawBuf[to] == ' '))