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     /// change current position
00074     BMFORCEINLINE
00075     void seek(int delta) { buf_ += delta; }
00076 protected:
00077    const unsigned char*   buf_;
00078    const unsigned char*   start_;
00079 };
00080 
00081 
00082 // ----------------------------------------------------------------
00083 /**
00084    Class for decoding data from memory buffer.
00085    Properly handles aligment issues with integer data types.
00086 */
00087 class decoder : public decoder_base
00088 {
00089 public:
00090     decoder(const unsigned char* buf);
00091     bm::short_t get_16();
00092     bm::word_t get_32();
00093     void get_32(bm::word_t* w, unsigned count);
00094     void get_16(bm::short_t* s, unsigned count);
00095 };
00096 
00097 // ----------------------------------------------------------------
00098 /**
00099    Class for decoding data from memory buffer.
00100    Properly handles aligment issues with integer data types.
00101    Converts data to big endian architecture 
00102    (presumed it was encoded as little endian)
00103 */
00104 typedef decoder decoder_big_endian;
00105 
00106 
00107 // ----------------------------------------------------------------
00108 /**
00109    Class for decoding data from memory buffer.
00110    Properly handles aligment issues with integer data types.
00111    Converts data to little endian architecture 
00112    (presumed it was encoded as big endian)
00113 */
00114 class decoder_little_endian : public decoder_base
00115 {
00116 public:
00117     decoder_little_endian(const unsigned char* buf);
00118     bm::short_t get_16();
00119     bm::word_t get_32();
00120     void get_32(bm::word_t* w, unsigned count);
00121     void get_16(bm::short_t* s, unsigned count);
00122 };
00123 
00124 
00125 
00126 // ----------------------------------------------------------------
00127 // Implementation details. 
00128 // ----------------------------------------------------------------
00129 
00130 /*! 
00131     \fn encoder::encoder(unsigned char* buf, unsigned size) 
00132     \brief Construction.
00133     \param buf - memory buffer pointer.
00134     \param size - size of the buffer
00135 */
00136 inline encoder::encoder(unsigned char* buf, unsigned size)
00137 : buf_(buf), start_(buf), size_(size)
00138 {
00139 }
00140 
00141 /*!
00142    \fn void encoder::put_8(unsigned char c) 
00143    \brief Puts one character into the encoding buffer.
00144    \param c - character to encode
00145 */
00146 BMFORCEINLINE void encoder::put_8(unsigned char c)
00147 {
00148     *buf_++ = c;
00149 }
00150 
00151 /*!
00152    \fn encoder::put_16(bm::short_t s)
00153    \brief Puts short word (16 bits) into the encoding buffer.
00154    \param s - short word to encode
00155 */
00156 BMFORCEINLINE void encoder::put_16(bm::short_t s)
00157 {
00158     *buf_++ = (unsigned char) s;
00159     s >>= 8;
00160     *buf_++ = (unsigned char) s;
00161 }
00162 
00163 /*!
00164    \brief Method puts array of short words (16 bits) into the encoding buffer.
00165 */
00166 inline void encoder::put_16(const bm::short_t* s, unsigned count)
00167 {
00168     unsigned char* buf = buf_;
00169     const bm::short_t* s_end = s + count;
00170     do 
00171     {
00172         bm::short_t w16 = *s++;
00173         unsigned char a = (unsigned char)  w16;
00174         unsigned char b = (unsigned char) (w16 >> 8);
00175         
00176         *buf++ = a;
00177         *buf++ = b;
00178                 
00179     } while (s < s_end);
00180     
00181     buf_ = (unsigned char*)buf;
00182 }
00183 
00184 
00185 /*!
00186    \fn unsigned encoder::size() const
00187    \brief Returns size of the current encoding stream.
00188 */
00189 inline unsigned encoder::size() const
00190 {
00191     return (unsigned)(buf_ - start_);
00192 }
00193 
00194 /*!
00195    \fn void encoder::put_32(bm::word_t w)
00196    \brief Puts 32 bits word into encoding buffer.
00197    \param w - word to encode.
00198 */
00199 BMFORCEINLINE void encoder::put_32(bm::word_t w)
00200 {
00201     *buf_++ = (unsigned char) w;
00202     *buf_++ = (unsigned char) (w >> 8);
00203     *buf_++ = (unsigned char) (w >> 16);
00204     *buf_++ = (unsigned char) (w >> 24);
00205 }
00206 
00207 /*!
00208     \brief Encodes array of 32-bit words
00209 */
00210 inline 
00211 void encoder::put_32(const bm::word_t* w, unsigned count)
00212 {
00213     unsigned char* buf = buf_;
00214     const bm::word_t* w_end = w + count;
00215     do 
00216     {
00217         bm::word_t w32 = *w++;
00218         unsigned char a = (unsigned char) w32;
00219         unsigned char b = (unsigned char) (w32 >> 8);
00220         unsigned char c = (unsigned char) (w32 >> 16);
00221         unsigned char d = (unsigned char) (w32 >> 24);
00222 
00223         *buf++ = a;
00224         *buf++ = b;
00225         *buf++ = c;
00226         *buf++ = d;
00227     } while (w < w_end);
00228     
00229     buf_ = (unsigned char*)buf;
00230 }
00231 
00232 
00233 // ---------------------------------------------------------------------
00234 
00235 /*!
00236    \fn decoder::decoder(const unsigned char* buf) 
00237    \brief Construction
00238    \param buf - pointer to the decoding memory. 
00239 */
00240 inline decoder::decoder(const unsigned char* buf) 
00241 : decoder_base(buf)
00242 {
00243 }
00244 
00245 /*!
00246    \fn bm::short_t decoder::get_16()
00247    \brief Reads 16bit word from the decoding buffer.
00248 */
00249 BMFORCEINLINE bm::short_t decoder::get_16() 
00250 {
00251     bm::short_t a = (bm::short_t)(buf_[0] + ((bm::short_t)buf_[1] << 8));
00252     buf_ += sizeof(a);
00253     return a;
00254 }
00255 
00256 /*!
00257    \fn bm::word_t decoder::get_32()
00258    \brief Reads 32 bit word from the decoding buffer.
00259 */
00260 BMFORCEINLINE bm::word_t decoder::get_32() 
00261 {
00262     bm::word_t a = buf_[0]+ ((unsigned)buf_[1] << 8) +
00263                    ((unsigned)buf_[2] << 16) + ((unsigned)buf_[3] << 24);
00264     buf_+=sizeof(a);
00265     return a;
00266 }
00267 
00268 
00269 /*!
00270    \fn void decoder::get_32(bm::word_t* w, unsigned count)
00271    \brief Reads block of 32-bit words from the decoding buffer.
00272    \param w - pointer on memory block to read into.
00273    \param count - size of memory block in words.
00274 */
00275 inline void decoder::get_32(bm::word_t* w, unsigned count)
00276 {
00277     if (!w) 
00278     {
00279         seek(count * 4);
00280         return;
00281     }
00282     const unsigned char* buf = buf_;
00283     const bm::word_t* w_end = w + count;
00284     do 
00285     {
00286         bm::word_t a = buf[0]+ ((unsigned)buf[1] << 8) +
00287                    ((unsigned)buf[2] << 16) + ((unsigned)buf[3] << 24);
00288         *w++ = a;
00289         buf += sizeof(a);
00290     } while (w < w_end);
00291     buf_ = (unsigned char*)buf;
00292 }
00293 
00294 /*!
00295    \fn void decoder::get_16(bm::short_t* s, unsigned count)
00296    \brief Reads block of 32-bit words from the decoding buffer.
00297    \param s - pointer on memory block to read into.
00298    \param count - size of memory block in words.
00299 */
00300 inline void decoder::get_16(bm::short_t* s, unsigned count)
00301 {
00302     if (!s) 
00303     {
00304         seek(count * 2);
00305         return;
00306     }
00307 
00308     const unsigned char* buf = buf_;
00309     const bm::short_t* s_end = s + count;
00310     do 
00311     {
00312         bm::short_t a = (bm::short_t)(buf[0] + ((bm::short_t)buf[1] << 8));
00313         *s++ = a;
00314         buf += sizeof(a);
00315     } while (s < s_end);
00316     buf_ = (unsigned char*)buf;
00317 }
00318 
00319 
00320 
00321 // ---------------------------------------------------------------------
00322 
00323 inline decoder_little_endian::decoder_little_endian(const unsigned char* buf)
00324 : decoder_base(buf)
00325 {
00326 }
00327 
00328 BMFORCEINLINE bm::short_t decoder_little_endian::get_16()
00329 {
00330     bm::short_t a = ((bm::short_t)buf_[0] << 8) + ((bm::short_t)buf_[1]);
00331     buf_ += sizeof(a);
00332     return a;
00333 }
00334 
00335 BMFORCEINLINE bm::word_t decoder_little_endian::get_32() 
00336 {
00337     bm::word_t a = ((unsigned)buf_[0] << 24)+ ((unsigned)buf_[1] << 16) +
00338                    ((unsigned)buf_[2] << 8) + ((unsigned)buf_[3]);
00339     buf_+=sizeof(a);
00340     return a;
00341 }
00342 
00343 inline void decoder_little_endian::get_32(bm::word_t* w, unsigned count)
00344 {
00345     if (!w) 
00346     {
00347         seek(count * 4);
00348         return;
00349     }
00350 
00351     const unsigned char* buf = buf_;
00352     const bm::word_t* w_end = w + count;
00353     do 
00354     {
00355         bm::word_t a = ((unsigned)buf[0] << 24)+ ((unsigned)buf[1] << 16) +
00356                        ((unsigned)buf[2] << 8) + ((unsigned)buf[3]);
00357         *w++ = a;
00358         buf += sizeof(a);
00359     } while (w < w_end);
00360     buf_ = (unsigned char*)buf;
00361 }
00362 
00363 inline void decoder_little_endian::get_16(bm::short_t* s, unsigned count)
00364 {
00365     if (!s) 
00366     {
00367         seek(count * 2);
00368         return;
00369     }
00370 
00371     const unsigned char* buf = buf_;
00372     const bm::short_t* s_end = s + count;
00373     do 
00374     {
00375         bm::short_t a = ((bm::short_t)buf[0] << 8) + ((bm::short_t)buf[1]);
00376         *s++ = a;
00377         buf += sizeof(a);
00378     } while (s < s_end);
00379     buf_ = (unsigned char*)buf;
00380 }
00381 
00382 
00383 } // namespace bm
00384 
00385 #endif
00386 
00387 

Generated on Sun Aug 5 14:12:26 2007 for BitMagic by  doxygen 1.4.1