// Copyright 2006 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__
#define UTIL_DEBUGINFO_BYTEREADER_INL_H__

#include "common/dwarf/bytereader.h"

#include <assert.h>
#include <stdint.h>

namespace dwarf2reader {

inline uint8_t ByteReader::ReadOneByte(const uint8_t *buffer) const {
  return buffer[0];
}

inline uint16_t ByteReader::ReadTwoBytes(const uint8_t *buffer) const {
  const uint16_t buffer0 = buffer[0];
  const uint16_t buffer1 = buffer[1];
  if (endian_ == ENDIANNESS_LITTLE) {
    return buffer0 | buffer1 << 8;
  } else {
    return buffer1 | buffer0 << 8;
  }
}

inline uint64_t ByteReader::ReadFourBytes(const uint8_t *buffer) const {
  const uint32_t buffer0 = buffer[0];
  const uint32_t buffer1 = buffer[1];
  const uint32_t buffer2 = buffer[2];
  const uint32_t buffer3 = buffer[3];
  if (endian_ == ENDIANNESS_LITTLE) {
    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24;
  } else {
    return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24;
  }
}

inline uint64_t ByteReader::ReadEightBytes(const uint8_t *buffer) const {
  const uint64_t buffer0 = buffer[0];
  const uint64_t buffer1 = buffer[1];
  const uint64_t buffer2 = buffer[2];
  const uint64_t buffer3 = buffer[3];
  const uint64_t buffer4 = buffer[4];
  const uint64_t buffer5 = buffer[5];
  const uint64_t buffer6 = buffer[6];
  const uint64_t buffer7 = buffer[7];
  if (endian_ == ENDIANNESS_LITTLE) {
    return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 |
      buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56;
  } else {
    return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 |
      buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56;
  }
}

// Read an unsigned LEB128 number.  Each byte contains 7 bits of
// information, plus one bit saying whether the number continues or
// not.

inline uint64_t ByteReader::ReadUnsignedLEB128(const uint8_t *buffer,
                                             size_t* len) const {
  uint64_t result = 0;
  size_t num_read = 0;
  unsigned int shift = 0;
  uint8_t byte;

  do {
    byte = *buffer++;
    num_read++;

    result |= (static_cast<uint64_t>(byte & 0x7f)) << shift;

    shift += 7;

  } while (byte & 0x80);

  *len = num_read;

  return result;
}

// Read a signed LEB128 number.  These are like regular LEB128
// numbers, except the last byte may have a sign bit set.

inline int64_t ByteReader::ReadSignedLEB128(const uint8_t *buffer,
                                          size_t* len) const {
  int64_t result = 0;
  unsigned int shift = 0;
  size_t num_read = 0;
  uint8_t byte;

  do {
      byte = *buffer++;
      num_read++;
      result |= (static_cast<uint64_t>(byte & 0x7f) << shift);
      shift += 7;
  } while (byte & 0x80);

  if ((shift < 8 * sizeof (result)) && (byte & 0x40))
    result |= -((static_cast<int64_t>(1)) << shift);
  *len = num_read;
  return result;
}

inline uint64_t ByteReader::ReadOffset(const uint8_t *buffer) const {
  assert(this->offset_reader_);
  return (this->*offset_reader_)(buffer);
}

inline uint64_t ByteReader::ReadAddress(const uint8_t *buffer) const {
  assert(this->address_reader_);
  return (this->*address_reader_)(buffer);
}

inline void ByteReader::SetCFIDataBase(uint64_t section_base,
                                       const uint8_t *buffer_base) {
  section_base_ = section_base;
  buffer_base_ = buffer_base;
  have_section_base_ = true;
}

inline void ByteReader::SetTextBase(uint64_t text_base) {
  text_base_ = text_base;
  have_text_base_ = true;
}

inline void ByteReader::SetDataBase(uint64_t data_base) {
  data_base_ = data_base;
  have_data_base_ = true;
}

inline void ByteReader::SetFunctionBase(uint64_t function_base) {
  function_base_ = function_base;
  have_function_base_ = true;
}

inline void ByteReader::ClearFunctionBase() {
  have_function_base_ = false;
}

}  // namespace dwarf2reader

#endif  // UTIL_DEBUGINFO_BYTEREADER_INL_H__
