Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

listkey.cpp

00001 /******************************************************************************
00002  *  listkey.cpp - code for base class 'ListKey'.  ListKey is the basis for all
00003  *                              types of keys that have lists of specified indexes
00004  *                              (e.g. a list of verses, place, etc.)
00005  */
00006 
00007 #include <utilfuns.h>
00008 #include <string.h>
00009 #include <stdlib.h>
00010 #include <swkey.h>
00011 #include <listkey.h>
00012 
00013 static const char *classes[] = {"ListKey", "SWKey", "SWObject", 0};
00014 SWClass ListKey::classdef(classes);
00015 
00016 /******************************************************************************
00017  * ListKey Constructor - initializes instance of ListKey
00018  *
00019  * ENT: ikey - text key
00020  */
00021 
00022 ListKey::ListKey(const char *ikey): SWKey(ikey) {
00023         arraymax = 0;
00024         ClearList();
00025         init();
00026 }
00027 
00028 
00029 ListKey::ListKey(ListKey const &k) : SWKey(k.keytext) {
00030         arraymax = k.arraymax;
00031         arraypos = k.arraypos;
00032         arraycnt = k.arraycnt;
00033         array = (arraymax)?(SWKey **)malloc(k.arraymax * sizeof(SWKey *)):0;
00034         for (int i = 0; i < arraycnt; i++)
00035                 array[i] = k.array[i]->clone();
00036         init();
00037 }
00038 
00039 
00040 void ListKey::init() {
00041         myclass = &classdef;
00042 }
00043 
00044 
00045 SWKey *ListKey::clone() const
00046 {
00047         return new ListKey(*this);
00048 }
00049 
00050 /******************************************************************************
00051  * ListKey Destructor - cleans up instance of ListKey
00052  */
00053 
00054 ListKey::~ListKey()
00055 {
00056         ClearList();
00057 }
00058 
00059 
00060 /******************************************************************************
00061  * ListKey::ClearList   - Clears out elements of list
00062  */
00063 
00064 void ListKey::ClearList()
00065 {
00066         int loop;
00067 
00068         if (arraymax) {
00069                 for (loop = 0; loop < arraycnt; loop++)
00070                         delete array[loop];
00071 
00072                 free(array);
00073                 arraymax  = 0;
00074         }
00075         arraycnt  = 0;
00076         arraypos  = 0;
00077         array     = 0;
00078 }
00079 
00080 
00081 /******************************************************************************
00082  * ListKey::copyFrom Equates this ListKey to another ListKey object
00083  *
00084  * ENT: ikey - other ListKey object
00085  */
00086 
00087 void ListKey::copyFrom(const ListKey &ikey) {
00088         ClearList();
00089 
00090         arraymax = ikey.arraymax;
00091         arraypos = ikey.arraypos;
00092         arraycnt = ikey.arraycnt;
00093         array = (arraymax)?(SWKey **)malloc(ikey.arraymax * sizeof(SWKey *)):0;
00094         for (int i = 0; i < arraycnt; i++)
00095                 array[i] = ikey.array[i]->clone();
00096 
00097         SetToElement(0);
00098 }
00099 
00100 
00101 /******************************************************************************
00102  * ListKey::add - Adds an element to the list
00103  */
00104 
00105 void ListKey::add(const SWKey &ikey) {
00106         if (++arraycnt > arraymax) {
00107                 array = (SWKey **) ((array) ? realloc(array, (arraycnt + 32) * sizeof(SWKey *)) : calloc(arraycnt + 32, sizeof(SWKey *)));
00108                 arraymax = arraycnt + 32;
00109         }
00110         array[arraycnt-1] = ikey.clone();
00111         SetToElement(arraycnt-1);
00112 }
00113 
00114 
00115 
00116 /******************************************************************************
00117  * ListKey::setPosition(SW_POSITION)    - Positions this key
00118  *
00119  * ENT: p       - position
00120  *
00121  * RET: *this
00122  */
00123 
00124 void ListKey::setPosition(SW_POSITION p) {
00125         switch (p) {
00126         case 1: // GCC won't compile P_TOP
00127                 SetToElement(0);
00128                 break;
00129         case 2: // GCC won't compile P_BOTTOM
00130                 SetToElement(arraycnt-1);
00131                 break;
00132         }
00133 }
00134 
00135 
00136 /******************************************************************************
00137  * ListKey::increment - Increments a number of elements
00138  */
00139 
00140 void ListKey::increment(int step) {
00141         if (step < 0) {
00142                 decrement(step*-1);
00143                 return;
00144         }
00145         Error();                // clear error
00146         for(; step && !Error(); step--) {
00147                 if (arraypos < arraycnt) {
00148                         (*(array[arraypos]))++;
00149                         if (array[arraypos]->Error()) {
00150                                 SetToElement(arraypos+1);
00151                         }
00152                         else *this = (const char *)(*array[arraypos]);
00153                 }
00154                 else error = KEYERR_OUTOFBOUNDS;
00155         }
00156 }
00157 
00158 
00159 /******************************************************************************
00160  * ListKey::decrement - Decrements a number of elements
00161  */
00162 
00163 void ListKey::decrement(int step) {
00164         if (step < 0) {
00165                 increment(step*-1);
00166                 return;
00167         }
00168         Error();                // clear error
00169         for(; step && !Error(); step--) {
00170                 if (arraypos > -1) {
00171                         (*(array[arraypos]))--;
00172                         if (array[arraypos]->Error()) {
00173                                 SetToElement(arraypos-1, BOTTOM);
00174                         }
00175                         else *this = (const char *)(*array[arraypos]);
00176                 }
00177                 else error = KEYERR_OUTOFBOUNDS;
00178         }
00179 }
00180 
00181 
00182 /******************************************************************************
00183  * ListKey::Count       - Returns number of elements in list
00184  */
00185 
00186 int ListKey::Count() {
00187         return arraycnt;
00188 }
00189 
00190 
00191 /******************************************************************************
00192  * ListKey::SetToElement        - Sets key to element number
00193  *
00194  * ENT: ielement        - element number to set to
00195  *
00196  * RET: error status
00197  */
00198 
00199 char ListKey::SetToElement(int ielement, SW_POSITION pos) {
00200         arraypos = ielement;
00201         if (arraypos >= arraycnt) {
00202                 arraypos = (arraycnt>0)?arraycnt - 1:0;
00203                 error = KEYERR_OUTOFBOUNDS;
00204         }
00205         else {
00206                 if (arraypos < 0) {
00207                         arraypos = 0;
00208                         error = KEYERR_OUTOFBOUNDS;
00209                 }
00210                 else {
00211                         error = 0;
00212                 }
00213         }
00214         
00215         if (arraycnt) {
00216                 (*array[arraypos]) = pos;
00217                 *this = (const char *)(*array[arraypos]);
00218         }
00219         else *this = "";
00220         
00221         return error;
00222 }
00223 
00224 
00225 /******************************************************************************
00226  * ListKey::GetElement  - Gets a key element number
00227  *
00228  * ENT: pos     - element number to get (or default current)
00229  *
00230  * RET: Key or null on error
00231  */
00232 
00233 SWKey *ListKey::GetElement(int pos) {
00234         if (pos >=0) {
00235                 if (pos >=arraycnt)
00236                         error = KEYERR_OUTOFBOUNDS;
00237         }
00238         else pos = arraypos;
00239         return (error) ? 0:array[pos];
00240 }
00241         
00242 
00243 /******************************************************************************
00244  * ListKey::Remove      - Removes current element from list
00245  */
00246 
00247 void ListKey::Remove() {
00248         if ((arraypos > -1) && (arraypos < arraycnt)) {
00249                 delete array[arraypos];
00250                 if (arraypos < arraycnt - 1)
00251                         memmove(&array[arraypos], &array[arraypos+1], (arraycnt - arraypos - 1) * sizeof(SWKey *));
00252                 arraycnt--;
00253                 
00254                 SetToElement((arraypos)?arraypos-1:0);
00255         }
00256 }

Generated on Thu Jun 20 22:12:59 2002 for The Sword Project by doxygen1.2.15