// 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_OSTREAMS_H_
#define V8_OSTREAMS_H_

#include <stddef.h>
#include <stdio.h>
#include <string.h>

#include "include/v8config.h"
#include "src/base/macros.h"

namespace v8 {
namespace internal {

// An abstract base class for output streams with a cut-down standard interface.
class OStream {
 public:
  OStream() : hex_(false) { }
  virtual ~OStream() { }

  // For manipulators like 'os << endl' or 'os << flush', etc.
  OStream& operator<<(OStream& (*manipulator)(OStream& os)) {
    return manipulator(*this);
  }

  // Numeric conversions.
  OStream& operator<<(short x);  // NOLINT(runtime/int)
  OStream& operator<<(unsigned short x);  // NOLINT(runtime/int)
  OStream& operator<<(int x);
  OStream& operator<<(unsigned int x);
  OStream& operator<<(long x);  // NOLINT(runtime/int)
  OStream& operator<<(unsigned long x);  // NOLINT(runtime/int)
  OStream& operator<<(long long x);  // NOLINT(runtime/int)
  OStream& operator<<(unsigned long long x);  // NOLINT(runtime/int)
  OStream& operator<<(double x);
  OStream& operator<<(void* x);

  // Character output.
  OStream& operator<<(char x);
  OStream& operator<<(signed char x);
  OStream& operator<<(unsigned char x);
  OStream& operator<<(const char* s) { return write(s, strlen(s)); }
  OStream& put(char c) { return write(&c, 1); }

  // Primitive format flag handling, can be extended if needed.
  OStream& dec();
  OStream& hex();

  virtual OStream& write(const char* s, size_t n) = 0;
  virtual OStream& flush() = 0;

 private:
  template<class T> OStream& print(const char* format, T x);

  bool hex_;

  DISALLOW_COPY_AND_ASSIGN(OStream);
};


// Some manipulators.
OStream& flush(OStream& os);  // NOLINT(runtime/references)
OStream& endl(OStream& os);  // NOLINT(runtime/references)
OStream& dec(OStream& os);  // NOLINT(runtime/references)
OStream& hex(OStream& os);  // NOLINT(runtime/references)


// An output stream writing to a character buffer.
class OStringStream: public OStream {
 public:
  OStringStream() : size_(0), capacity_(32), data_(allocate(capacity_)) {
    data_[0] = '\0';
  }
  ~OStringStream() { deallocate(data_, capacity_); }

  size_t size() const { return size_; }
  size_t capacity() const { return capacity_; }
  const char* data() const { return data_; }

  // Internally, our character data is always 0-terminated.
  const char* c_str() const { return data(); }

  virtual OStringStream& write(const char* s, size_t n) V8_OVERRIDE;
  virtual OStringStream& flush() V8_OVERRIDE;

 private:
  // Primitive allocator interface, can be extracted if needed.
  static char* allocate (size_t n) { return new char[n]; }
  static void deallocate (char* s, size_t n) { delete[] s; }

  void reserve(size_t requested_capacity);

  size_t size_;
  size_t capacity_;
  char* data_;

  DISALLOW_COPY_AND_ASSIGN(OStringStream);
};


// An output stream writing to a file.
class OFStream: public OStream {
 public:
  explicit OFStream(FILE* f) : f_(f) { }
  virtual ~OFStream() { }

  virtual OFStream& write(const char* s, size_t n) V8_OVERRIDE;
  virtual OFStream& flush() V8_OVERRIDE;

 private:
  FILE* const f_;

  DISALLOW_COPY_AND_ASSIGN(OFStream);
};


// A wrapper to disambiguate uint16_t and uc16.
struct AsUC16 {
  explicit AsUC16(uint16_t v) : value(v) {}
  uint16_t value;
};


OStream& operator<<(OStream& os, const AsUC16& c);
} }  // namespace v8::internal

#endif  // V8_OSTREAMS_H_
