summaryrefslogtreecommitdiff
path: root/src/keys/versetreekey.cpp
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:54:01 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-03-29 10:54:01 -0400
commit71a39f4652cd51df814c930dd268f3c9ad2aee86 (patch)
tree5994350a603908c4e4d660bc9d72c4ec43dd648e /src/keys/versetreekey.cpp
parent03134fa5f6f25d92724ce4c183f9bbe12a9e37dc (diff)
Imported Upstream version 1.6.0+dfsg
Diffstat (limited to 'src/keys/versetreekey.cpp')
-rw-r--r--src/keys/versetreekey.cpp238
1 files changed, 234 insertions, 4 deletions
diff --git a/src/keys/versetreekey.cpp b/src/keys/versetreekey.cpp
index b73672d..edfbcc3 100644
--- a/src/keys/versetreekey.cpp
+++ b/src/keys/versetreekey.cpp
@@ -1,9 +1,27 @@
/******************************************************************************
* VerseTreeKey.cpp - code for class 'VerseTreeKey'- versekey using treekey
* for data retrieval
+ *
+ *
+ * Copyright 2009 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 <versetreekey.h>
+#include <ctype.h>
SWORD_NAMESPACE_START
@@ -20,7 +38,7 @@ SWClass VerseTreeKey::classdef(classes);
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey)
{
- this->treeKey = treeKey;
+ init(treeKey);
if (ikey)
parse();
}
@@ -35,7 +53,7 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const SWKey *ikey) : VerseKey(ikey)
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey)
{
- this->treeKey = treeKey;
+ init(treeKey);
if (ikey)
parse();
}
@@ -43,13 +61,22 @@ VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *ikey) : VerseKey(ikey)
VerseTreeKey::VerseTreeKey(VerseTreeKey const &k) : VerseKey(k)
{
- treeKey = k.treeKey;
+ init(k.treeKey);
}
VerseTreeKey::VerseTreeKey(TreeKey *treeKey, const char *min, const char *max) : VerseKey(min, max)
{
- this->treeKey = treeKey;
+ init(treeKey);
+}
+
+
+void VerseTreeKey::init(TreeKey *treeKey)
+{
+ myclass = &classdef;
+ this->treeKey = (TreeKey *)treeKey->clone();
+ this->treeKey->setPositionChangeListener(this);
+ internalPosChange = false;
}
@@ -59,6 +86,33 @@ SWKey *VerseTreeKey::clone() const
}
+int VerseTreeKey::getBookAbbrev(const char *iabbr)
+{
+ int bookno = VerseKey::getBookAbbrev(iabbr);
+ if (bookno < 0) {
+/*
+ vector<struct sbook>::iterator it = find(books, iabbr);
+ if (it == books.end()) {
+ TreeKey *tkey = this->treeKey;
+ int saveError = tkey->Error();
+ long bookmark = tkey->getOffset();
+ SWBuf segment;
+ internalPosChange = true;
+ do {
+ segment = (SWBuf)tkey->getLocalName();
+ } while (tkey->parent());
+ segment << 1;
+ if (saveError) {
+ error = saveError;
+ }
+ tkey->setOffset(bookmark);
+ }
+ books.push_back(sbook(iabbr));
+*/
+ }
+ return bookno;
+}
+
/******************************************************************************
* VerseTreeKey Destructor - cleans up instance of VerseTreeKey
*
@@ -66,7 +120,183 @@ SWKey *VerseTreeKey::clone() const
*/
VerseTreeKey::~VerseTreeKey() {
+ delete treeKey;
+}
+
+
+void VerseTreeKey::decrement(int steps) {
+ int treeError = 0;
+ if (!error) lastGoodOffset = getTreeKey()->getOffset();
+ do {
+ treeKey->decrement();
+ treeError = treeKey->Error();
+ // iterate until 3 levels and no versekey parse errors
+ } while (!treeError && ((treeKey->getLevel() < 3) || error));
+ if (error && !treeError) {
+ int saveError = error;
+ increment();
+ error = saveError;
+ }
+ if (treeError) {
+ treeKey->setOffset(lastGoodOffset);
+ error = treeError;
+ }
+ if (_compare(UpperBound()) > 0) {
+ positionFrom(UpperBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+ if (_compare(LowerBound()) < 0) {
+ positionFrom(LowerBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+}
+
+
+void VerseTreeKey::increment(int steps) {
+ int treeError = 0;
+ if (!error) lastGoodOffset = getTreeKey()->getOffset();
+ do {
+ treeKey->increment();
+ treeError = treeKey->Error();
+ // iterate until 3 levels and no versekey parse errors
+ } while (!treeError && ((treeKey->getLevel() < 3) || error));
+ if (error && !treeError) {
+ int saveError = error;
+ decrement();
+ error = saveError;
+ }
+ if (treeError) {
+ treeKey->setOffset(lastGoodOffset);
+ error = treeError;
+ }
+ // bounds
+ if (_compare(UpperBound()) > 0) {
+ positionFrom(UpperBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
+ if (_compare(LowerBound()) < 0) {
+ positionFrom(LowerBound());
+ error = KEYERR_OUTOFBOUNDS;
+ }
}
+void VerseTreeKey::positionChanged() {
+ if (!internalPosChange) {
+ TreeKey *tkey = this->TreeKey::PositionChangeListener::getTreeKey();
+ int saveError = tkey->Error();
+ long bookmark = tkey->getOffset();
+ SWBuf seg[4];
+ internalPosChange = true;
+ int legs = 0;
+ do {
+ seg[legs] = tkey->getLocalName();
+ legs++;
+ } while (tkey->parent() && (legs < 4));
+
+ legs--;
+
+ if ((legs < 2) && (!seg[0].length() || seg[0] == "/")) { //"[ Module Heading ]";
+ testament = 0;
+ book = 0;
+ chapter = 0;
+ setVerse(0);
+ }
+ else if ((legs < 2)
+ && ((!strncmp(seg[0].c_str(), "[ Testament ", 12)) && //"[ Testament n Heading ]";
+ (isdigit(seg[0][12])) &&
+ (!strcmp(seg[0].c_str()+13, " Heading ]")))) {
+ testament = (seg[0][12]-48);
+ book = 0;
+ chapter = 0;
+ setVerse(0);
+ } //path = "[ Module Heading ]";
+ else {
+ setBookName(seg[--legs]);
+ chapter = (legs > 0) ? atoi(seg[--legs]) : 0;
+ setVerse((legs > 0) ? atoi(seg[--legs]) : 0);
+ }
+
+// setText(path);
+ if (saveError) {
+ error = saveError;
+ }
+ tkey->setOffset(bookmark);
+ tkey->setError(saveError);
+ internalPosChange = false;
+ }
+}
+
+
+void VerseTreeKey::syncVerseToTree() {
+ internalPosChange = true;
+ SWBuf path;
+ if (!Testament()) path = "/"; // "[ Module Heading ]";
+ else if (!Book()) path.setFormatted("/[ Testament %d Heading ]", Testament());
+ else path.setFormatted("/%s/%d/%d", getOSISBookName(), getChapter(), getVerse());
+ if (getSuffix()) path += getSuffix();
+ long bookmark = treeKey->getOffset();
+ treeKey->setText(path);
+
+ // if our module has jacked inconsistencies, then let's put our tree back to where it was
+ if (treeKey->Error()) {
+ treeKey->setOffset(bookmark);
+ }
+
+ internalPosChange = false;
+}
+
+
+TreeKey *VerseTreeKey::getTreeKey() {
+ syncVerseToTree();
+ return treeKey;
+}
+
+// can autonormalize yet (ever?)
+void VerseTreeKey::Normalize(char autocheck) {
+ error = 0;
+}
+
+long VerseTreeKey::NewIndex() const {
+ return treeKey->getOffset();
+}
+
+
+void VerseTreeKey::setPosition(SW_POSITION p) {
+
+ if (isBoundSet()) {
+ return VerseKey::setPosition(p);
+ }
+
+ switch (p) {
+ case POS_TOP:
+ Error();
+ treeKey->setPosition(p);
+ increment();
+ decrement();
+ Error();
+ break;
+ case POS_BOTTOM:
+ Error();
+ treeKey->setPosition(p);
+ decrement();
+ increment();
+ Error();
+ break;
+ case POS_MAXVERSE:
+ case POS_MAXCHAPTER:
+ VerseKey::setPosition(p);
+ break;
+ }
+}
+
+
+/******************************************************************************
+ * VerseTreeKey::copyFrom - Equates this VerseTreeKey to another VerseTreeKey
+
+void VerseTreeKey::copyFrom(const VerseTreeKey &ikey) {
+ VerseKey::copyFrom(ikey);
+}
+ */
+
SWORD_NAMESPACE_END