Main Page | Class Hierarchy | Class List | File List | Class Members

/Users/baford/proj/netsteria/sst/lib/util.h

00001 #ifndef SST_UTIL_H
00002 #define SST_UTIL_H
00003 
00004 #include <QList>
00005 #include <QHash>
00006 #include <QString>
00007 #include <QByteArray>
00008 #include <QPointer>
00009 #include <QHostAddress>
00010 
00011 #include <openssl/bn.h>
00012 
00013 
00014 namespace SST {
00015 
00016 class XdrStream;
00017 
00018 
00019 // Sorted lists with incremental insertion via binary search.
00020 template<typename T> class SortList : public QList<T>
00021 {
00022         // Find the position at which an item is or should be located.
00023         // May optionally restrict the search to a specified range of items,
00024         // if something about the location of the item is already known.
00025         inline int find(const T &value, int lo = 0,
00026                         int hi = QList<T>::size()) const {
00027                 while (lo < hi) {
00028                         int mid = (hi + lo) / 2;
00029                         if (this->at(mid) < value)
00030                                 lo = mid+1;
00031                         else
00032                                 hi = mid;
00033                 }
00034                 return hi;
00035         }
00036 
00037         // Find an item via binary search, returning -1 if not present.
00038         inline int indexOf(const T &value, int from = 0) const {
00039                 int i = pos(value, from);
00040                 if (i >= QList<T>::size() || value < QList<T>::at(i))
00041                         return -1;
00042                 return i;
00043         }
00044 
00045         // Insert an item at its proper position in the list,
00046         // before any existing items having the same comparative position.
00047         inline void insert(const T &value) {
00048                 insert(pos(value), value);
00049         }
00050 };
00051 
00052 
00053 
00054 // This class holds a set of QPointers,
00055 // whose members automatically disappear as their targets get deleted.
00056 template<typename T> class QPointerSet
00057 {
00058         // G++ doesn't seem to like the hairy nested template invocations
00059         // needed to make the internal hash object depend properly on T,
00060         // so we just make it use QObject and cast away...
00061         typedef QHash<QObject*, QPointer<QObject> > Hash;
00062         typedef QHash<QObject*, QPointer<QObject> >::iterator
00063                         HashIter;
00064         typedef QHash<QObject*, QPointer<QObject> >::const_iterator
00065                         HashConstIter;
00066 
00067         Hash hash;
00068 
00069 public:
00070         inline void insert(T *ptr) { hash.insert(ptr, ptr); }
00071         inline void remove(T *ptr) { hash.remove(ptr); }
00072         inline bool contains(T *ptr) { return hash.value(ptr) == ptr; }
00073 
00074         class const_iterator
00075         {
00076                 HashConstIter i;        // Current position
00077                 HashConstIter e;        // End position
00078 
00079         public:
00080 
00081                 // Skip null pointers, moving forward
00082                 inline void skipfwd()
00083                         { while (i != e && i.value() == NULL) i++; }
00084 
00085                 inline const_iterator(const HashConstIter &i,
00086                                         const HashConstIter &e)
00087                         : i(i), e(e) { skipfwd(); }
00088 
00089                 inline const_iterator &operator++()
00090                         { i++; skipfwd(); return *this; }
00091 
00092                 inline bool operator==(const const_iterator &o) const
00093                         { return i == o.i; }
00094                 inline bool operator!=(const const_iterator &o) const
00095                         { return i != o.i; }
00096 
00097                 inline T *operator*() const
00098                         { return reinterpret_cast<T*>(&(*i.value())); }
00099         };
00100 
00101         inline const_iterator begin() const
00102                 { return const_iterator(hash.constBegin(), hash.constEnd()); }
00103         inline const_iterator end() const
00104                 { return const_iterator(hash.constEnd(), hash.constEnd()); }
00105 
00106         inline const_iterator constBegin() const
00107                 { return const_iterator(hash.constBegin(), hash.constEnd()); }
00108         inline const_iterator constEnd() const
00109                 { return const_iterator(hash.constEnd(), hash.constEnd()); }
00110 };
00111 
00112 
00113 // Generate cryptographically random and pseudo-random bytes
00114 QByteArray randBytes(int size);
00115 QByteArray pseudoRandBytes(int size);
00116 
00117 // Convert between OpenSSL BIGNUMs and QByteArrays
00118 BIGNUM *ba2bn(const QByteArray &ba, BIGNUM *ret = NULL);
00119 QByteArray bn2ba(const BIGNUM *bn);
00120 
00121 XdrStream &operator<<(XdrStream &xs, BIGNUM *bn);
00122 XdrStream &operator>>(XdrStream &xs, BIGNUM *&bn);
00123 
00124 
00125 // Convenient representation for a network endpoint: an (address, port) pair.
00126 struct Endpoint
00127 {
00128         // Type codes for XDR externalization
00129         enum Type {
00130                 IPv4 = 1,
00131                 IPv6 = 2
00132         };
00133 
00134         QHostAddress addr;
00135         quint16 port;
00136 
00137         Endpoint();
00138         Endpoint(quint32 ip4addr, quint16 port);
00139         Endpoint(const QHostAddress &addr, quint16 port);
00140 
00141         inline bool isNull() const { return addr.isNull() && port == 0; }
00142 
00143         inline bool operator==(const Endpoint &other) const
00144                 { return addr == other.addr && port == other.port; }
00145         inline bool operator!=(const Endpoint &other) const
00146                 { return !(addr == other.addr && port == other.port); }
00147 
00148         QString toString() const;
00149 
00150         void encode(XdrStream &xs) const;
00151         void decode(XdrStream &xs);
00152 };
00153 
00154 inline XdrStream &operator<<(XdrStream &xs, const Endpoint &ep)
00155         { ep.encode(xs); return xs; }
00156 inline XdrStream &operator>>(XdrStream &xs, Endpoint &ep)
00157         { ep.decode(xs); return xs; }
00158 
00159 
00160 // Convert a byte count to a string using standard notation: KB, MB, etc.
00161 QString bytesNumber(qint64 size);
00162 
00163 
00164 } // namespace SST
00165 
00166 
00167 // Hash function for SST Endpoint structs
00168 uint qHash(const SST::Endpoint &ep);
00169 
00170 
00171 #endif  // SST_UTIL_H

Generated on Wed Mar 28 11:48:05 2007 for SST by doxygen 1.3.4