00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <ctype.h>
00010 #include <stdio.h>
00011 #include <fcntl.h>
00012 #include <errno.h>
00013 #include <stdlib.h>
00014
00015 #ifndef __GNUC__
00016 #include <io.h>
00017 #else
00018 #include <unistd.h>
00019 #endif
00020
00021 #include <string.h>
00022 #include <utilfuns.h>
00023 #include <versekey.h>
00024 #include <zverse.h>
00025 #include <sysdata.h>
00026
00027
00028 #ifndef O_BINARY
00029 #define O_BINARY 0
00030 #endif
00031
00032
00033
00034
00035
00036
00037 int zVerse::instance = 0;
00038
00039 const char zVerse::uniqueIndexID[] = {'X', 'r', 'v', 'c', 'b'};
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 zVerse::zVerse(const char *ipath, int fileMode, int blockType, SWCompress *icomp)
00052 {
00053 char buf[127];
00054
00055 nl = '\n';
00056 path = 0;
00057 cacheBufIdx = -1;
00058 cacheTestament = 0;
00059 cacheBuf = 0;
00060 dirtyCache = false;
00061 stdstr(&path, ipath);
00062
00063 if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
00064 path[strlen(path)-1] = 0;
00065
00066 compressor = (icomp) ? icomp : new SWCompress();
00067
00068 if (fileMode == -1) {
00069 fileMode = O_RDWR;
00070 }
00071
00072 sprintf(buf, "%s/ot.%czs", path, uniqueIndexID[blockType]);
00073 idxfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00074
00075 sprintf(buf, "%s/nt.%czs", path, uniqueIndexID[blockType]);
00076 idxfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00077
00078 sprintf(buf, "%s/ot.%czz", path, uniqueIndexID[blockType]);
00079 textfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00080
00081 sprintf(buf, "%s/nt.%czz", path, uniqueIndexID[blockType]);
00082 textfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00083
00084 sprintf(buf, "%s/ot.%czv", path, uniqueIndexID[blockType]);
00085 compfp[0] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00086
00087 sprintf(buf, "%s/nt.%czv", path, uniqueIndexID[blockType]);
00088 compfp[1] = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true);
00089
00090 instance++;
00091 }
00092
00093
00094
00095
00096
00097
00098 zVerse::~zVerse()
00099 {
00100 int loop1;
00101
00102 if (cacheBuf) {
00103 flushCache();
00104 free(cacheBuf);
00105 }
00106
00107 if (path)
00108 delete [] path;
00109
00110 if (compressor)
00111 delete compressor;
00112
00113 --instance;
00114
00115 for (loop1 = 0; loop1 < 2; loop1++) {
00116 FileMgr::systemFileMgr.close(idxfp[loop1]);
00117 FileMgr::systemFileMgr.close(textfp[loop1]);
00118 FileMgr::systemFileMgr.close(compfp[loop1]);
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 void zVerse::findoffset(char testmt, long idxoff, long *start, unsigned short *size)
00137 {
00138
00139
00140
00141 unsigned long ulBuffNum=0;
00142 unsigned long ulVerseStart=0;
00143 unsigned short usVerseSize=0;
00144 unsigned long ulCompOffset=0;
00145 unsigned long ulCompSize=0;
00146 unsigned long ulUnCompSize=0;
00147 char *pcCompText=NULL;
00148
00149 *start = *size = 0;
00150
00151 idxoff *= 10;
00152 if (!testmt) {
00153 testmt = ((idxfp[0]) ? 1:2);
00154 }
00155
00156
00157 if (compfp[testmt-1]->getFd() < 1)
00158 return;
00159
00160 long newOffset = lseek(compfp[testmt-1]->getFd(), idxoff, SEEK_SET);
00161 if (newOffset == idxoff) {
00162 if (read(compfp[testmt-1]->getFd(), &ulBuffNum, 4) != 4) {
00163 printf ("Error reading ulBuffNum\n");
00164 return;
00165 }
00166 }
00167 else return;
00168
00169 ulBuffNum = swordtoarch32(ulBuffNum);
00170
00171 if (read(compfp[testmt-1]->getFd(), &ulVerseStart, 4) < 2)
00172 {
00173 printf ("Error reading ulVerseStart\n");
00174 return;
00175 }
00176 if (read(compfp[testmt-1]->getFd(), &usVerseSize, 2) < 2)
00177 {
00178 printf ("Error reading usVerseSize\n");
00179 return;
00180 }
00181
00182 *start = swordtoarch32(ulVerseStart);
00183 *size = swordtoarch16(usVerseSize);
00184
00185 if (*size) {
00186 if (((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf)) {
00187
00188 return;
00189 }
00190
00191
00192
00193
00194 if (lseek(idxfp[testmt-1]->getFd(), ulBuffNum*12, SEEK_SET)!=(long) ulBuffNum*12)
00195 {
00196 printf ("Error seeking compressed file index\n");
00197 return;
00198 }
00199 if (read(idxfp[testmt-1]->getFd(), &ulCompOffset, 4)<4)
00200 {
00201 printf ("Error reading ulCompOffset\n");
00202 return;
00203 }
00204 if (read(idxfp[testmt-1]->getFd(), &ulCompSize, 4)<4)
00205 {
00206 printf ("Error reading ulCompSize\n");
00207 return;
00208 }
00209 if (read(idxfp[testmt-1]->getFd(), &ulUnCompSize, 4)<4)
00210 {
00211 printf ("Error reading ulUnCompSize\n");
00212 return;
00213 }
00214
00215 ulCompOffset = swordtoarch32(ulCompOffset);
00216 ulCompSize = swordtoarch32(ulCompSize);
00217 ulUnCompSize = swordtoarch32(ulUnCompSize);
00218
00219 if (lseek(textfp[testmt-1]->getFd(), ulCompOffset, SEEK_SET)!=(long)ulCompOffset)
00220 {
00221 printf ("Error: could not seek to right place in compressed text\n");
00222 return;
00223 }
00224 pcCompText = new char[ulCompSize];
00225
00226 if (read(textfp[testmt-1]->getFd(), pcCompText, ulCompSize)<(long)ulCompSize)
00227 {
00228 printf ("Error reading compressed text\n");
00229 return;
00230 }
00231 compressor->zBuf(&ulCompSize, pcCompText);
00232
00233 if (cacheBuf) {
00234 flushCache();
00235 free(cacheBuf);
00236 }
00237
00238 unsigned long len = 0;
00239 compressor->Buf(0, &len);
00240 cacheBuf = (char *)calloc(len + 1, 1);
00241 memcpy(cacheBuf, compressor->Buf(), len);
00242
00243 cacheTestament = testmt;
00244 cacheBufIdx = ulBuffNum;
00245 }
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 void zVerse::swgettext(char testmt, long start, unsigned short size, char *inbuf)
00260 {
00261 memset(inbuf, 0, size);
00262 if (size > 2) {
00263 strncpy(inbuf, &(cacheBuf[start]), size-2);
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 void zVerse::settext(char testmt, long idxoff, const char *buf, long len)
00278 {
00279 if (!testmt)
00280 testmt = ((idxfp[0]) ? 1:2);
00281 if ((!dirtyCache) || (cacheBufIdx < 0)) {
00282 cacheBufIdx = lseek(idxfp[testmt-1]->getFd(), 0, SEEK_END) / 12;
00283 cacheTestament = testmt;
00284 if (cacheBuf)
00285 free(cacheBuf);
00286 cacheBuf = (char *)calloc(len ? len : strlen(buf)+1, 1);
00287 }
00288 else cacheBuf = (char *)((cacheBuf)?realloc(cacheBuf, strlen(cacheBuf)+(len ? len : strlen(buf)+1)):calloc((len ? len : strlen(buf)+1), 1));
00289
00290 dirtyCache = true;
00291
00292 unsigned long start, outstart;
00293 unsigned long outBufIdx = cacheBufIdx;
00294 unsigned short size;
00295 unsigned short outsize;
00296
00297 idxoff *= 10;
00298 size = outsize = len ? len : strlen(buf);
00299
00300 start = strlen(cacheBuf);
00301
00302 if (!size)
00303 start = outBufIdx = 0;
00304
00305 outBufIdx = archtosword32(outBufIdx);
00306 outstart = archtosword32(start);
00307 outsize = archtosword16(size);
00308
00309 lseek(compfp[testmt-1]->getFd(), idxoff, SEEK_SET);
00310 write(compfp[testmt-1]->getFd(), &outBufIdx, 4);
00311 write(compfp[testmt-1]->getFd(), &outstart, 4);
00312 write(compfp[testmt-1]->getFd(), &outsize, 2);
00313 strcat(cacheBuf, buf);
00314 }
00315
00316
00317 void zVerse::flushCache() {
00318 if (dirtyCache) {
00319 unsigned long idxoff;
00320 unsigned long start, outstart;
00321 unsigned long size, outsize;
00322 unsigned long zsize, outzsize;
00323
00324 idxoff = cacheBufIdx * 12;
00325 size = outsize = zsize = outzsize = strlen(cacheBuf);
00326 if (size) {
00327
00328
00329
00330
00331 compressor->Buf(cacheBuf);
00332 compressor->zBuf(&zsize);
00333 outzsize = zsize;
00334
00335 start = outstart = lseek(textfp[cacheTestament-1]->getFd(), 0, SEEK_END);
00336
00337 outstart = archtosword32(start);
00338 outsize = archtosword32(size);
00339 outzsize = archtosword32(zsize);
00340
00341 write(textfp[cacheTestament-1]->getFd(), compressor->zBuf(&zsize), zsize);
00342
00343 lseek(idxfp[cacheTestament-1]->getFd(), idxoff, SEEK_SET);
00344 write(idxfp[cacheTestament-1]->getFd(), &outstart, 4);
00345 write(idxfp[cacheTestament-1]->getFd(), &outzsize, 4);
00346 write(idxfp[cacheTestament-1]->getFd(), &outsize, 4);
00347 }
00348 dirtyCache = false;
00349 }
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 void zVerse::linkentry(char testmt, long destidxoff, long srcidxoff) {
00361 long bufidx;
00362 long start;
00363 unsigned short size;
00364
00365 destidxoff *= 10;
00366 srcidxoff *= 10;
00367
00368 if (!testmt)
00369 testmt = ((idxfp[1]) ? 1:2);
00370
00371
00372 lseek(compfp[testmt-1]->getFd(), srcidxoff, SEEK_SET);
00373 read(compfp[testmt-1]->getFd(), &bufidx, 4);
00374 read(compfp[testmt-1]->getFd(), &start, 4);
00375 read(compfp[testmt-1]->getFd(), &size, 2);
00376
00377
00378 lseek(compfp[testmt-1]->getFd(), destidxoff, SEEK_SET);
00379 write(compfp[testmt-1]->getFd(), &bufidx, 4);
00380 write(compfp[testmt-1]->getFd(), &start, 4);
00381 write(compfp[testmt-1]->getFd(), &size, 2);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 char zVerse::createModule(const char *ipath, int blockBound)
00393 {
00394 char *path = 0;
00395 char *buf = new char [ strlen (ipath) + 20 ];
00396 FileDesc *fd, *fd2;
00397
00398 stdstr(&path, ipath);
00399
00400 if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
00401 path[strlen(path)-1] = 0;
00402
00403 sprintf(buf, "%s/ot.%czs", path, uniqueIndexID[blockBound]);
00404 unlink(buf);
00405 fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00406 fd->getFd();
00407 FileMgr::systemFileMgr.close(fd);
00408
00409 sprintf(buf, "%s/nt.%czs", path, uniqueIndexID[blockBound]);
00410 unlink(buf);
00411 fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00412 fd->getFd();
00413 FileMgr::systemFileMgr.close(fd);
00414
00415 sprintf(buf, "%s/ot.%czz", path, uniqueIndexID[blockBound]);
00416 unlink(buf);
00417 fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00418 fd->getFd();
00419 FileMgr::systemFileMgr.close(fd);
00420
00421 sprintf(buf, "%s/nt.%czz", path, uniqueIndexID[blockBound]);
00422 unlink(buf);
00423 fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00424 fd2->getFd();
00425 FileMgr::systemFileMgr.close(fd);
00426
00427 sprintf(buf, "%s/ot.%czv", path, uniqueIndexID[blockBound]);
00428 unlink(buf);
00429 fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00430 fd->getFd();
00431
00432 sprintf(buf, "%s/nt.%czv", path, uniqueIndexID[blockBound]);
00433 unlink(buf);
00434 fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
00435 fd2->getFd();
00436
00437 VerseKey vk;
00438 vk.Headings(1);
00439 long offset = 0;
00440 short size = 0;
00441 for (vk = TOP; !vk.Error(); vk++) {
00442 write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &offset, 4);
00443 write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &offset, 4);
00444 write((vk.Testament() == 1) ? fd->getFd() : fd2->getFd(), &size, 2);
00445 }
00446
00447 FileMgr::systemFileMgr.close(fd);
00448 FileMgr::systemFileMgr.close(fd2);
00449
00450 delete [] path;
00451
00452
00453
00454
00455
00456 return 0;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 void zVerse::preptext(char *buf)
00469 {
00470 char *to, *from, space = 0, cr = 0, realdata = 0, nlcnt = 0;
00471
00472 for (to = from = buf; *from; from++) {
00473 switch (*from) {
00474 case 10:
00475 if (!realdata)
00476 continue;
00477 space = (cr) ? 0 : 1;
00478 cr = 0;
00479 nlcnt++;
00480 if (nlcnt > 1) {
00481
00482 *to++ = nl;
00483
00484 }
00485 continue;
00486 case 13:
00487 if (!realdata)
00488 continue;
00489 *to++ = nl;
00490 space = 0;
00491 cr = 1;
00492 continue;
00493 }
00494 realdata = 1;
00495 nlcnt = 0;
00496 if (space) {
00497 space = 0;
00498 if (*from != ' ') {
00499 *to++ = ' ';
00500 from--;
00501 continue;
00502 }
00503 }
00504 *to++ = *from;
00505 }
00506 *to = 0;
00507
00508 if (to > buf) {
00509 for (to--; to > buf; to--) {
00510 if ((*to == 10) || (*to == ' '))
00511 *to = 0;
00512 else break;
00513 }
00514 }
00515 }