// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/text_buffer.h"

#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/unicode.h"
#include "platform/utils.h"

namespace dart {

TextBuffer::TextBuffer(intptr_t buf_size) {
  ASSERT(buf_size > 0);
  buf_ = reinterpret_cast<char*>(malloc(buf_size));
  if (buf_ == NULL) {
    OUT_OF_MEMORY();
  }
  buf_size_ = buf_size;
  Clear();
}

TextBuffer::~TextBuffer() {
  free(buf_);
  buf_ = NULL;
}

void TextBuffer::Clear() {
  msg_len_ = 0;
  buf_[0] = '\0';
}

char* TextBuffer::Steal() {
  char* r = buf_;
  buf_ = NULL;
  buf_size_ = 0;
  msg_len_ = 0;
  return r;
}

void TextBuffer::AddChar(char ch) {
  EnsureCapacity(sizeof(ch));
  buf_[msg_len_] = ch;
  msg_len_++;
  buf_[msg_len_] = '\0';
}

void TextBuffer::AddRaw(const uint8_t* buffer, intptr_t buffer_length) {
  EnsureCapacity(buffer_length);
  memmove(&buf_[msg_len_], buffer, buffer_length);
  msg_len_ += buffer_length;
  buf_[msg_len_] = '\0';
}

intptr_t TextBuffer::Printf(const char* format, ...) {
  va_list args;
  va_start(args, format);
  intptr_t remaining = buf_size_ - msg_len_;
  ASSERT(remaining >= 0);
  intptr_t len = Utils::VSNPrint(buf_ + msg_len_, remaining, format, args);
  va_end(args);
  if (len >= remaining) {
    EnsureCapacity(len);
    remaining = buf_size_ - msg_len_;
    ASSERT(remaining > len);
    va_list args2;
    va_start(args2, format);
    intptr_t len2 = Utils::VSNPrint(buf_ + msg_len_, remaining, format, args2);
    va_end(args2);
    ASSERT(len == len2);
  }
  msg_len_ += len;
  buf_[msg_len_] = '\0';
  return len;
}

// Write a UTF-32 code unit so it can be read by a JSON parser in a string
// literal. Use official encoding from JSON specification. http://json.org/
void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) {
  switch (codeunit) {
    case '"':
      AddRaw(reinterpret_cast<uint8_t const*>("\\\""), 2);
      break;
    case '\\':
      AddRaw(reinterpret_cast<uint8_t const*>("\\\\"), 2);
      break;
    case '/':
      AddRaw(reinterpret_cast<uint8_t const*>("\\/"), 2);
      break;
    case '\b':
      AddRaw(reinterpret_cast<uint8_t const*>("\\b"), 2);
      break;
    case '\f':
      AddRaw(reinterpret_cast<uint8_t const*>("\\f"), 2);
      break;
    case '\n':
      AddRaw(reinterpret_cast<uint8_t const*>("\\n"), 2);
      break;
    case '\r':
      AddRaw(reinterpret_cast<uint8_t const*>("\\r"), 2);
      break;
    case '\t':
      AddRaw(reinterpret_cast<uint8_t const*>("\\t"), 2);
      break;
    default:
      if (codeunit < 0x20) {
        EscapeAndAddUTF16CodeUnit(codeunit);
      } else {
        char encoded[6];
        intptr_t length = Utf8::Length(codeunit);
        Utf8::Encode(codeunit, encoded);
        AddRaw(reinterpret_cast<uint8_t const*>(encoded), length);
      }
  }
}

// Write an incomplete UTF-16 code unit so it can be read by a JSON parser in a
// string literal.
void TextBuffer::EscapeAndAddUTF16CodeUnit(uint16_t codeunit) {
  Printf("\\u%04X", codeunit);
}

void TextBuffer::AddString(const char* s) {
  Printf("%s", s);
}

void TextBuffer::AddEscapedString(const char* s) {
  intptr_t len = strlen(s);
  for (int i = 0; i < len; i++) {
    EscapeAndAddCodeUnit(s[i]);
  }
}

void TextBuffer::EnsureCapacity(intptr_t len) {
  intptr_t remaining = buf_size_ - msg_len_;
  if (remaining <= len) {
    intptr_t new_size = buf_size_ + Utils::Maximum(buf_size_, len + 1);
    char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size));
    if (new_buf == NULL) {
      OUT_OF_MEMORY();
    }
    buf_ = new_buf;
    buf_size_ = new_size;
  }
}

void BufferFormatter::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VPrint(format, args);
  va_end(args);
}

void BufferFormatter::VPrint(const char* format, va_list args) {
  intptr_t available = size_ - position_;
  if (available <= 0) return;
  intptr_t written =
      Utils::VSNPrint(buffer_ + position_, available, format, args);
  if (written >= 0) {
    position_ += (available <= written) ? available : written;
  }
}

}  // namespace dart
