//===-- StringPrinter.cpp ----------------------------------------*- C++
//-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/DataFormatters/StringPrinter.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "llvm/Support/ConvertUTF.h"

#include <ctype.h>
#include <locale>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

// we define this for all values of type but only implement it for those we care
// about
// that's good because we get linker errors for any unsupported type
template <lldb_private::formatters::StringPrinter::StringElementType type>
static StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl(uint8_t *buffer, uint8_t *buffer_end, uint8_t *&next);

// mimic isprint() for Unicode codepoints
static bool isprint(char32_t codepoint) {
  if (codepoint <= 0x1F || codepoint == 0x7F) // C0
  {
    return false;
  }
  if (codepoint >= 0x80 && codepoint <= 0x9F) // C1
  {
    return false;
  }
  if (codepoint == 0x2028 || codepoint == 0x2029) // line/paragraph separators
  {
    return false;
  }
  if (codepoint == 0x200E || codepoint == 0x200F ||
      (codepoint >= 0x202A &&
       codepoint <= 0x202E)) // bidirectional text control
  {
    return false;
  }
  if (codepoint >= 0xFFF9 &&
      codepoint <= 0xFFFF) // interlinears and generally specials
  {
    return false;
  }
  return true;
}

template <>
StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl<StringPrinter::StringElementType::ASCII>(uint8_t *buffer,
                                                          uint8_t *buffer_end,
                                                          uint8_t *&next) {
  StringPrinter::StringPrinterBufferPointer<> retval = {nullptr};

  switch (*buffer) {
  case 0:
    retval = {"\\0", 2};
    break;
  case '\a':
    retval = {"\\a", 2};
    break;
  case '\b':
    retval = {"\\b", 2};
    break;
  case '\f':
    retval = {"\\f", 2};
    break;
  case '\n':
    retval = {"\\n", 2};
    break;
  case '\r':
    retval = {"\\r", 2};
    break;
  case '\t':
    retval = {"\\t", 2};
    break;
  case '\v':
    retval = {"\\v", 2};
    break;
  case '\"':
    retval = {"\\\"", 2};
    break;
  case '\\':
    retval = {"\\\\", 2};
    break;
  default:
    if (isprint(*buffer))
      retval = {buffer, 1};
    else {
      uint8_t *data = new uint8_t[5];
      sprintf((char *)data, "\\x%02x", *buffer);
      retval = {data, 4, [](const uint8_t *c) { delete[] c; }};
      break;
    }
  }

  next = buffer + 1;
  return retval;
}

static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1) {
  return (c0 - 192) * 64 + (c1 - 128);
}
static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1,
                                       unsigned char c2) {
  return (c0 - 224) * 4096 + (c1 - 128) * 64 + (c2 - 128);
}
static char32_t ConvertUTF8ToCodePoint(unsigned char c0, unsigned char c1,
                                       unsigned char c2, unsigned char c3) {
  return (c0 - 240) * 262144 + (c2 - 128) * 4096 + (c2 - 128) * 64 + (c3 - 128);
}

template <>
StringPrinter::StringPrinterBufferPointer<>
GetPrintableImpl<StringPrinter::StringElementType::UTF8>(uint8_t *buffer,
                                                         uint8_t *buffer_end,
                                                         uint8_t *&next) {
  StringPrinter::StringPrinterBufferPointer<> retval{nullptr};

  unsigned utf8_encoded_len = getNumBytesForUTF8(*buffer);

  if (1 + buffer_end - buffer < utf8_encoded_len) {
    // I don't have enough bytes - print whatever I have left
    retval = {buffer, static_cast<size_t>(1 + buffer_end - buffer)};
    next = buffer_end + 1;
    return retval;
  }

  char32_t codepoint = 0;
  switch (utf8_encoded_len) {
  case 1:
    // this is just an ASCII byte - ask ASCII
    return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(
        buffer, buffer_end, next);
  case 2:
    codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer,
                                       (unsigned char)*(buffer + 1));
    break;
  case 3:
    codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer,
                                       (unsigned char)*(buffer + 1),
                                       (unsigned char)*(buffer + 2));
    break;
  case 4:
    codepoint = ConvertUTF8ToCodePoint(
        (unsigned char)*buffer, (unsigned char)*(buffer + 1),
        (unsigned char)*(buffer + 2), (unsigned char)*(buffer + 3));
    break;
  default:
    // this is probably some bogus non-character thing
    // just print it as-is and hope to sync up again soon
    retval = {buffer, 1};
    next = buffer + 1;
    return retval;
  }

  if (codepoint) {
    switch (codepoint) {
    case 0:
      retval = {"\\0", 2};
      break;
    case '\a':
      retval = {"\\a", 2};
      break;
    case '\b':
      retval = {"\\b", 2};
      break;
    case '\f':
      retval = {"\\f", 2};
      break;
    case '\n':
      retval = {"\\n", 2};
      break;
    case '\r':
      retval = {"\\r", 2};
      break;
    case '\t':
      retval = {"\\t", 2};
      break;
    case '\v':
      retval = {"\\v", 2};
      break;
    case '\"':
      retval = {"\\\"", 2};
      break;
    case '\\':
      retval = {"\\\\", 2};
      break;
    default:
      if (isprint(codepoint))
        retval = {buffer, utf8_encoded_len};
      else {
        uint8_t *data = new uint8_t[11];
        sprintf((char *)data, "\\U%08x", (unsigned)codepoint);
        retval = {data, 10, [](const uint8_t *c) { delete[] c; }};
        break;
      }
    }

    next = buffer + utf8_encoded_len;
    return retval;
  }

  // this should not happen - but just in case.. try to resync at some point
  retval = {buffer, 1};
  next = buffer + 1;
  return retval;
}

// Given a sequence of bytes, this function returns:
// a sequence of bytes to actually print out + a length
// the following unscanned position of the buffer is in next
static StringPrinter::StringPrinterBufferPointer<>
GetPrintable(StringPrinter::StringElementType type, uint8_t *buffer,
             uint8_t *buffer_end, uint8_t *&next) {
  if (!buffer)
    return {nullptr};

  switch (type) {
  case StringPrinter::StringElementType::ASCII:
    return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(
        buffer, buffer_end, next);
  case StringPrinter::StringElementType::UTF8:
    return GetPrintableImpl<StringPrinter::StringElementType::UTF8>(
        buffer, buffer_end, next);
  default:
    return {nullptr};
  }
}

StringPrinter::EscapingHelper
StringPrinter::GetDefaultEscapingHelper(GetPrintableElementType elem_type) {
  switch (elem_type) {
  case GetPrintableElementType::UTF8:
    return [](uint8_t *buffer, uint8_t *buffer_end,
              uint8_t *&next) -> StringPrinter::StringPrinterBufferPointer<> {
      return GetPrintable(StringPrinter::StringElementType::UTF8, buffer,
                          buffer_end, next);
    };
  case GetPrintableElementType::ASCII:
    return [](uint8_t *buffer, uint8_t *buffer_end,
              uint8_t *&next) -> StringPrinter::StringPrinterBufferPointer<> {
      return GetPrintable(StringPrinter::StringElementType::ASCII, buffer,
                          buffer_end, next);
    };
  }
  llvm_unreachable("bad element type");
}

// use this call if you already have an LLDB-side buffer for the data
template <typename SourceDataType>
static bool DumpUTFBufferToStream(
    ConversionResult (*ConvertFunction)(const SourceDataType **,
                                        const SourceDataType *, UTF8 **, UTF8 *,
                                        ConversionFlags),
    const StringPrinter::ReadBufferAndDumpToStreamOptions &dump_options) {
  Stream &stream(*dump_options.GetStream());
  if (dump_options.GetPrefixToken() != 0)
    stream.Printf("%s", dump_options.GetPrefixToken());
  if (dump_options.GetQuote() != 0)
    stream.Printf("%c", dump_options.GetQuote());
  auto data(dump_options.GetData());
  auto source_size(dump_options.GetSourceSize());
  if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd()) {
    const int bufferSPSize = data.GetByteSize();
    if (dump_options.GetSourceSize() == 0) {
      const int origin_encoding = 8 * sizeof(SourceDataType);
      source_size = bufferSPSize / (origin_encoding / 4);
    }

    const SourceDataType *data_ptr =
        (const SourceDataType *)data.GetDataStart();
    const SourceDataType *data_end_ptr = data_ptr + source_size;

    const bool zero_is_terminator = dump_options.GetBinaryZeroIsTerminator();

    if (zero_is_terminator) {
      while (data_ptr < data_end_ptr) {
        if (!*data_ptr) {
          data_end_ptr = data_ptr;
          break;
        }
        data_ptr++;
      }

      data_ptr = (const SourceDataType *)data.GetDataStart();
    }

    lldb::DataBufferSP utf8_data_buffer_sp;
    UTF8 *utf8_data_ptr = nullptr;
    UTF8 *utf8_data_end_ptr = nullptr;

    if (ConvertFunction) {
      utf8_data_buffer_sp.reset(new DataBufferHeap(4 * bufferSPSize, 0));
      utf8_data_ptr = (UTF8 *)utf8_data_buffer_sp->GetBytes();
      utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize();
      ConvertFunction(&data_ptr, data_end_ptr, &utf8_data_ptr,
                      utf8_data_end_ptr, lenientConversion);
      if (false == zero_is_terminator)
        utf8_data_end_ptr = utf8_data_ptr;
      utf8_data_ptr =
          (UTF8 *)utf8_data_buffer_sp->GetBytes(); // needed because the
                                                   // ConvertFunction will
                                                   // change the value of the
                                                   // data_ptr
    } else {
      // just copy the pointers - the cast is necessary to make the compiler
      // happy
      // but this should only happen if we are reading UTF8 data
      utf8_data_ptr =
          const_cast<UTF8 *>(reinterpret_cast<const UTF8 *>(data_ptr));
      utf8_data_end_ptr =
          const_cast<UTF8 *>(reinterpret_cast<const UTF8 *>(data_end_ptr));
    }

    const bool escape_non_printables = dump_options.GetEscapeNonPrintables();
    lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback;
    if (escape_non_printables) {
      if (Language *language = Language::FindPlugin(dump_options.GetLanguage()))
        escaping_callback = language->GetStringPrinterEscapingHelper(
            lldb_private::formatters::StringPrinter::GetPrintableElementType::
                UTF8);
      else
        escaping_callback =
            lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(
                lldb_private::formatters::StringPrinter::
                    GetPrintableElementType::UTF8);
    }

    // since we tend to accept partial data (and even partially malformed data)
    // we might end up with no NULL terminator before the end_ptr
    // hence we need to take a slower route and ensure we stay within boundaries
    for (; utf8_data_ptr < utf8_data_end_ptr;) {
      if (zero_is_terminator && !*utf8_data_ptr)
        break;

      if (escape_non_printables) {
        uint8_t *next_data = nullptr;
        auto printable =
            escaping_callback(utf8_data_ptr, utf8_data_end_ptr, next_data);
        auto printable_bytes = printable.GetBytes();
        auto printable_size = printable.GetSize();
        if (!printable_bytes || !next_data) {
          // GetPrintable() failed on us - print one byte in a desperate resync
          // attempt
          printable_bytes = utf8_data_ptr;
          printable_size = 1;
          next_data = utf8_data_ptr + 1;
        }
        for (unsigned c = 0; c < printable_size; c++)
          stream.Printf("%c", *(printable_bytes + c));
        utf8_data_ptr = (uint8_t *)next_data;
      } else {
        stream.Printf("%c", *utf8_data_ptr);
        utf8_data_ptr++;
      }
    }
  }
  if (dump_options.GetQuote() != 0)
    stream.Printf("%c", dump_options.GetQuote());
  if (dump_options.GetSuffixToken() != 0)
    stream.Printf("%s", dump_options.GetSuffixToken());
  if (dump_options.GetIsTruncated())
    stream.Printf("...");
  return true;
}

lldb_private::formatters::StringPrinter::ReadStringAndDumpToStreamOptions::
    ReadStringAndDumpToStreamOptions(ValueObject &valobj)
    : ReadStringAndDumpToStreamOptions() {
  SetEscapeNonPrintables(
      valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables());
}

lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::
    ReadBufferAndDumpToStreamOptions(ValueObject &valobj)
    : ReadBufferAndDumpToStreamOptions() {
  SetEscapeNonPrintables(
      valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables());
}

lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::
    ReadBufferAndDumpToStreamOptions(
        const ReadStringAndDumpToStreamOptions &options)
    : ReadBufferAndDumpToStreamOptions() {
  SetStream(options.GetStream());
  SetPrefixToken(options.GetPrefixToken());
  SetSuffixToken(options.GetSuffixToken());
  SetQuote(options.GetQuote());
  SetEscapeNonPrintables(options.GetEscapeNonPrintables());
  SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator());
  SetLanguage(options.GetLanguage());
}

namespace lldb_private {

namespace formatters {

template <>
bool StringPrinter::ReadStringAndDumpToStream<
    StringPrinter::StringElementType::ASCII>(
    const ReadStringAndDumpToStreamOptions &options) {
  assert(options.GetStream() && "need a Stream to print the string to");
  Error my_error;

  ProcessSP process_sp(options.GetProcessSP());

  if (process_sp.get() == nullptr || options.GetLocation() == 0)
    return false;

  size_t size;
  const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
  bool is_truncated = false;

  if (options.GetSourceSize() == 0)
    size = max_size;
  else if (!options.GetIgnoreMaxLength()) {
    size = options.GetSourceSize();
    if (size > max_size) {
      size = max_size;
      is_truncated = true;
    }
  } else
    size = options.GetSourceSize();

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(size, 0));

  process_sp->ReadCStringFromMemory(
      options.GetLocation(), (char *)buffer_sp->GetBytes(), size, my_error);

  if (my_error.Fail())
    return false;

  const char *prefix_token = options.GetPrefixToken();
  char quote = options.GetQuote();

  if (prefix_token != 0)
    options.GetStream()->Printf("%s%c", prefix_token, quote);
  else if (quote != 0)
    options.GetStream()->Printf("%c", quote);

  uint8_t *data_end = buffer_sp->GetBytes() + buffer_sp->GetByteSize();

  const bool escape_non_printables = options.GetEscapeNonPrintables();
  lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback;
  if (escape_non_printables) {
    if (Language *language = Language::FindPlugin(options.GetLanguage()))
      escaping_callback = language->GetStringPrinterEscapingHelper(
          lldb_private::formatters::StringPrinter::GetPrintableElementType::
              ASCII);
    else
      escaping_callback =
          lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(
              lldb_private::formatters::StringPrinter::GetPrintableElementType::
                  ASCII);
  }

  // since we tend to accept partial data (and even partially malformed data)
  // we might end up with no NULL terminator before the end_ptr
  // hence we need to take a slower route and ensure we stay within boundaries
  for (uint8_t *data = buffer_sp->GetBytes(); *data && (data < data_end);) {
    if (escape_non_printables) {
      uint8_t *next_data = nullptr;
      auto printable = escaping_callback(data, data_end, next_data);
      auto printable_bytes = printable.GetBytes();
      auto printable_size = printable.GetSize();
      if (!printable_bytes || !next_data) {
        // GetPrintable() failed on us - print one byte in a desperate resync
        // attempt
        printable_bytes = data;
        printable_size = 1;
        next_data = data + 1;
      }
      for (unsigned c = 0; c < printable_size; c++)
        options.GetStream()->Printf("%c", *(printable_bytes + c));
      data = (uint8_t *)next_data;
    } else {
      options.GetStream()->Printf("%c", *data);
      data++;
    }
  }

  const char *suffix_token = options.GetSuffixToken();

  if (suffix_token != 0)
    options.GetStream()->Printf("%c%s", quote, suffix_token);
  else if (quote != 0)
    options.GetStream()->Printf("%c", quote);

  if (is_truncated)
    options.GetStream()->Printf("...");

  return true;
}

template <typename SourceDataType>
static bool ReadUTFBufferAndDumpToStream(
    const StringPrinter::ReadStringAndDumpToStreamOptions &options,
    ConversionResult (*ConvertFunction)(const SourceDataType **,
                                        const SourceDataType *, UTF8 **, UTF8 *,
                                        ConversionFlags)) {
  assert(options.GetStream() && "need a Stream to print the string to");

  if (options.GetLocation() == 0 ||
      options.GetLocation() == LLDB_INVALID_ADDRESS)
    return false;

  lldb::ProcessSP process_sp(options.GetProcessSP());

  if (!process_sp)
    return false;

  const int type_width = sizeof(SourceDataType);
  const int origin_encoding = 8 * type_width;
  if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32)
    return false;
  // if not UTF8, I need a conversion function to return proper UTF8
  if (origin_encoding != 8 && !ConvertFunction)
    return false;

  if (!options.GetStream())
    return false;

  uint32_t sourceSize = options.GetSourceSize();
  bool needs_zero_terminator = options.GetNeedsZeroTermination();

  bool is_truncated = false;
  const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();

  if (!sourceSize) {
    sourceSize = max_size;
    needs_zero_terminator = true;
  } else if (!options.GetIgnoreMaxLength()) {
    if (sourceSize > max_size) {
      sourceSize = max_size;
      is_truncated = true;
    }
  }

  const int bufferSPSize = sourceSize * type_width;

  lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize, 0));

  if (!buffer_sp->GetBytes())
    return false;

  Error error;
  char *buffer = reinterpret_cast<char *>(buffer_sp->GetBytes());

  if (needs_zero_terminator)
    process_sp->ReadStringFromMemory(options.GetLocation(), buffer,
                                     bufferSPSize, error, type_width);
  else
    process_sp->ReadMemoryFromInferior(options.GetLocation(),
                                       (char *)buffer_sp->GetBytes(),
                                       bufferSPSize, error);

  if (error.Fail()) {
    options.GetStream()->Printf("unable to read data");
    return true;
  }

  DataExtractor data(buffer_sp, process_sp->GetByteOrder(),
                     process_sp->GetAddressByteSize());

  StringPrinter::ReadBufferAndDumpToStreamOptions dump_options(options);
  dump_options.SetData(data);
  dump_options.SetSourceSize(sourceSize);
  dump_options.SetIsTruncated(is_truncated);

  return DumpUTFBufferToStream(ConvertFunction, dump_options);
}

template <>
bool StringPrinter::ReadStringAndDumpToStream<
    StringPrinter::StringElementType::UTF8>(
    const ReadStringAndDumpToStreamOptions &options) {
  return ReadUTFBufferAndDumpToStream<UTF8>(options, nullptr);
}

template <>
bool StringPrinter::ReadStringAndDumpToStream<
    StringPrinter::StringElementType::UTF16>(
    const ReadStringAndDumpToStreamOptions &options) {
  return ReadUTFBufferAndDumpToStream<UTF16>(options, ConvertUTF16toUTF8);
}

template <>
bool StringPrinter::ReadStringAndDumpToStream<
    StringPrinter::StringElementType::UTF32>(
    const ReadStringAndDumpToStreamOptions &options) {
  return ReadUTFBufferAndDumpToStream<UTF32>(options, ConvertUTF32toUTF8);
}

template <>
bool StringPrinter::ReadBufferAndDumpToStream<
    StringPrinter::StringElementType::UTF8>(
    const ReadBufferAndDumpToStreamOptions &options) {
  assert(options.GetStream() && "need a Stream to print the string to");

  return DumpUTFBufferToStream<UTF8>(nullptr, options);
}

template <>
bool StringPrinter::ReadBufferAndDumpToStream<
    StringPrinter::StringElementType::ASCII>(
    const ReadBufferAndDumpToStreamOptions &options) {
  // treat ASCII the same as UTF8
  // FIXME: can we optimize ASCII some more?
  return ReadBufferAndDumpToStream<StringElementType::UTF8>(options);
}

template <>
bool StringPrinter::ReadBufferAndDumpToStream<
    StringPrinter::StringElementType::UTF16>(
    const ReadBufferAndDumpToStreamOptions &options) {
  assert(options.GetStream() && "need a Stream to print the string to");

  return DumpUTFBufferToStream(ConvertUTF16toUTF8, options);
}

template <>
bool StringPrinter::ReadBufferAndDumpToStream<
    StringPrinter::StringElementType::UTF32>(
    const ReadBufferAndDumpToStreamOptions &options) {
  assert(options.GetStream() && "need a Stream to print the string to");

  return DumpUTFBufferToStream(ConvertUTF32toUTF8, options);
}

} // namespace formatters

} // namespace lldb_private
