aboutsummaryrefslogtreecommitdiffstats
path: root/utilities/step2vpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utilities/step2vpl.cpp')
-rw-r--r--utilities/step2vpl.cpp419
1 files changed, 419 insertions, 0 deletions
diff --git a/utilities/step2vpl.cpp b/utilities/step2vpl.cpp
new file mode 100644
index 0000000..6065257
--- /dev/null
+++ b/utilities/step2vpl.cpp
@@ -0,0 +1,419 @@
+#include <iostream>
+#include <string>
+#include <stdio.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <lzsscomprs.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+using namespace std;
+
+long SECTIONSLEVELSTART = 38;
+long SECTIONSLEVELSIZE = 29;
+
+long VIEWABLEBLOCKSTART = 0;
+long VIEWABLEBLOCKSIZE = 0;
+
+typedef struct {
+ short versionRecordSize;
+ short publisherID;
+ short bookID;
+ short setID;
+ char conversionProgramVerMajor;
+ char conversionProgramVerMinor;
+ char leastCompatSTEPVerMajor;
+ char leastCompatSTEPVerMinor;
+ char encryptionType;
+ char editionID;
+ short modifiedBy;
+} Version;
+
+typedef struct {
+ short sectionsHeaderRecordSize;
+ long levelEntriesCount; // this is listed as nonGlossBlocksCount in spec!
+ long glossEntriesCount;
+ short levelEntriesSize;
+ long reserved;
+} SectionsHeader;
+
+typedef struct {
+ short viewableHeaderRecordSize;
+ long viewableBlocksCount; // this is listed as nonGlossBlocksCount in spec!
+ long glossBlocksCount;
+ char compressionType; // 0 - none; 1 - LZSS
+ char reserved1;
+ short blockEntriesSize;
+ short reserved2;
+} ViewableHeader;
+
+typedef struct {
+ short vSyncHeaderRecordSize;
+ short startBookNumber;
+ short endBookNumber;
+ short bookPointerEntriesSize;
+ short syncPointEntriesSize;
+ long reserved1_1;
+ short reserved1_2;
+} VSyncHeader;
+
+typedef struct {
+ long offset;
+ long uncompressedSize;
+ long size;
+} ViewableBlock;
+
+typedef struct {
+ long offset; // offset into VSYNC.IDX to first VSyncPoint
+ short count; // number of VSyncPoints for this book
+} VSyncBooksInfo;
+
+typedef struct {
+ short chapter;
+ short verse;
+ long offset; // offset into SECTIONS.IDX
+} VSyncPoint;
+
+typedef struct {
+ long parentOffset; // many of these are 0 if glossary
+ long previousOffset;
+ long nextOffset;
+ long viewableOffset;
+ short startLevel;
+ char level;
+ long nameOffset;
+ long outSync_1;
+ short outSync_2;
+} SectionLevelInfo;
+
+void readVersion(int fd, Version *versionRecord);
+void readHeaderControlWordAreaText(int fd, char **buf);
+void readViewableHeader(int fd, ViewableHeader *viewableHeaderRecord);
+void readVSyncHeader(int fd, VSyncHeader *vSyncHeaderRecord);
+void readVSyncBooksInfo(int fd, VSyncHeader *, VSyncBooksInfo **vSyncBooksInfo);
+void readViewableBlock(int fd, ViewableBlock *vb);
+void readViewableBlockText(int fd, ViewableBlock *vb, char **buf);
+void readSectionsHeader(int fd, SectionsHeader *sectionsHeaderRecord);
+void readSectionLevelInfo(int fd, SectionLevelInfo *sli);
+void readSectionName(int fd, SectionLevelInfo *sli, char **name);
+void displayBook(int fdbook, int fdviewable, int fdvsync, int fdsections, VSyncBooksInfo *vSyncBooksInfo);
+void extractVerseText(int fdviewable, int fdbook, SectionLevelInfo *sectionLevelInfo, char **verseText);
+void cleanBuf(char *buf);
+
+SWCompress *compress = 0;
+
+int main(int argc, char **argv) {
+
+ compress = new LZSSCompress();
+ char *buf;
+ Version versionRecord;
+ VSyncHeader vSyncHeaderRecord;
+ VSyncBooksInfo *vSyncBooksInfo;
+ SectionsHeader sectionsHeaderRecord;
+ ViewableHeader viewableHeaderRecord;
+
+
+ if (argc < 2) {
+ cerr << "usage: "<< *argv << " <database to step module>\n";
+ exit (-1);
+ }
+
+ string bookpath = argv[1];
+ string fileName;
+
+ if ((argv[1][strlen(argv[1])-1] != '/') &&
+ (argv[1][strlen(argv[1])-1] != '\\'))
+ bookpath += "/";
+
+ fileName = bookpath + "Book.dat";
+ int fdbook = open(fileName.c_str(), O_RDONLY|O_BINARY);
+
+ if (fdbook < 1) {
+ cerr << "error, couldn't open file: " << fileName << "\n";
+ exit (-2);
+ }
+
+ readVersion(fdbook, &versionRecord);
+ readHeaderControlWordAreaText(fdbook, &buf);
+ delete [] buf;
+
+
+ fileName = bookpath + "Viewable.idx";
+ int fdviewable = open(fileName.c_str(), O_RDONLY|O_BINARY);
+
+ if (fdviewable < 1) {
+ cerr << "error, couldn't open file: " << fileName << "\n";
+ exit (-3);
+ }
+
+ readVersion(fdviewable, &versionRecord);
+ readViewableHeader(fdviewable, &viewableHeaderRecord);
+
+ VIEWABLEBLOCKSTART = lseek(fdviewable, 0, SEEK_CUR);
+ VIEWABLEBLOCKSIZE = viewableHeaderRecord.blockEntriesSize;
+
+
+ fileName = bookpath + "Vsync.idx";
+ int fdvsync = open(fileName.c_str(), O_RDONLY|O_BINARY);
+
+ if (fdvsync < 1) {
+ cerr << "error, couldn't open file: " << fileName << "\n";
+ exit (-4);
+ }
+
+ fileName = bookpath + "Sections.idx";
+ int fdsections = open(fileName.c_str(), O_RDONLY|O_BINARY);
+
+ if (fdsections < 1) {
+ cerr << "error, couldn't open file: " << fileName << "\n";
+ exit (-4);
+ }
+ readVersion(fdsections, &versionRecord);
+ readSectionsHeader(fdsections, &sectionsHeaderRecord);
+ SECTIONSLEVELSTART = lseek(fdsections, 0, SEEK_CUR);
+ SECTIONSLEVELSIZE = sectionsHeaderRecord.levelEntriesSize;
+
+ readVersion(fdvsync, &versionRecord);
+ readVSyncHeader(fdvsync, &vSyncHeaderRecord);
+ readVSyncBooksInfo(fdvsync, &vSyncHeaderRecord, &vSyncBooksInfo);
+ int bookCount = vSyncHeaderRecord.endBookNumber - vSyncHeaderRecord.startBookNumber;
+ for (int i = 0; i <= bookCount; i++) {
+ displayBook(fdbook, fdviewable, fdvsync, fdsections, &vSyncBooksInfo[i]);
+ }
+
+ close(fdviewable);
+ close(fdvsync);
+ close(fdsections);
+ close(fdbook);
+
+}
+
+
+
+void readVersion(int fd, Version *versionRecord) {
+
+ read(fd, &(versionRecord->versionRecordSize), 2);
+ read(fd, &(versionRecord->publisherID), 2);
+ read(fd, &(versionRecord->bookID), 2);
+ read(fd, &(versionRecord->setID), 2);
+ read(fd, &(versionRecord->conversionProgramVerMajor), 1);
+ read(fd, &(versionRecord->conversionProgramVerMinor), 1);
+ read(fd, &(versionRecord->leastCompatSTEPVerMajor), 1);
+ read(fd, &(versionRecord->leastCompatSTEPVerMinor), 1);
+ read(fd, &(versionRecord->encryptionType), 1);
+ read(fd, &(versionRecord->editionID), 1);
+ read(fd, &(versionRecord->modifiedBy), 2);
+
+ int skip = versionRecord->versionRecordSize - 16/*sizeof(struct Version*/;
+
+ if (skip) {
+ char skipbuf[skip];
+ read(fd, skipbuf, skip);
+ }
+}
+
+
+void readSectionsHeader(int fd, SectionsHeader *sectionsHeaderRecord) {
+
+ read(fd, &(sectionsHeaderRecord->sectionsHeaderRecordSize), 2);
+ read(fd, &(sectionsHeaderRecord->levelEntriesCount), 4);
+ read(fd, &(sectionsHeaderRecord->glossEntriesCount), 4);
+ read(fd, &(sectionsHeaderRecord->levelEntriesSize), 2);
+ read(fd, &(sectionsHeaderRecord->reserved), 4);
+
+ int skip = sectionsHeaderRecord->sectionsHeaderRecordSize - 16/*sizeof(struct ViewableHeader)*/;
+
+ if (skip) {
+ char skipbuf[skip];
+ read(fd, skipbuf, skip);
+ }
+}
+
+
+void readViewableHeader(int fd, ViewableHeader *viewableHeaderRecord) {
+
+ read(fd, &(viewableHeaderRecord->viewableHeaderRecordSize), 2);
+ read(fd, &(viewableHeaderRecord->viewableBlocksCount), 4);
+ read(fd, &(viewableHeaderRecord->glossBlocksCount), 4);
+ read(fd, &(viewableHeaderRecord->compressionType), 1);
+ read(fd, &(viewableHeaderRecord->reserved1), 1);
+ read(fd, &(viewableHeaderRecord->blockEntriesSize), 2);
+ read(fd, &(viewableHeaderRecord->reserved2), 2);
+
+ int skip = viewableHeaderRecord->viewableHeaderRecordSize - 16/*sizeof(struct ViewableHeader)*/;
+
+ if (skip) {
+ char skipbuf[skip];
+ read(fd, skipbuf, skip);
+ }
+}
+
+
+void readVSyncHeader(int fd, VSyncHeader *vSyncHeaderRecord) {
+
+ read(fd, &(vSyncHeaderRecord->vSyncHeaderRecordSize), 2);
+ read(fd, &(vSyncHeaderRecord->startBookNumber), 2);
+ read(fd, &(vSyncHeaderRecord->endBookNumber), 2);
+ read(fd, &(vSyncHeaderRecord->bookPointerEntriesSize), 2);
+ read(fd, &(vSyncHeaderRecord->syncPointEntriesSize), 2);
+ read(fd, &(vSyncHeaderRecord->reserved1_1), 4);
+ read(fd, &(vSyncHeaderRecord->reserved1_2), 2);
+
+ int skip = vSyncHeaderRecord->vSyncHeaderRecordSize - 16/*sizeof(VSyncHeader)*/;
+
+ if (skip) {
+ char skipbuf[skip];
+ read(fd, skipbuf, skip);
+ }
+}
+
+
+void readViewableBlockText(int fd, ViewableBlock *vb, char **buf) {
+ unsigned long size = vb->size;
+
+ *buf = new char [ ((vb->size > vb->uncompressedSize) ? vb->size : vb->uncompressedSize) + 1 ];
+ lseek(fd, vb->offset, SEEK_SET);
+ read(fd, *buf, vb->size);
+
+ compress->zBuf(&size, *buf);
+ strcpy(*buf, compress->Buf());
+}
+
+
+void readViewableBlock(int fd, ViewableBlock *vb) {
+
+ read(fd, &(vb->offset), 4);
+ read(fd, &(vb->uncompressedSize), 4);
+ read(fd, &(vb->size), 4);
+}
+
+
+void readHeaderControlWordAreaText(int fd, char **buf) {
+ long headerControlWordAreaSize;
+ read(fd, &headerControlWordAreaSize, 4);
+
+ *buf = new char [headerControlWordAreaSize + 1];
+
+ read(fd, *buf, headerControlWordAreaSize);
+ (*buf)[headerControlWordAreaSize] = 0;
+
+}
+
+void readVSyncBooksInfo(int fd, VSyncHeader *vSyncHeaderRecord, VSyncBooksInfo **vSyncBooksInfo) {
+
+ int bookCount = vSyncHeaderRecord->endBookNumber - vSyncHeaderRecord->startBookNumber;
+ *vSyncBooksInfo = new VSyncBooksInfo[bookCount];
+ for (int i = 0; i <= bookCount; i++) {
+ read(fd, &(*vSyncBooksInfo)[i].offset, 4);
+ read(fd, &(*vSyncBooksInfo)[i].count, 2);
+ }
+}
+
+void displayBook(int fdbook, int fdviewable, int fdvsync, int fdsections, VSyncBooksInfo *vSyncBooksInfo) {
+ VSyncPoint vSyncPoint;
+
+ lseek(fdvsync, vSyncBooksInfo->offset, SEEK_SET);
+
+ for (int i = 0; i < vSyncBooksInfo->count; i++) {
+
+ SectionLevelInfo sectionLevelInfo;
+ char *sectionName;
+ char *verseText;
+
+ read(fdvsync, &(vSyncPoint.chapter), 2);
+ read(fdvsync, &(vSyncPoint.verse), 2);
+ read(fdvsync, &(vSyncPoint.offset), 4);
+ vSyncPoint.offset = SECTIONSLEVELSTART + (vSyncPoint.offset * SECTIONSLEVELSIZE);
+ lseek(fdsections, vSyncPoint.offset, SEEK_SET);
+ readSectionLevelInfo(fdsections, &sectionLevelInfo);
+ readSectionName(fdsections, &sectionLevelInfo, &sectionName);
+ cout << sectionName << " ";
+ delete [] sectionName;
+ extractVerseText(fdviewable, fdbook, &sectionLevelInfo, &verseText);
+ cleanBuf(verseText);
+ cout << verseText << "\n";
+ delete [] verseText;
+ }
+}
+
+
+void extractVerseText(int fdviewable, int fdbook, SectionLevelInfo *sectionLevelInfo, char **verseText) {
+ char numberBuf[16];
+ string startToken;
+ ViewableBlock vb;
+ int len = 0;
+ static long lastEntryOffset = -1;
+ static class FreeCachedEntryText {
+ public:
+ char *entryText;
+ FreeCachedEntryText() { entryText = 0; }
+ ~FreeCachedEntryText() { if (entryText) delete [] entryText; }
+ } _freeCachedEntryText;
+
+ if (sectionLevelInfo->viewableOffset != lastEntryOffset) {
+ if (_freeCachedEntryText.entryText)
+ delete [] _freeCachedEntryText.entryText;
+
+ lseek(fdviewable, sectionLevelInfo->viewableOffset, SEEK_SET);
+ readViewableBlock(fdviewable, &vb);
+ readViewableBlockText(fdbook, &vb, &(_freeCachedEntryText.entryText));
+ lastEntryOffset = sectionLevelInfo->viewableOffset;
+ }
+ sprintf(numberBuf, "%d", sectionLevelInfo->startLevel);
+ startToken = "\\stepstartlevel";
+ startToken += numberBuf;
+ char *start = strstr(_freeCachedEntryText.entryText, startToken.c_str());
+ if (start) {
+ start += strlen(startToken.c_str());
+ char *end = strstr(start, "\\stepstartlevel");
+ if (end)
+ len = end - start;
+ else len = strlen(start);
+ }
+ *verseText = new char [ len + 1 ];
+ strncpy(*verseText, start, len);
+ (*verseText)[len] = 0;
+}
+
+
+void readSectionName(int fd, SectionLevelInfo *sli, char **name) {
+ short size;
+ lseek(fd, sli->nameOffset, SEEK_SET);
+ read(fd, &size, 2);
+ *name = new char [ size + 1 ];
+ read(fd, *name, size);
+ (*name)[size] = 0;
+}
+
+void readSectionLevelInfo(int fd, SectionLevelInfo *sli) {
+
+ read(fd, &(sli->parentOffset), 4);
+ read(fd, &(sli->previousOffset), 4);
+ read(fd, &(sli->nextOffset), 4);
+ read(fd, &(sli->viewableOffset), 4);
+ sli->viewableOffset = VIEWABLEBLOCKSTART + (VIEWABLEBLOCKSIZE * sli->viewableOffset);
+ read(fd, &(sli->startLevel), 2);
+ read(fd, &(sli->level), 1);
+ read(fd, &(sli->nameOffset), 4);
+ read(fd, &(sli->outSync_1), 4);
+ read(fd, &(sli->outSync_2), 2);
+}
+
+void cleanBuf(char *buf) {
+ char *from = buf;
+ char *to = buf;
+
+ while (*from) {
+ if ((*from != 10) && (*from != 13)) {
+ *to++ = *from++;
+ }
+ else {
+ from++;
+ }
+ }
+ *to = 0;
+}