Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Namespace Members | Data Fields | Globals | Examples

encoding.h

Go to the documentation of this file.
00001 /*
00002 Copyright(c) 2002-2005 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
00003 
00004 
00005 Permission is hereby granted, free of charge, to any person 
00006 obtaining a copy of this software and associated documentation 
00007 files (the "Software"), to deal in the Software without restriction, 
00008 including without limitation the rights to use, copy, modify, merge, 
00009 publish, distribute, sublicense, and/or sell copies of the Software, 
00010 and to permit persons to whom the Software is furnished to do so, 
00011 subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included 
00014 in all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00017 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
00018 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00019 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00020 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
00021 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
00022 OTHER DEALINGS IN THE SOFTWARE.
00023 
00024 
00025 For more information please visit:   http://bmagic.sourceforge.net
00026 
00027 */
00028 
00029 #ifndef ENCODING_H__INCLUDED__
00030 #define ENCODING_H__INCLUDED__
00031 
00032 #include <memory.h>
00033 
00034 namespace bm
00035 {
00036 
00037 // ----------------------------------------------------------------
00038 /*!
00039    \brief Memory encoding.
00040    
00041    Class for encoding data into memory. 
00042    Properly handles aligment issues with integer data types.
00043 */
00044 class encoder
00045 {
00046 public:
00047     encoder(unsigned char* buf, unsigned size);
00048     void put_8(unsigned char c);
00049     void put_16(bm::short_t  s);
00050     void put_16(const bm::short_t* s, unsigned count);
00051     void put_32(bm::word_t  w);
00052     void put_32(const bm::word_t* w, unsigned count);
00053     unsigned size() const;
00054 private:
00055     unsigned char*  buf_;
00056     unsigned char*  start_;
00057     unsigned int    size_;
00058 };
00059 
00060 // ----------------------------------------------------------------
00061 /**
00062     Base class for all decoding functionality
00063 */
00064 class decoder_base
00065 {
00066 public:
00067     decoder_base(const unsigned char* buf) { buf_ = start_ = buf; }
00068     /// Reads character from the decoding buffer. 
00069     BMFORCEINLINE unsigned char get_8() { return *buf_++; }
00070     /// Returns size of the current decoding stream.
00071     BMFORCEINLINE 
00072     unsigned size() const { return (unsigned)(buf_ - start_); }
00073 protected:
00074    const unsigned char*   buf_;
00075    const unsigned char*   start_;
00076 };
00077 
00078 
00079 // ----------------------------------------------------------------
00080 /**
00081    Class for decoding data from memory buffer.
00082    Properly handles aligment issues with integer data types.
00083 */
00084 class decoder : public decoder_base
00085 {
00086 public:
00087     decoder(const unsigned char* buf);
00088     bm::short_t get_16();
00089     bm::word_t get_32();
00090     void get_32(bm::word_t* w, unsigned count);
00091     void get_16(bm::short_t* s, unsigned count);
00092 };
00093 
00094 // ----------------------------------------------------------------
00095 /**
00096    Class for decoding data from memory buffer.
00097    Properly handles aligment issues with integer data types.
00098    Converts data to big endian architecture 
00099    (presumed it was encoded as little endian)
00100 */
00101 typedef decoder decoder_big_endian;
00102 
00103 
00104 // ----------------------------------------------------------------
00105 /**
00106    Class for decoding data from memory buffer.
00107    Properly handles aligment issues with integer data types.
00108    Converts data to little endian architecture 
00109    (presumed it was encoded as big endian)
00110 */
00111 class decoder_little_endian : public decoder_base
00112 {
00113 public:
00114     decoder_little_endian(const unsigned char* buf);
00115     bm::short_t get_16();
00116     bm::word_t get_32();
00117     void get_32(bm::word_t* w, unsigned count);
00118     void get_16(bm::short_t* s, unsigned count);
00119 };
00120 
00121 
00122 
00123 // ----------------------------------------------------------------
00124 // Implementation details. 
00125 // ----------------------------------------------------------------
00126 
00127 /*! 
00128     \fn encoder::encoder(unsigned char* buf, unsigned size) 
00129     \brief Construction.
00130     \param buf - memory buffer pointer.
00131     \param size - size of the buffer
00132 */
00133 inline encoder::encoder(unsigned char* buf, unsigned size)
00134 : buf_(buf), start_(buf), size_(size)
00135 {
00136 }
00137 
00138 /*!
00139    \fn void encoder::put_8(unsigned char c) 
00140    \brief Puts one character into the encoding buffer.
00141    \param c - character to encode
00142 */
00143 BMFORCEINLINE void encoder::put_8(unsigned char c)
00144 {
00145     *buf_++ = c;
00146 }
00147 
00148 /*!
00149    \fn encoder::put_16(bm::short_t s)
00150    \brief Puts short word (16 bits) into the encoding buffer.
00151    \param s - short word to encode
00152 */
00153 BMFORCEINLINE void encoder::put_16(bm::short_t s)
00154 {
00155     *buf_++ = (unsigned char) s;
00156     s >>= 8;
00157     *buf_++ = (unsigned char) s;
00158 }
00159 
00160 /*!
00161    \brief Method puts array of short words (16 bits) into the encoding buffer.
00162 */
00163 inline void encoder::put_16(const bm::short_t* s, unsigned count)
00164 {
00165     unsigned char* buf = buf_;
00166     const bm::short_t* s_end = s + count;
00167     do 
00168     {
00169         bm::short_t w16 = *s++;
00170         unsigned char a = (unsigned char)  w16;
00171         unsigned char b = (unsigned char) (w16 >> 8);
00172         
00173         *buf++ = a;
00174         *buf++ = b;
00175                 
00176     } while (s < s_end);
00177     
00178     buf_ = (unsigned char*)buf;
00179 }
00180 
00181 
00182 /*!
00183    \fn unsigned encoder::size() const
00184    \brief Returns size of the current encoding stream.
00185 */
00186 inline unsigned encoder::size() const
00187 {
00188     return (unsigned)(buf_ - start_);
00189 }
00190 
00191 /*!
00192    \fn void encoder::put_32(bm::word_t w)
00193    \brief Puts 32 bits word into encoding buffer.
00194    \param w - word to encode.
00195 */
00196 BMFORCEINLINE void encoder::put_32(bm::word_t w)
00197 {
00198     *buf_++ = (unsigned char) w;
00199     *buf_++ = (unsigned char) (w >> 8);
00200     *buf_++ = (unsigned char) (w >> 16);
00201     *buf_++ = (unsigned char) (w >> 24);
00202 }
00203 
00204 /*!
00205     \brief Encodes array of 32-bit words
00206 */
00207 inline void encoder::put_32(const bm::word_t* w, unsigned count)
00208 {
00209     unsigned char* buf = buf_;
00210     const bm::word_t* w_end = w + count;
00211     do 
00212     {
00213         bm::word_t w32 = *w++;
00214         unsigned char a = (unsigned char) w32;
00215         unsigned char b = (unsigned char) (w32 >> 8);
00216         unsigned char c = (unsigned char) (w32 >> 16);
00217         unsigned char d = (unsigned char) (w32 >> 24);
00218 
00219         *buf++ = a;
00220         *buf++ = b;
00221         *buf++ = c;
00222         *buf++ = d;
00223     } while (w < w_end);
00224     
00225     buf_ = (unsigned char*)buf;
00226 }
00227 
00228 
00229 // ---------------------------------------------------------------------
00230 
00231 /*!
00232    \fn decoder::decoder(const unsigned char* buf) 
00233    \brief Construction
00234    \param buf - pointer to the decoding memory. 
00235 */
00236 inline decoder::decoder(const unsigned char* buf) 
00237 : decoder_base(buf)
00238 {
00239 }
00240 
00241 /*!
00242    \fn bm::short_t decoder::get_16()
00243    \brief Reads 16bit word from the decoding buffer.
00244 */
00245 BMFORCEINLINE bm::short_t decoder::get_16() 
00246 {
00247     bm::short_t a = (bm::short_t)(buf_[0] + ((bm::short_t)buf_[1] << 8));
00248     buf_ += sizeof(a);
00249     return a;
00250 }
00251 
00252 /*!
00253    \fn bm::word_t decoder::get_32()
00254    \brief Reads 32 bit word from the decoding buffer.
00255 */
00256 BMFORCEINLINE bm::word_t decoder::get_32() 
00257 {
00258     bm::word_t a = buf_[0]+ ((unsigned)buf_[1] << 8) +
00259                    ((unsigned)buf_[2] << 16) + ((unsigned)buf_[3] << 24);
00260     buf_+=sizeof(a);
00261     return a;
00262 }
00263 
00264 
00265 /*!
00266    \fn void decoder::get_32(bm::word_t* w, unsigned count)
00267    \brief Reads block of 32-bit words from the decoding buffer.
00268    \param w - pointer on memory block to read into.
00269    \param count - size of memory block in words.
00270 */
00271 inline void decoder::get_32(bm::word_t* w, unsigned count)
00272 {
00273 
00274     const unsigned char* buf = buf_;
00275     const bm::word_t* w_end = w + count;
00276     do 
00277     {
00278         bm::word_t a = buf[0]+ ((unsigned)buf[1] << 8) +
00279                    ((unsigned)buf[2] << 16) + ((unsigned)buf[3] << 24);
00280         *w++ = a;
00281         buf += sizeof(a);
00282     } while (w < w_end);
00283     buf_ = (unsigned char*)buf;
00284 }
00285 
00286 /*!
00287    \fn void decoder::get_16(bm::short_t* s, unsigned count)
00288    \brief Reads block of 32-bit words from the decoding buffer.
00289    \param s - pointer on memory block to read into.
00290    \param count - size of memory block in words.
00291 */
00292 inline void decoder::get_16(bm::short_t* s, unsigned count)
00293 {
00294     const unsigned char* buf = buf_;
00295     const bm::short_t* s_end = s + count;
00296     do 
00297     {
00298         bm::short_t a = (bm::short_t)(buf[0] + ((bm::short_t)buf[1] << 8));
00299         *s++ = a;
00300         buf += sizeof(a);
00301     } while (s < s_end);
00302     buf_ = (unsigned char*)buf;
00303 }
00304 
00305 
00306 
00307 // ---------------------------------------------------------------------
00308 
00309 inline decoder_little_endian::decoder_little_endian(const unsigned char* buf)
00310 : decoder_base(buf)
00311 {
00312 }
00313 
00314 BMFORCEINLINE bm::short_t decoder_little_endian::get_16()
00315 {
00316     bm::short_t a = ((bm::short_t)buf_[0] << 8) + ((bm::short_t)buf_[1]);
00317     buf_ += sizeof(a);
00318     return a;
00319 }
00320 
00321 BMFORCEINLINE bm::word_t decoder_little_endian::get_32() 
00322 {
00323     bm::word_t a = ((unsigned)buf_[0] << 24)+ ((unsigned)buf_[1] << 16) +
00324                    ((unsigned)buf_[2] << 8) + ((unsigned)buf_[3]);
00325     buf_+=sizeof(a);
00326     return a;
00327 }
00328 
00329 inline void decoder_little_endian::get_32(bm::word_t* w, unsigned count)
00330 {
00331     const unsigned char* buf = buf_;
00332     const bm::word_t* w_end = w + count;
00333     do 
00334     {
00335         bm::word_t a = ((unsigned)buf[0] << 24)+ ((unsigned)buf[1] << 16) +
00336                        ((unsigned)buf[2] << 8) + ((unsigned)buf[3]);
00337         *w++ = a;
00338         buf += sizeof(a);
00339     } while (w < w_end);
00340     buf_ = (unsigned char*)buf;
00341 }
00342 
00343 inline void decoder_little_endian::get_16(bm::short_t* s, unsigned count)
00344 {
00345     const unsigned char* buf = buf_;
00346     const bm::short_t* s_end = s + count;
00347     do 
00348     {
00349         bm::short_t a = ((bm::short_t)buf[0] << 8) + ((bm::short_t)buf[1]);
00350         *s++ = a;
00351         buf += sizeof(a);
00352     } while (s < s_end);
00353     buf_ = (unsigned char*)buf;
00354 }
00355 
00356 
00357 } // namespace bm
00358 
00359 #endif
00360 
00361 

Generated on Thu Apr 20 13:28:46 2006 for BitMagic by  doxygen 1.4.1