//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"

using namespace llvm;
using namespace llvm::codeview;

Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
  RecordLimit Limit;
  Limit.MaxLength = MaxLength;
  Limit.BeginOffset = getCurrentOffset();
  Limits.push_back(Limit);
  return Error::success();
}

Error CodeViewRecordIO::endRecord() {
  assert(!Limits.empty() && "Not in a record!");
  Limits.pop_back();
  // We would like to assert that we actually read / wrote all the bytes that we
  // expected to for this record, but unfortunately we can't do this.  Some
  // producers such as MASM over-allocate for certain types of records and
  // commit the extraneous data, so when reading we can't be sure every byte
  // will have been read.  And when writing we over-allocate temporarily since
  // we don't know how big the record is until we're finished writing it, so
  // even though we don't commit the extraneous data, we still can't guarantee
  // we're at the end of the allocated data.
  return Error::success();
}

uint32_t CodeViewRecordIO::maxFieldLength() const {
  assert(!Limits.empty() && "Not in a record!");

  // The max length of the next field is the minimum of all lengths that would
  // be allowed by any of the sub-records we're in.  In practice, we can only
  // ever be at most 1 sub-record deep (in a FieldList), but this works for
  // the general case.
  uint32_t Offset = getCurrentOffset();
  Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
  for (auto X : makeArrayRef(Limits).drop_front()) {
    Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
    if (ThisMin.hasValue())
      Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
  }
  assert(Min.hasValue() && "Every field must have a maximum length!");

  return *Min;
}

Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
  if (isReading())
    return Reader->padToAlignment(Align);
  return Writer->padToAlignment(Align);
}

Error CodeViewRecordIO::skipPadding() {
  assert(!isWriting() && "Cannot skip padding while writing!");

  if (Reader->bytesRemaining() == 0)
    return Error::success();

  uint8_t Leaf = Reader->peek();
  if (Leaf < LF_PAD0)
    return Error::success();
  // Leaf is greater than 0xf0. We should advance by the number of bytes in
  // the low 4 bits.
  unsigned BytesToAdvance = Leaf & 0x0F;
  return Reader->skip(BytesToAdvance);
}

Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
  if (isWriting()) {
    if (auto EC = Writer->writeBytes(Bytes))
      return EC;
  } else {
    if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
  ArrayRef<uint8_t> BytesRef(Bytes);
  if (auto EC = mapByteVectorTail(BytesRef))
    return EC;
  if (!isWriting())
    Bytes.assign(BytesRef.begin(), BytesRef.end());

  return Error::success();
}

Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
  if (isWriting()) {
    if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
      return EC;
    return Error::success();
  }

  uint32_t I;
  if (auto EC = Reader->readInteger(I))
    return EC;
  TypeInd.setIndex(I);
  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
  if (isWriting()) {
    if (Value >= 0) {
      if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
        return EC;
    } else {
      if (auto EC = writeEncodedSignedInteger(Value))
        return EC;
    }
  } else {
    APSInt N;
    if (auto EC = consume(*Reader, N))
      return EC;
    Value = N.getExtValue();
  }

  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
  if (isWriting()) {
    if (auto EC = writeEncodedUnsignedInteger(Value))
      return EC;
  } else {
    APSInt N;
    if (auto EC = consume(*Reader, N))
      return EC;
    Value = N.getZExtValue();
  }
  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
  if (isWriting()) {
    if (Value.isSigned())
      return writeEncodedSignedInteger(Value.getSExtValue());
    return writeEncodedUnsignedInteger(Value.getZExtValue());
  }

  return consume(*Reader, Value);
}

Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
  if (isWriting()) {
    // Truncate if we attempt to write too much.
    StringRef S = Value.take_front(maxFieldLength() - 1);
    if (auto EC = Writer->writeCString(S))
      return EC;
  } else {
    if (auto EC = Reader->readCString(Value))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::mapGuid(GUID &Guid) {
  constexpr uint32_t GuidSize = 16;
  if (maxFieldLength() < GuidSize)
    return make_error<CodeViewError>(cv_error_code::insufficient_buffer);

  if (isWriting()) {
    if (auto EC = Writer->writeBytes(Guid.Guid))
      return EC;
  } else {
    ArrayRef<uint8_t> GuidBytes;
    if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
      return EC;
    memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
  }
  return Error::success();
}

Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
  if (isWriting()) {
    for (auto V : Value) {
      if (auto EC = mapStringZ(V))
        return EC;
    }
    if (auto EC = Writer->writeInteger<uint8_t>(0))
      return EC;
  } else {
    StringRef S;
    if (auto EC = mapStringZ(S))
      return EC;
    while (!S.empty()) {
      Value.push_back(S);
      if (auto EC = mapStringZ(S))
        return EC;
    };
  }
  return Error::success();
}

Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
  assert(Value < 0 && "Encoded integer is not signed!");
  if (Value >= std::numeric_limits<int8_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
      return EC;
    if (auto EC = Writer->writeInteger<int8_t>(Value))
      return EC;
  } else if (Value >= std::numeric_limits<int16_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
      return EC;
    if (auto EC = Writer->writeInteger<int16_t>(Value))
      return EC;
  } else if (Value >= std::numeric_limits<int32_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
      return EC;
    if (auto EC = Writer->writeInteger<int32_t>(Value))
      return EC;
  } else {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
      return EC;
    if (auto EC = Writer->writeInteger(Value))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
  if (Value < LF_NUMERIC) {
    if (auto EC = Writer->writeInteger<uint16_t>(Value))
      return EC;
  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
      return EC;
    if (auto EC = Writer->writeInteger<uint16_t>(Value))
      return EC;
  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
      return EC;
    if (auto EC = Writer->writeInteger<uint32_t>(Value))
      return EC;
  } else {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
      return EC;
    if (auto EC = Writer->writeInteger(Value))
      return EC;
  }

  return Error::success();
}
