// 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 ByteReader::ReadOneByte(const uint8_t *buffer) const {
  return buffer[0];
}

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

inline uint64 ByteReader::ReadFourBytes(const uint8_t *buffer) const {
  const uint32 buffer0 = buffer[0];
  const uint32 buffer1 = buffer[1];
  const uint32 buffer2 = buffer[2];
  const uint32 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 ByteReader::ReadEightBytes(const uint8_t *buffer) const {
  const uint64 buffer0 = buffer[0];
  const uint64 buffer1 = buffer[1];
  const uint64 buffer2 = buffer[2];
  const uint64 buffer3 = buffer[3];
  const uint64 buffer4 = buffer[4];
  const uint64 buffer5 = buffer[5];
  const uint64 buffer6 = buffer[6];
  const uint64 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 ByteReader::ReadUnsignedLEB128(const uint8_t *buffer,
                                             size_t* len) const {
  uint64 result = 0;
  size_t num_read = 0;
  unsigned int shift = 0;
  uint8_t byte;

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

    result |= (static_cast<uint64>(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 ByteReader::ReadSignedLEB128(const uint8_t *buffer,
                                          size_t* len) const {
  int64 result = 0;
  unsigned int shift = 0;
  size_t num_read = 0;
  uint8_t byte;

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

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

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

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

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

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

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

inline void ByteReader::SetFunctionBase(uint64 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__
