1 /******************************************************************************
2  *
3  *  swkey.h -	code for base class 'swkey'.  swkey is the basis for all
4  *		types of keys for indexing into modules (e.g. verse, word,
5  *		place, etc.)
6  *
7  * $Id: swkey.h 3515 2017-11-01 11:38:09Z scribe $
8  *
9  * Copyright 1998-2013 CrossWire Bible Society (http://www.crosswire.org)
10  *	CrossWire Bible Society
11  *	P. O. Box 2528
12  *	Tempe, AZ  85280-2528
13  *
14  * This program is free software; you can redistribute it and/or modify it
15  * under the terms of the GNU General Public License as published by the
16  * Free Software Foundation version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * General Public License for more details.
22  *
23  */
24 
25 #ifndef SWKEY_H
26 #define SWKEY_H
27 
28 #include <swobject.h>
29 
30 #include <defs.h>
31 #include <sysdata.h>
32 #include <utilstr.h>
33 
34 SWORD_NAMESPACE_START
35 
36 #define KEYERR_OUTOFBOUNDS 1
37 
38 #define SWKEY_OPERATORS \
39   SWKey &operator =(const char *ikey) { setText(ikey); return *this; } \
40   SWKey &operator =(const SWKey &ikey) { positionFrom(ikey); return *this; } \
41   SWKey &operator =(SW_POSITION pos) { setPosition(pos); return *this; } \
42   operator const char *() const { return getText(); } \
43   bool operator ==(const SWKey &ikey) { return equals(ikey); } \
44   bool operator !=(const SWKey &ikey) { return !equals(ikey); } \
45   virtual bool operator >(const SWKey &ikey) { return (compare(ikey) > 0); } \
46   virtual bool operator <(const SWKey &ikey) { return (compare(ikey) < 0); } \
47   virtual bool operator >=(const SWKey &ikey) { return (compare(ikey) > -1); }  \
48   virtual bool operator <=(const SWKey &ikey) { return (compare(ikey) < 1); } \
49   SWKey &operator -=(int steps) { decrement(steps); return *this; } \
50   SWKey &operator +=(int steps) { increment(steps); return *this; } \
51   SWKey &operator ++()    { increment(1); return *this; } \
52   SWKey  operator ++(int) { SWKey temp = *this; increment(1); return temp; } \
53   SWKey &operator --()    { decrement(1); return *this; } \
54   SWKey  operator --(int) { SWKey temp = *this; decrement(1); return temp; }
55 
56 
57 /** For use with = operator to position key.
58 */
59 class SW_POSITION {
60 	char pos;
61 public:
SW_POSITION(char ipos)62 	SW_POSITION(char ipos) { pos = ipos; }
63 	operator char() { return pos; }
64 };
65 
66 #define POS_TOP ((char)1)
67 #define POS_BOTTOM ((char)2)
68 
69 #define TOP SW_POSITION(POS_TOP)
70 #define BOTTOM SW_POSITION(POS_BOTTOM)
71 
72 class SWLocale;
73 
74 /** SWKey is used for positioning an SWModule to a specific entry.
75  *	It always represents a possible location into a module and can additionally represent
76  *	a domain of entries (e.g. "John 3:16" in the domain "John 1:1 - Mark 5:25")
77  */
78 class SWDLLEXPORT SWKey : public SWObject {
79 
80 	class LocaleCache {
81 	public:
82 		char *name;
83 		SWLocale *locale;
LocaleCache()84 			LocaleCache() {
85 			name = 0;
86 			locale = 0;
87 		}
~LocaleCache()88 		 virtual ~LocaleCache() {
89 			if (name)
90 			delete[]name;
91 		}
92 	};
93 	static LocaleCache localeCache;
94 	// for caching; don't use directly, call getPrivateLocale()
95 	mutable SWLocale *locale;
96 
97 
98 	long index;
99 	static SWClass classdef;
100 	void init();
101 
102 
103 protected:
104 	char *keytext;
105 	mutable char *rangeText;
106 	mutable bool boundSet;
107 	bool persist;
108 	mutable char error;
109 
110 	char *localeName;
111 	SWLocale *getPrivateLocale() const;
112 
113 
114 public:
115 
116 	// misc storage for whatever
117 	__u64 userData;
118 
119 	/** initializes instance of SWKey from a string
120 	 * All keys can be reduced to a string representation which should be able
121 	 *	to be used to again set the key to the same position
122 	 * @param ikey string to use for initializing this new key
123 	 */
124 	SWKey(const char *ikey = 0);
125 
126 	/** Copy Constructor
127 	 * @param k The SWKey object to copy.
128 	 */
129 	SWKey(const SWKey &k);
130 
131 	/** Destructor, cleans up this instance of SWKey
132 	 */
133 	virtual ~SWKey();
134 
135 	/** Returns a new exact clone of this SWKey object.  This allocates
136 	 * a new SWKey which must be deleted by the caller
137 	 * @return new clone of this key
138 	 */
139 	virtual SWKey *clone() const;
140 
141 
142 	/** Gets whether this key should persist in any module to which it is set
143 	 * otherwise just a copy will be used in the module.
144 	 * @return 1 - persists in module; 0 - a copy is attempted
145 	 */
146 	bool isPersist() const;
Persist()147 	SWDEPRECATED char Persist() const { return isPersist(); }
148 
149 	/** Sets whether this key should persist in any module to which it is set
150 	 * otherwise just a copy will be used in the module.
151 	 * @param ipersist value which to set persist;
152 	 * @return 1 - persists in module; 0 - a copy is attempted
153 	 */
Persist(signed char ipersist)154 	SWDEPRECATED char Persist(signed char ipersist) { setPersist(ipersist!=0); return isPersist(); }
155 	void setPersist(bool ipersist);
156 
157 	/** Gets and clears error status
158 	 * @return error status
159 	 */
Error()160 	SWDEPRECATED char Error() { return popError(); }
161 	virtual char popError();
getError()162 	virtual char getError() { return error; }
setError(char err)163 	virtual void setError(char err) { error = err; }
164 
165 	/** Sets this SWKey with a character string
166 	 * @param ikey string used to set this key
167 	 */
168 	virtual void setText(const char *ikey);
169 
170 	/** Copies as much info (position, range, etc.) as possible from another SWKey object
171 	 * @param ikey other SWKey object from which to copy
172 	 */
173 	virtual void copyFrom(const SWKey &ikey);
positionFrom(const SWKey & ikey)174 	virtual void positionFrom(const SWKey &ikey) { copyFrom(ikey); }
175 
176 	/** returns string representation of this key
177 	 */
178 	virtual const char *getText() const;
getShortText()179 	virtual const char *getShortText() const { return getText(); }
180 	virtual const char *getRangeText() const;
181 	virtual const char *getOSISRefRangeText() const;
isBoundSet()182 	virtual bool isBoundSet() const { return boundSet; }
clearBound()183 	virtual void clearBound() const { boundSet = false; }
184 
185 	/** Compares this key object to another SWKey object
186 	 * @param ikey key to compare with this one
187 	 * @return >0 if this key is greater than compare key;
188 	 *	<0 if this key is smaller than compare key;
189 	 *	0 if the keys are the same
190 	 */
191 	virtual int compare(const SWKey &ikey);
192 
193 	/** test equality of this SWKey object's position with another SWKey
194 	 * @param ikey key to compare with this one
195 	 * @return true if the key positions are equal
196 	 */
equals(const SWKey & ikey)197 	virtual bool equals(const SWKey &ikey) { return !compare(ikey); }
198 
199 	virtual void setPosition(SW_POSITION);
200 
201 	/** Decrements key a number of entry positions
202 	 * This is only valid if isTraversable is true
203 	 * @param steps Number of entries to jump backward
204 	 */
205 	virtual void decrement(int steps = 1);
206 
207 	/** Increments key a number of entry positions
208 	 * This is only valid if isTraversable is true
209 	 * @param steps Number of entries to jump forward
210 	 */
211 	virtual void increment(int steps = 1);
212 
213 	/** Whether or not this key can be ++ -- incremented
214 	 */
isTraversable()215 	virtual bool isTraversable() const { return false; }
216 
getLocale()217 	char *getLocale() const { return localeName; }
setLocale(const char * name)218 	void setLocale(const char *name) { stdstr(&localeName, name); locale = 0;	} // this will force an on demand lookup of our locale
219 
220 	/** Use this function to get an index position within a module.
221 	 */
getIndex()222 	virtual long getIndex() const { return index; }
223 
224 	/** See documentation for @ref Index()
225 	 */
setIndex(long iindex)226 	virtual void setIndex(long iindex) { index = iindex; }
227 
228 	SWKEY_OPERATORS
229 
230 	};
231 
232 SWORD_NAMESPACE_END
233 #endif
234