1 /******************************************************************************
2 *
3 * zcom.cpp - code for class 'zCom'- a module that reads raw commentary
4 * files
5 *
6 * $Id: zcom.cpp 3073 2014-03-05 00:27:52Z scribe $
7 *
8 * Copyright 1996-2013 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 <ctype.h>
25 #include <stdio.h>
26 #include <fcntl.h>
27
28 #include <swbuf.h>
29 #include <zverse.h>
30 #include <versekey.h>
31 #include <zcom.h>
32 #include <filemgr.h>
33
34 SWORD_NAMESPACE_START
35
36 /******************************************************************************
37 * zCom Constructor - Initializes data for instance of zCom
38 *
39 * ENT: ipath - path to data files
40 * iname - Internal name for module
41 * idesc - Name to display to user for module
42 * iblockType - verse, chapter, book, etc. of index chunks
43 * icomp - Compressor object
44 * idisp - Display object to use for displaying
45 */
46
zCom(const char * ipath,const char * iname,const char * idesc,int iblockType,SWCompress * icomp,SWDisplay * idisp,SWTextEncoding enc,SWTextDirection dir,SWTextMarkup mark,const char * ilang,const char * versification)47 zCom::zCom(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char *ilang, const char *versification) : zVerse(ipath, -1, iblockType, icomp), SWCom(iname, idesc, idisp, enc, dir, mark, ilang, versification)/*, SWCompress()*/
48 {
49 blockType = iblockType;
50 lastWriteKey = 0;
51 }
52
53 /******************************************************************************
54 * zCom Destructor - Cleans up instance of zCom
55 */
56
~zCom()57 zCom::~zCom() {
58 flushCache();
59
60 if (lastWriteKey)
61 delete lastWriteKey;
62 }
63
64
isWritable() const65 bool zCom::isWritable() const {
66 return ((idxfp[0]->getFd() > 0) && ((idxfp[0]->mode & FileMgr::RDWR) == FileMgr::RDWR));
67 }
68
69
70 /******************************************************************************
71 * zCom::getRawEntry - Returns the current verse buffer
72 *
73 * RET: buffer with verse
74 */
75
getRawEntryBuf() const76 SWBuf &zCom::getRawEntryBuf() const {
77 long start = 0;
78 unsigned short size = 0;
79 unsigned long buffnum = 0;
80 VerseKey &key = getVerseKey();
81
82 findOffset(key.getTestament(), key.getTestamentIndex(), &start, &size, &buffnum);
83 entrySize = size; // support getEntrySize call
84
85 entryBuf = "";
86
87 zReadText(key.getTestament(), start, size, buffnum, entryBuf);
88 rawFilter(entryBuf, &key);
89
90 // if (!isUnicode())
91 prepText(entryBuf);
92
93 return entryBuf;
94 }
95
96
sameBlock(VerseKey * k1,VerseKey * k2)97 bool zCom::sameBlock(VerseKey *k1, VerseKey *k2) {
98 if (k1->getTestament() != k2->getTestament())
99 return false;
100
101 switch (blockType) {
102 case VERSEBLOCKS:
103 if (k1->getVerse() != k2->getVerse())
104 return false;
105 case CHAPTERBLOCKS:
106 if (k1->getChapter() != k2->getChapter())
107 return false;
108 case BOOKBLOCKS:
109 if (k1->getBook() != k2->getBook())
110 return false;
111 }
112 return true;
113 }
114
setEntry(const char * inbuf,long len)115 void zCom::setEntry(const char *inbuf, long len) {
116 VerseKey *key = &getVerseKey();
117
118 // see if we've jumped across blocks since last write
119 if (lastWriteKey) {
120 if (!sameBlock(lastWriteKey, key)) {
121 flushCache();
122 }
123 delete lastWriteKey;
124 }
125
126 doSetText(key->getTestament(), key->getTestamentIndex(), inbuf, len);
127
128 lastWriteKey = (VerseKey *)key->clone(); // must delete
129 }
130
131
linkEntry(const SWKey * inkey)132 void zCom::linkEntry(const SWKey *inkey) {
133 VerseKey *destkey = &getVerseKey();
134 const VerseKey *srckey = &getVerseKey(inkey);
135
136 doLinkEntry(destkey->getTestament(), destkey->getTestamentIndex(), srckey->getTestamentIndex());
137
138 if (inkey != srckey) // free our key if we created a VerseKey
139 delete srckey;
140 }
141
142 /******************************************************************************
143 * zCom::deleteEntry - deletes this entry
144 *
145 * RET: *this
146 */
147
deleteEntry()148 void zCom::deleteEntry() {
149
150 VerseKey *key = &getVerseKey();
151 doSetText(key->getTestament(), key->getTestamentIndex(), "");
152 }
153
154
155 /******************************************************************************
156 * zCom::increment - Increments module key a number of entries
157 *
158 * ENT: increment - Number of entries to jump forward
159 *
160 * RET: *this
161 */
162
increment(int steps)163 void zCom::increment(int steps) {
164 long start;
165 unsigned short size;
166 unsigned long buffnum;
167 VerseKey *tmpkey = &getVerseKey();
168
169 findOffset(tmpkey->getTestament(), tmpkey->getTestamentIndex(), &start, &size, &buffnum);
170
171 SWKey lastgood = *tmpkey;
172 while (steps) {
173 long laststart = start;
174 unsigned short lastsize = size;
175 SWKey lasttry = *tmpkey;
176 (steps > 0) ? ++(*key) : --(*key);
177 tmpkey = &getVerseKey();
178
179 if ((error = key->popError())) {
180 *key = lastgood;
181 break;
182 }
183 long index = tmpkey->getTestamentIndex();
184 findOffset(tmpkey->getTestament(), index, &start, &size, &buffnum);
185 if (
186 (((laststart != start) || (lastsize != size)) // we're a different entry
187 // && (start > 0)
188 && (size)) // and we actually have a size
189 ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links
190 steps += (steps < 0) ? 1 : -1;
191 lastgood = *tmpkey;
192 }
193 }
194 error = (error) ? KEYERR_OUTOFBOUNDS : 0;
195 }
196
isLinked(const SWKey * k1,const SWKey * k2) const197 bool zCom::isLinked(const SWKey *k1, const SWKey *k2) const {
198 long start1, start2;
199 unsigned short size1, size2;
200 unsigned long buffnum1, buffnum2;
201 VerseKey *vk1 = &getVerseKey(k1);
202 VerseKey *vk2 = &getVerseKey(k2);
203 if (vk1->getTestament() != vk2->getTestament()) return false;
204
205 findOffset(vk1->getTestament(), vk1->getTestamentIndex(), &start1, &size1, &buffnum1);
206 findOffset(vk2->getTestament(), vk2->getTestamentIndex(), &start2, &size2, &buffnum2);
207 return start1 == start2 && buffnum1 == buffnum2;
208 }
209
hasEntry(const SWKey * k) const210 bool zCom::hasEntry(const SWKey *k) const {
211 long start;
212 unsigned short size;
213 unsigned long buffnum;
214 VerseKey *vk = &getVerseKey(k);
215
216 findOffset(vk->getTestament(), vk->getTestamentIndex(), &start, &size, &buffnum);
217 return size;
218 }
219
220 SWORD_NAMESPACE_END
221