1 /******************************************************************************
2 *
3 * rawverse.cpp - code for class 'RawVerse'- a module that reads raw text
4 * files: ot and nt using indexs ??.bks ??.cps ??.vss
5 * and provides lookup and parsing functions based on
6 * class VerseKey
7 *
8 * $Id: rawverse.cpp 3439 2016-10-23 08:32:02Z scribe $
9 *
10 * Copyright 1997-2013 CrossWire Bible Society (http://www.crosswire.org)
11 * CrossWire Bible Society
12 * P. O. Box 2528
13 * Tempe, AZ 85280-2528
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation version 2.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 */
25
26
27
28 #include <ctype.h>
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <errno.h>
32
33 #include <utilstr.h>
34 #include <rawverse.h>
35 #include <versekey.h>
36 #include <sysdata.h>
37 #include <filemgr.h>
38 #include <swbuf.h>
39
40
41 SWORD_NAMESPACE_START
42
43 /******************************************************************************
44 * RawVerse Statics
45 */
46
47 int RawVerse::instance = 0;
48 const char RawVerse::nl = '\n';
49
50
51 /******************************************************************************
52 * RawVerse Constructor - Initializes data for instance of RawVerse
53 *
54 * ENT: ipath - path of the directory where data and index files are located.
55 * be sure to include the trailing separator (e.g. '/' or '\')
56 * (e.g. 'modules/texts/rawtext/webster/')
57 */
58
RawVerse(const char * ipath,int fileMode)59 RawVerse::RawVerse(const char *ipath, int fileMode)
60 {
61 SWBuf buf;
62
63 path = 0;
64 stdstr(&path, ipath);
65
66 if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
67 path[strlen(path)-1] = 0;
68
69 if (fileMode == -1) { // try read/write if possible
70 fileMode = FileMgr::RDWR;
71 }
72
73 buf.setFormatted("%s/ot.vss", path);
74 idxfp[0] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
75
76 buf.setFormatted("%s/nt.vss", path);
77 idxfp[1] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
78
79 buf.setFormatted("%s/ot", path);
80 textfp[0] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
81
82 buf.setFormatted("%s/nt", path);
83 textfp[1] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
84
85 instance++;
86 }
87
88
89 /******************************************************************************
90 * RawVerse Destructor - Cleans up instance of RawVerse
91 */
92
~RawVerse()93 RawVerse::~RawVerse()
94 {
95 int loop1;
96
97 if (path)
98 delete [] path;
99
100 --instance;
101
102 for (loop1 = 0; loop1 < 2; loop1++) {
103 FileMgr::getSystemFileMgr()->close(idxfp[loop1]);
104 FileMgr::getSystemFileMgr()->close(textfp[loop1]);
105 }
106 }
107
108
109 /******************************************************************************
110 * RawVerse::findoffset - Finds the offset of the key verse from the indexes
111 *
112 * ENT: testmt - testament to find (0 - Bible/module introduction)
113 * idxoff - offset into .vss
114 * start - address to store the starting offset
115 * size - address to store the size of the entry
116 */
117
findOffset(char testmt,long idxoff,long * start,unsigned short * size) const118 void RawVerse::findOffset(char testmt, long idxoff, long *start, unsigned short *size) const {
119 idxoff *= 6;
120 if (!testmt)
121 testmt = ((idxfp[1]) ? 1:2);
122
123 if (idxfp[testmt-1]->getFd() >= 0) {
124 idxfp[testmt-1]->seek(idxoff, SEEK_SET);
125 __s32 tmpStart;
126 __u16 tmpSize;
127 idxfp[testmt-1]->read(&tmpStart, 4);
128 long len = idxfp[testmt-1]->read(&tmpSize, 2); // read size
129
130 *start = swordtoarch32(tmpStart);
131 *size = swordtoarch16(tmpSize);
132
133 if (len < 2) {
134 *size = (unsigned short)((*start) ? (textfp[testmt-1]->seek(0, SEEK_END) - (long)*start) : 0); // if for some reason we get an error reading size, make size to end of file
135 }
136 }
137 else {
138 *start = 0;
139 *size = 0;
140 }
141 }
142
143
144 /******************************************************************************
145 * RawVerse::readtext - gets text at a given offset
146 *
147 * ENT: testmt - testament file to search in (0 - Old; 1 - New)
148 * start - starting offset where the text is located in the file
149 * size - size of text entry + 2 (null)(null)
150 * buf - buffer to store text
151 *
152 */
153
readText(char testmt,long start,unsigned short size,SWBuf & buf) const154 void RawVerse::readText(char testmt, long start, unsigned short size, SWBuf &buf) const {
155 buf = "";
156 buf.setFillByte(0);
157 buf.setSize(size + 1);
158 if (!testmt)
159 testmt = ((idxfp[1]) ? 1:2);
160 if (size) {
161 if (textfp[testmt-1]->getFd() >= 0) {
162 textfp[testmt-1]->seek(start, SEEK_SET);
163 textfp[testmt-1]->read(buf.getRawData(), (int)size);
164 }
165 }
166 }
167
168
169 /******************************************************************************
170 * RawVerse::settext - Sets text for current offset
171 *
172 * ENT: testmt - testament to find (0 - Bible/module introduction)
173 * idxoff - offset into .vss
174 * buf - buffer to store
175 * len - length of buffer (0 - null terminated)
176 */
177
doSetText(char testmt,long idxoff,const char * buf,long len)178 void RawVerse::doSetText(char testmt, long idxoff, const char *buf, long len)
179 {
180 __s32 start;
181 __u16 size;
182
183 idxoff *= 6;
184 if (!testmt)
185 testmt = ((idxfp[1]) ? 1:2);
186
187 size = (len < 0) ? strlen(buf) : len;
188
189 start = (__s32)textfp[testmt-1]->seek(0, SEEK_END);
190 idxfp[testmt-1]->seek(idxoff, SEEK_SET);
191
192 if (size) {
193 textfp[testmt-1]->seek(start, SEEK_SET);
194 textfp[testmt-1]->write(buf, (int)size);
195
196 // add a new line to make data file easier to read in an editor
197 textfp[testmt-1]->write(&nl, 1);
198 }
199 else {
200 start = 0;
201 }
202
203 start = archtosword32(start);
204 size = archtosword16(size);
205
206 idxfp[testmt-1]->write(&start, 4);
207 idxfp[testmt-1]->write(&size, 2);
208 }
209
210
211 /******************************************************************************
212 * RawVerse::linkentry - links one entry to another
213 *
214 * ENT: testmt - testament to find (0 - Bible/module introduction)
215 * destidxoff - dest offset into .vss
216 * srcidxoff - source offset into .vss
217 */
218
doLinkEntry(char testmt,long destidxoff,long srcidxoff)219 void RawVerse::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
220 __s32 start;
221 __u16 size;
222
223 destidxoff *= 6;
224 srcidxoff *= 6;
225
226 if (!testmt)
227 testmt = ((idxfp[1]) ? 1:2);
228
229 // get source
230 idxfp[testmt-1]->seek(srcidxoff, SEEK_SET);
231 idxfp[testmt-1]->read(&start, 4);
232 idxfp[testmt-1]->read(&size, 2);
233
234 // write dest
235 idxfp[testmt-1]->seek(destidxoff, SEEK_SET);
236 idxfp[testmt-1]->write(&start, 4);
237 idxfp[testmt-1]->write(&size, 2);
238 }
239
240
241 /******************************************************************************
242 * RawVerse::createModule - Creates new module files
243 *
244 * ENT: path - directory to store module files
245 * RET: error status
246 */
247
createModule(const char * ipath,const char * v11n)248 char RawVerse::createModule(const char *ipath, const char *v11n)
249 {
250 char *path = 0;
251 char *buf = new char [ strlen (ipath) + 20 ];
252 FileDesc *fd, *fd2;
253
254 stdstr(&path, ipath);
255
256 if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
257 path[strlen(path)-1] = 0;
258
259 sprintf(buf, "%s/ot", path);
260 FileMgr::removeFile(buf);
261 fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
262 fd->getFd();
263 FileMgr::getSystemFileMgr()->close(fd);
264
265 sprintf(buf, "%s/nt", path);
266 FileMgr::removeFile(buf);
267 fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
268 fd->getFd();
269 FileMgr::getSystemFileMgr()->close(fd);
270
271 sprintf(buf, "%s/ot.vss", path);
272 FileMgr::removeFile(buf);
273 fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
274 fd->getFd();
275
276 sprintf(buf, "%s/nt.vss", path);
277 FileMgr::removeFile(buf);
278 fd2 = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
279 fd2->getFd();
280
281 VerseKey vk;
282 vk.setVersificationSystem(v11n);
283 vk.setIntros(1);
284
285 __s32 offset = 0;
286 __u16 size = 0;
287 offset = archtosword32(offset);
288 size = archtosword16(size);
289
290 for (vk = TOP; !vk.popError(); vk++) {
291 if (vk.getTestament() < 2) {
292 fd->write(&offset, 4);
293 fd->write(&size, 2);
294 }
295 else {
296 fd2->write(&offset, 4);
297 fd2->write(&size, 2);
298 }
299 }
300 fd2->write(&offset, 4);
301 fd2->write(&size, 2);
302
303 FileMgr::getSystemFileMgr()->close(fd);
304 FileMgr::getSystemFileMgr()->close(fd2);
305
306 delete [] path;
307 delete [] buf;
308
309 return 0;
310 }
311
312 SWORD_NAMESPACE_END
313