15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- LEB128.h -----------------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_SUPPORT_LEB128_H_ 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_SUPPORT_LEB128_H_ 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdint.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace leb128 { 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotypedef unsigned char ByteType; 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* Forward declarations */ 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode(ByteType*& pBuf, IntType pValue); 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 2637b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntType decode(const ByteType* pBuf, size_t& pSize); 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 2937b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntType decode(const ByteType*& pBuf); 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Given an integer, this function returns the number of bytes required to 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * encode it in ULEB128 format. 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t size(IntType pValue) { 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t size = 1; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (pValue > 0x80) { 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pValue >>= 7; 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++size; 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return size; 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Write an unsigned integer in ULEB128 to the given buffer. The client should 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * ensure there's enough space in the buffer to hold the result. Update the 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * given buffer pointer to the point just past the end of the write value and 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * return the number of bytes being written. 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode<uint64_t>(ByteType*& pBuf, uint64_t pValue); 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode<uint32_t>(ByteType*& pBuf, uint32_t pValue); 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Encoding functions for signed LEB128. 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 6037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode<int64_t>(ByteType*& pBuf, int64_t pValue); 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode<int32_t>(ByteType*& pBuf, int32_t pValue); 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Read an integer encoded in ULEB128 format from the given buffer. pSize will 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * contain the number of bytes used in the buffer to encode the returned 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * integer. 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t decode<uint64_t>(const ByteType* pBuf, size_t& pSize); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Read an integer encoded in ULEB128 format from the given buffer. Update the 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * given buffer pointer to the point just past the end of the read value. 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 7937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t decode<uint64_t>(const ByteType*& pBuf); 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Decoding functions for signed LEB128. 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesint64_t decode<int64_t>(const ByteType* pBuf, size_t& pSize); 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesint64_t decode<int64_t>(const ByteType*& pBuf); 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * The functions below handle the signed byte stream. This helps the user to get 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * rid of annoying type conversions when using the LEB128 encoding/decoding APIs 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * defined above. 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t encode(char*& pBuf, IntType pValue) { 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 10137b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntType decode(const char* pBuf, size_t& pSize) { 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename IntType> 10637b74a387bb3993387029859c2d9d051c41c724eStephen HinesIntType decode(const char*& pBuf) { 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf)); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace leb128 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif // MCLD_SUPPORT_LEB128_H_ 114