// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_STRING_STREAM_H_
#define V8_STRING_STREAM_H_

#include "src/handles.h"

namespace v8 {
namespace internal {

class StringAllocator {
 public:
  virtual ~StringAllocator() { }
  // Allocate a number of bytes.
  virtual char* allocate(unsigned bytes) = 0;
  // Allocate a larger number of bytes and copy the old buffer to the new one.
  // bytes is an input and output parameter passing the old size of the buffer
  // and returning the new size.  If allocation fails then we return the old
  // buffer and do not increase the size.
  virtual char* grow(unsigned* bytes) = 0;
};


// Normal allocator uses new[] and delete[].
class HeapStringAllocator FINAL : public StringAllocator {
 public:
  ~HeapStringAllocator() { DeleteArray(space_); }
  virtual char* allocate(unsigned bytes) OVERRIDE;
  virtual char* grow(unsigned* bytes) OVERRIDE;

 private:
  char* space_;
};


class FmtElm FINAL {
 public:
  FmtElm(int value) : type_(INT) {  // NOLINT
    data_.u_int_ = value;
  }
  explicit FmtElm(double value) : type_(DOUBLE) {
    data_.u_double_ = value;
  }
  FmtElm(const char* value) : type_(C_STR) {  // NOLINT
    data_.u_c_str_ = value;
  }
  FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
    data_.u_lc_str_ = &value;
  }
  FmtElm(Object* value) : type_(OBJ) {  // NOLINT
    data_.u_obj_ = value;
  }
  FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
    data_.u_handle_ = value.location();
  }
  FmtElm(void* value) : type_(POINTER) {  // NOLINT
    data_.u_pointer_ = value;
  }

 private:
  friend class StringStream;
  enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
  Type type_;
  union {
    int u_int_;
    double u_double_;
    const char* u_c_str_;
    const Vector<const uc16>* u_lc_str_;
    Object* u_obj_;
    Object** u_handle_;
    void* u_pointer_;
  } data_;
};


class StringStream FINAL {
 public:
  explicit StringStream(StringAllocator* allocator):
    allocator_(allocator),
    capacity_(kInitialCapacity),
    length_(0),
    buffer_(allocator_->allocate(kInitialCapacity)) {
    buffer_[0] = 0;
  }

  bool Put(char c);
  bool Put(String* str);
  bool Put(String* str, int start, int end);
  void Add(Vector<const char> format, Vector<FmtElm> elms);
  void Add(const char* format);
  void Add(Vector<const char> format);
  void Add(const char* format, FmtElm arg0);
  void Add(const char* format, FmtElm arg0, FmtElm arg1);
  void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
  void Add(const char* format,
           FmtElm arg0,
           FmtElm arg1,
           FmtElm arg2,
           FmtElm arg3);
  void Add(const char* format,
           FmtElm arg0,
           FmtElm arg1,
           FmtElm arg2,
           FmtElm arg3,
           FmtElm arg4);

  // Getting the message out.
  void OutputToFile(FILE* out);
  void OutputToStdOut() { OutputToFile(stdout); }
  void Log(Isolate* isolate);
  Handle<String> ToString(Isolate* isolate);
  SmartArrayPointer<const char> ToCString() const;
  int length() const { return length_; }

  // Object printing support.
  void PrintName(Object* o);
  void PrintFixedArray(FixedArray* array, unsigned int limit);
  void PrintByteArray(ByteArray* ba);
  void PrintUsingMap(JSObject* js_object);
  void PrintPrototype(JSFunction* fun, Object* receiver);
  void PrintSecurityTokenIfChanged(Object* function);
  // NOTE: Returns the code in the output parameter.
  void PrintFunction(Object* function, Object* receiver, Code** code);

  // Reset the stream.
  void Reset() {
    length_ = 0;
    buffer_[0] = 0;
  }

  // Mentioned object cache support.
  void PrintMentionedObjectCache(Isolate* isolate);
  static void ClearMentionedObjectCache(Isolate* isolate);
#ifdef DEBUG
  static bool IsMentionedObjectCacheClear(Isolate* isolate);
#endif

  static const int kInitialCapacity = 16;

 private:
  void PrintObject(Object* obj);

  StringAllocator* allocator_;
  unsigned capacity_;
  unsigned length_;  // does not include terminating 0-character
  char* buffer_;

  bool full() const { return (capacity_ - length_) == 1; }
  int space() const { return capacity_ - length_; }

  DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
};

} }  // namespace v8::internal

#endif  // V8_STRING_STREAM_H_
