// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <limits>

#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_protocol.h"

namespace spdy {

// We mark a read only SpdyFrameBuilder with a special capacity_.
static const size_t kCapacityReadOnly = std::numeric_limits<size_t>::max();

SpdyFrameBuilder::SpdyFrameBuilder()
    : buffer_(NULL),
      capacity_(0),
      length_(0),
      variable_buffer_offset_(0) {
  Resize(kInitialPayload);
}

SpdyFrameBuilder::SpdyFrameBuilder(const char* data, int data_len)
    : buffer_(const_cast<char*>(data)),
      capacity_(kCapacityReadOnly),
      length_(data_len),
      variable_buffer_offset_(0) {
}

SpdyFrameBuilder::~SpdyFrameBuilder() {
  if (capacity_ != kCapacityReadOnly)
    delete[] buffer_;
}

bool SpdyFrameBuilder::ReadUInt16(void** iter, uint16* result) const {
  DCHECK(iter);
  if (!*iter)
    *iter = const_cast<char*>(buffer_);

  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
    return false;

  *result = ntohs(*(reinterpret_cast<uint16*>(*iter)));

  UpdateIter(iter, sizeof(*result));
  return true;
}

bool SpdyFrameBuilder::ReadUInt32(void** iter, uint32* result) const {
  DCHECK(iter);
  if (!*iter)
    *iter = const_cast<char*>(buffer_);

  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
    return false;

  *result = ntohl(*(reinterpret_cast<uint32*>(*iter)));

  UpdateIter(iter, sizeof(*result));
  return true;
}

bool SpdyFrameBuilder::ReadString(void** iter, std::string* result) const {
  DCHECK(iter);

  uint16 len;
  if (!ReadUInt16(iter, &len))
    return false;

  if (!IteratorHasRoomFor(*iter, len))
    return false;

  char* chars = reinterpret_cast<char*>(*iter);
  result->assign(chars, len);

  UpdateIter(iter, len);
  return true;
}

bool SpdyFrameBuilder::ReadBytes(void** iter, const char** data,
                                 uint16 length) const {
  DCHECK(iter);
  DCHECK(data);

  if (!IteratorHasRoomFor(*iter, length))
    return false;

  *data = reinterpret_cast<const char*>(*iter);

  UpdateIter(iter, length);
  return true;
}

bool SpdyFrameBuilder::ReadData(void** iter, const char** data,
                                uint16* length) const {
  DCHECK(iter);
  DCHECK(data);
  DCHECK(length);

  if (!ReadUInt16(iter, length))
    return false;

  return ReadBytes(iter, data, *length);
}

bool SpdyFrameBuilder::WriteString(const std::string& value) {
  if (value.size() > 0xffff)
    return false;

  if (!WriteUInt16(static_cast<int>(value.size())))
    return false;

  return WriteBytes(value.data(), static_cast<uint16>(value.size()));
}

bool SpdyFrameBuilder::WriteBytes(const void* data, uint16 data_len) {
  DCHECK(capacity_ != kCapacityReadOnly);

  char* dest = BeginWrite(data_len);
  if (!dest)
    return false;

  memcpy(dest, data, data_len);

  EndWrite(dest, data_len);
  length_ += data_len;
  return true;
}

char* SpdyFrameBuilder::BeginWriteData(uint16 length) {
  DCHECK_EQ(variable_buffer_offset_, 0U) <<
    "There can only be one variable buffer in a SpdyFrameBuilder";

  if (!WriteUInt16(length))
    return NULL;

  char *data_ptr = BeginWrite(length);
  if (!data_ptr)
    return NULL;

  variable_buffer_offset_ = data_ptr - buffer_ - sizeof(int);

  // EndWrite doesn't necessarily have to be called after the write operation,
  // so we call it here to pad out what the caller will eventually write.
  EndWrite(data_ptr, length);
  return data_ptr;
}

char* SpdyFrameBuilder::BeginWrite(size_t length) {
  size_t needed_size = length_ + length;
  if (needed_size > capacity_ && !Resize(std::max(capacity_ * 2, needed_size)))
    return NULL;

#ifdef ARCH_CPU_64_BITS
  DCHECK_LE(length, std::numeric_limits<uint32>::max());
#endif

  return buffer_ + length_;
}

void SpdyFrameBuilder::EndWrite(char* dest, int length) {
}

bool SpdyFrameBuilder::Resize(size_t new_capacity) {
  if (new_capacity <= capacity_)
    return true;

  char* p = new char[new_capacity];
  if (!p)
    return false;
  if (buffer_) {
    memcpy(p, buffer_, capacity_);
    delete[] buffer_;
  }
  buffer_ = p;
  capacity_ = new_capacity;
  return true;
}

}  // namespace spdy
