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