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