[sword-svn] r3138 - in trunk: . cmake include lib/vcppmake src/mgr src/modules/comments src/modules/comments/zcom4 src/modules/common src/modules/texts src/modules/texts/ztext4

chrislit at crosswire.org chrislit at crosswire.org
Mon Mar 17 03:10:26 MST 2014


Author: chrislit
Date: 2014-03-17 03:10:26 -0700 (Mon, 17 Mar 2014)
New Revision: 3138

Added:
   trunk/include/zcom4.h
   trunk/include/ztext4.h
   trunk/include/zverse4.h
   trunk/src/modules/comments/zcom4/
   trunk/src/modules/comments/zcom4/Makefile
   trunk/src/modules/comments/zcom4/Makefile.am
   trunk/src/modules/comments/zcom4/zcom4.cpp
   trunk/src/modules/common/zverse4.cpp
   trunk/src/modules/texts/ztext4/
   trunk/src/modules/texts/ztext4/Makefile
   trunk/src/modules/texts/ztext4/Makefile.am
   trunk/src/modules/texts/ztext4/ztext4.cpp
Modified:
   trunk/ChangeLog
   trunk/cmake/sources.cmake
   trunk/include/Makefile.am
   trunk/lib/vcppmake/libsword.vcxproj
   trunk/src/mgr/swmgr.cpp
   trunk/src/modules/comments/Makefile.am
   trunk/src/modules/common/Makefile.am
   trunk/src/modules/texts/Makefile.am
Log:
added zVerse4, zText4, & zCom4 classes (may still be a bit rough)


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/ChangeLog	2014-03-17 10:10:26 UTC (rev 3138)
@@ -1,5 +1,9 @@
 API ChangeLog
 
+17-Mar-2014	Chris Little <chrislit at crosswire.org>
+	Added zVerse4, zText4, & zCom4 classes to support compressed text/
+		commentary modules with entry sizes > 64k
+
 3-Mar-2014	Chris Little <chrislit at crosswire.org>
 	Added support for bzip2 (Burrows-Wheeler) module compression via libbz2
 	Added support for xz (LZMA2) module compression via liblzma

Modified: trunk/cmake/sources.cmake
===================================================================
--- trunk/cmake/sources.cmake	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/cmake/sources.cmake	2014-03-17 10:10:26 UTC (rev 3138)
@@ -48,6 +48,7 @@
 	src/modules/comments/rawcom4/rawcom4.cpp
 	src/modules/comments/rawfiles/rawfiles.cpp
 	src/modules/comments/zcom/zcom.cpp
+	src/modules/comments/zcom4/zcom4.cpp
 	src/modules/common/rawstr.cpp
 	src/modules/common/rawstr4.cpp
 	src/modules/common/swcomprs.cpp
@@ -56,6 +57,7 @@
 	src/modules/common/rawverse4.cpp
 	src/modules/common/swcipher.cpp
 	src/modules/common/zverse.cpp
+	src/modules/common/zverse4.cpp
 	src/modules/common/zstr.cpp
 	src/modules/common/entriesblk.cpp
 	src/modules/common/sapphire.cpp
@@ -158,6 +160,7 @@
 	src/modules/texts/rawtext/rawtext.cpp
 	src/modules/texts/rawtext4/rawtext4.cpp
 	src/modules/texts/ztext/ztext.cpp
+	src/modules/texts/ztext4/ztext4.cpp
 )
 SOURCE_GROUP("src\\modules" FILES ${sword_base_module_SOURCES})
 
@@ -414,12 +417,15 @@
 	include/versetreekey.h
 	include/xzcomprs.h
 	include/zcom.h
+	include/zcom4.h
 	include/zconf.h
 	include/zipcomprs.h
 	include/zld.h
 	include/zstr.h
 	include/ztext.h
+	include/ztext4.h
 	include/zverse.h
+	include/zverse4.h
 
 	include/canon_kjva.h
 	include/canon_leningrad.h

Modified: trunk/include/Makefile.am
===================================================================
--- trunk/include/Makefile.am	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/include/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -165,13 +165,16 @@
 pkginclude_HEADERS += $(swincludedir)/versekey.h
 pkginclude_HEADERS += $(swincludedir)/versetreekey.h
 pkginclude_HEADERS += $(swincludedir)/zcom.h
+pkginclude_HEADERS += $(swincludedir)/zcom4.h
 pkginclude_HEADERS += $(swincludedir)/zipcomprs.h
 pkginclude_HEADERS += $(swincludedir)/bz2comprs.h
 pkginclude_HEADERS += $(swincludedir)/xzcomprs.h
 pkginclude_HEADERS += $(swincludedir)/zld.h
 pkginclude_HEADERS += $(swincludedir)/zstr.h
 pkginclude_HEADERS += $(swincludedir)/ztext.h
+pkginclude_HEADERS += $(swincludedir)/ztext4.h
 pkginclude_HEADERS += $(swincludedir)/zverse.h
+pkginclude_HEADERS += $(swincludedir)/zverse4.h
 
 pkginclude_HEADERS += $(swincludedir)/canon_kjva.h
 pkginclude_HEADERS += $(swincludedir)/canon_leningrad.h

Added: trunk/include/zcom4.h
===================================================================
--- trunk/include/zcom4.h	                        (rev 0)
+++ trunk/include/zcom4.h	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ *  zcom4.h - 	code for class 'zCom4'- a module that reads compressed text
+ *     	       	files: ot and nt using indexs ??.vss
+ *
+ * $Id: zcom4.h 2833 2013-06-29 06:40:28Z chrislit $
+ *
+ * Copyright 1996-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef ZCOM4_H
+#define ZCOM4_H
+
+#include <swcom.h>
+
+#include <defs.h>
+
+SWORD_NAMESPACE_START
+
+class SWDLLEXPORT zCom4 : public zVerse4, public SWCom {
+
+	VerseKey *lastWriteKey;
+	bool sameBlock(VerseKey * lastWriteKey, VerseKey * key);
+	int blockType;
+
+
+public:
+
+	zCom4(const char *ipath, const char *iname = 0, const char *idesc = 0,
+			int blockType = CHAPTERBLOCKS, SWCompress *icomp = 0,
+			SWDisplay *idisp = 0, SWTextEncoding encoding = ENC_UNKNOWN,
+			SWTextDirection dir = DIRECTION_LTR,
+			SWTextMarkup markup = FMT_UNKNOWN, const char *ilang = 0,
+			const char *versification = "KJV");
+	virtual ~zCom4();
+	virtual SWBuf &getRawEntryBuf() const;
+	virtual void increment(int steps = 1);
+	virtual void decrement(int steps = 1) { increment(-steps); }
+
+	// write interface ----------------------------
+	virtual bool isWritable() const;
+	static char createModule(const char *path, int blockBound, const char *v11n = "KJV") {
+		return zVerse4::createModule(path, blockBound, v11n);
+	}
+	virtual void setEntry(const char *inbuf, long len = -1);	// Modify current module entry
+	virtual void linkEntry(const SWKey * linkKey);	// Link current module entry to other module entry
+	virtual void deleteEntry();	// Delete current module entry
+	// end write interface ------------------------
+
+	virtual void rawZFilter(SWBuf &buf, char direction = 0) const { rawFilter(buf, (SWKey *)(long)direction); }// hack, use key as direction for enciphering
+
+	// swcacher interface ----------------------
+	virtual void flush() { flushCache(); }
+	// end swcacher interface ----------------------
+
+	virtual bool isLinked(const SWKey *k1, const SWKey *k2) const;
+	virtual bool hasEntry(const SWKey *k) const;
+	
+	SWMODULE_OPERATORS
+
+};
+
+SWORD_NAMESPACE_END
+
+#endif

Added: trunk/include/ztext4.h
===================================================================
--- trunk/include/ztext4.h	                        (rev 0)
+++ trunk/include/ztext4.h	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,90 @@
+/******************************************************************************
+ *
+ *  ztext4.h -	code for class 'zText4'- a module that reads compressed text
+ *		files: ot and nt using indexs ??.vss
+ *
+ * $Id: ztext4.h 3126 2014-03-14 11:59:36Z chrislit $
+ *
+ * Copyright 1996-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef ZTEXT4_H
+#define ZTEXT4_H
+
+#include <zverse4.h>
+#include <swtext.h>
+
+#include <defs.h>
+
+namespace lucene { namespace index {
+class IndexReader;
+}}
+
+namespace lucene { namespace search {
+class IndexSearcher;
+}}
+
+SWORD_NAMESPACE_START
+
+/*** SWModule implementation for compressed modules
+* This class handles compressed modules.
+* It should not be used in frontends, unless you are doing very special things.
+*/
+class SWDLLEXPORT zText4:public zVerse4, public SWText {
+
+	VerseKey *lastWriteKey;
+	bool sameBlock(VerseKey * lastWriteKey, VerseKey * key);
+	int blockType;
+
+public:
+	zText4(const char *ipath, const char *iname = 0, const char *idesc = 0,
+			int blockType = CHAPTERBLOCKS, SWCompress *icomp = 0,
+			SWDisplay *idisp = 0, SWTextEncoding encoding = ENC_UNKNOWN,
+			SWTextDirection dir = DIRECTION_LTR,
+			SWTextMarkup markup = FMT_UNKNOWN, const char *ilang = 0,
+			const char *versification = "KJV");
+
+	virtual ~zText4();
+	virtual SWBuf &getRawEntryBuf() const;
+
+	virtual void increment(int steps = 1);
+	virtual void decrement(int steps = 1) { increment(-steps); }
+
+	// write interface ----------------------------
+	virtual bool isWritable() const;
+	static char createModule(const char *path, int blockBound, const char *v11n = "KJV") {
+		return zVerse4::createModule(path, blockBound, v11n);
+	}
+
+	virtual void setEntry(const char *inbuf, long len = -1);	// Modify current module entry
+	virtual void linkEntry(const SWKey *linkKey);	// Link current module entry to other module entry
+	virtual void deleteEntry();	// Delete current module entry
+	// end write interface ------------------------
+  
+	virtual void rawZFilter(SWBuf &buf, char direction = 0) const { rawFilter(buf, (SWKey *)(long)direction); }// hack, use key as direction for enciphering
+
+	// swcacher interface ----------------------
+	virtual void flush() { flushCache(); }
+	// end swcacher interface ----------------------
+
+	virtual bool isLinked(const SWKey *k1, const SWKey *k2) const;
+	virtual bool hasEntry(const SWKey *k) const;
+	
+	SWMODULE_OPERATORS
+};
+
+SWORD_NAMESPACE_END
+#endif

Added: trunk/include/zverse4.h
===================================================================
--- trunk/include/zverse4.h	                        (rev 0)
+++ trunk/include/zverse4.h	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ *  zverse4.h -		code for class 'zVerse4'- a module that reads raw text
+ *			files:  ot and nt using indexs ??.bks ??.cps ??.vss
+ *			and provides lookup and parsing functions based on
+ *			class VerseKey
+ *
+ * $Id: zverse4.h 2833 2013-06-29 06:40:28Z chrislit $
+ *
+ * Copyright 2000-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+
+#ifndef ZVERSE4_H
+#define ZVERSE4_H
+
+#include <defs.h>
+
+SWORD_NAMESPACE_START
+
+class FileDesc;
+class SWCompress;
+class SWBuf;
+
+class SWDLLEXPORT zVerse4 {
+	SWCompress *compressor;
+
+protected:
+	static int instance;		// number of instantiated zVerse4 objects or derivitives
+
+	FileDesc *idxfp[2];
+	FileDesc *textfp[2];
+	FileDesc *compfp[2];
+	char *path;
+	void doSetText(char testmt, long idxoff, const char *buf, long len = 0);
+	void doLinkEntry(char testmt, long destidxoff, long srcidxoff);
+	void flushCache() const;
+	mutable char *cacheBuf;
+	mutable unsigned int cacheBufSize;
+	mutable char cacheTestament;
+	mutable long cacheBufIdx;
+	mutable bool dirtyCache;
+
+public:
+
+#define	VERSEBLOCKS 2
+#define	CHAPTERBLOCKS 3
+#define	BOOKBLOCKS 4
+
+	static const char uniqueIndexID[];
+
+
+	// fileMode default = RDONLY
+	zVerse4(const char *ipath, int fileMode = -1, int blockType = CHAPTERBLOCKS, SWCompress * icomp = 0);
+	virtual ~zVerse4();
+
+	void findOffset(char testmt, long idxoff, long *start, unsigned long *size, unsigned long *buffnum) const;
+	void zReadText(char testmt, long start, unsigned long size, unsigned long buffnum, SWBuf &buf) const;
+	virtual void rawZFilter(SWBuf &buf, char direction = 0) const { (void) buf; (void) direction; }
+	static char createModule(const char *path, int blockBound, const char *v11n = "KJV");
+};
+
+SWORD_NAMESPACE_END
+#endif

Modified: trunk/lib/vcppmake/libsword.vcxproj
===================================================================
--- trunk/lib/vcppmake/libsword.vcxproj	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/lib/vcppmake/libsword.vcxproj	2014-03-17 10:10:26 UTC (rev 3138)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -290,13 +290,16 @@
     <ClCompile Include="..\..\src\keys\versekey.cpp" />
     <ClCompile Include="..\..\src\keys\versetreekey.cpp" />
     <ClCompile Include="..\..\src\modules\comments\zcom\zcom.cpp" />
+    <ClCompile Include="..\..\src\modules\comments\zcom4\zcom4.cpp" />
     <ClCompile Include="..\..\src\modules\common\zipcomprs.cpp" />
     <ClCompile Include="..\..\src\modules\common\bz2comprs.cpp" />
     <ClCompile Include="..\..\src\modules\common\xzcomprs.cpp" />
     <ClCompile Include="..\..\src\modules\lexdict\zld\zld.cpp" />
     <ClCompile Include="..\..\src\modules\common\zstr.cpp" />
     <ClCompile Include="..\..\src\modules\texts\ztext\ztext.cpp" />
+    <ClCompile Include="..\..\src\modules\texts\ztext4\ztext4.cpp" />
     <ClCompile Include="..\..\src\modules\common\zverse.cpp" />
+    <ClCompile Include="..\..\src\modules\common\zverse4.cpp" />
     <ClCompile Include="..\..\src\utilfuns\zlib\zutil.c" />
   </ItemGroup>
   <ItemGroup>
@@ -465,6 +468,7 @@
     <ClInclude Include="..\..\include\versetreekey.h" />
     <ClInclude Include="..\..\include\versificationmgr.h" />
     <ClInclude Include="..\..\include\zcom.h" />
+    <ClInclude Include="..\..\include\zcom4.h" />
     <ClInclude Include="..\..\include\zconf.h" />
     <ClInclude Include="..\..\include\zipcomprs.h" />
     <ClInclude Include="..\..\include\bz2comprs.h" />
@@ -473,7 +477,9 @@
     <ClInclude Include="..\..\include\zlib.h" />
     <ClInclude Include="..\..\include\zstr.h" />
     <ClInclude Include="..\..\include\ztext.h" />
+    <ClInclude Include="..\..\include\ztext4.h" />
     <ClInclude Include="..\..\include\zverse.h" />
+    <ClInclude Include="..\..\include\zverse4.h" />
     <ClInclude Include="..\..\src\utilfuns\zlib\crc32.h" />
     <ClInclude Include="..\..\src\utilfuns\zlib\deflate.h" />
     <ClInclude Include="..\..\src\utilfuns\zlib\gzguts.h" />
@@ -489,4 +495,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>

Modified: trunk/src/mgr/swmgr.cpp
===================================================================
--- trunk/src/mgr/swmgr.cpp	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/src/mgr/swmgr.cpp	2014-03-17 10:10:26 UTC (rev 3138)
@@ -74,8 +74,10 @@
 #include <cipherfil.h>
 #include <rawfiles.h>
 #include <ztext.h>
+#include <ztext4.h>
 #include <zld.h>
 #include <zcom.h>
+#include <zcom4.h>
 #include <lzsscomprs.h>
 #include <utf8greekaccents.h>
 #include <utf8cantillation.h>
@@ -940,7 +942,7 @@
 		direction = DIRECTION_LTR;
 	}
 
-	if ((!stricmp(driver, "zText")) || (!stricmp(driver, "zCom"))) {
+	if ((!stricmp(driver, "zText")) || (!stricmp(driver, "zCom")) || (!stricmp(driver, "zText4")) || (!stricmp(driver, "zCom4"))) {
 		SWCompress *compress = 0;
 		int blockType = CHAPTERBLOCKS;
 		misc1 = ((entry = section.find("BlockType")) != section.end()) ? (*entry).second : (SWBuf)"CHAPTER";
@@ -973,6 +975,10 @@
 		if (compress) {
 			if (!stricmp(driver, "zText"))
 				newmod = new zText(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
+			else if (!stricmp(driver, "zText4"))
+				newmod = new zText4(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
+			else if (!stricmp(driver, "zCom4"))
+				newmod = new zCom4(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
 			else
 				newmod = new zCom(datapath.c_str(), name, description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str(), versification);
 		}

Modified: trunk/src/modules/comments/Makefile.am
===================================================================
--- trunk/src/modules/comments/Makefile.am	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/src/modules/comments/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -6,4 +6,5 @@
 include ../src/modules/comments/rawcom4/Makefile.am
 include ../src/modules/comments/rawfiles/Makefile.am
 include ../src/modules/comments/zcom/Makefile.am
+include ../src/modules/comments/zcom4/Makefile.am
 include ../src/modules/comments/hrefcom/Makefile.am

Added: trunk/src/modules/comments/zcom4/Makefile
===================================================================
--- trunk/src/modules/comments/zcom4/Makefile	                        (rev 0)
+++ trunk/src/modules/comments/zcom4/Makefile	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,5 @@
+
+root := ../../../..
+
+all:
+	make -C ${root}

Added: trunk/src/modules/comments/zcom4/Makefile.am
===================================================================
--- trunk/src/modules/comments/zcom4/Makefile.am	                        (rev 0)
+++ trunk/src/modules/comments/zcom4/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,2 @@
+zcom4dir = $(top_srcdir)/src/modules/comments/zcom4
+libsword_la_SOURCES += $(zcom4dir)/zcom4.cpp

Added: trunk/src/modules/comments/zcom4/zcom4.cpp
===================================================================
--- trunk/src/modules/comments/zcom4/zcom4.cpp	                        (rev 0)
+++ trunk/src/modules/comments/zcom4/zcom4.cpp	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ *  zcom4.cpp -	code for class 'zCom4'- a module that reads compressed
+ *		commentary files
+ *
+ * $Id: zcom4.cpp 3073 2014-03-05 00:27:52Z scribe $
+ *
+ * Copyright 1996-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <swbuf.h>
+#include <zverse4.h>
+#include <versekey.h>
+#include <zcom4.h>
+#include <filemgr.h>
+
+SWORD_NAMESPACE_START
+
+/******************************************************************************
+ * zCom4 Constructor - Initializes data for instance of zCom4
+ *
+ * ENT:	ipath - path to data files
+ *		iname - Internal name for module
+ *		idesc - Name to display to user for module
+ *		iblockType - verse, chapter, book, etc. of index chunks
+ *		icomp - Compressor object
+ *		idisp - Display object to use for displaying
+ */
+
+zCom4::zCom4(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) : zVerse4(ipath, -1, iblockType, icomp), SWCom(iname, idesc, idisp, enc, dir, mark, ilang, versification)/*, SWCompress()*/
+{
+	blockType = iblockType;
+	lastWriteKey = 0;
+}
+
+/******************************************************************************
+ * zCom4 Destructor - Cleans up instance of zCom4
+ */
+
+zCom4::~zCom4() {
+	flushCache();
+
+	if (lastWriteKey)
+		delete lastWriteKey;
+}
+
+
+bool zCom4::isWritable() const {
+	return ((idxfp[0]->getFd() > 0) && ((idxfp[0]->mode & FileMgr::RDWR) == FileMgr::RDWR));
+}
+
+
+/******************************************************************************
+ * zCom4::getRawEntry	- Returns the current verse buffer
+ *
+ * RET: buffer with verse
+ */
+
+SWBuf &zCom4::getRawEntryBuf() const {
+	long  start = 0;
+	unsigned long size = 0;
+	unsigned long buffnum = 0;
+	VerseKey &key = getVerseKey();
+
+	findOffset(key.getTestament(), key.getTestamentIndex(), &start, &size, &buffnum);
+	entrySize = size;        // support getEntrySize call
+			  
+	entryBuf = "";
+	
+	zReadText(key.getTestament(), start, size, buffnum, entryBuf);
+	rawFilter(entryBuf, &key);
+
+//	if (!isUnicode())
+		prepText(entryBuf);
+
+	return entryBuf;
+}
+
+
+bool zCom4::sameBlock(VerseKey *k1, VerseKey *k2) {
+	if (k1->getTestament() != k2->getTestament())
+		return false;
+
+	switch (blockType) {
+	case VERSEBLOCKS:
+		if (k1->getVerse() != k2->getVerse())
+			return false;
+	case CHAPTERBLOCKS:
+		if (k1->getChapter() != k2->getChapter())
+			return false;
+	case BOOKBLOCKS:
+		if (k1->getBook() != k2->getBook())
+			return false;
+	}
+	return true;
+}
+
+void zCom4::setEntry(const char *inbuf, long len) {
+	VerseKey *key = &getVerseKey();
+
+	// see if we've jumped across blocks since last write
+	if (lastWriteKey) {
+		if (!sameBlock(lastWriteKey, key)) {
+			flushCache();
+		}
+		delete lastWriteKey;
+	}
+
+	doSetText(key->getTestament(), key->getTestamentIndex(), inbuf, len);
+
+	lastWriteKey = (VerseKey *)key->clone();	// must delete
+}
+
+
+void zCom4::linkEntry(const SWKey *inkey) {
+	VerseKey *destkey = &getVerseKey();
+	const VerseKey *srckey = &getVerseKey(inkey);
+
+	doLinkEntry(destkey->getTestament(), destkey->getTestamentIndex(), srckey->getTestamentIndex());
+
+	if (inkey != srckey) // free our key if we created a VerseKey
+		delete srckey;
+}
+
+/******************************************************************************
+ * zCom4::deleteEntry	- deletes this entry
+ *
+ * RET: *this
+ */
+
+void zCom4::deleteEntry() {
+
+	VerseKey *key = &getVerseKey();
+	doSetText(key->getTestament(), key->getTestamentIndex(), "");
+}
+
+
+/******************************************************************************
+ * zCom4::increment	- Increments module key a number of entries
+ *
+ * ENT:	increment	- Number of entries to jump forward
+ *
+ * RET: *this
+ */
+
+void zCom4::increment(int steps) {
+	long  start;
+	unsigned long size;
+	unsigned long buffnum;
+	VerseKey *tmpkey = &getVerseKey();
+
+	findOffset(tmpkey->getTestament(), tmpkey->getTestamentIndex(), &start, &size, &buffnum);
+
+	SWKey lastgood = *tmpkey;
+	while (steps) {
+		long laststart = start;
+		unsigned long lastsize = size;
+		SWKey lasttry = *tmpkey;
+		(steps > 0) ? ++(*key) : --(*key);
+		tmpkey = &getVerseKey();
+
+		if ((error = key->popError())) {
+			*key = lastgood;
+			break;
+		}
+		long index = tmpkey->getTestamentIndex();
+		findOffset(tmpkey->getTestament(), index, &start, &size, &buffnum);
+		if (
+			(((laststart != start) || (lastsize != size))	// we're a different entry
+//				&& (start > 0) 
+				&& (size))	// and we actually have a size
+				||(!skipConsecutiveLinks)) {	// or we don't want to skip consecutive links
+			steps += (steps < 0) ? 1 : -1;
+			lastgood = *tmpkey;
+		}
+	}
+	error = (error) ? KEYERR_OUTOFBOUNDS : 0;
+}
+
+bool zCom4::isLinked(const SWKey *k1, const SWKey *k2) const {
+	long start1, start2;
+	unsigned long size1, size2;
+	unsigned long buffnum1, buffnum2;
+	VerseKey *vk1 = &getVerseKey(k1);
+	VerseKey *vk2 = &getVerseKey(k2);
+	if (vk1->getTestament() != vk2->getTestament()) return false;
+
+	findOffset(vk1->getTestament(), vk1->getTestamentIndex(), &start1, &size1, &buffnum1);
+	findOffset(vk2->getTestament(), vk2->getTestamentIndex(), &start2, &size2, &buffnum2);
+	return start1 == start2 && buffnum1 == buffnum2;
+}
+
+bool zCom4::hasEntry(const SWKey *k) const {
+	long start;
+	unsigned long size;
+	unsigned long buffnum;
+	VerseKey *vk = &getVerseKey(k);
+
+	findOffset(vk->getTestament(), vk->getTestamentIndex(), &start, &size, &buffnum);
+	return size;
+}
+
+SWORD_NAMESPACE_END

Modified: trunk/src/modules/common/Makefile.am
===================================================================
--- trunk/src/modules/common/Makefile.am	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/src/modules/common/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -21,6 +21,7 @@
 libsword_la_SOURCES += $(commondir)/rawverse4.cpp
 libsword_la_SOURCES += $(commondir)/swcipher.cpp
 libsword_la_SOURCES += $(commondir)/zverse.cpp
+libsword_la_SOURCES += $(commondir)/zverse4.cpp
 libsword_la_SOURCES += $(commondir)/zstr.cpp
 libsword_la_SOURCES += $(commondir)/entriesblk.cpp
 libsword_la_SOURCES += $(commondir)/sapphire.cpp

Added: trunk/src/modules/common/zverse4.cpp
===================================================================
--- trunk/src/modules/common/zverse4.cpp	                        (rev 0)
+++ trunk/src/modules/common/zverse4.cpp	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,516 @@
+/******************************************************************************
+ *
+ *  zverse4.cpp -	code for class 'zVerse4'- a module that reads raw text
+ *			files:  ot and nt using indexs ??.bks ??.cps ??.vss
+ *			and provides lookup and parsing functions based on
+ *			class VerseKey for compressed modules
+ *
+ * $Id: zverse4.cpp 3104 2014-03-12 05:37:09Z scribe $
+ *
+ * Copyright 1996-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <utilstr.h>
+#include <versekey.h>
+#include <zverse4.h>
+#include <sysdata.h>
+#include <swbuf.h>
+#include <filemgr.h>
+#include <swcomprs.h>
+
+
+SWORD_NAMESPACE_START
+
+/******************************************************************************
+ * zVerse4 Statics
+ */
+
+int zVerse4::instance = 0;
+
+const char zVerse4::uniqueIndexID[] = {'X', 'r', 'v', 'c', 'b'};
+
+/******************************************************************************
+ * zVerse4 Constructor - Initializes data for instance of zVerse4
+ *
+ * ENT:	ipath - path of the directory where data and index files are located.
+ *		be sure to include the trailing separator (e.g. '/' or '\')
+ *		(e.g. 'modules/texts/rawtext/webster/')
+ *		fileMode - open mode for the files (FileMgr::RDONLY, etc.)
+ *		blockType - verse, chapter, book, etc.
+ */
+
+zVerse4::zVerse4(const char *ipath, int fileMode, int blockType, SWCompress *icomp)
+{
+	// this line, instead of just defaulting, to keep FileMgr out of header
+	if (fileMode == -1) fileMode = FileMgr::RDONLY;
+
+	SWBuf buf;
+
+	path = 0;
+	cacheBufIdx = -1;
+	cacheTestament = 0;
+	cacheBuf = 0;
+	dirtyCache = false;
+	stdstr(&path, ipath);
+
+	if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
+		path[strlen(path)-1] = 0;
+
+	compressor = (icomp) ? icomp : new SWCompress();
+
+	if (fileMode == -1) { // try read/write if possible
+		fileMode = FileMgr::RDWR;
+	}
+		
+	buf.setFormatted("%s/ot.%czs", path, uniqueIndexID[blockType]);
+	idxfp[0] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+
+	buf.setFormatted("%s/nt.%czs", path, uniqueIndexID[blockType]);
+	idxfp[1] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+
+	buf.setFormatted("%s/ot.%czz", path, uniqueIndexID[blockType]);
+	textfp[0] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+
+	buf.setFormatted("%s/nt.%czz", path, uniqueIndexID[blockType]);
+	textfp[1] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+
+	buf.setFormatted("%s/ot.%czv", path, uniqueIndexID[blockType]);
+	compfp[0] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+
+	buf.setFormatted("%s/nt.%czv", path, uniqueIndexID[blockType]);
+	compfp[1] = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
+	
+	instance++;
+}
+
+
+/******************************************************************************
+ * zVerse4 Destructor - Cleans up instance of zVerse4
+ */
+
+zVerse4::~zVerse4()
+{
+	int loop1;
+
+	if (cacheBuf) {
+		flushCache();
+		free(cacheBuf);
+	}
+
+	if (path)
+		delete [] path;
+
+	if (compressor)
+		delete compressor;
+
+	--instance;
+
+	for (loop1 = 0; loop1 < 2; loop1++) {
+		FileMgr::getSystemFileMgr()->close(idxfp[loop1]);
+		FileMgr::getSystemFileMgr()->close(textfp[loop1]);
+		FileMgr::getSystemFileMgr()->close(compfp[loop1]);
+	}
+}
+
+
+/******************************************************************************
+ * zVerse4::findoffset	- Finds the offset of the key verse from the indexes
+ *
+ *
+ *
+ * ENT: testmt	- testament to find (0 - Bible/module introduction)
+ *	book	- book      to find (0 - testament    introduction)
+ *	chapter	- chapter   to find (0 - book         introduction)
+ *	verse	- verse     to find (0 - chapter      introduction)
+ *	start	- address to store the starting offset
+ *	size	- address to store the size of the entry
+ */
+
+void zVerse4::findOffset(char testmt, long idxoff, long *start, unsigned long *size, unsigned long *buffnum) const
+{
+	__u32 ulBuffNum    = 0;	          // buffer number
+	__u32 ulVerseStart = 0;	       // verse offset within buffer
+	__u32 usVerseSize  = 0;	       // verse size
+	// set start to offset in
+	// set size to
+	// set
+	*start = *size = *buffnum = 0;
+	//fprintf(stderr, "Finding offset %ld\n", idxoff);
+	idxoff *= 12; // TODO: Is this the correct size? (throughout)
+	if (!testmt) {
+		testmt = ((idxfp[0]) ? 1:2);
+	}
+	
+	// assert we have and valid file descriptor
+	if (compfp[testmt-1]->getFd() < 1)
+		return;
+		
+	long newOffset = compfp[testmt-1]->seek(idxoff, SEEK_SET);
+	if (newOffset == idxoff) {
+		if (compfp[testmt-1]->read(&ulBuffNum, 4) != 4) {
+			fprintf(stderr, "Error reading ulBuffNum\n");
+			return;
+		}
+	}
+	else return;	
+	
+	if (compfp[testmt-1]->read(&ulVerseStart, 4) < 4)
+	{
+		fprintf(stderr, "Error reading ulVerseStart\n");
+		return;
+	}
+	if (compfp[testmt-1]->read(&usVerseSize, 4) < 4)
+	{
+		fprintf(stderr, "Error reading usVerseSize\n");
+		return;
+	}
+
+	*buffnum = swordtoarch32(ulBuffNum);
+	*start = swordtoarch32(ulVerseStart);
+	*size = swordtoarch32(usVerseSize);
+
+}
+
+
+/******************************************************************************
+ * zVerse4::zreadtext	- gets text at a given offset
+ *
+ * ENT:	testmt	- testament file to search in (0 - Old; 1 - New)
+ *	start	- starting offset where the text is located in the file
+ *	size	- size of text entry + 1 (null)
+ *	buf	- buffer to store text
+ *
+ */
+
+void zVerse4::zReadText(char testmt, long start, unsigned long size, unsigned long ulBuffNum, SWBuf &inBuf) const {
+	__u32 ulCompOffset = 0;	       // compressed buffer start
+	__u32 ulCompSize   = 0;	             // buffer size compressed
+	__u32 ulUnCompSize = 0;	          // buffer size uncompressed
+
+	if (!testmt) {
+		testmt = ((idxfp[0]) ? 1:2);
+	}
+	
+	// assert we have and valid file descriptor
+	if (compfp[testmt-1]->getFd() < 1)
+		return;
+	
+	if (size && 
+		!(((long) ulBuffNum == cacheBufIdx) && (testmt == cacheTestament) && (cacheBuf))) {
+		//fprintf(stderr, "Got buffer number{%ld} versestart{%ld} versesize{%d}\n", ulBuffNum, ulVerseStart, usVerseSize);
+
+		if (idxfp[testmt-1]->seek(ulBuffNum*12, SEEK_SET)!=(long) ulBuffNum*12)
+		{
+			fprintf(stderr, "Error seeking compressed file index\n");
+			return;
+		}
+		if (idxfp[testmt-1]->read(&ulCompOffset, 4)<4)
+		{
+			fprintf(stderr, "Error reading ulCompOffset\n");
+			return;
+		}
+		if (idxfp[testmt-1]->read(&ulCompSize, 4)<4)
+		{
+			fprintf(stderr, "Error reading ulCompSize\n");
+			return;
+		}
+		if (idxfp[testmt-1]->read(&ulUnCompSize, 4)<4)
+		{
+			fprintf(stderr, "Error reading ulUnCompSize\n");
+			return;
+		}
+
+		ulCompOffset  = swordtoarch32(ulCompOffset);
+		ulCompSize  = swordtoarch32(ulCompSize);
+		ulUnCompSize  = swordtoarch32(ulUnCompSize);
+
+		if (textfp[testmt-1]->seek(ulCompOffset, SEEK_SET)!=(long)ulCompOffset)
+		{
+			fprintf(stderr, "Error: could not seek to right place in compressed text\n");
+			return;
+		}
+		SWBuf pcCompText;
+		pcCompText.setSize(ulCompSize+5);
+
+		if (textfp[testmt-1]->read(pcCompText.getRawData(), ulCompSize)<(long)ulCompSize) {
+			fprintf(stderr, "Error reading compressed text\n");
+			return;
+		}
+		pcCompText.setSize(ulCompSize);
+		rawZFilter(pcCompText, 0); // 0 = decipher
+		
+		unsigned long bufSize = ulCompSize;
+		compressor->zBuf(&bufSize, pcCompText.getRawData());
+
+		if (cacheBuf) {
+			flushCache();
+			free(cacheBuf);
+		}
+		
+		unsigned long len = 0;
+		compressor->Buf(0, &len);
+		cacheBuf = (char *)calloc(len + 1, 1);
+		memcpy(cacheBuf, compressor->Buf(), len);
+		cacheBufSize = strlen(cacheBuf);  // TODO: can we just use len?
+		cacheTestament = testmt;
+		cacheBufIdx = ulBuffNum;
+	}	
+	
+	inBuf = "";
+	if ((size > 0) && cacheBuf && ((unsigned)start < cacheBufSize)) {
+		inBuf.setFillByte(0);
+		inBuf.setSize(size+1);
+		strncpy(inBuf.getRawData(), &(cacheBuf[start]), size);
+		inBuf.setSize(strlen(inBuf.c_str()));
+	}
+}
+
+
+/******************************************************************************
+ * zVerse4::settext	- Sets text for current offset
+ *
+ * ENT: testmt	- testament to find (0 - Bible/module introduction)
+ *	idxoff	- offset into .vss
+ *	buf	- buffer to store
+ *      len     - length of buffer (0 - null terminated)
+ */
+
+void zVerse4::doSetText(char testmt, long idxoff, const char *buf, long len) {
+
+	len = (len < 0) ? strlen(buf) : len;
+	if (!testmt) 
+		testmt = ((idxfp[0]) ? 1:2);
+	if ((!dirtyCache) || (cacheBufIdx < 0)) {
+		cacheBufIdx = idxfp[testmt-1]->seek(0, SEEK_END) / 12;
+		cacheTestament = testmt;
+		if (cacheBuf)
+			free(cacheBuf);
+		cacheBuf = (char *)calloc(len + 1, 1);
+	}
+	else cacheBuf = (char *)((cacheBuf)?realloc(cacheBuf, strlen(cacheBuf)+(len + 1)):calloc((len + 1), 1));
+
+	dirtyCache = true;
+
+	__u32 start;
+	__u32 size;
+	__u32 outBufIdx = cacheBufIdx;
+
+	idxoff *= 12;
+	size = len;
+
+	start = strlen(cacheBuf);
+
+	if (!size)
+		start = outBufIdx = 0;
+
+	outBufIdx = archtosword32(outBufIdx);
+	start  = archtosword32(start);
+	size   = archtosword32(size);
+
+	compfp[testmt-1]->seek(idxoff, SEEK_SET);
+	compfp[testmt-1]->write(&outBufIdx, 4);
+	compfp[testmt-1]->write(&start, 4);
+	compfp[testmt-1]->write(&size, 4);
+	strcat(cacheBuf, buf);
+}
+
+
+void zVerse4::flushCache() const {
+	if (dirtyCache) {
+		__u32 idxoff;
+		__u32 start, outstart;
+		__u32 size, outsize;
+		__u32 zsize, outzsize;
+
+		idxoff = cacheBufIdx * 12;
+		if (cacheBuf) {
+			size = outsize = zsize = outzsize = strlen(cacheBuf);
+			if (size) {
+				compressor->Buf(cacheBuf);
+				unsigned long tmpSize;
+				compressor->zBuf(&tmpSize);
+				outzsize = zsize = tmpSize;
+
+				SWBuf buf;
+				buf.setSize(zsize + 5);
+				memcpy(buf.getRawData(), compressor->zBuf(&tmpSize), tmpSize);
+				outzsize = zsize = tmpSize;
+				buf.setSize(zsize);
+				rawZFilter(buf, 1); // 1 = encipher
+
+				start = outstart = textfp[cacheTestament-1]->seek(0, SEEK_END);
+
+				outstart  = archtosword32(start);
+				outsize   = archtosword32(size);
+				outzsize  = archtosword32(zsize);
+
+				textfp[cacheTestament-1]->write(buf, zsize);
+
+				idxfp[cacheTestament-1]->seek(idxoff, SEEK_SET);
+				idxfp[cacheTestament-1]->write(&outstart, 4);
+				idxfp[cacheTestament-1]->write(&outzsize, 4);
+				idxfp[cacheTestament-1]->write(&outsize, 4);
+			}
+			free(cacheBuf);
+			cacheBuf = 0;
+		}
+		dirtyCache = false;
+	}
+}
+
+/******************************************************************************
+ * RawVerse::linkentry	- links one entry to another
+ *
+ * ENT: testmt	- testament to find (0 - Bible/module introduction)
+ *	destidxoff	- dest offset into .vss
+ *	srcidxoff		- source offset into .vss
+ */
+
+void zVerse4::doLinkEntry(char testmt, long destidxoff, long srcidxoff) {
+	__s32 bufidx;
+	__s32 start;
+	__u32 size;
+
+	destidxoff *= 12;
+	srcidxoff  *= 12;
+
+	if (!testmt)
+		testmt = ((idxfp[1]) ? 1:2);
+
+	// get source
+	compfp[testmt-1]->seek(srcidxoff, SEEK_SET);
+	compfp[testmt-1]->read(&bufidx, 4);
+	compfp[testmt-1]->read(&start, 4);
+	compfp[testmt-1]->read(&size, 4);
+
+	// write dest
+	compfp[testmt-1]->seek(destidxoff, SEEK_SET);
+	compfp[testmt-1]->write(&bufidx, 4);
+	compfp[testmt-1]->write(&start, 4);
+	compfp[testmt-1]->write(&size, 4);
+}
+
+
+/******************************************************************************
+ * RawVerse::CreateModule	- Creates new module files
+ *
+ * ENT: path	- directory to store module files
+ * RET: error status
+ */
+
+char zVerse4::createModule(const char *ipath, int blockBound, const char *v11n)
+{
+	char *path = 0;
+	char *buf = new char [ strlen (ipath) + 20 ];
+	char retVal = 0;
+	FileDesc *fd, *fd2;
+	__s32 offset = 0;
+	__s32 size = 0;
+	VerseKey vk;
+
+	stdstr(&path, ipath);
+
+	if ((path[strlen(path)-1] == '/') || (path[strlen(path)-1] == '\\'))
+		path[strlen(path)-1] = 0;
+
+	sprintf(buf, "%s/ot.%czs", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd->getFd() < 1) goto erroropen1;
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	sprintf(buf, "%s/nt.%czs", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd->getFd() < 1) goto erroropen1;
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	sprintf(buf, "%s/ot.%czz", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd->getFd() < 1) goto erroropen1;
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	sprintf(buf, "%s/nt.%czz", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd->getFd() < 1) goto erroropen1;
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	sprintf(buf, "%s/ot.%czv", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd->getFd() < 1) goto erroropen1;
+
+	sprintf(buf, "%s/nt.%czv", path, uniqueIndexID[blockBound]);
+	FileMgr::removeFile(buf);
+	fd2 = FileMgr::getSystemFileMgr()->open(buf, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	if (fd2->getFd() < 1) goto erroropen2;
+
+	vk.setVersificationSystem(v11n);
+	vk.setIntros(true);
+
+	offset = archtosword32(offset);
+	size   = archtosword32(size);
+
+	for (vk = TOP; !vk.popError(); vk++) {
+		if (vk.getTestament() < 2) {
+			if (fd->write(&offset, 4) != 4) goto writefailure;	//compBufIdxOffset
+			if (fd->write(&offset, 4) != 4) goto writefailure;
+			if (fd->write(&size, 4) != 4) goto writefailure;
+		}
+		else {
+			if (fd2->write(&offset, 4) != 4) goto writefailure;	//compBufIdxOffset
+			if (fd2->write(&offset, 4) != 4) goto writefailure;
+			if (fd2->write(&size, 4) != 4) goto writefailure;
+		}
+	}
+	fd2->write(&offset, 4);	//compBufIdxOffset
+	fd2->write(&offset, 4);
+	fd2->write(&size, 4);
+
+	goto cleanup;
+
+erroropen1:
+	retVal = -1;
+	goto cleanup1;
+
+erroropen2:
+	retVal = -1;
+	goto cleanup;
+
+writefailure:
+	retVal = -2;
+
+cleanup:
+	FileMgr::getSystemFileMgr()->close(fd2);
+cleanup1:
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	delete [] path;
+	delete [] buf;
+	
+	return retVal;
+}
+
+
+SWORD_NAMESPACE_END

Modified: trunk/src/modules/texts/Makefile.am
===================================================================
--- trunk/src/modules/texts/Makefile.am	2014-03-17 09:42:06 UTC (rev 3137)
+++ trunk/src/modules/texts/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -5,3 +5,4 @@
 include ../src/modules/texts/rawtext/Makefile.am
 include ../src/modules/texts/rawtext4/Makefile.am
 include ../src/modules/texts/ztext/Makefile.am
+include ../src/modules/texts/ztext4/Makefile.am

Added: trunk/src/modules/texts/ztext4/Makefile
===================================================================
--- trunk/src/modules/texts/ztext4/Makefile	                        (rev 0)
+++ trunk/src/modules/texts/ztext4/Makefile	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,5 @@
+
+root := ../../../..
+
+all:
+	make -C ${root}

Added: trunk/src/modules/texts/ztext4/Makefile.am
===================================================================
--- trunk/src/modules/texts/ztext4/Makefile.am	                        (rev 0)
+++ trunk/src/modules/texts/ztext4/Makefile.am	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,2 @@
+ztext4dir = $(top_srcdir)/src/modules/texts/ztext4
+libsword_la_SOURCES += $(ztext4dir)/ztext4.cpp

Added: trunk/src/modules/texts/ztext4/ztext4.cpp
===================================================================
--- trunk/src/modules/texts/ztext4/ztext4.cpp	                        (rev 0)
+++ trunk/src/modules/texts/ztext4/ztext4.cpp	2014-03-17 10:10:26 UTC (rev 3138)
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ *  ztext4.cpp -	code for class 'zText4'- a module that reads compressed
+ *			text files
+ *
+ * $Id: ztext4.cpp 2980 2013-09-14 21:51:47Z scribe $
+ *
+ * Copyright 1996-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sysdata.h>
+#include <versekey.h>
+#include <filemgr.h>
+
+#include <ztext4.h>
+
+SWORD_NAMESPACE_START
+
+/******************************************************************************
+ * zText4 Constructor - Initializes data for instance of zText4
+ *
+ * ENT:	ipath - path to data files
+ *		iname - Internal name for module
+ *		idesc - Name to display to user for module
+ *		iblockType - verse, chapter, book, etc. of index chunks
+ *		icomp - Compressor object
+ *		idisp - Display object to use for displaying
+ */
+
+zText4::zText4(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)
+		: zVerse4(ipath, FileMgr::RDWR, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang, versification) {
+	blockType = iblockType;
+	lastWriteKey = 0;
+}
+
+
+/******************************************************************************
+ * zText4 Destructor - Cleans up instance of zText4
+ */
+
+zText4::~zText4()
+{
+	flushCache();
+
+	if (lastWriteKey)
+		delete lastWriteKey;
+
+}
+
+
+bool zText4::isWritable() const { return ((idxfp[0]->getFd() > 0) && ((idxfp[0]->mode & FileMgr::RDWR) == FileMgr::RDWR)); }
+
+
+/******************************************************************************
+ * zText4::getRawEntry	- Returns the current verse buffer
+ *
+ * RET: buffer with verse
+ */
+
+SWBuf &zText4::getRawEntryBuf() const {
+	long  start = 0;
+	unsigned long size = 0;
+	unsigned long buffnum = 0;
+	VerseKey &key = getVerseKey();
+
+	findOffset(key.getTestament(), key.getTestamentIndex(), &start, &size, &buffnum);
+	entrySize = size;        // support getEntrySize call
+			  
+	entryBuf = "";
+	
+	zReadText(key.getTestament(), start, size, buffnum, entryBuf);
+	rawFilter(entryBuf, &key);
+
+//	if (!isUnicode())
+		prepText(entryBuf);
+
+	return entryBuf;
+}
+
+
+bool zText4::sameBlock(VerseKey *k1, VerseKey *k2) {
+	if (k1->getTestament() != k2->getTestament())
+		return false;
+
+	switch (blockType) {
+	case VERSEBLOCKS:
+		if (k1->getVerse() != k2->getVerse())
+			return false;
+	case CHAPTERBLOCKS:
+		if (k1->getChapter() != k2->getChapter())
+			return false;
+	case BOOKBLOCKS:
+		if (k1->getBook() != k2->getBook())
+			return false;
+	}
+	return true;
+}
+
+
+void zText4::setEntry(const char *inbuf, long len) {
+	VerseKey &key = getVerseKey();
+
+	// see if we've jumped across blocks since last write
+	if (lastWriteKey) {
+		if (!sameBlock(lastWriteKey, &key)) {
+			flushCache();
+		}
+		delete lastWriteKey;
+	}
+
+	doSetText(key.getTestament(), key.getTestamentIndex(), inbuf, len);
+
+	lastWriteKey = (VerseKey *)key.clone();	// must delete
+}
+
+
+void zText4::linkEntry(const SWKey *inkey) {
+	VerseKey &destkey = getVerseKey();
+	const VerseKey *srckey = &getVerseKey(inkey);
+	doLinkEntry(destkey.getTestament(), destkey.getTestamentIndex(), srckey->getTestamentIndex());
+}
+
+
+/******************************************************************************
+ * zFiles::deleteEntry	- deletes this entry
+ *
+ */
+
+void zText4::deleteEntry() {
+
+	VerseKey &key = getVerseKey();
+
+	doSetText(key.getTestament(), key.getTestamentIndex(), "");
+}
+
+
+/******************************************************************************
+ * zText4::increment	- Increments module key a number of entries
+ *
+ * ENT:	increment	- Number of entries to jump forward
+ *
+ */
+
+void zText4::increment(int steps) {
+	long start;
+	unsigned long size;
+	unsigned long buffnum;
+	VerseKey *tmpkey = &getVerseKey();
+
+	findOffset(tmpkey->getTestament(), tmpkey->getTestamentIndex(), &start, &size, &buffnum);
+
+	SWKey lastgood = *tmpkey;
+	while (steps) {
+		long laststart = start;
+		unsigned long lastsize = size;
+		SWKey lasttry = *tmpkey;
+		(steps > 0) ? ++(*key) : --(*key);
+		tmpkey = &getVerseKey();
+
+		if ((error = key->popError())) {
+			*key = lastgood;
+			break;
+		}
+		long index = tmpkey->getTestamentIndex();
+		findOffset(tmpkey->getTestament(), index, &start, &size, &buffnum);
+
+		if (
+			(
+				((laststart != start) || (lastsize != size))	// we're a different entry
+//				&& (start > 0)
+				&& (size)	// and we actually have a size
+			)
+			|| !skipConsecutiveLinks
+		) {	// or we don't want to skip consecutive links
+			steps += (steps < 0) ? 1 : -1;
+			lastgood = *tmpkey;
+		}
+	}
+	error = (error) ? KEYERR_OUTOFBOUNDS : 0;
+}
+
+
+bool zText4::isLinked(const SWKey *k1, const SWKey *k2) const {
+	long start1, start2;
+	unsigned long size1, size2;
+	unsigned long buffnum1, buffnum2;
+	VerseKey *vk1 = &getVerseKey(k1);
+	VerseKey *vk2 = &getVerseKey(k2);
+	if (vk1->getTestament() != vk2->getTestament()) return false;
+
+	findOffset(vk1->getTestament(), vk1->getTestamentIndex(), &start1, &size1, &buffnum1);
+	findOffset(vk2->getTestament(), vk2->getTestamentIndex(), &start2, &size2, &buffnum2);
+	return start1 == start2 && buffnum1 == buffnum2;
+}
+
+bool zText4::hasEntry(const SWKey *k) const {
+	long start;
+	unsigned long size;
+	unsigned long buffnum;
+	VerseKey *vk = &getVerseKey(k);
+
+	findOffset(vk->getTestament(), vk->getTestamentIndex(), &start, &size, &buffnum);
+	return size;
+}
+
+
+SWORD_NAMESPACE_END




More information about the sword-cvs mailing list