[sword-devel] Proposed parent/contained class for VerseKey: CanonVersifier?

Lynn Allan sword-devel@crosswire.org
Mon, 1 Dec 2003 07:21:09 -0700


I believe there would be advantages in having VerseKey derive from a base
class that basically is responsible only for "versification" using a
significantly modified canon.h. (or 'contain' ... see below???)

The proposed class, CanonVersifier, would *not* know anything about parsing
or listkey. The current problem with VerseKey, IMHO, is that its elaborate
parsing capability becomes an "octopus with tentacles" into a large amount
of code. It causes a lot of unfortunate dependencies so that a newbie
program containing:

printf("Hello newbie! Sword has now been demonstrated to be 'knitted
together' on your computer! \nEnjoy Col 3:23 = : %s\n so as to eventually
hear (rather than read) Matt 25:23 = %s\n", buf_Col323, buf_Matt2523);

becomes about 200kb instead of 24kb.

(An aside: the program that demonstrates the function:
void RemoveMostTagsAndExtraWhiteSpace(mutable char *buf);
uses a greatly simplified VerseKey that conceptually illustrates the
"division of labor" between the proposed CanonVersifier and the existing
VerseKey)

Some specifics for CanonVersifier.h (using doxygen notation)

/** @par constructor
 * From Verskey, continue using odd choice of char for testmt and bk.
 * (Every bit seems to count. Note that testmt would probably remain
"stateful")
 * To actually save bits, use unsigned short's for chap and verse, and
actual versification rather than int's
 */
CanonVersifier(char testmt, char book, unsigned short chap, unsigned short
verse);

/** @remark
 * Possible implementation available @
http://www.crosswire.org/forums/mvnforum/viewthread?thread=14
 */
unsigned short getMaxChapInBook(char bk);

/** @remark
 * Possible implementation available @
http://www.crosswire.org/forums/mvnforum/viewthread?thread=13
 */
unsigned short getMaxVerseInChap(char bk, unsigned short chap);

// increment function: should it be within CanonVersifier?
// decrement function: should it be within CanonVersifier?

Also, it would seem advantageous to have the hard-coded constants now within
canon.h be contained privately within CanonVersifier.cpp. Current practice
makes all these "magic offsets" visible to the entire world, which seems
contrary to data abstraction and data hiding. (When I put on my rarely used
"purist" hat, I am hard pressed to think of anything that warrants data
hiding more than these offsets.) Also, these hard-coded array constants
cause problems for generating precompiled headers, and might be part of
dramaticially improving rebuild times (along with removing array data from
one other .h file?).

Another proposed change: All of the offsets that are now within canon.h
could be unsigned shorts. This would actually save some bits as none are
greater than 25,000. There are about 6 to 10 easily found changes within the
existing VerseKey that would result from this.

To conclude, the existing VerseKey would be refactored to derive from
CanonVersifier. VerseKey would be limited to providing parsing capabilities.
All existing apps could continue to instantiate VerseKey objects. Future
apps that wanted to have minimal "footprint" (such as sword 'plug-ins'?)
could instantiate CanonVersefier objects. Unauthorized apps that tried to
use canon.h (and avoid sword-api for module access) would break ...  we'd
know who you are :-(

p.s. Perhaps VerseKey should "contain" an object of CanonVersifier, rather
than derive from it? It would seem to "has-a" rather than "is-a"??? That's a
question for architects with far greater experience and talent that this
scribbler.