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