1 /******************************************************************************
2  *
3  *  rawgenbook.cpp -	code for class 'RawGenBook'- a module that reads raw
4  *			text files: ot and nt using indexs ??.bks ??.cps ??.vss
5  *
6  * $Id: rawgenbook.cpp 3439 2016-10-23 08:32:02Z scribe $
7  *
8  * Copyright 2002-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 
25 
26 #include <stdio.h>
27 #include <fcntl.h>
28 
29 #include <rawgenbook.h>
30 #include <rawstr.h>
31 #include <utilstr.h>
32 #include <filemgr.h>
33 #include <sysdata.h>
34 #include <treekeyidx.h>
35 #include <versetreekey.h>
36 
37 SWORD_NAMESPACE_START
38 
39 /******************************************************************************
40  * RawGenBook Constructor - Initializes data for instance of RawGenBook
41  *
42  * ENT:	iname - Internal name for module
43  *	idesc - Name to display to user for module
44  *	idisp	 - Display object to use for displaying
45  */
46 
RawGenBook(const char * ipath,const char * iname,const char * idesc,SWDisplay * idisp,SWTextEncoding enc,SWTextDirection dir,SWTextMarkup mark,const char * ilang,const char * keyType)47 RawGenBook::RawGenBook(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang, const char *keyType)
48 		: SWGenBook(iname, idesc, idisp, enc, dir, mark, ilang) {
49 
50 	char *buf = new char [ strlen (ipath) + 20 ];
51 
52 	path = 0;
53 	stdstr(&path, ipath);
54 	verseKey = !strcmp("VerseKey", keyType);
55 
56 	if (verseKey) setType("Biblical Texts");
57 
58 	if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
59 		path[strlen(path)-1] = 0;
60 
61 	delete key;
62 	key = createKey();
63 
64 
65 	sprintf(buf, "%s.bdt", path);
66 	bdtfd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::RDWR, true);
67 
68 	delete [] buf;
69 
70 }
71 
72 
73 /******************************************************************************
74  * RawGenBook Destructor - Cleans up instance of RawGenBook
75  */
76 
~RawGenBook()77 RawGenBook::~RawGenBook() {
78 
79 	FileMgr::getSystemFileMgr()->close(bdtfd);
80 
81 	if (path)
82 		delete [] path;
83 
84 }
85 
86 
isWritable() const87 bool RawGenBook::isWritable() const {
88 	return ((bdtfd->getFd() > 0) && ((bdtfd->mode & FileMgr::RDWR) == FileMgr::RDWR));
89 }
90 
91 
92 /******************************************************************************
93  * RawGenBook::getRawEntry	- Returns the correct verse when char * cast
94  *					is requested
95  *
96  * RET: string buffer with verse
97  */
98 
getRawEntryBuf() const99 SWBuf &RawGenBook::getRawEntryBuf() const {
100 
101 	__u32 offset = 0;
102 	__u32 size = 0;
103 
104 	const TreeKey &key = getTreeKey();
105 
106 	int dsize;
107 	key.getUserData(&dsize);
108 	entryBuf = "";
109 	if (dsize > 7) {
110 		memcpy(&offset, key.getUserData(), 4);
111 		offset = swordtoarch32(offset);
112 
113 		memcpy(&size, key.getUserData() + 4, 4);
114 		size = swordtoarch32(size);
115 
116 		entrySize = size;        // support getEntrySize call
117 
118 		entryBuf.setFillByte(0);
119 		entryBuf.setSize(size);
120 		bdtfd->seek(offset, SEEK_SET);
121 		bdtfd->read(entryBuf.getRawData(), size);
122 
123 		rawFilter(entryBuf, 0);	// hack, decipher
124 		rawFilter(entryBuf, &key);
125 
126 //		   if (!isUnicode())
127 			SWModule::prepText(entryBuf);
128 	}
129 
130 	return entryBuf;
131 }
132 
133 
setEntry(const char * inbuf,long len)134 void RawGenBook::setEntry(const char *inbuf, long len) {
135 
136 	__u32 offset = (__u32)archtosword32(bdtfd->seek(0, SEEK_END));
137 	__u32 size = 0;
138 	TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
139 
140 	char userData[8];
141 
142 	if (len < 0)
143 		len = strlen(inbuf);
144 
145 	bdtfd->write(inbuf, len);
146 
147 	size = (__u32)archtosword32(len);
148 	memcpy(userData, &offset, 4);
149 	memcpy(userData+4, &size, 4);
150 	key->setUserData(userData, 8);
151 	key->save();
152 }
153 
154 
linkEntry(const SWKey * inkey)155 void RawGenBook::linkEntry(const SWKey *inkey) {
156 	TreeKeyIdx *srckey = 0;
157 	TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
158 	// see if we have a VerseKey * or decendant
159 	SWTRY {
160 		srckey = SWDYNAMIC_CAST(TreeKeyIdx, inkey);
161 	}
162 	SWCATCH ( ... ) {}
163 	// if we don't have a VerseKey * decendant, create our own
164 	if (!srckey) {
165 		srckey = (TreeKeyIdx *)createKey();
166 		(*srckey) = *inkey;
167 	}
168 
169 	key->setUserData(srckey->getUserData(), 8);
170 	key->save();
171 
172 	if (inkey != srckey) // free our key if we created a VerseKey
173 		delete srckey;
174 }
175 
176 
177 /******************************************************************************
178  * RawGenBook::deleteEntry	- deletes this entry
179  *
180  * RET: *this
181  */
182 
deleteEntry()183 void RawGenBook::deleteEntry() {
184 	TreeKeyIdx *key = ((TreeKeyIdx *)&(getTreeKey()));
185 	key->remove();
186 }
187 
188 
createModule(const char * ipath)189 char RawGenBook::createModule(const char *ipath) {
190 	char *path = 0;
191 	char *buf = new char [ strlen (ipath) + 20 ];
192 	FileDesc *fd;
193 	signed char retval;
194 
195 	stdstr(&path, ipath);
196 
197 	if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
198 		path[strlen(path)-1] = 0;
199 
200 	sprintf(buf, "%s.bdt", path);
201 	FileMgr::removeFile(buf);
202 	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
203 	fd->getFd();
204 	FileMgr::getSystemFileMgr()->close(fd);
205 
206 	retval = TreeKeyIdx::create(path);
207 	delete [] path;
208 	return retval;
209 }
210 
211 
createKey() const212 SWKey *RawGenBook::createKey() const {
213 	TreeKey *tKey = new TreeKeyIdx(path);
214 	if (verseKey) { SWKey *vtKey = new VerseTreeKey(tKey); delete tKey; return vtKey; }
215 	return tKey;
216 }
217 
hasEntry(const SWKey * k) const218 bool RawGenBook::hasEntry(const SWKey *k) const {
219 	TreeKey &key = getTreeKey(k);
220 
221 	int dsize;
222 	key.getUserData(&dsize);
223 	return (dsize > 7) && key.popError() == '\x00';
224 }
225 
226 SWORD_NAMESPACE_END
227