diff options
Diffstat (limited to 'src/modules/common/zstr.cpp')
-rw-r--r-- | src/modules/common/zstr.cpp | 718 |
1 files changed, 0 insertions, 718 deletions
diff --git a/src/modules/common/zstr.cpp b/src/modules/common/zstr.cpp deleted file mode 100644 index 92a4960..0000000 --- a/src/modules/common/zstr.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/****************************************************************************** - * zstr.cpp - code for class 'zStr'- a module that reads compressed text - * files and provides lookup and parsing functions based on - * class StrKey - */ - -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> - -#ifndef __GNUC__ -#include <io.h> -#else -#include <unistd.h> -#endif - -#include <stdlib.h> -#include <utilfuns.h> -#include <zstr.h> -#include <swcomprs.h> - -#include <sysdata.h> -#include <entriesblk.h> - -SWORD_NAMESPACE_START - -/****************************************************************************** - * zStr Statics - */ - -int zStr::instance = 0; -const int zStr::IDXENTRYSIZE = 8; -const int zStr::ZDXENTRYSIZE = 8; - - -/****************************************************************************** - * zStr Constructor - Initializes data for instance of zStr - * - * ENT: ipath - path of the directory where data and index files are located. - */ - -zStr::zStr(const char *ipath, int fileMode, long blockCount, SWCompress *icomp) { - char buf[127]; - - nl = '\n'; - lastoff = -1; - path = 0; - stdstr(&path, ipath); - - compressor = (icomp) ? icomp : new SWCompress(); - this->blockCount = blockCount; -#ifndef O_BINARY // O_BINARY is needed in Borland C++ 4.53 -#define O_BINARY 0 // If it hasn't been defined than we probably -#endif // don't need it. - - if (fileMode == -1) { // try read/write if possible - fileMode = O_RDWR; - } - - sprintf(buf, "%s.idx", path); - idxfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true); - - sprintf(buf, "%s.dat", path); - datfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true); - - sprintf(buf, "%s.zdx", path); - zdxfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true); - - sprintf(buf, "%s.zdt", path); - zdtfd = FileMgr::systemFileMgr.open(buf, fileMode|O_BINARY, true); - - if (datfd <= 0) { - sprintf(buf, "Error: %d", errno); - perror(buf); - } - - cacheBlock = 0; - cacheBlockIndex = -1; - cacheDirty = false; - - instance++; -} - - -/****************************************************************************** - * zStr Destructor - Cleans up instance of zStr - */ - -zStr::~zStr() { - - flushCache(); - - if (path) - delete [] path; - - --instance; - - FileMgr::systemFileMgr.close(idxfd); - FileMgr::systemFileMgr.close(datfd); - FileMgr::systemFileMgr.close(zdxfd); - FileMgr::systemFileMgr.close(zdtfd); - - - if (compressor) - delete compressor; - -} - - -/****************************************************************************** - * zStr::getidxbufdat - Gets the index string at the given dat offset - * NOTE: buf is calloc'd, or if not null, realloc'd and must - * be free'd by calling function - * - * ENT: ioffset - offset in dat file to lookup - * buf - address of pointer to allocate for storage of string - */ - -void zStr::getKeyFromDatOffset(long ioffset, char **buf) { - int size; - char ch; - if (datfd > 0) { - lseek(datfd->getFd(), ioffset, SEEK_SET); - for (size = 0; read(datfd->getFd(), &ch, 1) == 1; size++) { - if ((ch == '\\') || (ch == 10) || (ch == 13)) - break; - } - *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); - if (size) { - lseek(datfd->getFd(), ioffset, SEEK_SET); - read(datfd->getFd(), *buf, size); - } - (*buf)[size] = 0; - toupperstr_utf8(*buf, size*2); - } - else { - *buf = (*buf) ? (char *)realloc(*buf, 1) : (char *)malloc(1); - **buf = 0; - } -} - - -/****************************************************************************** - * zStr::getidxbuf - Gets the index string at the given idx offset - * NOTE: buf is calloc'd, or if not null, realloc'd - * and must be freed by calling function - * - * ENT: ioffset - offset in idx file to lookup - * buf - address of pointer to allocate for storage of string - */ - -void zStr::getKeyFromIdxOffset(long ioffset, char **buf) { - __u32 offset; - - if (idxfd > 0) { - lseek(idxfd->getFd(), ioffset, SEEK_SET); - read(idxfd->getFd(), &offset, sizeof(__u32)); - offset = swordtoarch32(offset); - getKeyFromDatOffset(offset, buf); - } -} - - -/****************************************************************************** - * zStr::findoffset - Finds the offset of the key string from the indexes - * - * ENT: key - key string to lookup - * offset - address to store the starting offset - * size - address to store the size of the entry - * away - number of entries before of after to jump - * (default = 0) - * - * RET: error status - */ - -signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) { - char *trybuf = 0, *key = 0, quitflag = 0; - signed char retval = 0; - __s32 headoff, tailoff, tryoff = 0, maxoff = 0; - __u32 start, size; - - if (idxfd->getFd() >= 0) { - tailoff = maxoff = lseek(idxfd->getFd(), 0, SEEK_END) - IDXENTRYSIZE; - if (*ikey) { - headoff = 0; - stdstr(&key, ikey, 3); - toupperstr_utf8(key, strlen(key)*3); - - while (headoff < tailoff) { - tryoff = (lastoff == -1) ? headoff + (((((tailoff / IDXENTRYSIZE) - (headoff / IDXENTRYSIZE))) / 2) * IDXENTRYSIZE) : lastoff; - lastoff = -1; - - getKeyFromIdxOffset(tryoff, &trybuf); - - if (!*trybuf && tryoff) { // In case of extra entry at end of idx (not first entry) - tryoff += (tryoff > (maxoff / 2))?-IDXENTRYSIZE:IDXENTRYSIZE; - retval = -1; - break; - } - - int diff = strcmp(key, trybuf); - if (!diff) - break; - - if (diff < 0) - tailoff = (tryoff == headoff) ? headoff : tryoff; - else headoff = tryoff; - if (tailoff == headoff + IDXENTRYSIZE) { - if (quitflag++) - headoff = tailoff; - } - } - if (headoff >= tailoff) - tryoff = headoff; - if (trybuf) - free(trybuf); - delete [] key; - } - else { tryoff = 0; } - - lseek(idxfd->getFd(), tryoff, SEEK_SET); - - start = size = 0; - retval = (read(idxfd->getFd(), &start, sizeof(__u32))==sizeof(__u32)) ? retval : -1; - retval = (read(idxfd->getFd(), &size, sizeof(__u32))==sizeof(__u32)) ? retval : -1; - start = swordtoarch32(start); - size = swordtoarch32(size); - - if (idxoff) - *idxoff = tryoff; - - while (away) { - __u32 laststart = start; - __u32 lastsize = size; - __s32 lasttry = tryoff; - tryoff += (away > 0) ? IDXENTRYSIZE : -IDXENTRYSIZE; - - bool bad = false; - if (((long)(tryoff + (away*IDXENTRYSIZE)) < -IDXENTRYSIZE) || (tryoff + (away*IDXENTRYSIZE) > (maxoff+IDXENTRYSIZE))) - bad = true; - else if (lseek(idxfd->getFd(), tryoff, SEEK_SET) < 0) - bad = true; - if (bad) { - retval = -1; - start = laststart; - size = lastsize; - tryoff = lasttry; - if (idxoff) - *idxoff = tryoff; - break; - } - read(idxfd->getFd(), &start, sizeof(__u32)); - read(idxfd->getFd(), &size, sizeof(__u32)); - start = swordtoarch32(start); - size = swordtoarch32(size); - - if (idxoff) - *idxoff = tryoff; - - - if (((laststart != start) || (lastsize != size)) && (start >= 0) && (size)) - away += (away < 0) ? 1 : -1; - } - - lastoff = tryoff; - } - else { - if (idxoff) - *idxoff = 0; - retval = -1; - } - return retval; -} - - -/****************************************************************************** - * zStr::preptext - Prepares the text before returning it to external - * objects - * - * ENT: buf - buffer where text is stored and where to store the prep'd - * text. - */ - -void zStr::prepText(SWBuf &buf) { - unsigned int to, from; - char space = 0, cr = 0, realdata = 0, nlcnt = 0; - char *rawBuf = buf.getRawData(); - for (to = from = 0; rawBuf[from]; from++) { - switch (rawBuf[from]) { - case 10: - if (!realdata) - continue; - space = (cr) ? 0 : 1; - cr = 0; - nlcnt++; - if (nlcnt > 1) { -// *to++ = nl; - rawBuf[to++] = 10; -// *to++ = nl[1]; -// nlcnt = 0; - } - continue; - case 13: - if (!realdata) - continue; -// *to++ = nl[0]; - rawBuf[to++] = 10; - space = 0; - cr = 1; - continue; - } - realdata = 1; - nlcnt = 0; - if (space) { - space = 0; - if (rawBuf[from] != ' ') { - rawBuf[to++] = ' '; - from--; - continue; - } - } - rawBuf[to++] = rawBuf[from]; - } - buf.setSize(to); - - while (to > 1) { // remove trailing excess - to--; - if ((rawBuf[to] == 10) || (rawBuf[to] == ' ')) - buf.setSize(to); - else break; - } -} - - -/****************************************************************************** - * zStr::getText - gets text at a given offset - * - * ENT: - * offset - idxoffset where the key is located. - * buf - buffer to store text - * idxbuf - buffer to store index key - * NOTE: buffer will be alloc'd / realloc'd and - * should be free'd by the client - * - */ - -void zStr::getText(long offset, char **idxbuf, char **buf) { - char *ch; - char *idxbuflocal = 0; - getKeyFromIdxOffset(offset, &idxbuflocal); - __u32 start; - __u32 size; - - do { - lseek(idxfd->getFd(), offset, SEEK_SET); - read(idxfd->getFd(), &start, sizeof(__u32)); - read(idxfd->getFd(), &size, sizeof(__u32)); - start = swordtoarch32(start); - size = swordtoarch32(size); - - *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); - *idxbuf = (*idxbuf) ? (char *)realloc(*idxbuf, size*2 + 1) : (char *)malloc(size*2 + 1); - memset(*buf, 0, size + 1); - memset(*idxbuf, 0, size + 1); - lseek(datfd->getFd(), start, SEEK_SET); - read(datfd->getFd(), *buf, (int)(size)); - - for (ch = *buf; *ch; ch++) { // skip over index string - if (*ch == 10) { - ch++; - break; - } - } - memmove(*buf, ch, size - (unsigned long)(ch-*buf)); - - // resolve link - if (!strncmp(*buf, "@LINK", 5)) { - for (ch = *buf; *ch; ch++) { // null before nl - if (*ch == 10) { - *ch = 0; - break; - } - } - findKeyIndex(*buf + 6, &offset); - } - else break; - } - while (true); // while we're resolving links - - if (idxbuflocal) { - __u32 localsize = strlen(idxbuflocal); - localsize = (localsize < (size - 1)) ? localsize : (size - 1); - strncpy(*idxbuf, idxbuflocal, localsize); - (*idxbuf)[localsize] = 0; - free(idxbuflocal); - } - __u32 block = 0; - __u32 entry = 0; - memmove(&block, *buf, sizeof(__u32)); - memmove(&entry, *buf + sizeof(__u32), sizeof(__u32)); - block = swordtoarch32(block); - entry = swordtoarch32(entry); - getCompressedText(block, entry, buf); -} - - -/****************************************************************************** - * zStr::getCompressedText - Get text entry from a compressed index / zdata - * file. - */ - -void zStr::getCompressedText(long block, long entry, char **buf) { - - __u32 size = 0; - - if (cacheBlockIndex != block) { - __u32 start = 0; - - lseek(zdxfd->getFd(), block * ZDXENTRYSIZE, SEEK_SET); - read(zdxfd->getFd(), &start, sizeof(__u32)); - read(zdxfd->getFd(), &size, sizeof(__u32)); - start = swordtoarch32(start); - size = swordtoarch32(size); - - SWBuf buf; - buf.setSize(size + 5); - lseek(zdtfd->getFd(), start, SEEK_SET); - read(zdtfd->getFd(), buf.getRawData(), size); - - flushCache(); - - unsigned long len = size; - buf.setSize(size); - rawZFilter(buf, 0); // 0 = decipher - - compressor->zBuf(&len, buf.getRawData()); - char *rawBuf = compressor->Buf(0, &len); - cacheBlock = new EntriesBlock(rawBuf, len); - cacheBlockIndex = block; - } - size = cacheBlock->getEntrySize(entry); - *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1); - strcpy(*buf, cacheBlock->getEntry(entry)); -} - - -/****************************************************************************** - * zLD::settext - Sets text for current offset - * - * ENT: key - key for this entry - * buf - buffer to store - * len - length of buffer (0 - null terminated) - */ - -void zStr::setText(const char *ikey, const char *buf, long len) { - - __u32 start, outstart; - __u32 size, outsize; - __s32 endoff; - long idxoff = 0; - __s32 shiftSize; - static const char nl[] = {13, 10}; - char *tmpbuf = 0; - char *key = 0; - char *dbKey = 0; - char *idxBytes = 0; - char *outbuf = 0; - char *ch = 0; - - len = (len < 0) ? strlen(buf) : len; - stdstr(&key, ikey, 3); - toupperstr_utf8(key, strlen(key)*3); - - char notFound = findKeyIndex(ikey, &idxoff, 0); - if (!notFound) { - getKeyFromIdxOffset(idxoff, &dbKey); - int diff = strcmp(key, dbKey); - if (diff < 0) { - } - else if (diff > 0) { - idxoff += IDXENTRYSIZE; - } - else if ((!diff) && (len > 0 /*we're not deleting*/)) { // got absolute entry - do { - lseek(idxfd->getFd(), idxoff, SEEK_SET); - read(idxfd->getFd(), &start, sizeof(__u32)); - read(idxfd->getFd(), &size, sizeof(__u32)); - start = swordtoarch32(start); - size = swordtoarch32(size); - - tmpbuf = new char [ size + 2 ]; - memset(tmpbuf, 0, size + 2); - lseek(datfd->getFd(), start, SEEK_SET); - read(datfd->getFd(), tmpbuf, size); - - for (ch = tmpbuf; *ch; ch++) { // skip over index string - if (*ch == 10) { - ch++; - break; - } - } - memmove(tmpbuf, ch, size - (unsigned long)(ch-tmpbuf)); - - // resolve link - if (!strncmp(tmpbuf, "@LINK", 5) && (len)) { - for (ch = tmpbuf; *ch; ch++) { // null before nl - if (*ch == 10) { - *ch = 0; - break; - } - } - findKeyIndex(tmpbuf + IDXENTRYSIZE, &idxoff); - delete [] tmpbuf; - } - else break; - } - while (true); // while we're resolving links - } - } - - endoff = lseek(idxfd->getFd(), 0, SEEK_END); - - shiftSize = endoff - idxoff; - - if (shiftSize > 0) { - idxBytes = new char [ shiftSize ]; - lseek(idxfd->getFd(), idxoff, SEEK_SET); - read(idxfd->getFd(), idxBytes, shiftSize); - } - - outbuf = new char [ len + strlen(key) + 5 ]; - sprintf(outbuf, "%s%c%c", key, 13, 10); - size = strlen(outbuf); - if (len > 0) { // NOT a link - if (!cacheBlock) { - flushCache(); - cacheBlock = new EntriesBlock(); - cacheBlockIndex = (lseek(zdxfd->getFd(), 0, SEEK_END) / ZDXENTRYSIZE); - } - else if (cacheBlock->getCount() >= blockCount) { - flushCache(); - cacheBlock = new EntriesBlock(); - cacheBlockIndex = (lseek(zdxfd->getFd(), 0, SEEK_END) / ZDXENTRYSIZE); - } - __u32 entry = cacheBlock->addEntry(buf); - cacheDirty = true; - outstart = archtosword32(cacheBlockIndex); - outsize = archtosword32(entry); - memcpy (outbuf + size, &outstart, sizeof(__u32)); - memcpy (outbuf + size + sizeof(__u32), &outsize, sizeof(__u32)); - size += (sizeof(__u32) * 2); - } - else { // link - memcpy(outbuf + size, buf, len); - size += len; - } - - start = lseek(datfd->getFd(), 0, SEEK_END); - - outstart = archtosword32(start); - outsize = archtosword32(size); - - lseek(idxfd->getFd(), idxoff, SEEK_SET); - if (len > 0) { - lseek(datfd->getFd(), start, SEEK_SET); - write(datfd->getFd(), outbuf, size); - - // add a new line to make data file easier to read in an editor - write(datfd->getFd(), &nl, 2); - - write(idxfd->getFd(), &outstart, sizeof(__u32)); - write(idxfd->getFd(), &outsize, sizeof(__u32)); - if (idxBytes) { - write(idxfd->getFd(), idxBytes, shiftSize); - } - } - else { // delete entry - if (idxBytes) { - write(idxfd->getFd(), idxBytes+IDXENTRYSIZE, shiftSize-IDXENTRYSIZE); - lseek(idxfd->getFd(), -1, SEEK_CUR); // last valid byte - FileMgr::systemFileMgr.trunc(idxfd); // truncate index - } - } - - if (idxBytes) - delete [] idxBytes; - delete [] key; - delete [] outbuf; - free(dbKey); -} - - -/****************************************************************************** - * zLD::linkentry - links one entry to another - * - * ENT: testmt - testament to find (0 - Bible/module introduction) - * destidxoff - dest offset into .vss - * srcidxoff - source offset into .vss - */ - -void zStr::linkEntry(const char *destkey, const char *srckey) { - char *text = new char [ strlen(destkey) + 7 ]; - sprintf(text, "@LINK %s", destkey); - setText(srckey, text); - delete [] text; -} - - -void zStr::flushCache() { - if (cacheBlock) { - if (cacheDirty) { - __u32 start = 0; - unsigned long size = 0; - __u32 outstart = 0, outsize = 0; - - const char *rawBuf = cacheBlock->getRawData(&size); - compressor->Buf(rawBuf, &size); - compressor->zBuf(&size); - - SWBuf buf; - buf.setSize(size + 5); - memcpy(buf.getRawData(), compressor->zBuf(&size), size); // 1 = encipher - buf.setSize(size); - rawZFilter(buf, 1); // 1 = encipher - - long zdxSize = lseek(zdxfd->getFd(), 0, SEEK_END); - long zdtSize = lseek(zdtfd->getFd(), 0, SEEK_END); - - if ((cacheBlockIndex * ZDXENTRYSIZE) > (zdxSize - ZDXENTRYSIZE)) { // New Block - start = zdtSize; - } - else { - lseek(zdxfd->getFd(), cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET); - read(zdxfd->getFd(), &start, sizeof(__u32)); - read(zdxfd->getFd(), &outsize, sizeof(__u32)); - start = swordtoarch32(start); - outsize = swordtoarch32(outsize); - if (start + outsize >= zdtSize) { // last entry, just overwrite - // start is already set - } - else if (size < outsize) { // middle entry, but smaller, that's fine and let's preserve bigger size - size = outsize; - } - else { // middle and bigger-- we have serious problems, for now let's put it at the end = lots of wasted space - start = zdtSize; - } - } - - - - outstart = archtosword32(start); - outsize = archtosword32((__u32)size); - - lseek(zdxfd->getFd(), cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET); - lseek(zdtfd->getFd(), start, SEEK_SET); - write(zdtfd->getFd(), buf, size); - - // add a new line to make data file easier to read in an editor - write(zdtfd->getFd(), &nl, 2); - - write(zdxfd->getFd(), &outstart, sizeof(__u32)); - write(zdxfd->getFd(), &outsize, sizeof(__u32)); - } - delete cacheBlock; - cacheBlock = 0; - } - cacheBlockIndex = -1; - cacheDirty = false; -} - - -/****************************************************************************** - * zLD::CreateModule - Creates new module files - * - * ENT: path - directory to store module files - * RET: error status - */ - -signed char zStr::createModule(const char *ipath) { - char *path = 0; - char *buf = new char [ strlen (ipath) + 20 ]; - FileDesc *fd, *fd2; - - stdstr(&path, ipath); - - if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\')) - path[strlen(path)-1] = 0; - - sprintf(buf, "%s.dat", path); - unlink(buf); - fd = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE); - fd->getFd(); - FileMgr::systemFileMgr.close(fd); - - sprintf(buf, "%s.idx", path); - unlink(buf); - fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE); - fd2->getFd(); - FileMgr::systemFileMgr.close(fd2); - - sprintf(buf, "%s.zdt", path); - unlink(buf); - fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE); - fd2->getFd(); - FileMgr::systemFileMgr.close(fd2); - - sprintf(buf, "%s.zdx", path); - unlink(buf); - fd2 = FileMgr::systemFileMgr.open(buf, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE); - fd2->getFd(); - FileMgr::systemFileMgr.close(fd2); - - delete [] path; - - return 0; -} - -SWORD_NAMESPACE_END |