~ubuntu-branches/debian/squeeze/sword/squeeze

« back to all changes in this revision

Viewing changes to src/modules/common/rawstr.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Marsden, Jonathan Marsden, Dmitrijs Ledkovs, Closed Bugs
  • Date: 2009-05-30 11:55:55 UTC
  • mfrom: (1.3.1 upstream) (6.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090530115555-r427zsn3amivdpfu
Tags: 1.6.0+dfsg-1
[ Jonathan Marsden ]
* New upstream release. (Closes: #507960) (LP: #320558)
* debian/patches/02_libver.diff:
  - Bump SONAME to 8 -- SWORD 1.6 is not backward compatible with 1.5.11.
* debian/patches/series:
  - Remove 10_diatheke.diff -- included in upstream source.
* debian/patches/:
  - Remove several old unused .diff files.
  - Add 11_regex_only_when_needed.diff to conditionally include regex lib.
  - Add 12_fix_compiler_warnings.diff to remove all compiler warnings.
  - Add 13_fix_osis2mod_compression_default.diff from upstream svn.
  - Add 14_closing_section_not_chapter.diff from upstream svn.
* debian/libsword7.*: 
  - Rename to libsword8.*
  - Change libsword7 to libsword8 within files.
* debian/rules: 
  - SONAME bump to 8.
  - Set library version check to >= 1.6
* debian/control:
  - Change libsword7 to libsword8.
  - Add libsword7 to Conflicts.
  - Fix case of sword to SWORD in package descriptions.
  - Bump Standards-Version to 3.8.1 (no changes needed).
  - Fix section for libsword-dbg to avoid lintian warning.
* debian/rules:
  - Add DFSG get-orig-source target.
* debian/copyright:
  - Fix various mistakes in initial attempt to document copyrights.

[ Dmitrijs Ledkovs ]
* debian/rules: Added utils.mk to use missing-files target and call it on
  each build.
* debian/libsword-dev.install: Added libsword.la, previously missing.
* debian/libsword7.install: Added missing libicu translit files.
* debian/control:
  - Updated all uses of SWORD version to 1.6
  - Added libsword-dbg package
* debian/watch: Fixed a small mistake which was resulting in extra "."
  in final version name.
* debian/rules: simplified manpage processing.
* debian/libsword8.lintian-overrides: added override for module
  installation directory.
* debian/copyright: Updated with information about everyfile.
  Closes: #513448 LP: #322638
* debian/diatheke.examples: moved examples here from the diatheke.install
* debian/rules:
  - enabled shell script based testsuite
  - added commented out cppunit testsuite
* debian/patches/40_missing_includes.diff: 
  - added several missing stdio.h includes to prevent FTBFS of testsuite.

[ Closed Bugs ]
* FTBFS on intrepid (LP: #305172)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *  rawstr.cpp   - code for class 'RawStr'- a module that reads raw text
 
3
 *                 files:  ot and nt using indexs ??.bks ??.cps ??.vss
 
4
 *                 and provides lookup and parsing functions based on
 
5
 *                 class StrKey
 
6
 *
 
7
 *
 
8
 * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org)
 
9
 *      CrossWire Bible Society
 
10
 *      P. O. Box 2528
 
11
 *      Tempe, AZ  85280-2528
 
12
 *
 
13
 * This program is free software; you can redistribute it and/or modify it
 
14
 * under the terms of the GNU General Public License as published by the
 
15
 * Free Software Foundation version 2.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful, but
 
18
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
20
 * General Public License for more details.
 
21
 *
 
22
 */
 
23
 
 
24
#include <stdio.h>
 
25
#include <fcntl.h>
 
26
#include <errno.h>
 
27
 
 
28
#include <stdlib.h>
 
29
#include <utilstr.h>
 
30
#include <rawstr.h>
 
31
#include <sysdata.h>
 
32
#include <swlog.h>
 
33
#include <filemgr.h>
 
34
#include <swbuf.h>
 
35
#include <stringmgr.h>
 
36
 
 
37
SWORD_NAMESPACE_START
 
38
 
 
39
/******************************************************************************
 
40
 * RawStr Statics
 
41
 */
 
42
 
 
43
int RawStr::instance = 0;
 
44
char RawStr::nl = '\n';
 
45
const int RawStr::IDXENTRYSIZE = 6;
 
46
 
 
47
 
 
48
 
 
49
/******************************************************************************
 
50
 * RawStr Constructor - Initializes data for instance of RawStr
 
51
 *
 
52
 * ENT: ipath - path of the directory where data and index files are located.
 
53
 *              be sure to include the trailing separator (e.g. '/' or '\')
 
54
 *              (e.g. 'modules/texts/rawtext/webster/')
 
55
 */
 
56
 
 
57
RawStr::RawStr(const char *ipath, int fileMode)
 
58
{
 
59
        SWBuf buf;
 
60
 
 
61
        lastoff = -1;
 
62
        path = 0;
 
63
        stdstr(&path, ipath);
 
64
 
 
65
        if (fileMode == -1) { // try read/write if possible
 
66
                fileMode = FileMgr::RDWR;
 
67
        }
 
68
                
 
69
        buf.setFormatted("%s.idx", path);
 
70
        idxfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
71
 
 
72
        buf.setFormatted("%s.dat", path);
 
73
        datfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
74
 
 
75
        if (datfd < 0) {
 
76
                SWLog::getSystemLog()->logError("%d", errno);
 
77
        }
 
78
 
 
79
        instance++;
 
80
}
 
81
 
 
82
 
 
83
/******************************************************************************
 
84
 * RawStr Destructor - Cleans up instance of RawStr
 
85
 */
 
86
 
 
87
RawStr::~RawStr()
 
88
{
 
89
        if (path)
 
90
                delete [] path;
 
91
 
 
92
        --instance;
 
93
 
 
94
        FileMgr::getSystemFileMgr()->close(idxfd);
 
95
        FileMgr::getSystemFileMgr()->close(datfd);
 
96
}
 
97
 
 
98
 
 
99
/******************************************************************************
 
100
 * RawStr::getidxbufdat - Gets the index string at the given idx offset
 
101
 *                                              NOTE: buf is allocated and must be freed by
 
102
 *                                                      calling function
 
103
 *
 
104
 * ENT: ioffset - offset in dat file to lookup
 
105
 *              buf             - address of pointer to allocate for storage of string
 
106
 */
 
107
 
 
108
void RawStr::getIDXBufDat(long ioffset, char **buf) const
 
109
{
 
110
        int size;
 
111
        char ch;
 
112
        if (datfd > 0) {
 
113
                datfd->seek(ioffset, SEEK_SET);
 
114
                for (size = 0; datfd->read(&ch, 1) == 1; size++) {
 
115
                        if ((ch == '\\') || (ch == 10) || (ch == 13))
 
116
                                break;
 
117
                }
 
118
                *buf = (*buf) ? (char *)realloc(*buf, size*2 + 1) : (char *)malloc(size*2 + 1);
 
119
                if (size) {
 
120
                        datfd->seek(ioffset, SEEK_SET);
 
121
                        datfd->read(*buf, size);
 
122
                }
 
123
                (*buf)[size] = 0;
 
124
                toupperstr_utf8(*buf, size*2);
 
125
        }
 
126
        else {
 
127
                *buf = (*buf) ? (char *)realloc(*buf, 1) : (char *)malloc(1);
 
128
                **buf = 0;
 
129
        }
 
130
}
 
131
 
 
132
 
 
133
/******************************************************************************
 
134
 * RawStr::getidxbuf    - Gets the index string at the given idx offset
 
135
 *                                              NOTE: buf is allocated and must be freed by
 
136
 *                                                      calling function
 
137
 *
 
138
 * ENT: ioffset - offset in idx file to lookup
 
139
 *              buf             - address of pointer to allocate for storage of string
 
140
 */
 
141
 
 
142
void RawStr::getIDXBuf(long ioffset, char **buf) const
 
143
{
 
144
        __u32 offset;
 
145
        
 
146
        if (idxfd > 0) {
 
147
                idxfd->seek(ioffset, SEEK_SET);
 
148
                idxfd->read(&offset, 4);
 
149
 
 
150
                offset = swordtoarch32(offset);
 
151
 
 
152
                getIDXBufDat(offset, buf);
 
153
        }
 
154
}
 
155
 
 
156
 
 
157
/******************************************************************************
 
158
 * RawStr::findoffset   - Finds the offset of the key string from the indexes
 
159
 *
 
160
 * ENT: key             - key string to lookup
 
161
 *              start   - address to store the starting offset
 
162
 *              size            - address to store the size of the entry
 
163
 *              away            - number of entries before of after to jump
 
164
 *                                      (default = 0)
 
165
 *
 
166
 * RET: error status -1 general error; -2 new file
 
167
 */
 
168
 
 
169
signed char RawStr::findOffset(const char *ikey, __u32 *start, __u16 *size, long away, __u32 *idxoff) const
 
170
{
 
171
        char *trybuf, *maxbuf, *key = 0, quitflag = 0;
 
172
        signed char retval = -1;
 
173
        long headoff, tailoff, tryoff = 0, maxoff = 0;
 
174
        int diff = 0;
 
175
        bool awayFromSubstrCheck = false;       
 
176
 
 
177
        if (idxfd->getFd() >=0) {
 
178
                tailoff = maxoff = idxfd->seek(0, SEEK_END) - 6;
 
179
                retval = (tailoff >= 0) ? 0 : -2;       // if NOT new file
 
180
                if (*ikey && retval != -2) {
 
181
                        headoff = 0;
 
182
 
 
183
                        stdstr(&key, ikey, 3);
 
184
                        toupperstr_utf8(key, strlen(key)*3);
 
185
 
 
186
                        int keylen = strlen(key);
 
187
                        bool substr = false;
 
188
 
 
189
                        trybuf = maxbuf = 0;
 
190
                        getIDXBuf(maxoff, &maxbuf);
 
191
                        
 
192
                        while (headoff < tailoff) {
 
193
                                tryoff = (lastoff == -1) ? headoff + ((((tailoff / 6) - (headoff / 6))) / 2) * 6 : lastoff;
 
194
                                lastoff = -1;
 
195
                                getIDXBuf(tryoff, &trybuf);
 
196
 
 
197
                                if (!*trybuf && tryoff) {               // In case of extra entry at end of idx (not first entry)
 
198
                                        tryoff += (tryoff > (maxoff / 2))?-6:6;
 
199
                                        retval = -1;
 
200
                                        break;
 
201
                                }
 
202
 
 
203
                                diff = strcmp(key, trybuf);
 
204
 
 
205
                                if (!diff)
 
206
                                        break;
 
207
 
 
208
                                if (!strncmp(trybuf, key, keylen)) substr = true;
 
209
 
 
210
                                if (diff < 0)
 
211
                                        tailoff = (tryoff == headoff) ? headoff : tryoff;
 
212
                                else headoff = tryoff;
 
213
 
 
214
                                if (tailoff == headoff + 6) {
 
215
                                        if (quitflag++)
 
216
                                                headoff = tailoff;
 
217
                                }
 
218
                        }
 
219
 
 
220
                        // didn't find exact match
 
221
                        if (headoff >= tailoff) {
 
222
                                tryoff = headoff;
 
223
                                if (!substr && ((tryoff != maxoff)||(strncmp(key, maxbuf, keylen)<0))) {
 
224
                                        awayFromSubstrCheck = true;
 
225
                                        away--; // if our entry doesn't startwith our key, prefer the previous entry over the next
 
226
                                }
 
227
                        }
 
228
                        if (trybuf)
 
229
                                free(trybuf);
 
230
                        delete [] key;
 
231
                        if (maxbuf)
 
232
                                free(maxbuf);
 
233
                }
 
234
                else    tryoff = 0;
 
235
 
 
236
                idxfd->seek(tryoff, SEEK_SET);
 
237
 
 
238
                __u32 tmpStart;
 
239
                __u16 tmpSize;
 
240
                *start = *size = tmpStart = tmpSize = 0;
 
241
                idxfd->read(&tmpStart, 4);
 
242
                idxfd->read(&tmpSize, 2);
 
243
                if (idxoff)
 
244
                        *idxoff = tryoff;
 
245
 
 
246
                *start = swordtoarch32(tmpStart);
 
247
                *size  = swordtoarch16(tmpSize);
 
248
 
 
249
                while (away) {
 
250
                        unsigned long laststart = *start;
 
251
                        unsigned short lastsize = *size;
 
252
                        long lasttry = tryoff;
 
253
                        tryoff += (away > 0) ? 6 : -6;
 
254
                
 
255
                        bool bad = false;
 
256
                        if (((tryoff + (away*6)) < -6) || (tryoff + (away*6) > (maxoff+6)))
 
257
                                bad = true;
 
258
                        else if (idxfd->seek(tryoff, SEEK_SET) < 0)
 
259
                                bad = true;
 
260
                        if (bad) {
 
261
                                if(!awayFromSubstrCheck)
 
262
                                        retval = -1;
 
263
                                *start = laststart;
 
264
                                *size = lastsize;
 
265
                                tryoff = lasttry;
 
266
                                if (idxoff)
 
267
                                        *idxoff = tryoff;
 
268
                                break;
 
269
                        }
 
270
                        idxfd->read(&tmpStart, 4);
 
271
                        idxfd->read(&tmpSize, 2);
 
272
                        if (idxoff)
 
273
                                *idxoff = tryoff;
 
274
 
 
275
                        *start = swordtoarch32(tmpStart);
 
276
                        *size  = swordtoarch16(tmpSize);
 
277
 
 
278
                        if (((laststart != *start) || (lastsize != *size)) && (*size))
 
279
                                away += (away < 0) ? 1 : -1;
 
280
                }
 
281
        
 
282
                lastoff = tryoff;
 
283
        }
 
284
        else {
 
285
                *start = 0;
 
286
                *size  = 0;
 
287
                if (idxoff)
 
288
                        *idxoff = 0;
 
289
                retval = -1;
 
290
        }
 
291
        return retval;
 
292
}
 
293
 
 
294
 
 
295
/******************************************************************************
 
296
 * RawStr::readtext     - gets text at a given offset
 
297
 *
 
298
 * ENT:
 
299
 *      start   - starting offset where the text is located in the file
 
300
 *      size            - size of text entry
 
301
 *      buf             - buffer to store text
 
302
 *
 
303
 */
 
304
 
 
305
void RawStr::readText(__u32 istart, __u16 *isize, char **idxbuf, SWBuf &buf)
 
306
{
 
307
        unsigned int ch;
 
308
        char *idxbuflocal = 0;
 
309
        getIDXBufDat(istart, &idxbuflocal);
 
310
        __u32 start = istart;
 
311
 
 
312
        do {
 
313
                if (*idxbuf)
 
314
                        delete [] *idxbuf;
 
315
 
 
316
                buf = "";
 
317
                buf.setFillByte(0);
 
318
                buf.setSize(++(*isize));
 
319
 
 
320
                *idxbuf = new char [ (*isize) ];
 
321
 
 
322
                datfd->seek(start, SEEK_SET);
 
323
                datfd->read(buf.getRawData(), (int)((*isize) - 1));
 
324
 
 
325
                for (ch = 0; buf[ch]; ch++) {           // skip over index string
 
326
                        if (buf[ch] == 10) {
 
327
                                ch++;
 
328
                                break;
 
329
                        }
 
330
                }
 
331
                buf = SWBuf(buf.c_str()+ch);
 
332
                // resolve link
 
333
                if (!strncmp(buf.c_str(), "@LINK", 5)) {
 
334
                        for (ch = 0; buf[ch]; ch++) {           // null before nl
 
335
                                if (buf[ch] == 10) {
 
336
                                        buf[ch] = 0;
 
337
                                        break;
 
338
                                }
 
339
                        }
 
340
                        findOffset(buf.c_str() + 6, &start, isize);
 
341
                }
 
342
                else break;
 
343
        }
 
344
        while (true);   // while we're resolving links
 
345
 
 
346
        if (idxbuflocal) {
 
347
                int localsize = strlen(idxbuflocal);
 
348
                localsize = (localsize < (*isize - 1)) ? localsize : (*isize - 1);
 
349
                strncpy(*idxbuf, idxbuflocal, localsize);
 
350
                (*idxbuf)[localsize] = 0;
 
351
                free(idxbuflocal);
 
352
        }
 
353
}
 
354
 
 
355
 
 
356
/******************************************************************************
 
357
 * RawLD::settext       - Sets text for current offset
 
358
 *
 
359
 * ENT: key     - key for this entry
 
360
 *      buf     - buffer to store
 
361
 *      len     - length of buffer (0 - null terminated)
 
362
 */
 
363
 
 
364
void RawStr::doSetText(const char *ikey, const char *buf, long len)
 
365
{
 
366
 
 
367
        __u32 start, outstart;
 
368
        __u32 idxoff;
 
369
        __u32 endoff;
 
370
        __s32 shiftSize;
 
371
        __u16 size;
 
372
        __u16 outsize;
 
373
        static const char nl[] = {13, 10};
 
374
        char *tmpbuf = 0;
 
375
        char *key = 0;
 
376
        char *dbKey = 0;
 
377
        char *idxBytes = 0;
 
378
        char *outbuf = 0;
 
379
        char *ch = 0;
 
380
 
 
381
        char errorStatus = findOffset(ikey, &start, &size, 0, &idxoff);
 
382
        stdstr(&key, ikey, 2);
 
383
        toupperstr_utf8(key, strlen(key)*2);
 
384
 
 
385
        len = (len < 0) ? strlen(buf) : len;
 
386
 
 
387
        getIDXBufDat(start, &dbKey);
 
388
 
 
389
        if (strcmp(key, dbKey) < 0) {
 
390
        }
 
391
        else if (strcmp(key, dbKey) > 0) {
 
392
                if (errorStatus != (char)-2)    // not a new file
 
393
                        idxoff += 6;
 
394
                else idxoff = 0;
 
395
        }
 
396
        else if ((!strcmp(key, dbKey)) && (len>0 /*we're not deleting*/)) { // got absolute entry
 
397
                do {
 
398
                        tmpbuf = new char [ size + 2 ];
 
399
                        memset(tmpbuf, 0, size + 2);
 
400
                        datfd->seek(start, SEEK_SET);
 
401
                        datfd->read(tmpbuf, (int)(size - 1));
 
402
 
 
403
                        for (ch = tmpbuf; *ch; ch++) {          // skip over index string
 
404
                                if (*ch == 10) {
 
405
                                        ch++;
 
406
                                        break;
 
407
                                }
 
408
                        }
 
409
                        memmove(tmpbuf, ch, size - (unsigned short)(ch-tmpbuf));
 
410
 
 
411
                        // resolve link
 
412
                        if (!strncmp(tmpbuf, "@LINK", 5) && (len)) {
 
413
                                for (ch = tmpbuf; *ch; ch++) {          // null before nl
 
414
                                        if (*ch == 10) {
 
415
                                                *ch = 0;
 
416
                                                break;
 
417
                                        }
 
418
                                }
 
419
                                findOffset(tmpbuf + 6, &start, &size, 0, &idxoff);
 
420
                        }
 
421
                        else break;
 
422
                }
 
423
                while (true);   // while we're resolving links
 
424
        }
 
425
 
 
426
        endoff = idxfd->seek(0, SEEK_END);
 
427
 
 
428
        shiftSize = endoff - idxoff;
 
429
 
 
430
        if (shiftSize > 0) {
 
431
                idxBytes = new char [ shiftSize ];
 
432
                idxfd->seek(idxoff, SEEK_SET);
 
433
                idxfd->read(idxBytes, shiftSize);
 
434
        }
 
435
 
 
436
        outbuf = new char [ len + strlen(key) + 5 ];
 
437
        sprintf(outbuf, "%s%c%c", key, 13, 10);
 
438
        size = strlen(outbuf);
 
439
        memcpy(outbuf + size, buf, len);
 
440
        size = outsize = size + (len);
 
441
 
 
442
        start = outstart = datfd->seek(0, SEEK_END);
 
443
 
 
444
        outstart = archtosword32(start);
 
445
        outsize  = archtosword16(size);
 
446
 
 
447
        idxfd->seek(idxoff, SEEK_SET);
 
448
        if (len > 0) {
 
449
                datfd->seek(start, SEEK_SET);
 
450
                datfd->write(outbuf, (int)size);
 
451
 
 
452
                // add a new line to make data file easier to read in an editor
 
453
                datfd->write(&nl, 2);
 
454
                
 
455
                idxfd->write(&outstart, 4);
 
456
                idxfd->write(&outsize, 2);
 
457
                if (idxBytes) {
 
458
                        idxfd->write(idxBytes, shiftSize);
 
459
                        delete [] idxBytes;
 
460
                }
 
461
        }
 
462
        else {  // delete entry
 
463
                if (idxBytes) {
 
464
                        idxfd->write(idxBytes+6, shiftSize-6);
 
465
                        idxfd->seek(-1, SEEK_CUR);      // last valid byte
 
466
                        FileMgr::getSystemFileMgr()->trunc(idxfd);      // truncate index
 
467
                        delete [] idxBytes;
 
468
                }
 
469
        }
 
470
 
 
471
        delete [] key;
 
472
        delete [] outbuf;
 
473
        free(dbKey);
 
474
}
 
475
 
 
476
 
 
477
/******************************************************************************
 
478
 * RawLD::linkentry     - links one entry to another
 
479
 *
 
480
 * ENT: testmt  - testament to find (0 - Bible/module introduction)
 
481
 *      destidxoff      - dest offset into .vss
 
482
 *      srcidxoff               - source offset into .vss
 
483
 */
 
484
 
 
485
void RawStr::doLinkEntry(const char *destkey, const char *srckey) {
 
486
        char *text = new char [ strlen(destkey) + 7 ];
 
487
        sprintf(text, "@LINK %s", destkey);
 
488
        doSetText(srckey, text);
 
489
        delete [] text;
 
490
}
 
491
 
 
492
/******************************************************************************
 
493
 * RawLD::CreateModule  - Creates new module files
 
494
 *
 
495
 * ENT: path    - directory to store module files
 
496
 * RET: error status
 
497
 */
 
498
 
 
499
signed char RawStr::createModule(const char *ipath)
 
500
{
 
501
        char *path = 0;
 
502
        char *buf = new char [ strlen (ipath) + 20 ];
 
503
        FileDesc *fd, *fd2;
 
504
 
 
505
        stdstr(&path, ipath);
 
506
 
 
507
        if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
 
508
                path[strlen(path)-1] = 0;
 
509
 
 
510
        sprintf(buf, "%s.dat", path);
 
511
        FileMgr::removeFile(buf);
 
512
        fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
 
513
        fd->getFd();
 
514
        FileMgr::getSystemFileMgr()->close(fd);
 
515
 
 
516
        sprintf(buf, "%s.idx", path);
 
517
        FileMgr::removeFile(buf);
 
518
        fd2 = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
 
519
        fd2->getFd();
 
520
        FileMgr::getSystemFileMgr()->close(fd2);
 
521
 
 
522
        delete [] path;
 
523
        
 
524
        return 0;
 
525
}
 
526
 
 
527
SWORD_NAMESPACE_END