Sirikata
libcore/include/sirikata/core/util/VInt.hpp
Go to the documentation of this file.
00001 /*  Sirikata -- Variable Length Serializable Integer
00002  *  VInt.hpp
00003  *
00004  *  Copyright (c) 2009, Daniel Reiter Horn
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 
00034 namespace Sirikata {
00035 template <class T> class VInt : public TotallyOrdered<T> {
00036 protected:
00037     T mData;
00038 public:
00039     enum MaxSerializedLengthConstraints {
00040         MAX_SERIALIZED_LENGTH=sizeof(T)+sizeof(T)/8+((sizeof(T)%8==0)?0:1)
00041     };
00042     bool odd() const {
00043         return mData&1;
00044     }
00045     T read() const {
00046         return mData;
00047     }
00048     uint64 readRawData()const {
00049         uint64 ander=0;
00050         for (size_t i=0;i<sizeof(T);++i) {
00051             ander<<=8;
00052             ander|=255;
00053         }
00054         uint64 retval=(uint64)mData;
00055         retval&=ander;
00056         return retval;
00057     }
00058     unsigned int serializedSize() const {
00059         uint64 tmp=readRawData();
00060         unsigned int retval=0;
00061         do {
00062             retval++;
00063             tmp/=128;
00064         }while (tmp);
00065         return retval;
00066     }
00067     unsigned int serialize(uint8 *destination, unsigned int maxsize) const {
00068         uint64 tmp=readRawData();
00069         unsigned int retval=0;
00070         do {
00071             if (retval>=maxsize) return 0;
00072             *destination = tmp&127;
00073             retval++;
00074             tmp/=128;
00075         }while (tmp&&(*destination++|=128));
00076         return retval;
00077     }
00078     bool unserialize(const uint8*src, unsigned int&size) {
00079         if (size==0) return false;
00080         unsigned int maxsize=size;
00081         uint64 retval=0;
00082         uint64 temp=0;
00083         for (size=0;size<maxsize;++size) {
00084             temp=src[size];
00085             bool endLoop=(temp&128)==0;
00086             temp&=127;
00087             temp<<=(size*7);
00088             retval|=temp;
00089             if (endLoop) {
00090                 mData=(T)retval;
00091                 ++size;
00092                 return true;
00093             }
00094         }
00095         return false;
00096     }
00097 
00098     VInt(){
00099         mData=0;
00100     }
00101     VInt(T num) {
00102         mData=num;
00103     }
00104 
00105     bool operator == (const VInt<T>&other)const {
00106         return mData==other.mData;
00107     }
00108     bool operator != (const VInt<T>&other)const {
00109         return mData!=other.mData;
00110     }
00111     bool operator < (const VInt<T>&other)const {
00112         return mData<other.mData;
00113     }    
00115     struct Hasher {
00117         size_t operator() (const VInt<T> &id) const{
00118             return std::tr1::hash<T>()(id.mData);
00119         }
00120     };    
00121 };
00122 
00123 }
00124