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//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_LEB128_H 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_LEB128_H 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdint.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace leb128 { 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotypedef unsigned char ByteType; 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* Forward declarations */ 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode(ByteType *&pBuf, IntType pValue); 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoIntType decode(const ByteType *pBuf, size_t &pSize); 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoIntType decode(const ByteType *&pBuf); 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Given an integer, this function returns the number of bytes required to 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * encode it in ULEB128 format. 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t size(IntType pValue) { 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t size = 1; 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (pValue > 0x80) { 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pValue >>= 7; 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++size; 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return size; 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Write an unsigned integer in ULEB128 to the given buffer. The client should 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * ensure there's enough space in the buffer to hold the result. Update the 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * given buffer pointer to the point just past the end of the write value and 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * return the number of bytes being written. 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue); 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue); 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Encoding functions for signed LEB128. 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode<int64_t>(ByteType *&pBuf, int64_t pValue); 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode<int32_t>(ByteType *&pBuf, int32_t pValue); 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Read an integer encoded in ULEB128 format from the given buffer. pSize will 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * contain the number of bytes used in the buffer to encode the returned 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * integer. 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize); 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Read an integer encoded in ULEB128 format from the given buffer. Update the 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * given buffer pointer to the point just past the end of the read value. 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t decode<uint64_t>(const ByteType *&pBuf); 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * Decoding functions for signed LEB128. 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoint64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize); 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<> 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoint64_t decode<int64_t>(const ByteType *&pBuf); 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * The functions below handle the signed byte stream. This helps the user to get 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * rid of annoying type conversions when using the LEB128 encoding/decoding APIs 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * defined above. 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t encode(char *&pBuf, IntType pValue) { 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoIntType decode(const char *pBuf, size_t &pSize) { 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<typename IntType> 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoIntType decode(const char *&pBuf) { 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf)); 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of leb128 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 118