Home | History | Annotate | Download | only in Support
      1 //===- LEB128.h -----------------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef MCLD_LEB128_H
     11 #define MCLD_LEB128_H
     12 #ifdef ENABLE_UNITTEST
     13 #include <gtest.h>
     14 #endif
     15 
     16 #include <stdint.h>
     17 #include <sys/types.h>
     18 
     19 namespace mcld {
     20 
     21 namespace leb128 {
     22 
     23 typedef unsigned char ByteType;
     24 
     25 /* Forward declarations */
     26 template<typename IntType>
     27 size_t encode(ByteType *&pBuf, IntType pValue);
     28 
     29 template<typename IntType>
     30 IntType decode(const ByteType *pBuf, size_t &pSize);
     31 
     32 template<typename IntType>
     33 IntType decode(const ByteType *&pBuf);
     34 
     35 /*
     36  * Given an integer, this function returns the number of bytes required to
     37  * encode it in ULEB128 format.
     38  */
     39 template<typename IntType>
     40 size_t size(IntType pValue) {
     41   size_t size = 1;
     42   while (pValue > 0x80) {
     43     pValue >>= 7;
     44     ++size;
     45   }
     46   return size;
     47 }
     48 
     49 /*
     50  * Write an unsigned integer in ULEB128 to the given buffer. The client should
     51  * ensure there's enough space in the buffer to hold the result. Update the
     52  * given buffer pointer to the point just past the end of the write value and
     53  * return the number of bytes being written.
     54  */
     55 template<>
     56 size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue);
     57 
     58 template<>
     59 size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue);
     60 
     61 /*
     62  * Encoding functions for signed LEB128.
     63  */
     64 template<>
     65 size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue);
     66 
     67 template<>
     68 size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue);
     69 
     70 /*
     71  * Read an integer encoded in ULEB128 format from the given buffer. pSize will
     72  * contain the number of bytes used in the buffer to encode the returned
     73  * integer.
     74  */
     75 template<>
     76 uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize);
     77 
     78 /*
     79  * Read an integer encoded in ULEB128 format from the given buffer. Update the
     80  * given buffer pointer to the point just past the end of the read value.
     81  */
     82 template<>
     83 uint64_t decode<uint64_t>(const ByteType *&pBuf);
     84 
     85 /*
     86  * Decoding functions for signed LEB128.
     87  */
     88 template<>
     89 int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize);
     90 
     91 template<>
     92 int64_t decode<int64_t>(const ByteType *&pBuf);
     93 
     94 /*
     95  * The functions below handle the signed byte stream. This helps the user to get
     96  * rid of annoying type conversions when using the LEB128 encoding/decoding APIs
     97  * defined above.
     98  */
     99 template<typename IntType>
    100 size_t encode(char *&pBuf, IntType pValue) {
    101   return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
    102 }
    103 
    104 template<typename IntType>
    105 IntType decode(const char *pBuf, size_t &pSize) {
    106   return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
    107 }
    108 
    109 template<typename IntType>
    110 IntType decode(const char *&pBuf) {
    111   return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf));
    112 }
    113 
    114 } // namespace of leb128
    115 } // namespace of mcld
    116 
    117 #endif
    118