<!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>