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