// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Provides CodeGenByteArrayStream class which generates C/C++ source code
// to define a byte array as a C string literal.
//
// Usage:
//   ofstream ofs("output.cc");
//   CodeGenByteArrayOutputStream codegen_stream(&ofs,
//                                               codegenstream::NOT_OWN_STREAM);
//   codegen_stream.OpenVarDef("MyVar");
//   codegen_stream.put(single_byte_data);
//   codegen_stream.write(large_data, large_data_size);
//   codegen_stream.CloseVarDef();

#ifndef MOZC_BASE_CODEGEN_BYTEARRAY_STREAM_H_
#define MOZC_BASE_CODEGEN_BYTEARRAY_STREAM_H_

#include <algorithm>
#include <ostream>
#include <streambuf>
#include <string>

#include "base/port.h"
#include "base/scoped_ptr.h"

#ifdef OS_ANDROID
// This is used only for code generation, so shouldn't be used from android
// platform.
#error "base/codegen_bytearray_stream.h shouldn't be used from android platform."
#endif

#ifdef OS_WIN
// Visual C++ does not support string literals longer than 65535 characters
// so integer arrays (e.g. arrays of uint64) are used to represent byte arrays
// on Windows.
//
// The generated code looks like:
//   const uint64 kVAR_data_wordtype[] = {
//       0x0123456789ABCDEF, ...
//   };
//   const char * const kVAR_data =
//       reinterpret_cast<const char *>(kVAR_data_wordtype);
//   const size_t kVAR_size = 123;
//
// This implementation works well with other toolchains, too, but we use
// string literals for other toolchains.
//
// The generated code with a string literal looks like:
//   const char kVAR_data[] =
//       "\\x12\\x34\\x56\\x78...";
//   const size_t kVAR_size = 123;
#define MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
#endif  // OS_WIN

#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
#include <iomanip>
#endif  // MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY

#ifndef MOZC_CODEGEN_BYTEARRAY_STREAM_WORD_TYPE
#define MOZC_CODEGEN_BYTEARRAY_STREAM_WORD_TYPE uint64
#endif  // MOZC_CODEGEN_BYTEARRAY_STREAM_WORD_TYPE

namespace mozc {

namespace codegenstream {
enum StreamOwner {
  NOT_OWN_STREAM,
  OWN_STREAM,
};
}  // namespace codegenstream

class BasicCodeGenByteArrayStreamBuf : public std::streambuf {
 public:
  typedef char_traits<char> traits_type;

  // Args:
  //   output_stream: The output stream to which generated code is written.
  //   own_output_stream: The object pointed to by |output_stream| will be
  //       destroyed if |own_output_stream| equals to |OWN_STREAM|.
  BasicCodeGenByteArrayStreamBuf(std::ostream *output_stream,
                                 codegenstream::StreamOwner own_output_stream)
      : internal_output_buffer_size_(kDefaultInternalBufferSize),
        internal_output_buffer_(new char[internal_output_buffer_size_]),
        output_stream_(output_stream), own_output_stream_(own_output_stream),
        is_open_(false), output_count_(0) {
    this->setp(internal_output_buffer_.get(),
               internal_output_buffer_.get() + internal_output_buffer_size_);
  }

  virtual ~BasicCodeGenByteArrayStreamBuf() {
    CloseVarDef();
    if (own_output_stream_ == codegenstream::OWN_STREAM) {
      delete output_stream_;
    }
  }

  // Writes the beginning of a variable definition.
  bool OpenVarDef(const string &var_name_base) {
    if (is_open_ || var_name_base.empty()) {
      return false;
    }
    var_name_base_ = var_name_base;
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
    *output_stream_ << "const "
                    << AS_STRING(MOZC_CODEGEN_BYTEARRAY_STREAM_WORD_TYPE)
                    << " k" << var_name_base_
                    << "_data_wordtype[] = {\n";
    output_stream_format_flags_ = output_stream_->flags();
    // Set the output format in the form of "0x000012340000ABCD".
    output_stream_->setf(ios_base::hex, ios_base::basefield);
    output_stream_->setf(ios_base::uppercase);
    output_stream_->setf(ios_base::right);
    output_stream_format_fill_ = output_stream_->fill('0');
    // Put the prefix "0x" by ourselves, otherwise it becomes "0X".
    output_stream_->unsetf(ios_base::showbase);
    word_buffer_ = 0;
#else
    *output_stream_ << "const char k" << var_name_base_ << "_data[] =\n";
#endif
    output_count_ = 0;
    return is_open_ = !output_stream_->fail();
  }

  // Writes the end of a variable definition.
  bool CloseVarDef() {
    if (!is_open_) {
      return false;
    }
    overflow();
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
    if (output_count_ % sizeof word_buffer_ != 0) {
      // Flush the remaining in |word_buffer_|.
      WriteWordBuffer();
    }
    output_stream_->flags(output_stream_format_flags_);
    output_stream_->fill(output_stream_format_fill_);
    *output_stream_ << "};\n"
                    << "const char * const k" << var_name_base_ << "_data = "
                    << "reinterpret_cast<const char *>("
                    << "k" << var_name_base_ << "_data_wordtype);\n";
#else
    if (output_count_ == 0) {
      *output_stream_ << "\"\"\n";
    } else if (output_count_ % kNumOfBytesOnOneLine != 0) {
      *output_stream_ << "\"\n";
    }
    *output_stream_ << ";\n";
#endif
    *output_stream_ << "const size_t k" << var_name_base_ << "_size = "
                    << output_count_ << ";\n";
    is_open_ = false;
    return !output_stream_->fail();
  }

 protected:
  // Flushes.
  virtual int sync() {
    return (overflow() != traits_type::eof() &&
            !output_stream_->flush().fail())
        ? 0 : -1;
  }

  // Writes a given character sequence.  The implementation is expected to be
  // more efficient than the one of the base class.
  virtual std::streamsize xsputn(const char *s, std::streamsize n) {
    if (n <= this->epptr() - this->pptr()) {
      traits_type::copy(this->pptr(), s, n);
      this->pbump(n);
      return n;
    } else {
      overflow();
      WriteBytes(reinterpret_cast<const char *>(s),
                 reinterpret_cast<const char *>(s + n));
      return n;
    }
  }

  // Writes the data body of a variable definition.
  virtual int overflow(int c = traits_type::eof()) {
    if (!is_open_) {
      return traits_type::eof();
    }
    if (this->pbase() && this->pptr() && this->pbase() < this->pptr()) {
      WriteBytes(reinterpret_cast<const char *>(this->pbase()),
                 reinterpret_cast<const char *>(this->pptr()));
    }
    if (!traits_type::eq_int_type(c, traits_type::eof())) {
      char buf = static_cast<char>(c);
      WriteBytes(reinterpret_cast<const char *>(&buf),
                 reinterpret_cast<const char *>(&buf + 1));
    }
    this->setp(internal_output_buffer_.get(),
               internal_output_buffer_.get() + internal_output_buffer_size_);
    return output_stream_->fail()
        ? traits_type::eof()
        : (traits_type::eq_int_type(c, traits_type::eof())
           ? traits_type::not_eof(c) : c);
  }

 private:
  static const size_t kDefaultInternalBufferSize = 4000 * 1024;  // 4 mega chars
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
  typedef MOZC_CODEGEN_BYTEARRAY_STREAM_WORD_TYPE WordType;
  static const size_t kNumOfBytesOnOneLine = 4 * sizeof(WordType);
#else
  static const size_t kNumOfBytesOnOneLine = 20;
#endif

  // Converts a raw byte stream to C source code.
  void WriteBytes(const char *begin, const char *end) {
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
    char * const buf = reinterpret_cast<char *>(&word_buffer_);
    const size_t kWordSize = sizeof word_buffer_;
    while (begin < end) {
      size_t output_length = min(static_cast<size_t>(end - begin),
                                 kWordSize - output_count_ % kWordSize);
      for (size_t i = 0; i < output_length; ++i) {
        buf[output_count_ % kWordSize + i] = *begin++;
      }
      output_count_ += output_length;
      if (output_count_ % kWordSize == 0) {
        WriteWordBuffer();
        *output_stream_ << (output_count_ % kNumOfBytesOnOneLine == 0
                            ? ",\n" : ", ");
      }
    }
#else
    static const char kHex[] = "0123456789ABCDEF";
    while (begin < end) {
      size_t bucket_size = min(static_cast<size_t>(end - begin),
                               kNumOfBytesOnOneLine
                               - output_count_ % kNumOfBytesOnOneLine);
      if (output_count_ % kNumOfBytesOnOneLine == 0) {
        *output_stream_ << '\"';
      }
      for (size_t i = 0; i < bucket_size; ++i) {
        *output_stream_ << "\\x"
                        << kHex[(*begin & 0xF0) >> 4]
                        << kHex[(*begin & 0x0F) >> 0];
        ++begin;
      }
      output_count_ += bucket_size;
      if (output_count_ % kNumOfBytesOnOneLine == 0) {
        *output_stream_ << "\"\n";
      }
    }
#endif
  }

#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
  void WriteWordBuffer() {
    *output_stream_ << "0x" << setw(2 * sizeof word_buffer_) << word_buffer_;
    word_buffer_ = 0;
  }
#endif

  size_t internal_output_buffer_size_;
  scoped_ptr<char[]> internal_output_buffer_;

  std::basic_ostream<char> *output_stream_;
  codegenstream::StreamOwner own_output_stream_;
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
  ios_base::fmtflags output_stream_format_flags_;
  char output_stream_format_fill_;
#endif

  bool is_open_;
  string var_name_base_;
  size_t output_count_;
#ifdef MOZC_CODEGEN_BYTEARRAY_STREAM_USES_WORD_ARRAY
  WordType word_buffer_;
#endif

  DISALLOW_COPY_AND_ASSIGN(BasicCodeGenByteArrayStreamBuf);
};

class CodeGenByteArrayOutputStream : public std::ostream {
 public:
  // Args:
  //   output_stream: The output stream to which generated code is written.
  //   own_output_stream: The object pointed to by |output_stream| will be
  //       destroyed if |own_output_stream| equals to |OWN_STREAM|.
  CodeGenByteArrayOutputStream(
      std::ostream *output_stream,
      codegenstream::StreamOwner own_output_stream)
      : std::ostream(NULL),
        streambuf_(output_stream, own_output_stream) {
    this->rdbuf(&streambuf_);
  }

  // Writes the beginning of a variable definition.
  // A call to |OpenVarDef| must precede any output to the instance.
  void OpenVarDef(const string &var_name_base) {
    if (!streambuf_.OpenVarDef(var_name_base)) {
      this->setstate(ios_base::failbit);
    }
  }

  // Writes the end of a variable definition.
  // An output to the instance after a call to |CloseVarDef| is not allowed
  // unless |OpenVarDef| is called with a different variable name.
  void CloseVarDef() {
    if (!streambuf_.CloseVarDef()) {
      this->setstate(ios_base::failbit);
    }
  }

 private:
  BasicCodeGenByteArrayStreamBuf streambuf_;

  DISALLOW_COPY_AND_ASSIGN(CodeGenByteArrayOutputStream);
};

}  // namespace mozc

#endif  // MOZC_BASE_CODEGEN_BYTEARRAY_STREAM_H_
