//===- 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);
  resetStreamedLen();
  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.

  if (isStreaming()) {
    // For streaming mode, add padding to align with 4 byte boundaries for each
    // record
    uint32_t Align = getStreamedLen() % 4;
    if (Align == 0)
      return Error::success();

    int PaddingBytes = 4 - Align;
    while (PaddingBytes > 0) {
      char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
      StringRef BytesSR = StringRef(&Pad, sizeof(Pad));
      Streamer->EmitBytes(BytesSR);
      --PaddingBytes;
    }
  }
  return Error::success();
}

uint32_t CodeViewRecordIO::maxFieldLength() const {
  if (isStreaming())
    return 0;

  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,
                                          const Twine &Comment) {
  if (isStreaming()) {
    emitComment(Comment);
    Streamer->EmitBinaryData(toStringRef(Bytes));
    incrStreamedLen(Bytes.size());
  } else 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,
                                          const Twine &Comment) {
  ArrayRef<uint8_t> BytesRef(Bytes);
  if (auto EC = mapByteVectorTail(BytesRef, Comment))
    return EC;
  if (!isWriting())
    Bytes.assign(BytesRef.begin(), BytesRef.end());

  return Error::success();
}

Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
  if (isStreaming()) {
    emitComment(Comment);
    Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
    incrStreamedLen(sizeof(TypeInd.getIndex()));
  } else if (isWriting()) {
    if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
      return EC;
  } else {
    uint32_t I;
    if (auto EC = Reader->readInteger(I))
      return EC;
    TypeInd.setIndex(I);
  }
  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value,
                                          const Twine &Comment) {
  if (isStreaming()) {
    if (Value >= 0)
      emitEncodedUnsignedInteger(static_cast<uint64_t>(Value), Comment);
    else
      emitEncodedSignedInteger(Value, Comment);
  } else 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,
                                          const Twine &Comment) {
  if (isStreaming())
    emitEncodedUnsignedInteger(Value, Comment);
  else 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, const Twine &Comment) {
  if (isStreaming()) {
    if (Value.isSigned())
      emitEncodedSignedInteger(Value.getSExtValue(), Comment);
    else
      emitEncodedUnsignedInteger(Value.getZExtValue(), Comment);
  } else if (isWriting()) {
    if (Value.isSigned())
      return writeEncodedSignedInteger(Value.getSExtValue());
    return writeEncodedUnsignedInteger(Value.getZExtValue());
  } else
    return consume(*Reader, Value);
  return Error::success();
}

Error CodeViewRecordIO::mapStringZ(StringRef &Value, const Twine &Comment) {
  if (isStreaming()) {
    auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1);
    emitComment(Comment);
    Streamer->EmitBytes(NullTerminatedString);
    incrStreamedLen(NullTerminatedString.size());
  } else 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, const Twine &Comment) {
  constexpr uint32_t GuidSize = 16;

  if (isStreaming()) {
    StringRef GuidSR =
        StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize);
    emitComment(Comment);
    Streamer->EmitBytes(GuidSR);
    incrStreamedLen(GuidSize);
    return Error::success();
  }

  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,
                                          const Twine &Comment) {

  if (!isReading()) {
    emitComment(Comment);
    for (auto V : Value) {
      if (auto EC = mapStringZ(V))
        return EC;
    }
    uint8_t FinalZero = 0;
    if (auto EC = mapInteger(FinalZero))
      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();
}

void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
                                                const Twine &Comment) {
  assert(Value < 0 && "Encoded integer is not signed!");
  if (Value >= std::numeric_limits<int8_t>::min()) {
    Streamer->EmitIntValue(LF_CHAR, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 1);
    incrStreamedLen(3);
  } else if (Value >= std::numeric_limits<int16_t>::min()) {
    Streamer->EmitIntValue(LF_SHORT, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 2);
    incrStreamedLen(4);
  } else if (Value >= std::numeric_limits<int32_t>::min()) {
    Streamer->EmitIntValue(LF_LONG, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 4);
    incrStreamedLen(6);
  } else {
    Streamer->EmitIntValue(LF_QUADWORD, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 4);
    incrStreamedLen(6);
  }
}

void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
                                                  const Twine &Comment) {
  if (Value < LF_NUMERIC) {
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 2);
    incrStreamedLen(2);
  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
    Streamer->EmitIntValue(LF_USHORT, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 2);
    incrStreamedLen(4);
  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
    Streamer->EmitIntValue(LF_ULONG, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 4);
    incrStreamedLen(6);
  } else {
    Streamer->EmitIntValue(LF_UQUADWORD, 2);
    emitComment(Comment);
    Streamer->EmitIntValue(Value, 8);
    incrStreamedLen(6);
  }
}

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();
}
