The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
step2vpl.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * step2vpl.cpp - Utility to export a STEP module as VPL
4  *
5  * $Id: step2vpl.cpp 3754 2020-07-10 17:45:48Z scribe $
6  *
7  * Copyright 2000-2013 CrossWire Bible Society (http://www.crosswire.org)
8  * CrossWire Bible Society
9  * P. O. Box 2528
10  * Tempe, AZ 85280-2528
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the
14  * Free Software Foundation version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  */
22 
23 #ifdef _MSC_VER
24  #pragma warning( disable: 4251 )
25  #pragma warning( disable: 4996 )
26 #endif
27 
28 #include <iostream>
29 #include <string>
30 #include <stdio.h>
31 #include <sys/stat.h>
32 
33 #include <fcntl.h>
34 
35 #ifndef __GNUC__
36 #include <io.h>
37 #else
38 #include <unistd.h>
39 #endif
40 
41 #include <filemgr.h>
42 #include <lzsscomprs.h>
43 
44 using namespace std;
45 #ifndef NO_SWORD_NAMESPACE
46 using namespace sword;
47 #endif
48 
51 
54 
55 typedef struct {
57  short publisherID;
58  short bookID;
59  short setID;
65  char editionID;
66  short modifiedBy;
67 } Version;
68 
69 typedef struct {
71  long levelEntriesCount; // this is listed as nonGlossBlocksCount in spec!
74  long reserved;
76 
77 typedef struct {
79  long viewableBlocksCount; // this is listed as nonGlossBlocksCount in spec!
81  char compressionType; // 0 - none; 1 - LZSS
82  char reserved1;
84  short reserved2;
86 
87 typedef struct {
94  short reserved1_2;
95 } VSyncHeader;
96 
97 typedef struct {
98  long offset;
100  long size;
101 } ViewableBlock;
102 
103 typedef struct {
104  long offset; // offset into VSYNC.IDX to first VSyncPoint
105  short count; // number of VSyncPoints for this book
107 
108 typedef struct {
109  short chapter;
110  short verse;
111  long offset; // offset into SECTIONS.IDX
112 } VSyncPoint;
113 
114 typedef struct {
115  long parentOffset; // many of these are 0 if glossary
119  short startLevel;
120  char level;
122  long outSync_1;
123  short outSync_2;
125 
126 void readVersion(int fd, Version *versionRecord);
127 void readHeaderControlWordAreaText(int fd, char **buf);
128 void readViewableHeader(int fd, ViewableHeader *viewableHeaderRecord);
129 void readVSyncHeader(int fd, VSyncHeader *vSyncHeaderRecord);
130 void readVSyncBooksInfo(int fd, VSyncHeader *, VSyncBooksInfo **vSyncBooksInfo);
131 void readViewableBlock(int fd, ViewableBlock *vb);
132 void readViewableBlockText(int fd, ViewableBlock *vb, char **buf);
133 void readSectionsHeader(int fd, SectionsHeader *sectionsHeaderRecord);
134 void readSectionLevelInfo(int fd, SectionLevelInfo *sli);
135 void readSectionName(int fd, SectionLevelInfo *sli, char **name);
136 void displayBook(int fdbook, int fdviewable, int fdvsync, int fdsections, VSyncBooksInfo *vSyncBooksInfo);
137 void extractVerseText(int fdviewable, int fdbook, SectionLevelInfo *sectionLevelInfo, char **verseText);
138 void cleanBuf(char *buf);
139 
141 
142 int main(int argc, char **argv) {
143 
144  compress = new LZSSCompress();
145  char *buf;
146  Version versionRecord;
147  VSyncHeader vSyncHeaderRecord;
148  VSyncBooksInfo *vSyncBooksInfo;
149  SectionsHeader sectionsHeaderRecord;
150  ViewableHeader viewableHeaderRecord;
151 
152 
153  if (argc < 2) {
154  cerr << "usage: "<< *argv << " <database to step module>\n";
155  exit (-1);
156  }
157 
158  string bookpath = argv[1];
159  string fileName;
160 
161  if ((argv[1][strlen(argv[1])-1] != '/') &&
162  (argv[1][strlen(argv[1])-1] != '\\'))
163  bookpath += "/";
164 
165  fileName = bookpath + "Book.dat";
166  int fdbook = FileMgr::openFileReadOnly(fileName.c_str());
167 
168  if (fdbook < 1) {
169  cerr << "error, couldn't open file: " << fileName << "\n";
170  exit (-2);
171  }
172 
173  readVersion(fdbook, &versionRecord);
174  readHeaderControlWordAreaText(fdbook, &buf);
175  delete [] buf;
176 
177 
178  fileName = bookpath + "Viewable.idx";
179  int fdviewable = FileMgr::openFileReadOnly(fileName.c_str());
180 
181  if (fdviewable < 1) {
182  cerr << "error, couldn't open file: " << fileName << "\n";
183  exit (-3);
184  }
185 
186  readVersion(fdviewable, &versionRecord);
187  readViewableHeader(fdviewable, &viewableHeaderRecord);
188 
189  VIEWABLEBLOCKSTART = lseek(fdviewable, 0, SEEK_CUR);
190  VIEWABLEBLOCKSIZE = viewableHeaderRecord.blockEntriesSize;
191 
192 
193  fileName = bookpath + "Vsync.idx";
194  int fdvsync = FileMgr::openFileReadOnly(fileName.c_str());
195 
196  if (fdvsync < 1) {
197  cerr << "error, couldn't open file: " << fileName << "\n";
198  exit (-4);
199  }
200 
201  fileName = bookpath + "Sections.idx";
202  int fdsections = FileMgr::openFileReadOnly(fileName.c_str());
203 
204  if (fdsections < 1) {
205  cerr << "error, couldn't open file: " << fileName << "\n";
206  exit (-4);
207  }
208  readVersion(fdsections, &versionRecord);
209  readSectionsHeader(fdsections, &sectionsHeaderRecord);
210  SECTIONSLEVELSTART = lseek(fdsections, 0, SEEK_CUR);
211  SECTIONSLEVELSIZE = sectionsHeaderRecord.levelEntriesSize;
212 
213  readVersion(fdvsync, &versionRecord);
214  readVSyncHeader(fdvsync, &vSyncHeaderRecord);
215  readVSyncBooksInfo(fdvsync, &vSyncHeaderRecord, &vSyncBooksInfo);
216  int bookCount = vSyncHeaderRecord.endBookNumber - vSyncHeaderRecord.startBookNumber;
217  for (int i = 0; i <= bookCount; i++) {
218  displayBook(fdbook, fdviewable, fdvsync, fdsections, &vSyncBooksInfo[i]);
219  }
220 
221  close(fdviewable);
222  close(fdvsync);
223  close(fdsections);
224  close(fdbook);
225 
226 }
227 
228 
229 
230 void readVersion(int fd, Version *versionRecord) {
231 
232  read(fd, &(versionRecord->versionRecordSize), 2);
233  read(fd, &(versionRecord->publisherID), 2);
234  read(fd, &(versionRecord->bookID), 2);
235  read(fd, &(versionRecord->setID), 2);
236  read(fd, &(versionRecord->conversionProgramVerMajor), 1);
237  read(fd, &(versionRecord->conversionProgramVerMinor), 1);
238  read(fd, &(versionRecord->leastCompatSTEPVerMajor), 1);
239  read(fd, &(versionRecord->leastCompatSTEPVerMinor), 1);
240  read(fd, &(versionRecord->encryptionType), 1);
241  read(fd, &(versionRecord->editionID), 1);
242  read(fd, &(versionRecord->modifiedBy), 2);
243 
244  int skip = versionRecord->versionRecordSize - 16/*sizeof(struct Version*/;
245 
246  if (skip) {
247  char *skipbuf = new char[skip];
248  read(fd, skipbuf, skip);
249  delete [] skipbuf;
250  }
251 }
252 
253 
254 void readSectionsHeader(int fd, SectionsHeader *sectionsHeaderRecord) {
255 
256  read(fd, &(sectionsHeaderRecord->sectionsHeaderRecordSize), 2);
257  read(fd, &(sectionsHeaderRecord->levelEntriesCount), 4);
258  read(fd, &(sectionsHeaderRecord->glossEntriesCount), 4);
259  read(fd, &(sectionsHeaderRecord->levelEntriesSize), 2);
260  read(fd, &(sectionsHeaderRecord->reserved), 4);
261 
262  int skip = sectionsHeaderRecord->sectionsHeaderRecordSize - 16/*sizeof(struct ViewableHeader)*/;
263 
264  if (skip) {
265  char *skipbuf = new char[skip];
266  read(fd, skipbuf, skip);
267  delete [] skipbuf;
268  }
269 }
270 
271 
272 void readViewableHeader(int fd, ViewableHeader *viewableHeaderRecord) {
273 
274  read(fd, &(viewableHeaderRecord->viewableHeaderRecordSize), 2);
275  read(fd, &(viewableHeaderRecord->viewableBlocksCount), 4);
276  read(fd, &(viewableHeaderRecord->glossBlocksCount), 4);
277  read(fd, &(viewableHeaderRecord->compressionType), 1);
278  read(fd, &(viewableHeaderRecord->reserved1), 1);
279  read(fd, &(viewableHeaderRecord->blockEntriesSize), 2);
280  read(fd, &(viewableHeaderRecord->reserved2), 2);
281 
282  int skip = viewableHeaderRecord->viewableHeaderRecordSize - 16/*sizeof(struct ViewableHeader)*/;
283 
284  if (skip) {
285  char *skipbuf = new char[skip];
286  read(fd, skipbuf, skip);
287  delete [] skipbuf;
288  }
289 }
290 
291 
292 void readVSyncHeader(int fd, VSyncHeader *vSyncHeaderRecord) {
293 
294  read(fd, &(vSyncHeaderRecord->vSyncHeaderRecordSize), 2);
295  read(fd, &(vSyncHeaderRecord->startBookNumber), 2);
296  read(fd, &(vSyncHeaderRecord->endBookNumber), 2);
297  read(fd, &(vSyncHeaderRecord->bookPointerEntriesSize), 2);
298  read(fd, &(vSyncHeaderRecord->syncPointEntriesSize), 2);
299  read(fd, &(vSyncHeaderRecord->reserved1_1), 4);
300  read(fd, &(vSyncHeaderRecord->reserved1_2), 2);
301 
302  int skip = vSyncHeaderRecord->vSyncHeaderRecordSize - 16/*sizeof(VSyncHeader)*/;
303 
304  if (skip) {
305  char *skipbuf = new char[skip];
306  read(fd, skipbuf, skip);
307  delete [] skipbuf;
308  }
309 }
310 
311 
312 void readViewableBlockText(int fd, ViewableBlock *vb, char **buf) {
313  unsigned long size = vb->size;
314 
315  *buf = new char [ ((vb->size > vb->uncompressedSize) ? vb->size : vb->uncompressedSize) + 1 ];
316  lseek(fd, vb->offset, SEEK_SET);
317  read(fd, *buf, vb->size);
318 
319  compress->setCompressedBuf(&size, *buf);
320  strcpy(*buf, compress->getUncompressedBuf());
321 }
322 
323 
324 void readViewableBlock(int fd, ViewableBlock *vb) {
325 
326  read(fd, &(vb->offset), 4);
327  read(fd, &(vb->uncompressedSize), 4);
328  read(fd, &(vb->size), 4);
329 }
330 
331 
332 void readHeaderControlWordAreaText(int fd, char **buf) {
333  long headerControlWordAreaSize;
334  read(fd, &headerControlWordAreaSize, 4);
335 
336  *buf = new char [headerControlWordAreaSize + 1];
337 
338  read(fd, *buf, headerControlWordAreaSize);
339  (*buf)[headerControlWordAreaSize] = 0;
340 
341 }
342 
343 void readVSyncBooksInfo(int fd, VSyncHeader *vSyncHeaderRecord, VSyncBooksInfo **vSyncBooksInfo) {
344 
345  int bookCount = vSyncHeaderRecord->endBookNumber - vSyncHeaderRecord->startBookNumber;
346  *vSyncBooksInfo = new VSyncBooksInfo[bookCount];
347  for (int i = 0; i <= bookCount; i++) {
348  read(fd, &(*vSyncBooksInfo)[i].offset, 4);
349  read(fd, &(*vSyncBooksInfo)[i].count, 2);
350  }
351 }
352 
353 void displayBook(int fdbook, int fdviewable, int fdvsync, int fdsections, VSyncBooksInfo *vSyncBooksInfo) {
354  VSyncPoint vSyncPoint;
355 
356  lseek(fdvsync, vSyncBooksInfo->offset, SEEK_SET);
357 
358  for (int i = 0; i < vSyncBooksInfo->count; i++) {
359 
360  SectionLevelInfo sectionLevelInfo;
361  char *sectionName;
362  char *verseText;
363 
364  read(fdvsync, &(vSyncPoint.chapter), 2);
365  read(fdvsync, &(vSyncPoint.verse), 2);
366  read(fdvsync, &(vSyncPoint.offset), 4);
367  vSyncPoint.offset = SECTIONSLEVELSTART + (vSyncPoint.offset * SECTIONSLEVELSIZE);
368  lseek(fdsections, vSyncPoint.offset, SEEK_SET);
369  readSectionLevelInfo(fdsections, &sectionLevelInfo);
370  readSectionName(fdsections, &sectionLevelInfo, &sectionName);
371  cout << sectionName << " ";
372  delete [] sectionName;
373  extractVerseText(fdviewable, fdbook, &sectionLevelInfo, &verseText);
374  cleanBuf(verseText);
375  cout << verseText << "\n";
376  delete [] verseText;
377  }
378 }
379 
380 
381 void extractVerseText(int fdviewable, int fdbook, SectionLevelInfo *sectionLevelInfo, char **verseText) {
382  char numberBuf[16];
383  string startToken;
384  ViewableBlock vb;
385  int len = 0;
386  static long lastEntryOffset = -1;
387  static class FreeCachedEntryText {
388  public:
389  char *entryText;
390  FreeCachedEntryText() { entryText = 0; }
391  ~FreeCachedEntryText() { if (entryText) delete [] entryText; }
392  } _freeCachedEntryText;
393 
394  if (sectionLevelInfo->viewableOffset != lastEntryOffset) {
395  if (_freeCachedEntryText.entryText)
396  delete [] _freeCachedEntryText.entryText;
397 
398  lseek(fdviewable, sectionLevelInfo->viewableOffset, SEEK_SET);
399  readViewableBlock(fdviewable, &vb);
400  readViewableBlockText(fdbook, &vb, &(_freeCachedEntryText.entryText));
401  lastEntryOffset = sectionLevelInfo->viewableOffset;
402  }
403  sprintf(numberBuf, "%d", sectionLevelInfo->startLevel);
404  startToken = "\\stepstartlevel";
405  startToken += numberBuf;
406  char *start = strstr(_freeCachedEntryText.entryText, startToken.c_str());
407  if (start) {
408  start += strlen(startToken.c_str());
409  char *end = strstr(start, "\\stepstartlevel");
410  if (end)
411  len = end - start;
412  else len = strlen(start);
413  }
414  *verseText = new char [ len + 1 ];
415  strncpy(*verseText, start, len);
416  (*verseText)[len] = 0;
417 }
418 
419 
420 void readSectionName(int fd, SectionLevelInfo *sli, char **name) {
421  short size;
422  lseek(fd, sli->nameOffset, SEEK_SET);
423  read(fd, &size, 2);
424  *name = new char [ size + 1 ];
425  read(fd, *name, size);
426  (*name)[size] = 0;
427 }
428 
430 
431  read(fd, &(sli->parentOffset), 4);
432  read(fd, &(sli->previousOffset), 4);
433  read(fd, &(sli->nextOffset), 4);
434  read(fd, &(sli->viewableOffset), 4);
436  read(fd, &(sli->startLevel), 2);
437  read(fd, &(sli->level), 1);
438  read(fd, &(sli->nameOffset), 4);
439  read(fd, &(sli->outSync_1), 4);
440  read(fd, &(sli->outSync_2), 2);
441 }
442 
443 void cleanBuf(char *buf) {
444  char *from = buf;
445  char *to = buf;
446 
447  while (*from) {
448  if ((*from != 10) && (*from != 13)) {
449  *to++ = *from++;
450  }
451  else {
452  from++;
453  }
454  }
455  *to = 0;
456 }
long uncompressedSize
Definition: step2vpl.cpp:99
short sectionsHeaderRecordSize
Definition: step2vpl.cpp:70
#define SEEK_CUR
Definition: zconf.h:245
short versionRecordSize
Definition: step2vpl.cpp:56
void readViewableBlockText(int fd, ViewableBlock *vb, char **buf)
Definition: step2vpl.cpp:312
long offset
Definition: step2vpl.cpp:111
static int openFileReadOnly(const char *fName)
Definition: filemgr.cpp:474
virtual void setCompressedBuf(unsigned long *len, char *buf=0)
Definition: swcomprs.cpp:101
long SECTIONSLEVELSIZE
Definition: step2vpl.cpp:50
short levelEntriesSize
Definition: step2vpl.cpp:73
short reserved1_2
Definition: step2vpl.cpp:94
long glossEntriesCount
Definition: step2vpl.cpp:72
short chapter
Definition: step2vpl.cpp:109
int main(int argc, char **argv)
Definition: addcomment.cpp:32
SWCompress * compress
Definition: step2vpl.cpp:140
short modifiedBy
Definition: step2vpl.cpp:66
short blockEntriesSize
Definition: step2vpl.cpp:83
void cleanBuf(char *buf)
Definition: step2vpl.cpp:443
short reserved2
Definition: step2vpl.cpp:84
long viewableBlocksCount
Definition: step2vpl.cpp:79
void readVSyncBooksInfo(int fd, VSyncHeader *, VSyncBooksInfo **vSyncBooksInfo)
Definition: step2vpl.cpp:343
void readSectionName(int fd, SectionLevelInfo *sli, char **name)
Definition: step2vpl.cpp:420
virtual char * getUncompressedBuf(unsigned long *len=0)
Definition: swcomprs.cpp:90
short publisherID
Definition: step2vpl.cpp:57
short syncPointEntriesSize
Definition: step2vpl.cpp:92
short vSyncHeaderRecordSize
Definition: step2vpl.cpp:88
short startBookNumber
Definition: step2vpl.cpp:89
char leastCompatSTEPVerMajor
Definition: step2vpl.cpp:62
char conversionProgramVerMinor
Definition: step2vpl.cpp:61
long VIEWABLEBLOCKSIZE
Definition: step2vpl.cpp:53
char compressionType
Definition: step2vpl.cpp:81
char leastCompatSTEPVerMinor
Definition: step2vpl.cpp:63
long SECTIONSLEVELSTART
Definition: step2vpl.cpp:49
#define SEEK_SET
Definition: zconf.h:244
long reserved1_1
Definition: step2vpl.cpp:93
int size
Definition: regex.c:5043
void readSectionsHeader(int fd, SectionsHeader *sectionsHeaderRecord)
Definition: step2vpl.cpp:254
short bookID
Definition: step2vpl.cpp:58
long VIEWABLEBLOCKSTART
Definition: step2vpl.cpp:52
long levelEntriesCount
Definition: step2vpl.cpp:71
void readViewableBlock(int fd, ViewableBlock *vb)
Definition: step2vpl.cpp:324
void extractVerseText(int fdviewable, int fdbook, SectionLevelInfo *sectionLevelInfo, char **verseText)
Definition: step2vpl.cpp:381
void readVersion(int fd, Version *versionRecord)
Definition: step2vpl.cpp:230
void displayBook(int fdbook, int fdviewable, int fdvsync, int fdsections, VSyncBooksInfo *vSyncBooksInfo)
Definition: step2vpl.cpp:353
long glossBlocksCount
Definition: step2vpl.cpp:80
char conversionProgramVerMajor
Definition: step2vpl.cpp:60
char editionID
Definition: step2vpl.cpp:65
char encryptionType
Definition: step2vpl.cpp:64
void readViewableHeader(int fd, ViewableHeader *viewableHeaderRecord)
Definition: step2vpl.cpp:272
short verse
Definition: step2vpl.cpp:110
void readSectionLevelInfo(int fd, SectionLevelInfo *sli)
Definition: step2vpl.cpp:429
short setID
Definition: step2vpl.cpp:59
short bookPointerEntriesSize
Definition: step2vpl.cpp:91
short viewableHeaderRecordSize
Definition: step2vpl.cpp:78
void readHeaderControlWordAreaText(int fd, char **buf)
Definition: step2vpl.cpp:332
short endBookNumber
Definition: step2vpl.cpp:90
void readVSyncHeader(int fd, VSyncHeader *vSyncHeaderRecord)
Definition: step2vpl.cpp:292