uniconfkey.h

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 2002 Net Integration Technologies, Inc.
00004  * 
00005  * UniConfKeys are paths in the UniConf hierarchy.
00006  */
00007 #ifndef __UNICONFKEY_H
00008 #define __UNICONFKEY_H
00009 
00010 #include "wvstring.h"
00011 #include "wvlinklist.h"
00012 
00013 
00014 // The Python headers try to #define ANY as void.  If we're building Python
00015 // wrappers, get rid of that.
00016 #undef ANY
00017 
00018 
00042 class UniConfKey
00043 {
00044     class Segment : public WvString
00045     {
00046     public:
00047         Segment() :
00048             WvString(WvString::empty)
00049         {
00050         }
00051         Segment(WvStringParm str) :
00052             WvString((!str)? WvString::empty: str)
00053         {
00054         }
00055         Segment(const Segment &segment) :
00056             WvString(segment)
00057         {
00058         }
00059         
00060         bool iswild() const
00061         {
00062             return *this == "*" || *this == "...";
00063         }
00064     };
00065 
00066     class SegmentVector
00067     {
00068         int _size, _used;
00069         Segment *vec;
00070     public:
00071         SegmentVector(int size) :
00072             _size(size),
00073             _used(0),
00074             vec(new Segment[_size])
00075         {
00076         }
00077         ~SegmentVector()
00078         {
00079             deletev vec;
00080         }
00081         
00082         void resize(int size, int shift = 0)
00083         {
00084             if (size <= _size)
00085             {
00086                 if (shift > 0)
00087                 {
00088                     for (int i=_used-1; i>=0; --i)
00089                         vec[i+shift] = vec[i];
00090                     _used += shift;
00091                 }
00092                 return;
00093             }
00094             Segment *old_vec = vec;
00095             vec = new Segment[size];
00096             if (old_vec)
00097             {
00098                 int limit = size-shift;
00099                 if (limit > _size)
00100                     limit = _size;
00101                 if (limit > _used)
00102                     limit = _used;
00103                 for (int i=0; i<limit; ++i)
00104                     vec[i+shift] = old_vec[i];
00105                 deletev old_vec;
00106             }
00107             _size = size;
00108             _used += shift;
00109         }
00110         void zap()
00111         {
00112             _used = 0;
00113         }
00114         int size() const
00115         {
00116             return _size;
00117         }
00118         int used() const
00119         {
00120             return _used;
00121         }
00122         
00123         void append(const Segment &segment)
00124         {
00125             vec[_used++] = segment;
00126         }
00127         void append(WvStringParm string)
00128         {
00129             append(Segment(string));
00130         }
00131         void replace(int index, const Segment &segment)
00132         {
00133             vec[index] = segment;
00134             if (index >= _used)
00135                 _used = index + 1;
00136         }
00137         void replace(int index, WvStringParm string)
00138         {
00139             replace(index, Segment(string));
00140         }
00141         const Segment &operator [](int index) const
00142         {
00143             return vec[index];
00144         }
00145     };
00146     
00147     struct Store
00148     {
00149         SegmentVector segments;
00150         int ref_count;
00151         
00152         Store(int size, int _ref_count, WvStringParm key = WvString::null);
00153     };
00154 
00155     Store *store;
00156     int left, right;
00157     
00158     static Store EMPTY_store; 
00159     static Store ANY_store;   
00160     static Store RECURSIVE_ANY_store; 
00162     UniConfKey(Store *_store, int _left, int _right) :
00163         store(_store),
00164         left(_left),
00165         right(_right)
00166     {
00167         store->ref_count++;
00168     }
00169         
00170     void unique();
00171     void normalize();
00172     UniConfKey &collapse();
00173 
00174 public:
00175     static UniConfKey EMPTY; 
00176     static UniConfKey ANY;   
00177     static UniConfKey RECURSIVE_ANY; 
00180     UniConfKey() :
00181         store(&EMPTY_store),
00182         left(0),
00183         right(0)
00184     {
00185         store->ref_count++;
00186     }
00187 
00196     UniConfKey(WvStringParm key) :
00197         store(new Store(4, 1, key)),
00198         left(0),
00199         right(store->segments.used())
00200     {
00201     }
00202 
00212     UniConfKey(const char *key) :
00213         store(new Store(4, 1, WvFastString(key))),
00214         left(0),
00215         right(store->segments.used())
00216     {
00217     }   
00218     
00220     UniConfKey(int key) :
00221         store(new Store(1, 1, WvFastString(key))),
00222         left(0),
00223         right(store->segments.used())
00224     {
00225     }
00226 
00231     UniConfKey(const UniConfKey &other) :
00232         store(other.store),
00233         left(other.left),
00234         right(other.right)
00235     {
00236         store->ref_count++;
00237     }
00238 
00244     UniConfKey(const UniConfKey &path, const UniConfKey &key);
00245 
00246     ~UniConfKey()
00247     {
00248         if (--store->ref_count == 0)
00249             delete store;
00250     }
00251 
00256     void append(const UniConfKey &other);
00257 
00262     void prepend(const UniConfKey &other);
00263 
00268     bool isempty() const
00269     {
00270         return right == left;
00271     }
00272 
00274     bool iswild() const;
00275 
00277     bool hastrailingslash() const
00278     {
00279         return right > left && !store->segments[right-1];
00280     }
00281 
00291     int numsegments() const
00292     {
00293         return right - left;
00294     }
00295 
00301     UniConfKey segment(int n) const
00302     {
00303         return range(n, n + 1);
00304     }
00305 
00311     UniConfKey pop(int n = 1);
00312     
00318     UniConfKey first(int n = 1) const
00319     {
00320         return range(0, n);
00321     }
00322 
00328     UniConfKey last(int n = 1) const
00329     {
00330         return range(numsegments() - n, __INT_MAX__);
00331     }
00332 
00339     UniConfKey removefirst(int n = 1) const
00340     {
00341         return range(n, __INT_MAX__);
00342     }
00343 
00350     UniConfKey removelast(int n = 1) const
00351     {
00352         return range(0, numsegments() - n);
00353     }
00354 
00361     UniConfKey range(int i, int j) const;
00362 
00374     WvString printable() const;
00375     operator WvString() const
00376         { return printable(); }
00377 
00381     const char *cstr() const
00382         { return printable(); }
00383 
00388     UniConfKey &operator= (const UniConfKey &other)
00389     {
00390         if (--store->ref_count == 0)
00391             delete store;
00392         store = other.store;
00393         left = other.left;
00394         right = other.right;
00395         ++store->ref_count;
00396         return *this;
00397     }
00398 
00406     int compareto(const UniConfKey &other) const;
00407 
00418     bool matches(const UniConfKey &pattern) const;
00419 
00420 
00424     bool suborsame(const UniConfKey &key) const;
00425     bool suborsame(const UniConfKey &key, UniConfKey &subkey) const;
00426 
00432     UniConfKey subkey(const UniConfKey &key) const;
00433 
00439     bool operator== (const UniConfKey &other) const
00440         { return compareto(other) == 0; }
00441         
00447     bool operator!= (const UniConfKey &other) const
00448         { return compareto(other) != 0; }
00449 
00455     bool operator< (const UniConfKey &other) const
00456         { return compareto(other) < 0; }
00457 
00458     class Iter;
00459 
00460     friend unsigned WvHash(const UniConfKey &k);
00461 };
00462 
00463 
00464 DeclareWvList(UniConfKey);
00465 
00467 class UniConfKey::Iter
00468 {
00469     const UniConfKey &key;
00470     int seg, max;
00471     UniConfKey curseg;
00472     
00473 public:
00474     Iter(const UniConfKey &_key) : key(_key) 
00475         { }
00476 
00477     void rewind()
00478         { seg = -1; max = key.numsegments(); }
00479     
00480     bool cur()
00481         { return seg >= 0 && seg < max; }
00482     
00483     bool next()
00484         { seg++; curseg = key.segment(seg); return cur(); }
00485     
00486     const UniConfKey *ptr() const
00487         { return &curseg; }
00488     
00489     WvIterStuff(const UniConfKey);
00490 };
00491 
00492 #endif // __UNICONFKEY_H

Generated on Thu Jan 24 16:50:55 2008 for WvStreams by  doxygen 1.5.4