include/util/bitset/encoding.h

Go to the documentation of this file.
00001 #ifndef BMENCODING_H__INCLUDED__
00002 #define BMENCODING_H__INCLUDED__
00003 /*
00004 Copyright(c) 2002-2009 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
00005 
00006 
00007 Permission is hereby granted, free of charge, to any person 
00008 obtaining a copy of this software and associated documentation 
00009 files (the "Software"), to deal in the Software without restriction, 
00010 including without limitation the rights to use, copy, modify, merge, 
00011 publish, distribute, sublicense, and/or sell copies of the Software, 
00012 and to permit persons to whom the Software is furnished to do so, 
00013 subject to the following conditions:
00014 
00015 The above copyright notice and this permission notice shall be included 
00016 in all copies or substantial portions of the Software.
00017 
00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00019 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
00020 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00021 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00022 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
00023 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
00024 OTHER DEALINGS IN THE SOFTWARE.
00025 
00026 
00027 For more information please visit:   http://bmagic.sourceforge.net
00028 
00029 */
00030 
00031 #include <memory.h>
00032 #include "bmutil.h"
00033 
00034 namespace bm
00035 {
00036 
00037 
00038 // ----------------------------------------------------------------
00039 /*!
00040    \brief Memory encoding.
00041    
00042    Class for encoding data into memory. 
00043    Properly handles aligment issues with integer data types.
00044 */
00045 class encoder
00046 {
00047 public:
00048     typedef unsigned char* position_type;
00049 public:
00050     encoder(unsigned char* buf, unsigned size);
00051     void put_8(unsigned char c);
00052     void put_16(bm::short_t  s);
00053     void put_16(const bm::short_t* s, unsigned count);
00054     void put_32(bm::word_t  w);
00055     void put_32(const bm::word_t* w, unsigned count);
00056     void put_prefixed_array_32(unsigned char c, 
00057                                const bm::word_t* w, unsigned count);
00058     void put_prefixed_array_16(unsigned char c, 
00059                                const bm::short_t* s, unsigned count,
00060                                bool encode_count);
00061     unsigned size() const;
00062     unsigned char* get_pos() const;
00063     void set_pos(unsigned char* buf_pos);
00064 private:
00065     unsigned char*  buf_;
00066     unsigned char*  start_;
00067     unsigned int    size_;
00068 };
00069 
00070 // ----------------------------------------------------------------
00071 /**
00072     Base class for all decoding functionality
00073 */
00074 class decoder_base
00075 {
00076 public:
00077     decoder_base(const unsigned char* buf) { buf_ = start_ = buf; }
00078     /// Reads character from the decoding buffer. 
00079     BMFORCEINLINE unsigned char get_8() { return *buf_++; }
00080     /// Returns size of the current decoding stream.
00081     BMFORCEINLINE 
00082     unsigned size() const { return (unsigned)(buf_ - start_); }
00083     /// change current position
00084     BMFORCEINLINE
00085     void seek(int delta) { buf_ += delta; }
00086 protected:
00087    const unsigned char*   buf_;
00088    const unsigned char*   start_;
00089 };
00090 
00091 
00092 // ----------------------------------------------------------------
00093 /**
00094    Class for decoding data from memory buffer.
00095    Properly handles aligment issues with integer data types.
00096 */
00097 class decoder : public decoder_base
00098 {
00099 public:
00100     decoder(const unsigned char* buf);
00101     bm::short_t get_16();
00102     bm::word_t get_32();
00103     void get_32(bm::word_t* w, unsigned count);
00104     void get_16(bm::short_t* s, unsigned count);
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 big endian architecture 
00112    (presumed it was encoded as little endian)
00113 */
00114 typedef decoder decoder_big_endian;
00115 
00116 
00117 // ----------------------------------------------------------------
00118 /**
00119    Class for decoding data from memory buffer.
00120    Properly handles aligment issues with integer data types.
00121    Converts data to little endian architecture 
00122    (presumed it was encoded as big endian)
00123 */
00124 class decoder_little_endian : public decoder_base
00125 {
00126 public:
00127     decoder_little_endian(const unsigned char* buf);
00128     bm::short_t get_16();
00129     bm::word_t get_32();
00130     void get_32(bm::word_t* w, unsigned count);
00131     void get_16(bm::short_t* s, unsigned count);
00132 };
00133 
00134 
00135 /** 
00136     Byte based writer for un-aligned bit streaming 
00137 
00138     @sa encoder
00139 */
00140 template<class TEncoder>
00141 class bit_out
00142 {
00143 public:
00144     bit_out(TEncoder& dest)
00145         : dest_(dest), used_bits_(0), accum_(0)
00146     {}
00147 
00148     ~bit_out()
00149     {
00150         if (used_bits_)
00151             dest_.put_32(accum_);
00152     }
00153 
00154     void put_bit(unsigned value)
00155     {
00156         BM_ASSERT(value <= 1);
00157         accum_ |= (value << used_bits_);
00158         if (++used_bits_ == (sizeof(accum_) * 8))
00159             flush_accum();
00160     }
00161 
00162     void put_bits(unsigned value, unsigned count)
00163     {
00164         unsigned used = used_bits_;
00165         unsigned acc = accum_;
00166 
00167         {
00168             unsigned mask = ~0;
00169             mask >>= (sizeof(accum_) * 8) - count;
00170             value &= mask;
00171         }
00172         for (;count;)
00173         {  
00174             acc |= value << used;
00175 
00176             unsigned free_bits = (sizeof(accum_) * 8) - used;
00177             if (count <= free_bits)
00178             {
00179                 used += count;
00180                 break;
00181             }
00182             else
00183             {
00184                 value >>= free_bits;
00185                 count -= free_bits;
00186                 dest_.put_32(acc);
00187                 acc = used = 0;
00188                 continue;
00189             }
00190         }
00191         used_bits_ = used;
00192         accum_ = acc;
00193     }
00194 
00195     void put_zero_bit()
00196     {
00197         if (++used_bits_ == (sizeof(accum_) * 8))
00198             flush_accum();        
00199     }
00200 
00201     void put_zero_bits(register unsigned count)
00202     {
00203         register unsigned used = used_bits_;
00204         unsigned free_bits = (sizeof(accum_) * 8) - used;
00205         if (count >= free_bits)
00206         {
00207             flush_accum();
00208             count -= free_bits;
00209             used = 0;
00210 
00211             for ( ;count >= sizeof(accum_) * 8; count -= sizeof(accum_) * 8)
00212             {
00213                 dest_.put_32(0);
00214             }
00215             used += count; 
00216         }
00217         else
00218         {
00219             used += count;
00220         }
00221         accum_ |= (1 << used);
00222         if (++used == (sizeof(accum_) * 8))
00223             flush_accum();
00224         else
00225             used_bits_ = used;
00226     }
00227 
00228 
00229     void gamma(unsigned value)
00230     {
00231         BM_ASSERT(value);
00232 
00233         unsigned logv = 
00234         #if defined(BM_x86) && (defined(__GNUG__) || defined(_MSC_VER))
00235             bm::bsr_asm32(value);
00236         #else
00237             bm::ilog2_LUT(value);
00238         #endif
00239 
00240         // Put zeroes + 1 bit
00241 
00242         unsigned used = used_bits_;
00243         unsigned acc = accum_;
00244         const unsigned acc_bits = (sizeof(acc) * 8);
00245         unsigned free_bits = acc_bits - used;
00246 
00247         {
00248         unsigned count = logv;
00249         if (count >= free_bits)
00250         {
00251             dest_.put_32(acc);
00252             acc = used ^= used;
00253             count -= free_bits;
00254 
00255             for ( ;count >= acc_bits; count -= acc_bits)
00256             {
00257                 dest_.put_32(0);
00258             }
00259             used += count; 
00260         }
00261         else
00262         {
00263             used += count;
00264         }
00265         acc |= (1 << used);
00266         if (++used == acc_bits)
00267         {
00268             dest_.put_32(acc);
00269             acc = used ^= used;
00270         }
00271         }
00272 
00273         // Put the value bits
00274         //
00275         {
00276             unsigned mask = (~0);
00277             mask >>= acc_bits - logv;
00278             value &= mask;
00279         }
00280         for (;logv;)
00281         {  
00282             acc |= value << used;
00283             free_bits = acc_bits - used;
00284             if (logv <= free_bits)
00285             {
00286                 used += logv;
00287                 break;
00288             }
00289             else
00290             {
00291                 value >>= free_bits;
00292                 logv -= free_bits;
00293                 dest_.put_32(acc);
00294                 acc = used ^= used;
00295                 continue;
00296             }
00297         } // for
00298 
00299         used_bits_ = used;
00300         accum_ = acc;
00301     }
00302 
00303 
00304     void flush()
00305     {
00306         if (used_bits_)
00307             flush_accum();
00308     }
00309 
00310 private:
00311     void flush_accum()
00312     {
00313         dest_.put_32(accum_);
00314         used_bits_ = accum_ = 0;
00315     }
00316 private:
00317     bit_out(const bit_out&);
00318     bit_out& operator=(const bit_out&);
00319 
00320 private:
00321     TEncoder&      dest_;      ///< Bit stream target
00322     unsigned       used_bits_; ///< Bits used in the accumulator
00323     unsigned       accum_;     ///< write bit accumulator 
00324 };
00325 
00326 
00327 /** 
00328     Byte based reader for un-aligned bit streaming 
00329 
00330     @sa encoder
00331 */
00332 template<class TDecoder>
00333 class bit_in
00334 {
00335 public:
00336     bit_in(TDecoder& decoder)
00337         : src_(decoder),
00338           used_bits_(sizeof(accum_) * 8),
00339           accum_(0)
00340     {
00341     }
00342 
00343     unsigned gamma()
00344     {
00345         unsigned acc = accum_;
00346         unsigned used = used_bits_;
00347 
00348         if (used == (sizeof(acc) * 8))
00349         {
00350             acc = src_.get_32();
00351             used ^= used;
00352         }
00353         unsigned zero_bits = 0;
00354         while (1)
00355         {
00356             if (acc == 0)
00357             {
00358                 zero_bits += (sizeof(acc) * 8) - used;
00359                 used = 0;
00360                 acc = src_.get_32();
00361                 continue;
00362             }
00363             unsigned first_bit_idx = 
00364                 #if defined(BM_x86) && (defined(__GNUG__) || defined(_MSC_VER))
00365                     bm::bsf_asm32(acc);
00366                 #else
00367                     bm::bit_scan_fwd(acc);
00368                 #endif
00369             acc >>= first_bit_idx;
00370             zero_bits += first_bit_idx;
00371             used += first_bit_idx;
00372             break;
00373         } // while
00374 
00375         // eat the border bit
00376         //
00377         if (used == (sizeof(acc) * 8))
00378         {
00379             acc = src_.get_32();
00380             used = 1;
00381         }
00382         else
00383         {
00384             ++used;
00385         }
00386         acc >>= 1;
00387 
00388         // get the value
00389         unsigned current;
00390         
00391         unsigned free_bits = (sizeof(acc) * 8) - used;
00392         if (zero_bits <= free_bits)
00393         {
00394         take_accum:
00395             current = 
00396                 (acc & block_set_table<true>::_left[zero_bits]) | (1 << zero_bits);
00397             acc >>= zero_bits;
00398             used += zero_bits;
00399             goto ret;
00400         }
00401 
00402         if (used == (sizeof(acc) * 8))
00403         {
00404             acc = src_.get_32();
00405             used ^= used;
00406             goto take_accum;
00407         }
00408 
00409         // take the part
00410         current = acc;
00411         // read the next word
00412         acc = src_.get_32();
00413         used = zero_bits - free_bits;
00414         current |= 
00415             ((acc & block_set_table<true>::_left[used]) << free_bits) | 
00416             (1 << zero_bits);
00417 
00418         acc >>= used;
00419     ret:
00420         accum_ = acc;
00421         used_bits_ = used;
00422         return current;
00423     }
00424 
00425 
00426 private:
00427     bit_in(const bit_in&);
00428     bit_in& operator=(const bit_in&);
00429 private:
00430     TDecoder&           src_;        ///< Source of bytes
00431     unsigned            used_bits_;  ///< Bits used in the accumulator
00432     unsigned            accum_;      ///< read bit accumulator
00433 };
00434 
00435 
00436 /**
00437     Functor for Elias Gamma encoding
00438 */
00439 template<typename T, typename TBitIO>
00440 class gamma_encoder
00441 {
00442 public:
00443     gamma_encoder(TBitIO& bout) : bout_(bout) 
00444     {}
00445         
00446     /**
00447         Encode word
00448     */
00449     BMFORCEINLINE
00450     void operator()(T value)
00451     {
00452         bout_.gamma(value);
00453     }
00454 private:
00455     gamma_encoder(const gamma_encoder&);
00456     gamma_encoder& operator=(const gamma_encoder&);
00457 private:
00458     TBitIO&  bout_;
00459 };
00460 
00461 
00462 /**
00463     Elias Gamma decoder
00464 */
00465 template<typename T, typename TBitIO>
00466 class gamma_decoder
00467 {
00468 public:
00469     gamma_decoder(TBitIO& bin) : bin_(bin) 
00470     {}
00471     
00472     /**
00473         Start encoding sequence
00474     */
00475     void start()
00476     {}
00477     
00478     /**
00479         Stop decoding sequence
00480     */
00481     void stop()
00482     {}
00483     
00484     /**
00485         Decode word
00486     */
00487     T operator()(void)
00488     {
00489         return bin_.gamma();
00490     }
00491 private:
00492     gamma_decoder(const gamma_decoder&);
00493     gamma_decoder& operator=(const gamma_decoder&);
00494 private:
00495     TBitIO&  bin_;
00496 };
00497 
00498 
00499 // ----------------------------------------------------------------
00500 // Implementation details. 
00501 // ----------------------------------------------------------------
00502 
00503 /*! 
00504     \fn encoder::encoder(unsigned char* buf, unsigned size) 
00505     \brief Construction.
00506     \param buf - memory buffer pointer.
00507     \param size - size of the buffer
00508 */
00509 inline encoder::encoder(unsigned char* buf, unsigned size)
00510 : buf_(buf), start_(buf), size_(size)
00511 {
00512 }
00513 /*!
00514     \grief Encode 8-bit prefix + an array
00515 */
00516 inline void encoder::put_prefixed_array_32(unsigned char c, 
00517                                            const bm::word_t* w, 
00518                                            unsigned count)
00519 {
00520     put_8(c);
00521     put_32(w, count);
00522 }
00523 
00524 /*!
00525     \grief Encode 8-bit prefix + an array 
00526 */
00527 inline void encoder::put_prefixed_array_16(unsigned char c, 
00528                                            const bm::short_t* s, 
00529                                            unsigned count,
00530                                            bool encode_count)
00531 {
00532     put_8(c);
00533     if (encode_count)
00534         put_16((bm::short_t) count);
00535     put_16(s, count);
00536 }
00537 
00538 
00539 /*!
00540    \fn void encoder::put_8(unsigned char c) 
00541    \brief Puts one character into the encoding buffer.
00542    \param c - character to encode
00543 */
00544 BMFORCEINLINE void encoder::put_8(unsigned char c)
00545 {
00546     *buf_++ = c;
00547 }
00548 
00549 /*!
00550    \fn encoder::put_16(bm::short_t s)
00551    \brief Puts short word (16 bits) into the encoding buffer.
00552    \param s - short word to encode
00553 */
00554 BMFORCEINLINE void encoder::put_16(bm::short_t s)
00555 {
00556 #if (BM_UNALIGNED_ACCESS_OK == 1)
00557     *((bm::short_t*)buf_) = s;
00558     buf_ += sizeof(s);
00559 #else
00560     *buf_++ = (unsigned char) s;
00561     s >>= 8;
00562     *buf_++ = (unsigned char) s;
00563 #endif
00564 }
00565 
00566 /*!
00567    \brief Method puts array of short words (16 bits) into the encoding buffer.
00568 */
00569 inline void encoder::put_16(const bm::short_t* s, unsigned count)
00570 {
00571 #if (BM_UNALIGNED_ACCESS_OK == 1)
00572     unsigned short* buf = (unsigned short*)buf_;
00573     const bm::short_t* s_end = s + count;
00574     do 
00575     {
00576         *buf++ = *s++;
00577     } while (s < s_end);
00578         
00579     buf_ = (unsigned char*)buf;
00580 #else
00581     unsigned char* buf = buf_;
00582     const bm::short_t* s_end = s + count;
00583     do 
00584     {
00585         bm::short_t w16 = *s++;
00586         unsigned char a = (unsigned char)  w16;
00587         unsigned char b = (unsigned char) (w16 >> 8);
00588         
00589         *buf++ = a;
00590         *buf++ = b;
00591                 
00592     } while (s < s_end);
00593     
00594     buf_ = (unsigned char*)buf;
00595 #endif
00596 }
00597 
00598 
00599 /*!
00600    \fn unsigned encoder::size() const
00601    \brief Returns size of the current encoding stream.
00602 */
00603 inline unsigned encoder::size() const
00604 {
00605     return (unsigned)(buf_ - start_);
00606 }
00607 
00608 /**
00609     \brief Get current memory stream position
00610 */
00611 inline encoder::position_type encoder::get_pos() const
00612 {
00613     return buf_;
00614 }
00615 
00616 /**
00617     \brief Set current memory stream position
00618 */
00619 inline void encoder::set_pos(encoder::position_type buf_pos)
00620 {
00621     buf_ = buf_pos;
00622 }
00623 
00624 
00625 /*!
00626    \fn void encoder::put_32(bm::word_t w)
00627    \brief Puts 32 bits word into encoding buffer.
00628    \param w - word to encode.
00629 */
00630 BMFORCEINLINE void encoder::put_32(bm::word_t w)
00631 {
00632 #if (BM_UNALIGNED_ACCESS_OK == 1)
00633     *((bm::word_t*) buf_) = w;
00634     buf_ += sizeof(w);
00635 #else
00636     *buf_++ = (unsigned char) w;
00637     *buf_++ = (unsigned char) (w >> 8);
00638     *buf_++ = (unsigned char) (w >> 16);
00639     *buf_++ = (unsigned char) (w >> 24);
00640 #endif
00641 }
00642 
00643 /*!
00644     \brief Encodes array of 32-bit words
00645 */
00646 inline 
00647 void encoder::put_32(const bm::word_t* w, unsigned count)
00648 {
00649 #if (BM_UNALIGNED_ACCESS_OK == 1)
00650     bm::word_t* buf = (bm::word_t*)buf_;
00651     const bm::word_t* w_end = w + count;
00652     do 
00653     {
00654         *buf++ = *w++;
00655     } while (w < w_end);
00656     
00657     buf_ = (unsigned char*)buf;
00658 #else
00659     unsigned char* buf = buf_;
00660     const bm::word_t* w_end = w + count;
00661     do 
00662     {
00663         bm::word_t w32 = *w++;
00664         unsigned char a = (unsigned char) w32;
00665         unsigned char b = (unsigned char) (w32 >> 8);
00666         unsigned char c = (unsigned char) (w32 >> 16);
00667         unsigned char d = (unsigned char) (w32 >> 24);
00668 
00669         *buf++ = a;
00670         *buf++ = b;
00671         *buf++ = c;
00672         *buf++ = d;
00673     } while (w < w_end);
00674     
00675     buf_ = (unsigned char*)buf;
00676 #endif
00677 }
00678 
00679 
00680 // ---------------------------------------------------------------------
00681 
00682 /*!
00683    \fn decoder::decoder(const unsigned char* buf) 
00684    \brief Construction
00685    \param buf - pointer to the decoding memory. 
00686 */
00687 inline decoder::decoder(const unsigned char* buf) 
00688 : decoder_base(buf)
00689 {
00690 }
00691 
00692 /*!
00693    \fn bm::short_t decoder::get_16()
00694    \brief Reads 16bit word from the decoding buffer.
00695 */
00696 BMFORCEINLINE bm::short_t decoder::get_16() 
00697 {
00698 #if (BM_UNALIGNED_ACCESS_OK == 1)
00699     bm::short_t a = *((bm::short_t*)buf_);
00700 #else
00701     bm::short_t a = (bm::short_t)(buf_[0] + ((bm::short_t)buf_[1] << 8));
00702 #endif
00703     buf_ += sizeof(a);
00704     return a;
00705 }
00706 
00707 /*!
00708    \fn bm::word_t decoder::get_32()
00709    \brief Reads 32 bit word from the decoding buffer.
00710 */
00711 BMFORCEINLINE bm::word_t decoder::get_32() 
00712 {
00713 #if (BM_UNALIGNED_ACCESS_OK == 1)
00714     bm::word_t a = *((bm::word_t*)buf_);
00715 #else
00716     bm::word_t a = buf_[0]+ ((unsigned)buf_[1] << 8) +
00717                    ((unsigned)buf_[2] << 16) + ((unsigned)buf_[3] << 24);
00718 #endif
00719     buf_+=sizeof(a);
00720     return a;
00721 }
00722 
00723 
00724 /*!
00725    \fn void decoder::get_32(bm::word_t* w, unsigned count)
00726    \brief Reads block of 32-bit words from the decoding buffer.
00727    \param w - pointer on memory block to read into.
00728    \param count - size of memory block in words.
00729 */
00730 inline void decoder::get_32(bm::word_t* w, unsigned count)
00731 {
00732     if (!w) 
00733     {
00734         seek(count * 4);
00735         return;
00736     }
00737 #if (BM_UNALIGNED_ACCESS_OK == 1)
00738     const bm::word_t* buf = (bm::word_t*)buf_;
00739     const bm::word_t* w_end = w + count;
00740     do 
00741     {
00742         *w++ = *buf++;
00743     } while (w < w_end);
00744 #else
00745     const unsigned char* buf = buf_;
00746     const bm::word_t* w_end = w + count;
00747     do 
00748     {
00749         bm::word_t a = buf[0]+ ((unsigned)buf[1] << 8) +
00750                    ((unsigned)buf[2] << 16) + ((unsigned)buf[3] << 24);
00751         *w++ = a;
00752         buf += sizeof(a);
00753     } while (w < w_end);
00754 #endif
00755     buf_ = (unsigned char*)buf;
00756 }
00757 
00758 /*!
00759    \fn void decoder::get_16(bm::short_t* s, unsigned count)
00760    \brief Reads block of 32-bit words from the decoding buffer.
00761    \param s - pointer on memory block to read into.
00762    \param count - size of memory block in words.
00763 */
00764 inline void decoder::get_16(bm::short_t* s, unsigned count)
00765 {
00766     if (!s) 
00767     {
00768         seek(count * 2);
00769         return;
00770     }
00771 #if (BM_UNALIGNED_ACCESS_OK == 1)
00772     const bm::short_t* buf = (bm::short_t*)buf_;
00773     const bm::short_t* s_end = s + count;
00774     do 
00775     {
00776         *s++ = *buf++;
00777     } while (s < s_end);
00778 #else
00779     const unsigned char* buf = buf_;
00780     const bm::short_t* s_end = s + count;
00781     do 
00782     {
00783         bm::short_t a = (bm::short_t)(buf[0] + ((bm::short_t)buf[1] << 8));
00784         *s++ = a;
00785         buf += sizeof(a);
00786     } while (s < s_end);
00787 #endif
00788     buf_ = (unsigned char*)buf;
00789 }
00790 
00791 
00792 
00793 // ---------------------------------------------------------------------
00794 
00795 inline decoder_little_endian::decoder_little_endian(const unsigned char* buf)
00796 : decoder_base(buf)
00797 {
00798 }
00799 
00800 BMFORCEINLINE bm::short_t decoder_little_endian::get_16()
00801 {
00802     bm::short_t a = ((bm::short_t)buf_[0] << 8) + ((bm::short_t)buf_[1]);
00803     buf_ += sizeof(a);
00804     return a;
00805 }
00806 
00807 BMFORCEINLINE bm::word_t decoder_little_endian::get_32() 
00808 {
00809     bm::word_t a = ((unsigned)buf_[0] << 24)+ ((unsigned)buf_[1] << 16) +
00810                    ((unsigned)buf_[2] << 8) + ((unsigned)buf_[3]);
00811     buf_+=sizeof(a);
00812     return a;
00813 }
00814 
00815 inline void decoder_little_endian::get_32(bm::word_t* w, unsigned count)
00816 {
00817     if (!w) 
00818     {
00819         seek(count * 4);
00820         return;
00821     }
00822 
00823     const unsigned char* buf = buf_;
00824     const bm::word_t* w_end = w + count;
00825     do 
00826     {
00827         bm::word_t a = ((unsigned)buf[0] << 24)+ ((unsigned)buf[1] << 16) +
00828                        ((unsigned)buf[2] << 8) + ((unsigned)buf[3]);
00829         *w++ = a;
00830         buf += sizeof(a);
00831     } while (w < w_end);
00832     buf_ = (unsigned char*)buf;
00833 }
00834 
00835 inline void decoder_little_endian::get_16(bm::short_t* s, unsigned count)
00836 {
00837     if (!s) 
00838     {
00839         seek(count * 2);
00840         return;
00841     }
00842 
00843     const unsigned char* buf = buf_;
00844     const bm::short_t* s_end = s + count;
00845     do 
00846     {
00847         bm::short_t a = ((bm::short_t)buf[0] << 8) + ((bm::short_t)buf[1]);
00848         *s++ = a;
00849         buf += sizeof(a);
00850     } while (s < s_end);
00851     buf_ = (unsigned char*)buf;
00852 }
00853 
00854 
00855 } // namespace bm
00856 
00857 #endif
00858 
00859 

Generated on Sun Dec 6 22:15:50 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:49 2009 by modify_doxy.py rev. 173732