2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
12 * The Original Code is the Sablotron XSLT Processor.
14 * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15 * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16 * Ginger Alliance Ltd. All Rights Reserved.
20 * Alternatively, the contents of this file may be used under the
21 * terms of the GNU General Public License Version 2 or later (the
22 * "GPL"), in which case the provisions of the GPL are applicable
23 * instead of those above. If you wish to allow use of your
24 * version of this file only under the terms of the GPL and not to
25 * allow others to use your version of this file under the MPL,
26 * indicate your decision by deleting the provisions above and
27 * replace them with the notice and other provisions required by
28 * the GPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under either the MPL or the
36 // most constants (list sizes etc.) are in base.h
43 // error.h will be included later:
44 #define BaseH_NoErrorH
49 typedef unsigned long Phrase;
53 #define QSORT_THRESHOLD 10 // insertsort is used for smaller lists
55 // List is a basic structure for ordered lists.
56 // If the T's are pointers, you may want to use PList instead, which
57 // allows you to delete the pointers (in List, they are just taken off the
61 class List /* : public SabObj */
64 List(int logBlocksize_ = LIST_SIZE_SMALL);
65 // append an element to the end of list
67 // remove last element from list
69 // remove all elements (shrink list to size 0)
71 // remove element with given index
73 // test whether list is empty
75 // number of elements in list
76 inline int number() const;
77 // get element with given index
78 T& operator[](int ndx) const;
80 inline T& last() const;
81 // swap two elements with given indices
82 virtual void swap(int,int);
83 void insertBefore(T newMember, int refIndex);
89 int blocksize, origBlocksize;
90 virtual T* claimMemory( int nbytes ) const { return (T*) malloc(nbytes); }
91 virtual T* reclaimMemory( T *p, int newbytes, int oldbytes ) const
92 { return (T*) realloc(p, newbytes); }
93 virtual void returnMemory( T* &p ) const { if (p) free(p); p = NULL; }
96 // PList is for lists whose members are pointers. It adds the possibility
97 // to delete pointers when removing them from the list.
98 // The Bool parameters in its methods say whether delete[] or delete should
99 // be used (TRUE/FALSE, respectively).
102 class PList : public List<T>
105 PList(int logBlocksize_ = LIST_SIZE_SMALL);
106 // free and remove the last pointer
108 // free and remove all pointers
110 // free and remove the given pointer
111 void freerm(int, Bool);
115 /*****************************************************************
118 is a class for "dynamic memory blocks", i.e. blocks that can
120 *****************************************************************/
135 void nadd(const char *data, int bytes);
136 Bool isEmpty() const;
137 char* getPointer() const;
138 char* compactToBuffer() const;
141 DynBlockItem *first, *last;
143 void compact() const;
144 int compactToBuffer_(char* buf, Bool kill_);
148 // block for the dynamic strings
149 class DynStrBlock : public DynBlock
152 // compact the string into one chunk,
153 // prepending 'firstPart' and appending 0.
154 char* compactString_(const char *firstPart, int firstLen);
158 /*****************************************************************
163 *****************************************************************/
171 // constructors: default, copy, from char, char* and from
174 Str(const Str& string);
178 Str(const char *chars);
179 Str(const DStr &dstring);
181 // assignment: from DStr, Str, char*, char, int, double
182 Str& operator=(const DStr& string);
183 Str& operator=(const Str& string);
184 Str& operator=(const char *chars);
185 Str& operator=(char c);
186 Str& operator=(int number);
187 Str& operator=(double dblnum);
189 // set self to a string of length 'len' (non-NULL-terminated)
190 void nset(const char* chars, int len);
192 // set self to an empty string
193 virtual void empty();
195 // test whether the string is void
196 Bool isEmpty() const;
198 // get byte with the given index
199 // NEEDS TO INCLUDE pack_()
200 char operator[](int index) const;
202 // convert to const char* (just return the internal pointer)
203 // NEEDS TO INCLUDE pack_()
204 virtual operator char*() const;
206 // test for < / == / > against a Str, char*
207 // NEEDS TO INCLUDE pack_()
208 int compare(const Str &other) const;
209 int compare(const char *otherChars) const;
211 // test for being lex-smaller than other Str, char*
212 // NEEDS TO INCLUDE pack_()
213 Bool operator< (const Str &);
214 Bool operator< (const char*);
216 // test for equality: to a Str, char*
217 // NEEDS TO INCLUDE pack_()
218 Bool operator== (const Str& other) const;
219 Bool operator== (const char* otherChars) const;
220 Bool operator== (char* otherChars) const;
222 // non-case-sensitive test for equality: to a Str, char*
223 // NEEDS TO INCLUDE pack_()
224 Bool eqNoCase(const Str& other) const;
225 Bool eqNoCase(const char* otherChars) const;
227 // get the byte length of the string
228 virtual int length() const;
230 // addition operator: with char*, Str and int
231 // NEEDS TO INCLUDE pack_()
232 DStr operator+ (const Str& other) const;
233 DStr operator+ (const char *otherChars) const;
234 DStr operator+ (int otherNum) const;
236 // convert *this to double, return FALSE if OK
237 Bool toDouble(double& retval) const;
239 DStr& appendSelf(DStr& other);
242 // THE FOLLOWING 3 FUNCTIONS WOULD BE BEST REMOVED
243 // output *this to another string with whitespace trimmed
244 void speakTerse(DStr &);
250 // deallocate all memory used
251 virtual void remove_() { returnMemory(text_); }
253 // pack all parts (in derived classes) to form a valid Str
254 virtual void pack_() const;
256 // claimMemory and returnMemory are to facilitate allocating the character data in an arena
257 virtual char* claimMemory( int nbytes ) const { return new char[nbytes]; }
259 virtual void returnMemory( char *&p ) const { if (p) delete[] p; p = NULL; }
266 /*****************************************************************
269 *****************************************************************/
271 class DStr : public Str
276 DStr(const char *chars);
277 DStr(const Str& string);
278 DStr(const DStr& dstring);
280 DStr& operator=(const DStr& other);
282 // append a string or whatever
283 DStr& operator+= (const DStr& other);
284 DStr& operator+= (const Str& other);
285 DStr& operator+= (const char* otherChars);
286 DStr& operator+= (char c);
287 DStr& operator+= (int num);
289 virtual DStr& appendSelf(DStr& other);
291 // nadd adds a non-zero-terminated string
292 DStr& nadd(const char *,int);
294 virtual operator char*() const;
295 virtual int length() const;
297 // consume is just like += but it steals the char*'s from 'other'.
299 DStr& operator consume(Str &other);
300 DStr& operator consume(DStr &other);
305 // deallocate all memory used
306 virtual void remove_();
307 // pack all parts (in derived classes) to form a valid Str
308 virtual void pack_() const;
315 // string constants and functions
319 void escapeChars(DStr& result, const Str& what,
320 const char* toEscape, const char** substitutes);
322 /* extern const Str* theEmptyString; */
324 /*****************************************************************
326 *****************************************************************/
328 class NamespaceStackObj /* : public SabObj */
335 class NamespaceStack : public PList<NamespaceStackObj*>
338 // find the index of the element with the given key
339 int findNum(const Str &_key) const;
340 // find the value of the element with the given key
341 const Str* getUri(const Str &) const;
342 Bool isHidden(const Str &) const;
343 void appendConstruct(const Str &prefix, const Str& uri,
347 /****************************************
349 ****************************************/
350 // container for a QName (e.g. "books:isbn") consisting
351 // of the "namespace prefix", "namespace URI" and the "local part"
355 friend class TreeConstructer;
358 QName(const QName &other);
359 // set the QName from the string received from expat (using NS_SEP)
360 QName& operator =(const QName& other);
361 Bool isEmpty() const;
364 // set just the prefix
365 void setPrefix(Phrase);
366 void setLocal(Phrase);
369 // return the full name
370 // Str getname(Tree& t) const;
371 // return the local part
372 Phrase getLocal() const;
374 Phrase getUri() const;
376 Phrase getPrefix() const;
377 // return true if a prefix is defined
378 Bool hasPrefix() const;
380 // check for equality to another qname
381 Bool operator==(const QName &) const;
383 // output to a string
384 // void speak(DStr&, SpeakMode) const;
385 // check if our own prefix is bound to the given namespace
386 // Bool prefixIsNS(const Str &s) const;
387 // get the associated dictionary
395 /*****************************************************************
397 *****************************************************************/
399 class QNameList : public PList<QName *>
402 // finds item with equal local-part and uri
403 int findNdx(const QName &what) const;
406 /****************************************
408 ****************************************/
412 // friend class TreeConstructer;
415 EQName(const EQName&);
416 Bool isEmpty() const;
419 void set(const QName&, const HashTable&);
420 void setPrefix(const Str&);
421 void setLocal(const Str&);
422 void setUri(const Str&);
424 // return the full name
425 void getname(Str& fullName) const;
426 // return the local part
427 const Str& getLocal() const;
429 const Str& getUri() const;
431 const Str& getPrefix() const;
432 // return true if a prefix is defined
433 Bool hasPrefix() const;
435 // check for equality to another qname
436 Bool operator==(const EQName &) const;
447 /*****************************************************************
449 *****************************************************************/
451 class StrStr /* : public SabObj */
459 class StrStrList : public PList<StrStr*>
462 // find the index of the element with the given key
463 int findNum(const Str &_key) const;
464 // find the value of the element with the given key
465 Str* find(const Str &) const;
466 void appendConstruct(const Str &key, const Str& value);
470 /*****************************************************************
472 *****************************************************************/
474 class EQNameList : public PList<EQName *>
477 const EQName* find(const EQName &what) const;
480 /*****************************************************************
481 E Q N a m e S t r L i s t
482 *****************************************************************/
485 EQNameStr(const EQName& key_, const Str& value_) : key(key_), value(value_)
492 class EQNameStrList : public PList<EQNameStr *>
498 int findNdx(const EQName &what) const;
499 const Str* find(const EQName &what) const;
500 void appendConstruct(const EQName &key, const Str& value);
503 /*****************************************************************
507 *****************************************************************/
510 class SList: public PList<T>
513 SList(int logBlocksize_);
514 // comparison of two elements
515 virtual int compare(int, int, void *data)
516 { assert(!"abstract compare"); return 0; }
517 // insertion of an element
518 void insert(T, void *data = NULL);
519 void sort(int from = 0, int to = - 1, void *data = NULL); // to == -1 means "nItems-1"
521 void quicksort(int bottom, int top, void *data);
522 void qsPartition(int& i, int& j, void *data);
523 void insertsort(int bottom, int top, void *data);
537 Expression *sortExpr;
539 Bool asText, ascend, upper1st;
541 : sortExpr(NULL), asText(TRUE), ascend(TRUE), upper1st(FALSE)
543 SortDef(Expression *sortExpr_, Str lang_,
544 Bool asText_, Bool ascend_, Bool upper1st_)
545 : sortExpr(sortExpr_), lang(lang_),
546 asText(asText_), ascend(ascend_), upper1st(upper1st_)
556 class SortDefList : public PList<SortDef*>
558 void appendConstruct(Expression *sortExpr_, Str lang_,
559 Bool asText_, Bool ascend_, Bool upper1st_)
561 append(new SortDef(sortExpr_, lang_,
562 asText_, ascend_, upper1st_));
566 /***************************************
568 ****************************************/
570 /****************************************/
571 /* exclusion prefix list */
573 class UriList : public PList<Phrase>
578 //void removeUri(Str & uri);
582 /*****************************************************************
584 t e m p l a t e m e t h o d s
586 *****************************************************************/
592 /*================================================================
594 ================================================================*/
597 List<T>::List(int logBlocksize_)
599 origBlocksize(TWO_TO(logBlocksize_))
608 void List<T>::append(T what)
610 if (nItems >= blocksize)
616 blocksize = origBlocksize;
617 block = (T*) claimMemory(blocksize * sizeof(T));
618 // FIXME: asserting memory request ok
622 block[nItems++] = what;
626 void List<T>::deppend()
630 if (!(nItems & (nItems - 1)) && (nItems >= origBlocksize)) // realloc at powers of 2
632 int oldblocksize = blocksize;
636 block = (T*) reclaimMemory(block, blocksize * sizeof(T),
637 oldblocksize * sizeof(T));
638 // FIXME: asserting memory request ok
646 // double the block size
652 blocksize = blocksize << 1;
653 int nbytes = blocksize * sizeof(T);
654 block = (T*) reclaimMemory(block, nbytes, nbytes >> 1);
655 // FIXME: asserting memory request ok
660 void List<T>::rm(int n)
662 assert((n >= 0) && (n < nItems));
663 memmove(block + n, block + n + 1, (nItems - n - 1) * sizeof(T));
668 void List<T>::swap(int i, int j)
670 assert((i >= 0) && (i < nItems));
671 assert((j >= 0) && (j < nItems));
678 void List<T>::deppendall()
690 inline int List<T>::number() const
702 inline T& List<T>::operator[](int ndx) const
704 assert((ndx < nItems) && (ndx >= 0));
709 inline T& List<T>::last() const
712 return block[nItems - 1];
716 Bool List<T>::isEmpty() const
718 return (Bool) (!nItems);
722 void List<T>::insertBefore(T newMember, int refIndex)
725 memmove(block + refIndex + 1, block + refIndex,
726 (number()-refIndex-1) * sizeof(T));
727 block[refIndex] = newMember;
730 /*================================================================
732 ================================================================*/
734 #define deleteScalarOrVector(PTR, VECT) \
735 {if (VECT) delete[] PTR; else delete PTR;}
738 PList<T>::PList(int logBlocksize_)
739 : List<T>(logBlocksize_)
744 void PList<T>::freelast(Bool asArray)
746 deleteScalarOrVector(this->last(), asArray);
751 void PList<T>::freeall(Bool asArray)
753 for (int i = 0; i < this->nItems; i++)
754 deleteScalarOrVector(this->block[i], asArray);
759 void PList<T>::freerm(int n, Bool asArray)
761 assert((n >= 0) && (n < this->nItems));
762 deleteScalarOrVector(this->block[n], asArray);
766 /*================================================================
768 ================================================================*/
771 SList<T>::SList(int logBlocksize_)
772 : PList<T>(logBlocksize_)
777 void SList<T>::insert(T what, void *data /* = NULL */)
780 int whatndx = this->number() - 1;
782 for (i=0; i < whatndx; i++)
783 if (compare(whatndx, i, data) == -1) break;
786 for (j = whatndx; j > i; j--)
787 this->operator[](j) = this->operator[](j-1);
788 this->operator[](i) = what;
793 void SList<T>::insertsort(int bottom, int top, void *data)
797 for (ceiling = bottom + 1; ceiling <= top; ceiling++)
799 //curr = this->block[ceiling];
801 for (k = ceiling - 1; k >= bottom && compare(k, ceiling) > 0; k--)
802 this->block[k+1] = this->block[k];
803 this->block[k+1] = curr;
804 * but need to use swap() to drag extra pointers along
806 for (k = ceiling - 1; k >= bottom && compare(k, k + 1, data) > 0; k--)
812 void SList<T>::qsPartition(int& bottom, int& top, void *data)
814 int middle = (bottom + top) >> 1;
815 if (compare(bottom, top, data) > 0) this->swap(bottom, top);
816 if (compare(middle, top, data) > 0) this->swap(middle, top);
817 if (compare(bottom, middle, data) > 0) this->swap(bottom, middle);
818 // T pivot = this->block[middle];
819 while (bottom <= top)
821 // boundary conditions fixed by Tim
822 while ((++bottom <= top) && compare(bottom, middle, data) <= 0);
823 while ((--top >= bottom) && (compare(top, middle, data) >= 0));
827 if (middle == bottom)
829 else if (middle == top)
831 this->swap(bottom, top);
837 void SList<T>::quicksort(int bottom, int top, void *data)
839 assert(QSORT_THRESHOLD >= 3);
840 int i = bottom, j = top;
841 if (top - bottom < QSORT_THRESHOLD)
842 insertsort(bottom, top, data);
845 qsPartition(i, j, data);
846 quicksort(bottom, j, data);
847 quicksort(i, top, data);
852 void SList<T>::sort(int from /* = 0 */, int to /* = - 1 */, void *data /* = NULL */)
854 /* cannot initialize 'to' to nItems-1 directly as g++ reports error */
856 to = this->nItems - 1;
857 if (this->nItems < 2)
859 quicksort(from, to, data);
862 /******************* expression list moved here ***************/
863 typedef PList<Expression *> ExprList;
865 #endif //ifndef DataStrHIncl