//===-- RecordSerialization.cpp -------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Utilities for serializing and deserializing CodeView records.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/BinaryByteStream.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;

/// Reinterpret a byte array as an array of characters. Does not interpret as
/// a C string, as StringRef has several helpers (split) that make that easy.
StringRef llvm::codeview::getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
  return StringRef(reinterpret_cast<const char *>(LeafData.data()),
                   LeafData.size());
}

StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
  return getBytesAsCharacters(LeafData).split('\0').first;
}

Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
  // Used to avoid overload ambiguity on APInt constructor.
  bool FalseVal = false;
  uint16_t Short;
  if (auto EC = Reader.readInteger(Short))
    return EC;

  if (Short < LF_NUMERIC) {
    Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
                 /*isUnsigned=*/true);
    return Error::success();
  }

  switch (Short) {
  case LF_CHAR: {
    int8_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(8, N, true), false);
    return Error::success();
  }
  case LF_SHORT: {
    int16_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(16, N, true), false);
    return Error::success();
  }
  case LF_USHORT: {
    uint16_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(16, N, false), true);
    return Error::success();
  }
  case LF_LONG: {
    int32_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(32, N, true), false);
    return Error::success();
  }
  case LF_ULONG: {
    uint32_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(32, N, FalseVal), true);
    return Error::success();
  }
  case LF_QUADWORD: {
    int64_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(64, N, true), false);
    return Error::success();
  }
  case LF_UQUADWORD: {
    uint64_t N;
    if (auto EC = Reader.readInteger(N))
      return EC;
    Num = APSInt(APInt(64, N, false), true);
    return Error::success();
  }
  }
  return make_error<CodeViewError>(cv_error_code::corrupt_record,
                                   "Buffer contains invalid APSInt type");
}

Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
  ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
  BinaryByteStream S(Bytes, llvm::support::little);
  BinaryStreamReader SR(S);
  auto EC = consume(SR, Num);
  Data = Data.take_back(SR.bytesRemaining());
  return EC;
}

/// Decode a numeric leaf value that is known to be a uint64_t.
Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
                                      uint64_t &Num) {
  APSInt N;
  if (auto EC = consume(Reader, N))
    return EC;
  if (N.isSigned() || !N.isIntN(64))
    return make_error<CodeViewError>(cv_error_code::corrupt_record,
                                     "Data is not a numeric value!");
  Num = N.getLimitedValue();
  return Error::success();
}

Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
  return Reader.readInteger(Item);
}

Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
  ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
  BinaryByteStream S(Bytes, llvm::support::little);
  BinaryStreamReader SR(S);
  auto EC = consume(SR, Item);
  Data = Data.take_back(SR.bytesRemaining());
  return EC;
}

Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
  return Reader.readInteger(Item);
}

Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
  if (Reader.empty())
    return make_error<CodeViewError>(cv_error_code::corrupt_record,
                                     "Null terminated string buffer is empty!");

  return Reader.readCString(Item);
}

Expected<CVSymbol> llvm::codeview::readSymbolFromStream(BinaryStreamRef Stream,
                                                        uint32_t Offset) {
  return readCVRecordFromStream<SymbolKind>(Stream, Offset);
}
