diff options
Diffstat (limited to 'include/swmodule.h')
-rw-r--r-- | include/swmodule.h | 673 |
1 files changed, 673 insertions, 0 deletions
diff --git a/include/swmodule.h b/include/swmodule.h new file mode 100644 index 0000000..f1db7e9 --- /dev/null +++ b/include/swmodule.h @@ -0,0 +1,673 @@ +/****************************************************************************** + * swmodule.h - code for base class 'module'. Module is the basis for all + * types of modules (e.g. texts, commentaries, maps, lexicons, + * etc.) + * + * $Id: swmodule.h 2093 2007-09-28 19:20:22Z scribe $ + * + * Copyright 1998 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 SWMODULE_H +#define SWMODULE_H + +#include <swdisp.h> +#include <listkey.h> +#include <swconfig.h> + +#include <swcacher.h> +#include <swsearchable.h> + +#include <list> + +#include <defs.h> + +SWORD_NAMESPACE_START + +class SWOptionFilter; +class SWFilter; + +#define SEARCHFLAG_MATCHWHOLEENTRY 4096 + +#define SWMODULE_OPERATORS \ + operator const char *() { return RenderText(); } \ + operator SWKey &() { return *getKey(); } \ + operator SWKey *() { return getKey(); } \ + SWModule &operator <<(const char *inbuf) { setEntry(inbuf); return *this; } \ + SWModule &operator <<(const SWKey *sourceKey) { linkEntry(sourceKey); return *this; } \ + SWModule &operator -=(int steps) { decrement(steps); return *this; } \ + SWModule &operator +=(int steps) { increment(steps); return *this; } \ + SWModule &operator ++(int) { return *this += 1; } \ + SWModule &operator --(int) { return *this -= 1; } \ + SWModule &operator =(SW_POSITION p) { setPosition(p); return *this; } + + +typedef std::list < SWFilter * >FilterList; +typedef std::list < SWOptionFilter * >OptionFilterList; +typedef std::map < SWBuf, SWBuf, std::less < SWBuf > > AttributeValue; +typedef std::map < SWBuf, AttributeValue, std::less < SWBuf > > AttributeList; +typedef std::map < SWBuf, AttributeList, std::less < SWBuf > > AttributeTypeList; + +#define SWTextDirection char +#define SWTextEncoding char +#define SWTextMarkup char + +/** + * The class SWModule is the base class for all modules used in Sword. + * It provides functions to look up a text passage, to search in the module, + * to switch on/off the state of optional things like Strong's numbers or + * footnotes. + * + * SWModule has also functions to write to the data files. + */ + +// TODO: should all SWModule decendents be SWCachers? Only some really +// cache data. But if we don't do this, then we need another mechanism to +// check if we are an SWCacher. Maybe make SWModule extend SWObject (which +// it probably should anyway. But then we need to add all the cheezy +// heirarchy info to all he decendent classes for our SWDYNAMIC_CAST and +// then we can see if we implement SWCacher so we know whether or not to add +// to the yet to be developed cachemgr. +// Just leave for now. This lets us always able to call module->flush() +// to manually flush a cache, and doesn't hurt if there is no work done. + +class SWDLLEXPORT SWModule : public SWCacher, public SWSearchable { + +protected: + + ConfigEntMap ownConfig; + ConfigEntMap *config; + mutable AttributeTypeList entryAttributes; + mutable bool procEntAttr; + + char error; + bool skipConsecutiveLinks; + + /** the current key */ + SWKey *key; + + ListKey listKey; + char *modname; + char *moddesc; + char *modtype; + char *modlang; + + char direction; + char markup; + char encoding; + + /** this module's display object */ + SWDisplay *disp; + + static SWDisplay rawdisp; + SWBuf entryBuf; + + /** filters to be executed to remove all markup (for searches) */ + FilterList *stripFilters; + + /** filters to be executed immediately upon fileread */ + FilterList *rawFilters; + + /** filters to be executed to format for display */ + FilterList *renderFilters; + + /** filters to be executed to change markup to user prefs */ + OptionFilterList *optionFilters; + + /** filters to be executed to decode text for display */ + FilterList *encodingFilters; + + int entrySize; + mutable long entryIndex; // internal common storage for index + + +public: + + /** + * Set this bool to false to terminate the search which is executed by this module (search()). + * This is useful for threaded applications to terminate the search from another thread. + */ + bool terminateSearch; + + /** SWModule c-tor + * + * @param imodname Internal name for module; see also getName() + * @param imoddesc Name to display to user for module; see also getDescription() + * @param idisp Display object to use for displaying; see also getDisplay() + * @param imodtype Type of module (e.g. Biblical Text, Commentary, etc.); see also getType() + * @param encoding Encoding of the module (e.g. UTF-8) + * @param dir Direction of text flow (e.g. Right to Left for Hebrew) + * @param markup Source Markup of the module (e.g. OSIS) + * @param modlang Language of the module (e.g. en) + */ + SWModule(const char *imodname = 0, const char *imoddesc = 0, SWDisplay * idisp = 0, char *imodtype = 0, SWTextEncoding encoding = ENC_UNKNOWN, SWTextDirection dir = DIRECTION_LTR, SWTextMarkup markup = FMT_UNKNOWN, const char* modlang = 0); + + /** SWModule d-tor + */ + virtual ~SWModule(); + + /** Gets and clears error status + * + * @return error status + */ + virtual char Error(); + + /** + * @return True if this module is encoded in Unicode, otherwise returns false. + */ + virtual const bool isUnicode() const { return (encoding == (char)ENC_UTF8 || encoding == (char)ENC_SCSU); } + + // These methods are useful for modules that come from a standard SWORD install (most do). + // SWMgr will call setConfig. The user may use getConfig and getConfigEntry (if they + // are not comfortable with, or don't wish to use stl maps). + virtual void setConfig(ConfigEntMap *config); + virtual const ConfigEntMap &getConfig() const { return *config; } + virtual const char *getConfigEntry(const char *key) const; + + /** + * @return The size of the text entry for the module's current key position. + */ + virtual const int getEntrySize() const { return entrySize; } + + /** + * Sets a key to this module for position to a particular record + * + * @param ikey key with which to set this module + * @return error status + */ + virtual char setKey(const SWKey *ikey); + + /** + * Sets a key to this module for position to a particular record + * @param ikey The SWKey which should be used as new key. + * @return Error status + */ + char setKey(const SWKey &ikey) { return setKey(&ikey); } + /** + * @deprecated Use setKey() instead. + */ + char SetKey(const SWKey *ikey) { return setKey(ikey); } + /** + * @deprecated Use setKey() instead. + */ + char SetKey(const SWKey &ikey) { return setKey(ikey); } + /** + * @deprecated Use setKey() instead. + */ + char Key(const SWKey & ikey) { return setKey(ikey); } + + /** Gets the current module key + * @return the current key of this module + */ + virtual SWKey *getKey() const; + /** + * @deprecated Use getKey() instead. + */ + SWKey &Key() const { return *getKey(); } + + /** + * Sets/gets module KeyText + * @deprecated Use getKeyText/setKey + * @param ikeytext Value which to set keytext; [0]-only get + * @return pointer to keytext + */ + virtual const char *KeyText(const char *ikeytext = 0) { + if (ikeytext) setKey(ikeytext); + return *getKey(); + } + + /** + * gets the key text for the module. + * do we really need this? + */ + + virtual const char *getKeyText() const { + return *getKey(); + } + + + virtual long Index() const { return entryIndex; } + virtual long Index(long iindex) { entryIndex = iindex; return entryIndex; } + + /** Calls this module's display object and passes itself + * + * @return error status + */ + virtual char Display(); + + /** Gets display driver + * + * @return pointer to SWDisplay class for this module + */ + virtual SWDisplay *getDisplay() const; + + /** Sets display driver + * + * @param idisp pointer to SWDisplay class to assign to this module + */ + virtual void setDisplay(SWDisplay * idisp); + + /** + * @deprecated Use get/setDisplay() instead. + */ + SWDisplay *Disp(SWDisplay * idisp = 0) { + if (idisp) + setDisplay(idisp); + return getDisplay(); + } + + /** Gets module name + * + * @return pointer to modname + */ + virtual char *Name() const; + + /** Sets module name + * + * @param imodname Value which to set modname; [0]-only get + * @return pointer to modname + */ + virtual char *Name(const char *imodname); + + /** Gets module description + * + * @return pointer to moddesc + */ + virtual char *Description() const; + + /** Sets module description + * + * @param imoddesc Value which to set moddesc; [0]-only get + * @return pointer to moddesc + */ + virtual char *Description(const char *imoddesc); + + /** Gets module type + * + * @return pointer to modtype + */ + virtual char *Type() const; + + /** Sets module type + * + * @param imodtype Value which to set modtype; [0]-only get + * @return pointer to modtype + */ + virtual char *Type(const char *imodtype); + + /** Sets/gets module direction + * + * @param newdir Value which to set direction; [-1]-only get + * @return new direction + */ + virtual char Direction(signed char newdir = -1); + + /** Sets/gets module encoding + * + * @param enc Value which to set encoding; [-1]-only get + * @return Encoding + */ + virtual char Encoding(signed char enc = -1); + + /** Sets/gets module markup + * + * @param markup Vvalue which to set markup; [-1]-only get + * @return Markup + */ + virtual char Markup(signed char markup = -1); + + /** Sets/gets module language + * + * @param imodlang Value which to set modlang; [0]-only get + * @return pointer to modlang + */ + virtual char *Lang(const char *imodlang = 0); + + + // search interface ------------------------------------------------- + + /** Searches a module for a string + * + * @param istr string for which to search + * @param searchType type of search to perform + * >=0 - regex + * -1 - phrase + * -2 - multiword + * -3 - entryAttrib (eg. Word//Strongs/G1234/) + * -4 - Lucene + * @param flags options flags for search + * @param scope Key containing the scope. VerseKey or ListKey are useful here. + * @param justCheckIfSupported if set, don't search, + * only tell if this function supports requested search. + * @param percent Callback function to get the current search status in %. + * @param percentUserData User data that is given to the callback function as parameter. + * + * @return ListKey set to verses that contain istr + */ + virtual ListKey &search(const char *istr, int searchType = 0, int flags = 0, + SWKey * scope = 0, + bool * justCheckIfSupported = 0, + void (*percent) (char, void *) = &nullPercent, + void *percentUserData = 0); + + // for backward compat-- deprecated + virtual ListKey &Search(const char *istr, int searchType = 0, int flags = 0, + SWKey * scope = 0, + bool * justCheckIfSupported = 0, + void (*percent) (char, void *) = &nullPercent, + void *percentUserData = 0) { + return search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData); + } + + + /** Allocates a key of specific type for module + * The different reimplementatiosn of SWModule (e.g. SWText) support SWKey implementations, which support special. + * This functions returns a SWKey object which works with the current implementation of SWModule. For example for the SWText class it returns a VerseKey object. + * @see VerseKey, ListKey, SWText, SWLD, SWCom + * @return pointer to allocated key + */ + virtual SWKey *CreateKey(); + + /** This function is reimplemented by the different kinds + * of module objects + * @return the raw module text of the current entry + */ + virtual SWBuf &getRawEntryBuf() = 0; + + virtual const char *getRawEntry() { return getRawEntryBuf().c_str(); } + + // write interface ---------------------------- + /** Is the module writable? :) + * @return yes or no + */ + virtual bool isWritable() { return false; } + + /** Creates a new, empty module + * @param path path where to create the new module + * @return error + */ + static signed char createModule(const char *path); + + /** Modify the current module entry text - only if module isWritable() + */ + virtual void setEntry(const char *inbuf, long len= -1); + + /** Link the current module entry to another module entry - only if + * module isWritable() + */ + virtual void linkEntry(const SWKey *sourceKey); + + /** Delete current module entry - only if module isWritable() + */ + virtual void deleteEntry() {} + + // end write interface ------------------------ + + /** Decrements module key a number of entries + * @param steps Number of entries to jump backward + */ + virtual void decrement(int steps = 1); + + /** Increments module key a number of entries + * @param steps Number of entries to jump forward + */ + virtual void increment(int steps = 1); + + /** Positions this modules to a logical position entry + * @param pos position (e.g. TOP, BOTTOM) + */ + virtual void setPosition(SW_POSITION pos); + + /** OptionFilterBuffer a text buffer + * @param filters the FilterList of filters to iterate + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void filterBuffer(OptionFilterList *filters, SWBuf &buf, SWKey *key); + + /** FilterBuffer a text buffer + * @param filters the FilterList of filters to iterate + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void filterBuffer(FilterList *filters, SWBuf &buf, SWKey *key); + + /** Adds a RenderFilter to this module's renderFilters queue. + * Render Filters are called when the module is asked to produce + * renderable text. + * @param newFilter the filter to add + * @return *this + */ + virtual SWModule &AddRenderFilter(SWFilter *newfilter) { + renderFilters->push_back(newfilter); + return *this; + } + + /** Retrieves a container of render filters associated with this + * module. + * @return container of render filters + */ + virtual const FilterList &getRenderFilters() const { + return *renderFilters; + } + + /** Removes a RenderFilter from this module's renderFilters queue + * @param oldfilter the filter to remove + * @return *this + */ + virtual SWModule &RemoveRenderFilter(SWFilter *oldfilter) { + renderFilters->remove(oldfilter); + return *this; + } + + /** Replaces a RenderFilter in this module's renderfilters queue + * @param oldfilter the filter to remove + * @param newfilter the filter to add in its place + * @return *this + */ + virtual SWModule &ReplaceRenderFilter(SWFilter *oldfilter, SWFilter *newfilter) { + FilterList::iterator iter; + for (iter = renderFilters->begin(); iter != renderFilters->end(); iter++) { + if (*iter == oldfilter) + *iter = newfilter; + } + return *this; + } + + /** RenderFilter run a buf through this module's Render Filters + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void renderFilter(SWBuf &buf, SWKey *key) { + filterBuffer(renderFilters, buf, key); + } + + /** Adds an EncodingFilter to this module's @see encodingFilters queue. + * Encoding Filters are called immediately when the module is read + * from data source, to assure we have desired internal data stream + * (e.g. UTF-8 for text modules) + * @param newfilter the filter to add + * @return *this + */ + virtual SWModule &AddEncodingFilter(SWFilter *newfilter) { + encodingFilters->push_back(newfilter); + return *this; + } + + /** Removes an EncodingFilter from this module's encodingFilters queue + * @param oldfilter the filter to remove + * @return *this + */ + virtual SWModule &RemoveEncodingFilter(SWFilter *oldfilter) { + encodingFilters->remove(oldfilter); + return *this; + } + + /** Replaces an EncodingFilter in this module's encodingfilters queue + * @param oldfilter the filter to remove + * @param newfilter the filter to add in its place + * @return *this + */ + virtual SWModule &ReplaceEncodingFilter(SWFilter *oldfilter, SWFilter *newfilter) { + FilterList::iterator iter; + for (iter = encodingFilters->begin(); iter != encodingFilters->end(); iter++) { + if (*iter == oldfilter) + *iter = newfilter; + } + return *this; + } + + /** encodingFilter run a buf through this module's Encoding Filters + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void encodingFilter(SWBuf &buf, SWKey *key) { + filterBuffer(encodingFilters, buf, key); + } + + /** Adds a StripFilter to this module's stripFilters queue. + * Strip filters are called when a module is asked to render + * an entry without any markup (like when searching). + * @param newfilter the filter to add + * @return *this + */ + virtual SWModule &AddStripFilter(SWFilter *newfilter) { + stripFilters->push_back(newfilter); + return *this; + } + + /** Adds a RawFilter to this module's rawFilters queue + * @param newfilter the filter to add + * @return *this + */ + virtual SWModule &AddRawFilter(SWFilter *newfilter) { + rawFilters->push_back(newfilter); + return *this; + } + + /** StripFilter run a buf through this module's Strip Filters + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void stripFilter(SWBuf &buf, SWKey *key) { + filterBuffer(stripFilters, buf, key); + } + + + /** RawFilter a text buffer + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void rawFilter(SWBuf &buf, SWKey *key) { + filterBuffer(rawFilters, buf, key); + } + + /** Adds an OptionFilter to this module's optionFilters queue. + * Option Filters are used to turn options in the text on + * or off, or so some other state (e.g. Strong's Number, + * Footnotes, Cross References, etc.) + * @param newfilter the filter to add + * @return *this + */ + virtual SWModule &AddOptionFilter(SWOptionFilter *newfilter) { + optionFilters->push_back(newfilter); + return *this; + } + + /** OptionFilter a text buffer + * @param buf the buffer to filter + * @param key key location from where this buffer was extracted + */ + virtual void optionFilter(SWBuf &buf, SWKey *key) { + filterBuffer(optionFilters, buf, key); + } + + /** Produces plain text, without markup, of the current module entry, + * or supplied text + * + * @param buf buf to massage instead of current module entry; + * if buf is 0, the current text will be used + * @param len max len to process + * @return result buffer + */ + virtual const char *StripText(const char *buf = 0, int len = -1); + + /** Produces renderable text of the current module entry or supplied text + * + * @param buf buffer to massage instead of current module entry; + * if buf is 0, the current module position text will be used + * @param len max len to process + * @param render for internal use + * @return result buffer + */ + virtual const char *RenderText(const char *buf = 0, int len = -1, bool render = true); + + /** Produces plain text, without markup, of the module entry at the supplied key + * @param tmpKey desired module entry + * @return result buffer + */ + virtual const char *StripText(SWKey *tmpKey); + + /** Produces renderable text of the module entry at the supplied key + * @param tmpKey key to use to grab text + * @return this module's text at specified key location massaged by Render filters + */ + virtual const char *RenderText(SWKey *tmpKey); + + /** Whether or not to only hit one entry when iterating encounters + * consecutive links when iterating + * @param val = true means only include entry once in iteration + */ + virtual void setSkipConsecutiveLinks(bool val) { skipConsecutiveLinks = val; } + + /** Whether or not to only hit one entry when iterating encounters + * consecutive links when iterating + */ + virtual bool getSkipConsecutiveLinks() { return skipConsecutiveLinks; } + + /** Entry Attributes are special data pertaining to the current entry. + * To see what Entry Attributes exists for a specific entry of a module, + * the example examples/cmdline/lookup.cpp is a good utility which + * displays this information. It is also useful as an example of how + * to access such. + */ + virtual AttributeTypeList &getEntryAttributes() const { return entryAttributes; } + + /** Processing Entry Attributes can be expensive. This method allows + * turning the processing off if they are not desired. Some internal + * engine processing turns them off (like searching) temporarily for + * optimization. + */ + virtual void processEntryAttributes(bool val) const { procEntAttr = val; } + + /** Whether or not we're processing Entry Attributes + */ + virtual bool isProcessEntryAttributes() const { return procEntAttr; } + + // OPERATORS ----------------------------------------------------------------- + + virtual signed char createSearchFramework( + void (*percent) (char, void *) = &nullPercent, + void *percentUserData = 0); + virtual void deleteSearchFramework(); + virtual bool hasSearchFramework(); + + SWMODULE_OPERATORS + +}; + +SWORD_NAMESPACE_END +#endif |