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