void RawVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size) const { idxoff *= 6; if (!testmt) testmt = ((idxfp[1]) ? 1:2); if (idxfp[testmt-1]->getFd() >= 0) { idxfp[testmt-1]->seek(idxoff, SEEK_SET); int32_t tmpStart; uint16_t tmpSize; idxfp[testmt-1]->read(&tmpStart, 4); long len = idxfp[testmt-1]->read(&tmpSize, 2); // read size *start = swordtoarch32(tmpStart); *size = swordtoarch16(tmpSize); if (len < 2) { *size = (unsigned short)((*start) ? (textfp[testmt-1]->seek(0, SEEK_END) - (long)*start) : 0); // if for some reason we get an error reading size, make size to end of file } } else { *start = 0; *size = 0; } }
void zVerse::zReadText(char testmt, long start, unsigned short size, unsigned long ulBuffNum, SWBuf &inBuf) const { __u32 ulCompOffset = 0; // compressed buffer start __u32 ulCompSize = 0; // buffer size compressed __u32 ulUnCompSize = 0; // buffer size uncompressed if (!testmt) { testmt = ((idxfp[0]) ? 1:2); } // assert we have and valid file descriptor if (compfp[testmt-1]->getFd() < 1) return; if (size && !(((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf))) { //fprintf(stderr, "Got buffer number{%ld} versestart{%ld} versesize{%d}\n", ulBuffNum, ulVerseStart, usVerseSize); if (idxfp[testmt-1]->seek(ulBuffNum*12, SEEK_SET)!=(long) ulBuffNum*12) { fprintf(stderr, "Error seeking compressed file index\n"); return; } if (idxfp[testmt-1]->read(&ulCompOffset, 4)<4) { fprintf(stderr, "Error reading ulCompOffset\n"); return; } if (idxfp[testmt-1]->read(&ulCompSize, 4)<4) { fprintf(stderr, "Error reading ulCompSize\n"); return; } if (idxfp[testmt-1]->read(&ulUnCompSize, 4)<4) { fprintf(stderr, "Error reading ulUnCompSize\n"); return; } ulCompOffset = swordtoarch32(ulCompOffset); ulCompSize = swordtoarch32(ulCompSize); ulUnCompSize = swordtoarch32(ulUnCompSize); if (textfp[testmt-1]->seek(ulCompOffset, SEEK_SET)!=(long)ulCompOffset) { fprintf(stderr, "Error: could not seek to right place in compressed text\n"); return; } SWBuf pcCompText; pcCompText.setSize(ulCompSize+5); if (textfp[testmt-1]->read(pcCompText.getRawData(), ulCompSize)<(long)ulCompSize) { fprintf(stderr, "Error reading compressed text\n"); return; } pcCompText.setSize(ulCompSize); rawZFilter(pcCompText, 0); // 0 = decipher unsigned long bufSize = ulCompSize; compressor->zBuf(&bufSize, pcCompText.getRawData()); if (cacheBuf) { flushCache(); free(cacheBuf); } unsigned long len = 0; compressor->Buf(0, &len); cacheBuf = (char *)calloc(len + 1, 1); memcpy(cacheBuf, compressor->Buf(), len); cacheBufSize = strlen(cacheBuf); // TODO: can we just use len? cacheTestament = testmt; cacheBufIdx = ulBuffNum; } inBuf = ""; if ((size > 0) && cacheBuf && ((unsigned)start < cacheBufSize)) { inBuf.setFillByte(0); inBuf.setSize(size+1); strncpy(inBuf.getRawData(), &(cacheBuf[start]), size); inBuf.setSize(strlen(inBuf.c_str())); } }
signed char RawStr::findOffset(const char *ikey, __u32 *start, __u16 *size, long away, __u32 *idxoff) const { char *trybuf, *maxbuf, *key = 0, quitflag = 0; signed char retval = -1; long headoff, tailoff, tryoff = 0, maxoff = 0; int diff = 0; bool awayFromSubstrCheck = false; if (idxfd->getFd() >=0) { tailoff = maxoff = idxfd->seek(0, SEEK_END) - 6; retval = (tailoff >= 0) ? 0 : -2; // if NOT new file if (*ikey && retval != -2) { headoff = 0; stdstr(&key, ikey, 3); if (!caseSensitive) toupperstr_utf8(key, strlen(key)*3); int keylen = strlen(key); bool substr = false; trybuf = maxbuf = 0; getIDXBuf(maxoff, &maxbuf); while (headoff < tailoff) { tryoff = (lastoff == -1) ? headoff + ((((tailoff / 6) - (headoff / 6))) / 2) * 6 : lastoff; lastoff = -1; getIDXBuf(tryoff, &trybuf); if (!*trybuf && tryoff) { // In case of extra entry at end of idx (not first entry) tryoff += (tryoff > (maxoff / 2))?-6:6; retval = -1; break; } diff = strcmp(key, trybuf); if (!diff) break; if (!strncmp(trybuf, key, keylen)) substr = true; if (diff < 0) tailoff = (tryoff == headoff) ? headoff : tryoff; else headoff = tryoff; if (tailoff == headoff + 6) { if (quitflag++) headoff = tailoff; } } // didn't find exact match if (headoff >= tailoff) { tryoff = headoff; if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) { awayFromSubstrCheck = true; away--; // if our entry doesn't startwith our key, prefer the previous entry over the next } } if (trybuf) free(trybuf); delete [] key; if (maxbuf) free(maxbuf); } else tryoff = 0; idxfd->seek(tryoff, SEEK_SET); __u32 tmpStart; __u16 tmpSize; *start = *size = tmpStart = tmpSize = 0; idxfd->read(&tmpStart, 4); idxfd->read(&tmpSize, 2); if (idxoff) *idxoff = tryoff; *start = swordtoarch32(tmpStart); *size = swordtoarch16(tmpSize); while (away) { unsigned long laststart = *start; unsigned short lastsize = *size; long lasttry = tryoff; tryoff += (away > 0) ? 6 : -6; bool bad = false; if (((tryoff + (away*6)) < -6) || (tryoff + (away*6) > (maxoff+6))) bad = true; else if (idxfd->seek(tryoff, SEEK_SET) < 0) bad = true; if (bad) { if(!awayFromSubstrCheck) retval = -1; *start = laststart; *size = lastsize; tryoff = lasttry; if (idxoff) *idxoff = tryoff; break; } idxfd->read(&tmpStart, 4); idxfd->read(&tmpSize, 2); if (idxoff) *idxoff = tryoff; *start = swordtoarch32(tmpStart); *size = swordtoarch16(tmpSize); if (((laststart != *start) || (lastsize != *size)) && (*size)) away += (away < 0) ? 1 : -1; } lastoff = tryoff; } else { *start = 0; *size = 0; if (idxoff) *idxoff = 0; retval = -1; } return retval; }
int main(int /* argc */, char ** /* argv */) { printf("0x%.4x 0x%.4x\n", 255, swordtoarch16(255)); printf("0x%.8x 0x%.8x\n", 255, swordtoarch32(255)); // printf("0x%.16x 0x%.16llx\n", 255, __swap64(255)); return 0; }
void zStr::flushCache() const { static const char nl[] = {13, 10}; 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 = zdxfd->seek(0, SEEK_END); unsigned long zdtSize = zdtfd->seek(0, SEEK_END); if ((cacheBlockIndex * ZDXENTRYSIZE) > (zdxSize - ZDXENTRYSIZE)) { // New Block start = zdtSize; } else { zdxfd->seek(cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET); zdxfd->read(&start, 4); zdxfd->read(&outsize, 4); 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); zdxfd->seek(cacheBlockIndex * ZDXENTRYSIZE, SEEK_SET); zdtfd->seek(start, SEEK_SET); zdtfd->write(buf, size); // add a new line to make data file easier to read in an editor zdtfd->write(&nl, 2); zdxfd->write(&outstart, 4); zdxfd->write(&outsize, 4); } delete cacheBlock; cacheBlock = 0; } cacheBlockIndex = -1; cacheDirty = false; }
void zStr::setText(const char *ikey, const char *buf, long len) { static const char nl[] = {13, 10}; __u32 start, outstart; __u32 size, outsize; __s32 endoff; long idxoff = 0; __s32 shiftSize; 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); if (!caseSensitive) 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 { idxfd->seek(idxoff, SEEK_SET); idxfd->read(&start, 4); idxfd->read(&size, 4); start = swordtoarch32(start); size = swordtoarch32(size); tmpbuf = new char [ size + 2 ]; memset(tmpbuf, 0, size + 2); datfd->seek(start, SEEK_SET); datfd->read(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 = idxfd->seek(0, SEEK_END); shiftSize = endoff - idxoff; if (shiftSize > 0) { idxBytes = new char [ shiftSize ]; idxfd->seek(idxoff, SEEK_SET); idxfd->read(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 = (zdxfd->seek(0, SEEK_END) / ZDXENTRYSIZE); } else if (cacheBlock->getCount() >= blockCount) { flushCache(); cacheBlock = new EntriesBlock(); cacheBlockIndex = (zdxfd->seek(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 = datfd->seek(0, SEEK_END); outstart = archtosword32(start); outsize = archtosword32(size); idxfd->seek(idxoff, SEEK_SET); if (len > 0) { datfd->seek(start, SEEK_SET); datfd->write(outbuf, size); // add a new line to make data file easier to read in an editor datfd->write(&nl, 2); idxfd->write(&outstart, 4); idxfd->write(&outsize, 4); if (idxBytes) { idxfd->write(idxBytes, shiftSize); } } else { // delete entry if (idxBytes) { idxfd->write(idxBytes+IDXENTRYSIZE, shiftSize-IDXENTRYSIZE); idxfd->seek(-1, SEEK_CUR); // last valid byte FileMgr::getSystemFileMgr()->trunc(idxfd); // truncate index } } if (idxBytes) delete [] idxBytes; delete [] key; delete [] outbuf; free(dbKey); }
signed char zStr::findKeyIndex(const char *ikey, long *idxoff, long away) const { char *maxbuf = 0, *trybuf = 0, *key = 0, quitflag = 0; signed char retval = 0; __s32 headoff, tailoff, tryoff = 0, maxoff = 0; __u32 start, size; int diff = 0; bool awayFromSubstrCheck = false; if (idxfd->getFd() >= 0) { tailoff = maxoff = idxfd->seek(0, SEEK_END) - IDXENTRYSIZE; if (*ikey) { headoff = 0; stdstr(&key, ikey, 3); if (!caseSensitive) toupperstr_utf8(key, strlen(key)*3); int keylen = strlen(key); bool substr = false; getKeyFromIdxOffset(maxoff, &maxbuf); 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; } diff = strcmp(key, trybuf); if (!diff) break; if (!strncmp(trybuf, key, keylen)) substr = true; if (diff < 0) tailoff = (tryoff == headoff) ? headoff : tryoff; else headoff = tryoff; if (tailoff == headoff + IDXENTRYSIZE) { if (quitflag++) headoff = tailoff; } } // didn't find exact match if (headoff >= tailoff) { tryoff = headoff; if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) { awayFromSubstrCheck = true; away--; // if our entry doesn't startwith our key, prefer the previous entry over the next } } if (trybuf) free(trybuf); delete [] key; if (maxbuf) free(maxbuf); } else { tryoff = 0; } idxfd->seek(tryoff, SEEK_SET); start = size = 0; retval = (idxfd->read(&start, 4) == 4) ? retval : -1; retval = (idxfd->read(&size, 4) == 4) ? 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 (idxfd->seek(tryoff, SEEK_SET) < 0) bad = true; if (bad) { if(!awayFromSubstrCheck) retval = -1; start = laststart; size = lastsize; tryoff = lasttry; if (idxoff) *idxoff = tryoff; break; } idxfd->read(&start, 4); idxfd->read(&size, 4); start = swordtoarch32(start); size = swordtoarch32(size); if (idxoff) *idxoff = tryoff; if (((laststart != start) || (lastsize != size)) && (start) && (size)) away += (away < 0) ? 1 : -1; } lastoff = tryoff; } else { if (idxoff) *idxoff = 0; retval = -1; } return retval; }