OSDN Git Service

utakataの標準となる例外クラス及びマクロを定義した。
authorderui <derutakayu@user.sourceforge.jp>
Sun, 6 Dec 2009 11:43:32 +0000 (20:43 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Sun, 6 Dec 2009 11:43:32 +0000 (20:43 +0900)
type::TypeDescripterを廃止し、伴ってDataSpaceの定義を変更した。

37 files changed:
.gitignore
config.log
src/base_object.h
src/common/smart_ptr.h
src/common/textarrayformat.h
src/data_castor.h
src/data_space.cpp
src/data_space.h
src/encoding_reader.cpp
src/encoding_reader.h
src/exception.h [new file with mode: 0755]
src/exception_macro.h [new file with mode: 0644]
src/exception_std.h [new file with mode: 0644]
src/file_reader.cpp
src/file_reader.h
src/lexer_dispatcher.h
src/lexer_interface.h
src/object.cpp [deleted file]
src/object.h
src/reader_interface.h
src/string_reader.cpp
src/string_reader.h
src/test/Makefile
src/test/Makefile.am
src/test/Makefile.in
src/test/encoding_reader_test.cpp [new file with mode: 0755]
src/test/file_reader_test.cpp
src/test/string_reader_test.cpp
src/test/unicode_test.cpp
src/test/utf8_transcoder_test.cpp
src/transcoder_interface.h [new file with mode: 0755]
src/type.cpp
src/type.h
src/unicode.cpp
src/unicode.h
src/utf8_transcoder.cpp
src/utf8_transcoder.h

index 4ea32de..8986cb2 100644 (file)
@@ -42,3 +42,5 @@ utakata
 /src/Makefile
 /src/OMakefile.omc
 /src/test/OMakefile.omc
+/src/test/encoding_reader_test
+/src/test/file_reader_test
index da19041..47d4491 100644 (file)
@@ -998,3 +998,90 @@ on vaio_z
 
 config.status:777: creating src/test/Makefile
 config.status:1051: executing depfiles commands
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by utakata config.status 0.0.1, which was
+generated by GNU Autoconf 2.63.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status Makefile
+
+on vaio_z
+
+config.status:777: creating Makefile
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by utakata config.status 0.0.1, which was
+generated by GNU Autoconf 2.63.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status src/Makefile
+
+on vaio_z
+
+config.status:777: creating src/Makefile
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by utakata config.status 0.0.1, which was
+generated by GNU Autoconf 2.63.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status src/test/Makefile depfiles
+
+on vaio_z
+
+config.status:777: creating src/test/Makefile
+config.status:1051: executing depfiles commands
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by utakata config.status 0.0.1, which was
+generated by GNU Autoconf 2.63.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status src/test/Makefile depfiles
+
+on vaio_z
+
+config.status:777: creating src/test/Makefile
+config.status:1051: executing depfiles commands
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by utakata config.status 0.0.1, which was
+generated by GNU Autoconf 2.63.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status src/Makefile
+
+on vaio_z
+
+config.status:777: creating src/Makefile
index a89387e..c98ba47 100755 (executable)
 //   ~Hoge() {}
 //   std::string ToString() const {return "hoge";}
 // };
-  
+
 #ifndef _UTAKATA_SRC_BASE_OBJECT_H_
 #define _UTAKATA_SRC_BASE_OBJECT_H_
 
+#include <string>
 #include "src/common/uncopyable.h"
 #include "src/common/smart_ptr.h"
 
index 7288df6..390017c 100755 (executable)
@@ -110,7 +110,7 @@ template<class T> class smart_ptr {
 
   // 現在保持している型を新規に生成します。新規の生成では、デフォルトコ
   // ンストラクタが使用されます。
-  void add() {
+  void reset() {
     dec();
     init(new T, true);
   }
@@ -118,7 +118,7 @@ template<class T> class smart_ptr {
   // 外部より明示的に新しい管理対象オブジェクトを渡して初期化を行います。
   // ownerが指定されない場合、デフォルトで管理が行われます。
   template<class S>
-  void add(S* object, bool owner = true) {
+  void reset(S* object, bool owner = true) {
     dec();
     if (object != NULL) {
       init(object, owner);
@@ -129,7 +129,7 @@ template<class T> class smart_ptr {
   // ownerが指定されない場合、デフォルトで管理が行われます。
   // 削除時には、渡されたdeleterによって処理が行われます。
   template<class S>
-  void add(S* _p, ref_delete_base* ref, bool owner = true) {
+  void reset(S* _p, ref_delete_base* ref, bool owner = true) {
     dec();
     if (_p != NULL && ref != NULL) {
       init(_p, owner, ref);
@@ -164,7 +164,8 @@ template<class T> class smart_ptr {
 
   // 渡されたsmart_ptrを参照するように変更し、参照数を加算します。
   void inc(const smart_ptr<T>& p) {
-    swap(p);
+    ref_obj_ = p.ref_obj_;
+    obj_ = p.obj_;
     if (ref_obj_ != NULL) {
       ref_obj_->inc_ref();
     }
index 81f6e0f..231480f 100644 (file)
@@ -16,20 +16,7 @@ namespace utility {
 
 namespace textarrayformat {
 
-class OutOfIndexException : public std::exception
-{
- public:
-  OutOfIndexException(const std::string& str);
-  virtual ~OutOfIndexException() throw() {}
-
-  virtual const char* what() const throw();
-
- private:
-  const std::string str_;
-};
-
-class TextArrayReader
-{
+class TextArrayReader {
  public:
 
   explicit TextArrayReader(const TextArrayGenerator& is);
index 573a723..a9a7ed1 100755 (executable)
@@ -35,9 +35,8 @@ namespace data {
 
 template<typename T>
 class DataCastor {
-  // 各データ実体へのキャストを行うためのインターフェース。こ
-  // の関数オブジェクトを利用している限り、DataEntityのインター
-  // フェースがどうなっているかを気にする必要は無い。
+  // 各データ実体へのキャストを行うための関数オブジェクトの形をした
+  // インターフェースです。Objectの
  public:
   DataCastor() {}
   virtual ~DataCastor() {}
@@ -53,7 +52,7 @@ class DataCastor {
 // ためのポインタを渡し、内部用実体隠蔽オブジェクトの
 // 内容データをキャストした結果を返します。
 template<typename T>
-void DataCasting(ocnst data::Object& data, T* pointer) {
+void DataCasting(const data::Object& data, T* pointer) {
   pointer = DataCastor<T>(data);
 };
 };
index 96e11ef..58430d4 100755 (executable)
@@ -1,46 +1,20 @@
-#include "data_structure.h"
-#include "type.h"
+#include "src/data_space.h"
+#include "src/type.h"
 
-using namespace utakata::data;
-using namespace utakata;
+namespace data = utakata::data;
+namespace type = utakata::type;
 
-DataSpace::DataSpace(const smart_ptr<type::TypeDescripter>& data) :
-    space_(data)
-{}
+// 宣言のコメントを参照してください。
+data::DataSpace::DataSpace(const data::DataSpace& data)
+    : type_(new type::Type(*data.type_)), object_(data.object_) {}
 
-DataSpace::DataSpace(const DataSpace& space)
-{
-    swap(space);
-}
-
-DataSpace& DataSpace::operator=(const DataSpace& space)
-{
-    DataSpace tmp(space);
-    swap(tmp);
-    return *this;
-}
+// 宣言のコメントを参照してください。
+data::DataSpace::DataSpace(
+    const type::Type& type,
+    const utility::smart_ptr<interpreter::IObject>& object)
+    : type_(new type::Type(type)), object_(object) {}
 
-void DataSpace::swap(const DataSpace& space)
-{
-    // 指す領域を交換する。
+// 宣言のコメントを参照してください。
+void data::DataSpace::Swap(DataSpace& space) {
     space_ = space.space_;
 }
-
-type::TypeDescripter& DataSpace::getTypeDescripter()
-{
-    return *space_;
-}
-
-bool DataSpace::operator==(const DataSpace& space)
-{
-    // 現在保持しているTypeDescripterのspace_が同じ場所を
-    // 指しているかどうかを返す。
-
-    return space_ == space.space_;
-}
-
-bool DataSpace::operator!=(const DataSpace& space)
-{
-    return !(space_ == space.space_);
-}
-
index 9114d84..92dd07b 100755 (executable)
 // DataSpace同士の比較においては、utakata::type名前空間において、
 // 内部の利便性のためにオペレータオーバロードが実装されています。
 // DataSpace自体にはオペレータオーバロードは実装されません。
-#ifndef _DEVELOP_UTAKATA_SRC_DATA_SPACE_H_
-#define _DEVELOP_UTAKATA_SRC_DATA_SPACE_H_
-
+#ifndef _UTAKATA_SRC_DATA_SPACE_H_
+#define _UTAKATA_SRC_DATA_SPACE_H_
 
 #include <algorithm>
 #include "src/common/smart_ptr.h"
+#include "src/common/scoped_ptr.h"
 
 namespace utakata {
 
 namespace type {
-class TypeDescripter;
+class Type;
 };
 
+namespace interpreter {
+class IObject;
+}
+
 namespace data {
 
 class DataSpace {
@@ -31,32 +35,48 @@ class DataSpace {
   // オペレータオーバロードが実装されている。
  public:
   DataSpace(const DataSpace& space);
-  explicit DataSpace(const smart_ptr<type::TypeDescripter>& data);
+  DataSpace(const type::Type& type,
+            const utility::smart_ptr<interpreter::IObject>& object);
   virtual ~DataSpace() {}
 
   // DataSpaceが、渡されたspaceと同じ領域を指すように変更します。
-  DataSpace& operator=(const DataSpace& space);
+  DataSpace& operator=(const DataSpace& space) {
+    DataSpace tmp(space);
+    swap(tmp);
+    return *this;
+  }
+
+  // 内部で保持している型オブジェクトを返します。
+  const type::Type& type() {return *type_;}
 
-  const type::TypeDescripter& type_descripter() {return *type_descripter_;}
+  // 内部で保持されているオブジェクトの実体へのポインタを返します。
+  interpreter::IObject* object() {return object_.get();}
 
   // 同一の領域を保持している場合、trueを返します。
-  bool Equal(const DataSpace& space);
+  bool Equal(const DataSpace& space) {return object_ == space.object_;}
 
  private:
 
   // データ領域を交換する。
-  void swap(DataSpace& space);
+  void Swap(DataSpace& space);
 
-  // データの実体を保持するTypeDescripter
-  smart_ptr<type::TypeDescripter> type_descripter_;
+  // 保持している型に対する型オブジェクトを保持します。
+  utility::scoped_ptr<type::Type> type_;
+
+  // データ領域に格納されているオブジェクトへのポインタです。
+  utility::smart_ptr<interpreter::IObject> object_;
 };
 
 // DataSpace同士が同一領域を指している場合trueを返します。
-bool operator==(const DataSpace& space);
+bool operator==(const DataSpace& lh, const DataSpace& rh) {
+  return lh.Equal(rh);
+}
 
 // DataSpace同士が別々の領域を指している場合trueを返します。
-bool operator!=(const DataSpace& space);
-};
-};
+bool operator!=(const DataSpace& lh, const DataSpace& rh) {
+  return !(lh == rh);
+}
+}
+}
 
-#endif /* __HOME_DERUI_DEVELOP_UTAKATA_SRC_DATA_SPACE_H_ */
+#endif /* _UTAKATA_SRC_DATA_SPACE_H_ */
index f45a3da..ff9e290 100755 (executable)
-#include <exception>
-
-#include "reader.h"
-#include "transcoder.h"
-
-using namespace utakata;
-using namespace utakata::reader;
-
-ReaderException::ReaderException(std::string str) : str_(str)
-{}
-
-const char* ReaderException::what() const throw()
-{
-    return str_.c_str();
+#include <vector>
+#include "src/encoding_reader.h"
+#include "src/exception_std.h"
+#include "src/exception_macro.h"
+#include "src/transcoder_interface.h"
+
+namespace reader = utakata::reader;
+namespace exception = utakata::exception;
+
+// 1文字に相当するバイト数は、現在保持しているITranscoderに依存します。
+unsigned int reader::EncodingReader::Read() {
+  CheckInternal();
+  return transcoder_->Encode(reader_);
 }
 
-//======================================================================
+// 宣言のコメントを参照してください。
+std::vector<unsigned int> reader::EncodingReader::Read(unsigned int num) {
+  CheckInternal();
 
-StreamReader::StreamReader(smart_ptr<std::istream>& s,
-                           const smart_ptr<transcoder::ITranscoder>& t) :
-    stream_(s), trans_(t), pos_(0)
-{
-}
+  if (num <= 0) {
+    return std::vector<unsigned int>();
+  }
 
-unsigned long StreamReader::read()
-{
-    // 現在利用保持しているstreamから1バイト分だけ読出す。
-    // eofの場合、std::istream::traits_type::eofを返す。
+  std::vector<unsigned int> ret;
+  for (unsigned int i = 0; i < num && !reader_->IsEof(); ++i) {
+    unsigned int tmp = transcoder_->Encode(reader_);
+    ret.push_back(tmp);
+  }
 
-    validate();
-    
-    if (stream_->eof() || !stream_->good())
-    {
-        return std::istream::traits_type::eof();
-    }
-    ++pos_;
-
-    return trans_->encode(*stream_);
+  return ret;
 }
 
-std::vector<unsigned long> StreamReader::read(size_t num)
-{
-    // 指定したサイズ分のbyteを読出す。
-    // 指定サイズが読み出しきれず、eofになった場合には、eofは返さない。
-    validate();
-    
-    if (num <= 0)
-    {
-        throw ReaderException("must be greater than zero of read size");
-    }
-
-    if (stream_->eof() || !stream_->good())
-    {
-        return std::vector<unsigned long>();
-    }
-
-    std::vector<unsigned long> ret;
-    for (unsigned long i = 0; i < num; ++i)
-    {
-        unsigned long tmp = trans_->encode(*stream_);
-        ret.push_back(tmp);
-    }
-
-    pos_ += num;
-
-    return ret;
-}
+// 読出し前後のIReader::GetPosの差分だけ移動します。
+unsigned int reader::EncodingReader::Peek() {
+  CheckInternal();
 
-unsigned long StreamReader::peek()
-{
-    // 一度読みだして、読み出した分だけい再度設定する。
-    validate();
-    
-    if (stream_->eof() || !stream_->good())
-    {
-        return std::istream::traits_type::eof();
-    }
-
-    size_t prev = stream_->tellg();
-    unsigned long r = trans_->encode(*stream_);
-    for (size_t i = stream_->tellg(); i > prev; --i)
-    {
-        stream_->unget();
-    }
-
-    return r;
+  unsigned int previsous = reader_->GetPos();
+  unsigned int r = transcoder_->Encode(reader_);
+
+  reader_->Seek(reader_->GetPos() - previsous, reader::kBackward);
+  return r;
 }
 
-void StreamReader::unget(unsigned long ch)
-{
-    // 渡したchを元に戻す。成功しない場合には例外が発生する。
-    validate();
-    std::vector<int> dec = trans_->decode(ch);
+// 読出し前後のIReader::GetPosの分だけSeekします。
+std::vector<unsigned int> reader::EncodingReader::Peek(unsigned int num) {
+  CheckInternal();
 
-    std::vector<int>::reverse_iterator beg = dec.rbegin(), e = dec.rend();
-    for (; beg != e; ++beg)
-    {
-        stream_->putback(*beg);
-    }
+  if (num <= 0) {
+    return std::vector<unsigned int>();
+  }
 
-    --pos_;
-}
+  unsigned int previsous = reader_->GetPos();
+  std::vector<unsigned int> ret;
+  for (unsigned int i = 0; i < num && !reader_->IsEof(); ++i) {
+    unsigned int tmp = transcoder_->Encode(reader_);
+    ret.push_back(tmp);
+  }
 
-size_t StreamReader::pos() const
-{
-    return pos_;
+  reader_->Seek(reader_->GetPos() - previsous, reader::kBackward);
+  return ret;
 }
 
-bool StreamReader::isEOF()
-{
-    // 現在streamが終端かどうかを返す。
-    validate();
-    return stream_->eof();
+// 現在のreaderが末尾であればtrueを返しますが、readerがNULLの場合
+// 例外が発生します。
+bool reader::EncodingReader::IsEof() const {
+  CheckInternal();
+  return reader_->IsEof();
 }
 
-void StreamReader::validate()
-{
-    if (stream_.isNull())
-    {
-        throw ReaderException("stream must valid instantce but NULL!");
-    }
+// reader_あるいはtranscoder_がNULLである場合に、exception::NullExceptionを
+// 送出します。
+void reader::EncodingReader::CheckInternal() const {
+  if (reader_ == NULL) {
+    THROW_EXCEPTION_(exception::NullException,
+                     "reader is must to set valid pointer");
+  }
+
+  if (transcoder_.get() == NULL) {
+    THROW_EXCEPTION_(exception::NullException,
+                     "transcoder is must to set valid pointer");
+  }
 }
index 44c150d..d0b15b4 100644 (file)
@@ -2,12 +2,19 @@
 // このフロントエンドは、文字列・ファイル等からデータを読出すだけの
 // 機能を持つ別のインターフェースと組み合わせ、ITranscoderを適用した
 // データを取得します。
+// EncodingReaderは、特性上実装不可能であるメソッドについては実装を行いません。
+//
+// example
+// -------
+// StringReader r("hoge");
+// EncodingReader enc(&r, new UTF8Transcoder());
+// enc.Read();
 #ifndef _UTAKATA_SRC_ENCODING_READER_H_
 #define _UTAKATA_SRC_ENCODING_READER_H_
 
 #include <vector>
-
-#include "smart_ptr.h"
+#include "src/reader_interface.h"
+#include "src/common/smart_ptr.h"
 
 namespace utakata {
 
@@ -17,21 +24,27 @@ class ITranscoder;
 
 namespace reader {
 
-class IReader;
-class EncodingReader {
+class EncodingReader : public IReader {
   // 渡されたReaderからデータを読出す際に、ITranscoder::Encodeを利用して、
   // バイナリデータを文字列として読み出します。
   // 文字列として読出しますが、EncodingReaderから読出された時点で、全て
   // unicode文字列として読出されます。
  public:
+  // 利用するreaderとエンコードを行うITranscoder派生クラスを渡します。
+  // 渡されたITranscoder派生クラスのポインタは、EncodingReaderの終了時に
+  // 破棄されます。
+  EncodingReader(reader::IReader* reader,
+                 transcoder::ITranscoder* transcoder) :
+      reader_(reader), transcoder_(transcoder) {}
+  ~EncodingReader() {}
 
-  // 利用するistreamを指定する。
-  StreamReader(const smart_ptr<reader::IReader>& reader,
-               const smart_ptr<transcoder::ITranscoder>& transcoder);
-  ~StreamReader() {}
-
+  // 一文字分だけ読出して返します。
   unsigned int Read();
-  std::vector<unsigned int> Read(size_t num);
+
+  // 指定した文字数だけ読出して返します。指定されたnumよりも読出せた文字数が
+  // 読出せた分だけ返されます。
+  // numが0未満である場合、サイズ0のvectorが返されます。
+  std::vector<unsigned int> Read(unsigned int num);
 
   // 一文字分だけ先読みして返します。
   // 先読みのため、Readerの読み出し位置は更新されません。
@@ -40,15 +53,33 @@ class EncodingReader {
   // 指定された文字の分だけ先読みして返します。
   // 先読みのため、Readerの読み出し位置は更新されません。
   // num以下の文字しか読出せなかった場合、読出せた分だけ返されます。
-  std::vector<unsigned int> Peek(size_t num);
+  std::vector<unsigned int> Peek(unsigned int num);
 
   // 保持しているreaderが末尾に到達しているか返します。
   bool IsEof() const;
 
+  void set_transcoder(transcoder::ITranscoder* transcoder) {
+    transcoder_.reset(transcoder);
+  }
+
+  // 以下のメソッドについては、全て実装されません。
+  unsigned int GetPos() const {return 0;}
+  bool Seek(int seekpos, reader::SeekDirection direction) {return false;}
+  bool Seek(int seekpos, reader::SeekDirection direction,
+            size_t* seek_difference) {return false;}
+  void Begin() {}
+  unsigned int GetSize() const {return 0;}
+
  private:
 
-  smart_ptr<reader::IReader> reader_;
-  smart_ptr<transcoder::ITranscoder> trans_;
+  // reader_及びtranscoder_が有効な状態であるかどうかを調査します。
+  void CheckInternal() const;
+
+  // データの読み込みを行うreaderを保持します。
+  reader::IReader* reader_;
+
+  // 読出したデータを変換するためのTranscoderです。
+  utility::smart_ptr<transcoder::ITranscoder> transcoder_;
 };
 };
 };
diff --git a/src/exception.h b/src/exception.h
new file mode 100755 (executable)
index 0000000..806ad1b
--- /dev/null
@@ -0,0 +1,127 @@
+// exception
+//
+// utakataにおける全ての例外のベースクラスを定義します。
+// utakata::exception::Exceptionは、全ての例外のベースとして、std::exception
+// から派生します。
+// utakata内で発生した例外は、全てこのException例外、及びException例外の
+// 派生クラスを利用する必要があります。
+// utakata::exception::Exceptionは、送出されたファイル名、送出された関数名、
+// 送出された行数を記録しています。
+// また、Exceptionは自身を含め、Exception派生例外を記録することができます。
+// exception::Exceptionは、派生クラスを定義することができますが、共通変数など
+// は自動的に設定されることが無いため、適宜exception::Exceptionと同一順の
+// 引数を宣言し、superクラスのコンストラクタを呼ぶ必要があります。
+//
+// example
+// -------
+// // 派生クラスの定義例
+// #include "src/exception.h"
+// class HogeException : public Exception {
+//  public:
+//   HogeException(const std::string& message,
+//                 const exception::ExceptionInfo& info) :
+//       Exception(message, info) {}
+//
+//   HogeException(const Exception& prev,
+//                 const std::string& message,
+//                 const exception::ExceptionInfo& info) :
+//       Exception(prev, message, info) {}
+// };
+
+#ifndef _UTAKATA_SRC_EXCEPTION_H_
+#define _UTAKATA_SRC_EXCEPTION_H_
+
+#include <exception>
+#include <string>
+#include "src/common/smart_ptr.h"
+
+namespace utakata {
+namespace exception {
+
+struct ExceptionInfo {
+  // 例外の共通情報を保持するための構造体です。
+  // この構造体はException及びException派生クラスでは必須となります。
+  ExceptionInfo() : file_name(NULL), function_name(NULL), file_line(0) {}
+  ExceptionInfo(const char* filename, const char* functionname,
+                int fileline) : file_name(filename),
+                                function_name(functionname),
+                                file_line(fileline) {}
+  ExceptionInfo(const ExceptionInfo& info) :
+      file_name(info.file_name), function_name(info.function_name),
+      file_line(info.file_line) {}
+
+  // 例外が発生したファイル名です。__FILE__の結果が渡されることを想定し
+  // ています。
+  const char* file_name;
+
+  // 例外が発生した関数名です。__func__の結果が渡されることを想定してい
+  // ます。
+  const char* function_name;
+
+  // 例外が発生したファイルの行です。__LINE__の結果が渡されることを想定
+  // しています。
+  const int file_line;
+};
+
+class Exception : public std::exception {
+  // utakataの基本となる例外クラスです。それぞれのクラスは、
+  // この例外クラスを拡張することで、以前の例外を保持すること
+  // が可能になります。
+  // Exceptionは、exception_macro.hで定義されているマクロを利用して呼ばれる
+  // ことが想定されています。
+  // マクロの詳細はexception_macro.hを参照してください。
+  // Exception派生クラスは、Exceptionと同一の引数を定義している場合に限り、
+  // exception_macro.hのマクロを利用することができます。
+ public:
+
+  // 明示的なコピーコンストラクタです。渡したExceptionの各領域のみをコピー
+  // します。
+  Exception(const Exception& exception) :
+      previous_exception_(exception.previous_exception_),
+      message_(exception.message_), info_(exception.info_) {}
+
+  // 前回送出された例外が存在しない場合のコンストラクタです。
+  // すべての値が指定されることが必須となります。
+  Exception(const std::string& message, const ExceptionInfo& info) :
+      previous_exception_(), message_(message), info_(info) {}
+
+  // 前回送出された例外を記録します。
+  Exception(const Exception& prev, const std::string& message,
+            const ExceptionInfo& info) :
+      previous_exception_(new Exception(prev)), message_(message),
+      info_(info) {}
+  virtual ~Exception() throw() {}
+
+  // message_の内容を表示します。
+  virtual const char* what() const throw() {return message_.c_str();}
+
+  // 例外に設定されたメッセージを取得します。
+  const std::string& message() const {return message_;}
+
+  // 例外情報構造体を返します。
+  const ExceptionInfo& info() const {return info_;}
+
+  // 送出された例外に対して、前回の例外が存在するかどうかを返します。
+  bool HasPreviousException() const {return !previous_exception_.is_null();}
+
+  // 送出された例外に対する、一つ前に送出された例外を返します。
+  // 送出された例外が存在しない場合、NULLが返されます。
+  const Exception* previous_exception() const {
+    return previous_exception_.get();
+  }
+
+ private:
+  // 自身の前に送出された例外を保持します。前回送出された例外が存在しない場合、
+  // NULLが設定されています。
+  utility::smart_ptr<Exception> previous_exception_;
+
+  // 例外のメッセージが渡されます。
+  const std::string message_;
+
+  // 例外の基本情報を保持した構造体です。
+  ExceptionInfo info_;
+};
+}
+}
+
+#endif /* _UTAKATA_SRC_EXCEPTION_H_ */
diff --git a/src/exception_macro.h b/src/exception_macro.h
new file mode 100644 (file)
index 0000000..53c028c
--- /dev/null
@@ -0,0 +1,28 @@
+// exception_macro.h
+//
+// exception::Exception派生の例外を作成するためのマクロを提供します。
+// また、このマクロはexception::Exceptionが利用される場合にのみ適用される
+// ことが想定されています。
+// 派生クラスも、exception::Exceptionと同一の定義である必要があります。
+// 派生クラスの定義が異なる場合、常に同一の情報を利用する必要があります。
+// example
+// -------
+// //派生例外をthrowします。ファイル名、関数名、行数は自動的に設定されます。
+// THROW_EXCEPTION(DerivationException, "message");
+// // 前回送出例外を加えてthrowします。
+// THROW_EXCEPTION_AND_PREVIOUS(prev, DerivationException, "message");
+#ifndef _UTAKATA_SRC_EXCEPTION_MACRO_H_
+#define _UTAKATA_SRC_EXCEPTION_MACRO_H_
+
+// exception型の例外に、messageを付与して送出します。
+#define THROW_EXCEPTION_(EXCEPTION, message)                    \
+  throw EXCEPTION(message, utakata::exception::ExceptionInfo(   \
+      __FILE__, __func__, __LINE__))
+
+// exception型の例外に、前回送出した例外を付与して送出します。
+#define THROW_EXCEPTION_AND_PREVIOUS_(prev, exception, message)     \
+  throw EXCEPTION(prev, message, utakata::exception::ExceptionInfo( \
+      __FILE__, __func__, __LINE__))
+
+#endif /* _UTAKATA_SRC_EXCEPTION_MACRO_H_ */
+
diff --git a/src/exception_std.h b/src/exception_std.h
new file mode 100644 (file)
index 0000000..783397f
--- /dev/null
@@ -0,0 +1,59 @@
+// exception_std
+//
+// utakata内で標準的に利用される、汎用的な例外を定義します。
+// ここで定義されている例外は、全てexception::Exceptionから派生し、
+// exception_macro.hのマクロが適用可能となっています。
+//
+// ここで定義されている汎用例外は以下となります。
+//
+// exception::NullException
+//    -> NULLであってはならない場合に送出される例外です。
+// exception::OutOfRangeException
+//    -> 範囲外である場合に送出される例外です。
+#ifndef _UTAKATA_SRC_EXCEPTION_STD_H_
+#define _UTAKATA_SRC_EXCEPTION_STD_H_
+
+#include <string>
+#include "src/exception.h"
+
+namespace utakata {
+namespace exception {
+
+class NullException : public exception::Exception {
+  // NULLであることが想定外である場合に送出される例外です。
+ public:
+  NullException(const std::string& message, const ExceptionInfo& info) :
+      Exception(message, info) {}
+
+  // 前回送出された例外を記録します。
+  NullException(const Exception& prev, const std::string& message,
+            const ExceptionInfo& info) :
+      Exception(prev, message, info) {}
+
+  // message_の内容を表示します。
+  virtual const char* what() const throw() {
+    return std::string("NullException : " + message()).c_str();
+  }
+};
+
+class OutOfRangeException : public exception::Exception {
+  // 引数などが範囲外である場合などに送出される例外です。
+ public:
+  OutOfRangeException(const std::string& message, const ExceptionInfo& info) :
+      Exception(message, info) {}
+
+  // 前回送出された例外を記録します。
+  OutOfRangeException(const Exception& prev, const std::string& message,
+            const ExceptionInfo& info) :
+      Exception(prev, message, info) {}
+
+  // message_の内容を表示します。
+  virtual const char* what() const throw() {
+    return std::string("OutOfRangeException : " + message()).c_str();
+  }
+};
+}
+}
+
+#endif /* _UTAKATA_SRC_EXCEPTION_STD_H_ */
+
index 9b762c4..69fc230 100755 (executable)
@@ -7,11 +7,14 @@
 // FileReaderにおける読み出し位置は、先頭が0であるとされます。
 // 4文字渡して、2文字読出した時点で2となります。
 //
+#include <vector>
 #include <cstdio>
 #include <algorithm>
 
 #include "src/file_reader.h"
 
+#include "src/exception_macro.h"
+
 namespace reader = utakata::reader;
 
 reader::FileReader::~FileReader() {
@@ -54,13 +57,14 @@ void reader::FileReader::Close() {
 // ファイルから1バイト読み出す際には::freadを利用します。
 // 返り値の調査で1バイト読み出せているかをチェックし、例外の送出
 // 判断を行っています。
-unsigned char reader::FileReader::Read() {
+unsigned int reader::FileReader::Read() {
   CheckOpened();
   CheckEOF();
 
-  unsigned char byte = 0;
+  unsigned int byte = 0;
   if (::fread(&byte, 1, 1, file_pointer_) != 1) {
-    throw reader::IOException("file read error! `" + filename_ + "`");
+    THROW_EXCEPTION_(reader::IOException,
+                     "file read error `" + filename_ + "`");
   }
 
   ++pos_;
@@ -71,16 +75,15 @@ unsigned char reader::FileReader::Read() {
 // ファイルからの読み出しには::freadを利用します。
 // 返り値の調査で指定のバイト数を読み出せているかをチェックし、
 // 例外の送出判断を行っています。
-std::vector<unsigned char> reader::FileReader::Read(size_t num) {
+std::vector<unsigned int> reader::FileReader::Read(size_t num) {
   CheckOpened();
   CheckEOF();
 
-  if (num <= 0)
-  {
-    return std::vector<unsigned char>();
+  if (num <= 0) {
+    return std::vector<unsigned int>();
   }
 
-  std::vector<unsigned char> ret(num + 1, 0);
+  std::vector<unsigned int> ret(num + 1, 0);
   int readed = ::fread(&ret[0], 1, num, file_pointer_);
 
   pos_ += readed;
@@ -89,27 +92,26 @@ std::vector<unsigned char> reader::FileReader::Read(size_t num) {
 }
 
 // 1バイトだけ読出を行うため、1バイトだけ読出を行い、1バイト戻しています。
-unsigned char reader::FileReader::Peek() {
+unsigned int reader::FileReader::Peek() {
   CheckOpened();
   CheckEOF();
-  
-  unsigned char byte = Read();
+
+  unsigned int byte = Read();
   Seek(1, reader::kBackward);
 
   return byte;
 }
 
 // 指定された数量だけ読み出して、読み出せた分だけ戻しています。
-std::vector<unsigned char> reader::FileReader::Peek(size_t num) {
+std::vector<unsigned int> reader::FileReader::Peek(size_t num) {
   CheckOpened();
   CheckEOF();
 
-  if (num <= 0)
-  {
-    return std::vector<unsigned char>();
+  if (num <= 0) {
+    return std::vector<unsigned int>();
   }
 
-  std::vector<unsigned char> ret = Read(num);
+  std::vector<unsigned int> ret = Read(num);
   Seek(ret.size(), reader::kBackward);
   return ret;
 }
@@ -190,14 +192,16 @@ bool reader::FileReader::IsEof() const {
 // 関数宣言のコメントを参照してください。
 void reader::FileReader::CheckOpened() {
   if (!IsOpened()) {
-    throw reader::IOException("file isn't open yet! `" + filename_ + "`");
+    THROW_EXCEPTION_(reader::IOException,
+                     "file isn't open yet! `" + filename_ + "`");
   }
 }
 
 // 関数宣言のコメントを参照してください。
 void reader::FileReader::CheckEOF() {
   if (IsEof()) {
-    throw reader::EndOfDeviceException("end of File `" + filename_ + "`");
+    THROW_EXCEPTION_(reader::EndOfDeviceException,
+                     "end of File `" + filename_ + "`");
   }
 }
 
index d7423ac..ce32d6d 100755 (executable)
@@ -17,6 +17,7 @@
 #ifndef _UTAKATA_SRC_FILE_READER_H_
 #define _UTAKATA_SRC_FILE_READER_H_
 
+#include <vector>
 #include <string>
 #include "src/reader_interface.h"
 #include "src/common/uncopyable.h"
@@ -72,15 +73,15 @@ class FileReader : public IReader, private utility::Uncopyable {
   // 例外を投げなければなりません。
   // readでは、読み出し位置を更新します。
   // ファイルがオープンされていない場合には、常に例外が発生します。
-  unsigned char Read();
-  std::vector<unsigned char> Read(size_t num);
+  unsigned int Read();
+  std::vector<unsigned int> Read(size_t num);
 
   // デバイスから1バイトの読出しを行いますが、内部の読み出し位置は変化
   // しません。
   // peekした後、readを行うと、全く同一のバイトが得られます。
   // ファイルがオープンされていない場合には、常に例外が発生します。
-  unsigned char Peek();
-  std::vector<unsigned char> Peek(size_t num);
+  unsigned int Peek();
+  std::vector<unsigned int> Peek(size_t num);
 
   // 現在の読み出し位置を返します。
   // ファイルがオープンされていない場合、常に0が返されます。
@@ -118,7 +119,6 @@ class FileReader : public IReader, private utility::Uncopyable {
 
   // IsOpened() = trueである場合に、reader::IOExceptionを送出します。
   void CheckOpened();
-  
 
   // 読出ファイルへのファイルポインタです。
   // 常にバイナリ読出("wb")でファイルはオープンされます。
index 1ace602..9cfd6a7 100755 (executable)
@@ -60,7 +60,8 @@ class LexerDispatcher : private utility::Uncopyable {
  private:
 
   // ディスパッチ条件と、ディスパッチ対象の対です。
-  std::map<smart_ptr<ILexerDispatchTerms>, smart_ptr<IPartOfLexer> > dispatch_lexer_;
+  std::map<utility::smart_ptr<ILexerDispatchTerms>,
+           utility::smart_ptr<IPartOfLexer> > dispatch_lexer_;
 };
 
 class StringLexer : public ISubLexer
index b997a3a..b35f54a 100644 (file)
@@ -10,7 +10,8 @@
 #ifndef _UTAKATA_SRC_LEXER_INTERFACE_H_
 #define _UTAKATA_SRC_LEXER_INTERFACE_H_
 
-#include "smart_ptr.h"
+#include <string>
+#include "src/common/smart_ptr.h"
 
 namespace utakata {
 
@@ -28,17 +29,15 @@ class ILexeme;
 
 namespace lexer {
 
-class LexException : public std::exception
-{
+class LexException : public exception::Exception {
  public:
-  LexException(size_t pos, std::string str);
-  virtual ~LexException() throw() {}
-  const char* what() const throw();
-
- private:
-
-  size_t pos_;
-  std::string str_;
+  LexException(const std::string& message,
+               const utakata::exception::ExceptionInfo& info) :
+      Exception(message, info) {}
+  LexException(const utakata::exception::Exception& exception,
+               const std::string& message,
+               const utakata::exception::ExceptionInfo& info) :
+      Exception(exception, message, info) {}
 };
 
 class ILexerDispatchTerm {
@@ -60,8 +59,8 @@ class IPartOfLexer {
 
   // 読出しストリームへのポインタを受け取って、結果として生成した
   // ILexemeインターフェースの派生クラスを返します。
-  virtual smart_ptr<lexeme::ILexeme> Lex(const unicode::UniString& string,
-      reader::StreamReader* stream) = 0;
+  virtual utility::smart_ptr<lexeme::ILexeme> Lex(
+      const unicode::UniString& string, reader::StreamReader* stream) = 0;
 };
 
 class ILexerCreator {
diff --git a/src/object.cpp b/src/object.cpp
deleted file mode 100755 (executable)
index e9f075c..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "object.h"
-#include "type.h"
-
-using namespace utakata;
-
-data::Object::Object(bool changeable, const smart_ptr<DataSpace>& space) :
-    space_(space), changeable_(changeable)
-{
-}
-
-data::Object::Object(const data::Object& d)
-{
-    swap(d);
-}
-
-data::Object& data::Object::operator=(const data::Object& o)
-{
-    data::Object tmp(o);
-    swap(tmp);
-    return *this;
-}
-
-bool data::Object::enableChange() const
-{
-    return changeable_;
-}
-
-const smart_ptr<data::DataSpace> data::Object::getSpace() const
-{
-    return space_;
-}
-
-void data::Object::setSpace(const smart_ptr<data::DataSpace>& space)
-{
-    // 現在保持しているspaceを入れ替える。
-    // ここで入れ替えるのは、束縛する値を変更している(define)を指す。
-    space_ = space;
-}
-
-void data::Object::swap(const data::Object& o)
-{
-    space_ = o.space_;
-    changeable_ = o.changeable_;
-}
-
-bool data::instanceof(const data::Object& o, const type::Type& type)
-{
-    // Objectが保有するTypeと渡されたtypeが等しいかどうかを検査する。
-    return o.getSpace()->getTypeDescripter().getType() == type;
-}
index d7a1214..c5684c7 100755 (executable)
@@ -1,7 +1,6 @@
-#ifndef _OBJECT_H_
-#define _OBJECT_H_
+#ifndef _UTAKATA_SRC_OBJECT_H_
+#define _UTAKATA_SRC_OBJECT_H_
 
-#include "src/data_space.h"
 #include "src/common/smart_ptr.h"
 
 namespace utakata {
@@ -12,59 +11,53 @@ class Type;
 
 namespace data {
 
-class Object
-{
-
-  // インタプリタ中でオブジェクトとして扱われる全てのオブジェクト
-  // となる。
-  // 構文データも含め、全てのデータを取り扱う。
+class DataSpace;
+class Object {
+  // インタプリタ中でオブジェクトとして扱われる全てのオブジェクトです。
   // 全てのオブジェクトは、このオブジェクトに単純に「束縛」されるのみと
-  // なり、実装はその先のオブジェクトに完全に移譲されている。
-  // このオブジェクトは、そのままschemeでの変数となり、このオブジェクト
-  // が保持するのは、「変更可能性」と「オブジェクト格納領域」のみ
-  // となる。
-
+  // なり、実装はその先のオブジェクトに完全に移譲されさう。
+  // このオブジェクトは、そのままschemeでの変数であり、このオブジェクトは
+  // 「変更可能性」とオブジェクトの実体を保持するのみです。
  public:
 
-  Object(bool changeable, const smart_ptr<DataSpace>& space);
-  Object(const data::Object& o);
+  Object(bool changeable, const utility::smart_ptr<DataSpace>& space)
+      : space_(space), changeable_(changeable) {}
+  Object(const data::Object& o) : space_(o.space_),
+                                  changeable_(o.changeable_) {}
 
-  Object& operator=(const Object& o);
-  virtual ~Object(){}
+  Object& operator=(const Object& o) {
+    Object tmp(o);
+    swap(tmp);
+    return *this;
+  }
+
+  virtual ~Object() {}
   // 変更可能なオブジェクトであるかどうかを返す。
-  virtual bool enableChange() const;
+  virtual bool IsChangeable() const {return changeable_;}
 
-  // 実体のデータが格納されている領域を返す。
-  virtual const smart_ptr<DataSpace> getSpace() const;
-  virtual void setSpace(const smart_ptr<DataSpace>& space);
+  // 実体のデータが格納されている領域を返します。
+  virtual data::DataSpace& space() {return *space_;}
 
- private:
+  // 実体のデータが格納されている領域を入れ替えます。これは
+  // schemeにおけるdefineに相当します。
+  virtual void set_space(const utility::smart_ptr<DataSpace>& space) {
+    space_ = space;
+  }
 
-  void swap(const Object& o);
-
-  smart_ptr<DataSpace> space_;
-  bool changeable_;
-};
-
-class NullObject : public Object
-{
-  // ObjectのNull実装。このオブジェクトは、ObjectがNULL = 値
-  // を保持していないことを保証する。
-  // 通常のObjectでは、getSpace().isNullは成立しないが、このオブジェクトは
-  // 必ず成立する。
-  // このオブジェクトは、Nilと=であるconsに設定される。
-  // nilオブジェクトと、NullObjectは全く違う。
- public:
+ private:
 
-  NullObject();
-  virtual ~NullObject() {}
+  // 渡されたオブジェクトの内容を交換します。
+  void swap(Object& o) {
+    std::swap(space_, o.space_);
+    std::swap(changeable_, o.changeable_);
+  }
 
-  // 変更可能なオブジェクトであるかどうかを返す。
-  virtual bool enableChange() const {return false;}
+  // オブジェクトが指し示すデータ領域です。
+  utility::smart_ptr<data::DataSpace> space_;
 
-  // 実体のデータが格納されている領域を返す。
-  virtual smart_ptr<DataSpace> getSpace() {return smart_ptr<DataSpace>();}
-  virtual void setSpace(const smart_ptr<DataSpace>& space) {}
+  // このオブジェクトの変更可能性を示します。trueである場合、変更が
+  // 可能であると判断されます。
+  bool changeable_;
 };
 
 // 渡されたオブジェクトが、同一のTypeであるかどうかを返す。
@@ -72,7 +65,6 @@ class NullObject : public Object
 bool instanceof(const data::Object& o, const type::Type& type);
 
 };
-
 };
 
-#endif /* _OBJECT_H_ */
+#endif /* _UTAKATA_SRC_OBJECT_H_ */
index ca3e493..6e118af 100644 (file)
@@ -7,50 +7,38 @@
 
 #include <string>
 #include <vector>
-#include <exception>
+#include "src/exception.h"
 
 namespace utakata {
 
 namespace reader {
 
-class EndOfDeviceException : public std::exception {
+class EndOfDeviceException : public exception::Exception {
   // reader::IReaderインターフェースの派生クラスにおいて、
   // 末尾に到達しているにも関わらず読み出しが行われた場合に送出されます。
  public:
-  // 表示する文字列を渡します。
-  explicit EndOfDeviceException(std::string str) : str_() {
-    const std::string prefix("end of device : ");
-    str_ = prefix + str;
-  }
-
-  virtual ~EndOfDeviceException() throw() {};
-  const char* what() const throw() {
-    return str_.c_str();
-  }
-
- private:
-
-  std::string str_;
+  EndOfDeviceException(const std::string& message,
+                       const utakata::exception::ExceptionInfo& info) :
+      Exception(message, info) {}
+
+  EndOfDeviceException(const utakata::exception::Exception& exception,
+                       const std::string& message,
+                       const utakata::exception::ExceptionInfo& info) :
+      Exception(exception, message, info) {}
 };
 
-class IOException : public std::exception {
+class IOException : public exception::Exception {
   // reader::IReaderインターフェースの派生クラスにおいて、
   // 入出力に対して発生する例外です。
  public:
-  // 表示する文字列を渡します。
-  explicit IOException(std::string str) : str_() {
-    const std::string prefix("IOException : ");
-    str_ = prefix + str;
-  }
-
-  virtual ~IOException() throw() {};
-  const char* what() const throw() {
-    return str_.c_str();
-  }
-
- private:
-
-  std::string str_;
+  IOException(const std::string& message,
+              const utakata::exception::ExceptionInfo& info) :
+      Exception(message, info) {}
+
+  IOException(const utakata::exception::Exception& exception,
+              const std::string& message,
+              const utakata::exception::ExceptionInfo& info) :
+      Exception(exception, message, info) {}
 };
 
 // IReader::Seekの方向を制御します。
@@ -66,22 +54,21 @@ class IReader {
 
   virtual ~IReader() {}
 
-
   // 各種デバイスから一文字読出します。
   // 末尾に到達してなお読み出しが行われた場合、reader::EndOfDeviceException
   // 例外を投げなければなりません。
   // readでは、読み出し位置を更新します。
-  virtual unsigned char Read() = 0;
-  virtual std::vector<unsigned char> Read(size_t num) = 0;
+  virtual unsigned int Read() = 0;
+  virtual std::vector<unsigned int> Read(size_t num) = 0;
 
   // デバイスから1バイトの読出しを行いますが、内部の読み出し位置は変化
   // しません。
   // peekした後、readを行うと、全く同一のバイトが得られます。
-  virtual unsigned char Peek() = 0;
-  virtual std::vector<unsigned char> Peek(size_t num) = 0;
+  virtual unsigned int Peek() = 0;
+  virtual std::vector<unsigned int> Peek(size_t num) = 0;
 
   // 読出したバイト数を返します。
-  virtual size_t GetPos() const = 0;
+  virtual unsigned int GetPos() const = 0;
 
   // 現在位置から、指定された方向に指定された量だけ読み出し位置を進めます。
   // 移動に成功したらtrueを返します。
@@ -98,7 +85,7 @@ class IReader {
   virtual void Begin() = 0;
 
   // 読み出し対象のサイズを返します。
-  virtual size_t GetSize() const = 0;
+  virtual unsigned int GetSize() const = 0;
 
   // 読み出し位置が末尾であるかどうかを返します。
   virtual bool IsEof() const = 0;
index 72756ae..294b2d9 100755 (executable)
 // StringReaderにおける読み出し位置は、先頭が0であるとされます。
 // 4文字渡して、2文字読出した時点で2となります。
 //
+#include <vector>
 #include "src/string_reader.h"
+#include "src/exception_macro.h"
 
 namespace reader = utakata::reader;
 
 // 現在位置を示すイテレータの内容を返します。
-unsigned char reader::StringReader::Read() {
+unsigned int reader::StringReader::Read() {
   CheckInternal();
-  unsigned char byte = *iterator_++;
+  unsigned int byte = *iterator_++;
   ++pos_;
   return byte;
 }
 
 // 読み出しについては、iteratorを利用しています。
-std::vector<unsigned char> reader::StringReader::Read(size_t num) {
+std::vector<unsigned int> reader::StringReader::Read(size_t num) {
   CheckInternal();
 
-  if (num <= 0)
-  {
-    return std::vector<unsigned char>();
+  if (num <= 0) {
+    return std::vector<unsigned int>();
   }
 
-  std::vector<unsigned char> ret;
+  std::vector<unsigned int> ret;
   for (size_t i = 0; i < num && iterator_ != buffer_.end(); ++i) {
     ret.push_back(*iterator_++);
   }
@@ -42,24 +43,20 @@ std::vector<unsigned char> reader::StringReader::Read(size_t num) {
 }
 
 // イテレータの現在位置の文字を返します。位置は変更しません。
-unsigned char reader::StringReader::Peek() {
+unsigned int reader::StringReader::Peek() {
   CheckInternal();
   return *iterator_;
 }
 
 // 現在のイテレータのコピーを作成し、numだけ進めながら文字を取得します。
-std::vector<unsigned char> reader::StringReader::Peek(size_t num) {
+std::vector<unsigned int> reader::StringReader::Peek(size_t num) {
   CheckInternal();
   if (num <= 0) {
-    return std::vector<unsigned char>();
-  }
-
-  if (iterator_ == buffer_.end()) {
-    throw reader::EndOfDeviceException("end of String `" + buffer_ + "`");
+    return std::vector<unsigned int>();
   }
 
   reader::StringReader::internal_iterator peeker = iterator_;
-  std::vector<unsigned char> ret;
+  std::vector<unsigned int> ret;
   for (size_t i = 0; i < num && peeker != buffer_.end(); ++i) {
     ret.push_back(*peeker++);
   }
@@ -109,7 +106,6 @@ bool reader::StringReader::Seek(int seekpos,
 
   int count = 0;
   if (direction == reader::kForward) {
-
     for (int i = 0; i < seekpos && iterator_ != buffer_.end();
          ++i, ++pos_, ++iterator_, ++count) {}
     if (pos_ >= buffer_.size()) {
@@ -147,6 +143,7 @@ bool reader::StringReader::IsEof() const {
 
 void reader::StringReader::CheckInternal() {
   if (iterator_ == buffer_.end()) {
-    throw reader::EndOfDeviceException("end of String `" + buffer_ + "`");
+    THROW_EXCEPTION_(reader::EndOfDeviceException,
+                     "end of String `" + buffer_ + "`");
   }
 }
index 8feeed7..ee3760c 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _UTAKATA_SRC_STRING_READER_H_
 #define _UTAKATA_SRC_STRING_READER_H_
 
+#include <vector>
 #include <string>
 #include "src/reader_interface.h"
 #include "src/common/uncopyable.h"
@@ -44,14 +45,14 @@ class StringReader : public IReader, private utility::Uncopyable {
   // 末尾に到達してなお読み出しが行われた場合、reader::EndOfDeviceException
   // 例外を投げなければなりません。
   // readでは、読み出し位置を更新します。
-  unsigned char Read();
-  std::vector<unsigned char> Read(size_t num);
+  unsigned int Read();
+  std::vector<unsigned int> Read(size_t num);
 
   // デバイスから1バイトの読出しを行いますが、内部の読み出し位置は変化
   // しません。
   // peekした後、readを行うと、全く同一のバイトが得られます。
-  unsigned char Peek();
-  std::vector<unsigned char> Peek(size_t num);
+  unsigned int Peek();
+  std::vector<unsigned int> Peek(size_t num);
 
   // 現在の読み出し位置を返します。
   size_t GetPos() const;
index 5723a87..2f84de8 100644 (file)
@@ -31,7 +31,8 @@ NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 bin_PROGRAMS = string_reader_test$(EXEEXT) file_reader_test$(EXEEXT) \
-       utf8_transcoder_test$(EXEEXT)
+       utf8_transcoder_test$(EXEEXT) unicode_test$(EXEEXT) \
+       encoding_reader_test$(EXEEXT)
 subdir = src/test
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -44,6 +45,11 @@ CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
+am_encoding_reader_test_OBJECTS = encoding_reader.$(OBJEXT) \
+       string_reader.$(OBJEXT) utf8_transcoder.$(OBJEXT) \
+       encoding_reader_test.$(OBJEXT) gtest-all.$(OBJEXT)
+encoding_reader_test_OBJECTS = $(am_encoding_reader_test_OBJECTS)
+encoding_reader_test_LDADD = $(LDADD)
 am_file_reader_test_OBJECTS = file_reader_test.$(OBJEXT) \
        file_reader.$(OBJEXT) gtest-all.$(OBJEXT)
 file_reader_test_OBJECTS = $(am_file_reader_test_OBJECTS)
@@ -52,6 +58,11 @@ am_string_reader_test_OBJECTS = string_reader_test.$(OBJEXT) \
        string_reader.$(OBJEXT) gtest-all.$(OBJEXT)
 string_reader_test_OBJECTS = $(am_string_reader_test_OBJECTS)
 string_reader_test_LDADD = $(LDADD)
+am_unicode_test_OBJECTS = unicode_test.$(OBJEXT) unicode.$(OBJEXT) \
+       utf8_transcoder.$(OBJEXT) string_reader.$(OBJEXT) \
+       gtest-all.$(OBJEXT)
+unicode_test_OBJECTS = $(am_unicode_test_OBJECTS)
+unicode_test_LDADD = $(LDADD)
 am_utf8_transcoder_test_OBJECTS = utf8_transcoder.$(OBJEXT) \
        utf8_transcoder_test.$(OBJEXT) string_reader.$(OBJEXT) \
        gtest-all.$(OBJEXT)
@@ -65,10 +76,12 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 CXXLD = $(CXX)
 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
        -o $@
-SOURCES = $(file_reader_test_SOURCES) $(string_reader_test_SOURCES) \
+SOURCES = $(encoding_reader_test_SOURCES) $(file_reader_test_SOURCES) \
+       $(string_reader_test_SOURCES) $(unicode_test_SOURCES) \
        $(utf8_transcoder_test_SOURCES)
-DIST_SOURCES = $(file_reader_test_SOURCES) \
-       $(string_reader_test_SOURCES) $(utf8_transcoder_test_SOURCES)
+DIST_SOURCES = $(encoding_reader_test_SOURCES) \
+       $(file_reader_test_SOURCES) $(string_reader_test_SOURCES) \
+       $(unicode_test_SOURCES) $(utf8_transcoder_test_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -172,6 +185,10 @@ TESTS = $(bin_PROGRAMS)
 string_reader_test_SOURCES = string_reader_test.cpp ../string_reader.cpp gtest/gtest-all.cc
 file_reader_test_SOURCES = file_reader_test.cpp ../file_reader.cpp gtest/gtest-all.cc
 utf8_transcoder_test_SOURCES = ../utf8_transcoder.cpp utf8_transcoder_test.cpp  ../string_reader.cpp gtest/gtest-all.cc
+unicode_test_SOURCES = unicode_test.cpp ../unicode.cpp ../utf8_transcoder.cpp  ../string_reader.cpp gtest/gtest-all.cc
+encoding_reader_test_SOURCES = ../encoding_reader.cpp ../string_reader.cpp ../utf8_transcoder.cpp \
+       encoding_reader_test.cpp  gtest/gtest-all.cc
+
 all: all-am
 
 .SUFFIXES:
@@ -228,12 +245,18 @@ uninstall-binPROGRAMS:
 
 clean-binPROGRAMS:
        -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+encoding_reader_test$(EXEEXT): $(encoding_reader_test_OBJECTS) $(encoding_reader_test_DEPENDENCIES) 
+       @rm -f encoding_reader_test$(EXEEXT)
+       $(CXXLINK) $(encoding_reader_test_OBJECTS) $(encoding_reader_test_LDADD) $(LIBS)
 file_reader_test$(EXEEXT): $(file_reader_test_OBJECTS) $(file_reader_test_DEPENDENCIES) 
        @rm -f file_reader_test$(EXEEXT)
        $(CXXLINK) $(file_reader_test_OBJECTS) $(file_reader_test_LDADD) $(LIBS)
 string_reader_test$(EXEEXT): $(string_reader_test_OBJECTS) $(string_reader_test_DEPENDENCIES) 
        @rm -f string_reader_test$(EXEEXT)
        $(CXXLINK) $(string_reader_test_OBJECTS) $(string_reader_test_LDADD) $(LIBS)
+unicode_test$(EXEEXT): $(unicode_test_OBJECTS) $(unicode_test_DEPENDENCIES) 
+       @rm -f unicode_test$(EXEEXT)
+       $(CXXLINK) $(unicode_test_OBJECTS) $(unicode_test_LDADD) $(LIBS)
 utf8_transcoder_test$(EXEEXT): $(utf8_transcoder_test_OBJECTS) $(utf8_transcoder_test_DEPENDENCIES) 
        @rm -f utf8_transcoder_test$(EXEEXT)
        $(CXXLINK) $(utf8_transcoder_test_OBJECTS) $(utf8_transcoder_test_LDADD) $(LIBS)
@@ -244,11 +267,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+include ./$(DEPDIR)/encoding_reader.Po
+include ./$(DEPDIR)/encoding_reader_test.Po
 include ./$(DEPDIR)/file_reader.Po
 include ./$(DEPDIR)/file_reader_test.Po
 include ./$(DEPDIR)/gtest-all.Po
 include ./$(DEPDIR)/string_reader.Po
 include ./$(DEPDIR)/string_reader_test.Po
+include ./$(DEPDIR)/unicode.Po
+include ./$(DEPDIR)/unicode_test.Po
 include ./$(DEPDIR)/utf8_transcoder.Po
 include ./$(DEPDIR)/utf8_transcoder_test.Po
 
@@ -266,33 +293,19 @@ include ./$(DEPDIR)/utf8_transcoder_test.Po
 #      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
 #      $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-file_reader.o: ../file_reader.cpp
-       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.o -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
-       mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
-#      source='../file_reader.cpp' object='file_reader.o' libtool=no \
+encoding_reader.o: ../encoding_reader.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT encoding_reader.o -MD -MP -MF $(DEPDIR)/encoding_reader.Tpo -c -o encoding_reader.o `test -f '../encoding_reader.cpp' || echo '$(srcdir)/'`../encoding_reader.cpp
+       mv -f $(DEPDIR)/encoding_reader.Tpo $(DEPDIR)/encoding_reader.Po
+#      source='../encoding_reader.cpp' object='encoding_reader.o' libtool=no \
 #      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
-#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o encoding_reader.o `test -f '../encoding_reader.cpp' || echo '$(srcdir)/'`../encoding_reader.cpp
 
-file_reader.obj: ../file_reader.cpp
-       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.obj -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
-       mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
-#      source='../file_reader.cpp' object='file_reader.obj' libtool=no \
+encoding_reader.obj: ../encoding_reader.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT encoding_reader.obj -MD -MP -MF $(DEPDIR)/encoding_reader.Tpo -c -o encoding_reader.obj `if test -f '../encoding_reader.cpp'; then $(CYGPATH_W) '../encoding_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../encoding_reader.cpp'; fi`
+       mv -f $(DEPDIR)/encoding_reader.Tpo $(DEPDIR)/encoding_reader.Po
+#      source='../encoding_reader.cpp' object='encoding_reader.obj' libtool=no \
 #      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
-#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
-
-gtest-all.o: gtest/gtest-all.cc
-       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.o -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
-       mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
-#      source='gtest/gtest-all.cc' object='gtest-all.o' libtool=no \
-#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
-#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
-
-gtest-all.obj: gtest/gtest-all.cc
-       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.obj -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
-       mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
-#      source='gtest/gtest-all.cc' object='gtest-all.obj' libtool=no \
-#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
-#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o encoding_reader.obj `if test -f '../encoding_reader.cpp'; then $(CYGPATH_W) '../encoding_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../encoding_reader.cpp'; fi`
 
 string_reader.o: ../string_reader.cpp
        $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT string_reader.o -MD -MP -MF $(DEPDIR)/string_reader.Tpo -c -o string_reader.o `test -f '../string_reader.cpp' || echo '$(srcdir)/'`../string_reader.cpp
@@ -322,6 +335,48 @@ utf8_transcoder.obj: ../utf8_transcoder.cpp
 #      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
 #      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o utf8_transcoder.obj `if test -f '../utf8_transcoder.cpp'; then $(CYGPATH_W) '../utf8_transcoder.cpp'; else $(CYGPATH_W) '$(srcdir)/../utf8_transcoder.cpp'; fi`
 
+gtest-all.o: gtest/gtest-all.cc
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.o -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
+       mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
+#      source='gtest/gtest-all.cc' object='gtest-all.o' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
+
+gtest-all.obj: gtest/gtest-all.cc
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.obj -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+       mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
+#      source='gtest/gtest-all.cc' object='gtest-all.obj' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+
+file_reader.o: ../file_reader.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.o -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+       mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
+#      source='../file_reader.cpp' object='file_reader.o' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+
+file_reader.obj: ../file_reader.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.obj -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
+       mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
+#      source='../file_reader.cpp' object='file_reader.obj' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
+
+unicode.o: ../unicode.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unicode.o -MD -MP -MF $(DEPDIR)/unicode.Tpo -c -o unicode.o `test -f '../unicode.cpp' || echo '$(srcdir)/'`../unicode.cpp
+       mv -f $(DEPDIR)/unicode.Tpo $(DEPDIR)/unicode.Po
+#      source='../unicode.cpp' object='unicode.o' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unicode.o `test -f '../unicode.cpp' || echo '$(srcdir)/'`../unicode.cpp
+
+unicode.obj: ../unicode.cpp
+       $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unicode.obj -MD -MP -MF $(DEPDIR)/unicode.Tpo -c -o unicode.obj `if test -f '../unicode.cpp'; then $(CYGPATH_W) '../unicode.cpp'; else $(CYGPATH_W) '$(srcdir)/../unicode.cpp'; fi`
+       mv -f $(DEPDIR)/unicode.Tpo $(DEPDIR)/unicode.Po
+#      source='../unicode.cpp' object='unicode.obj' libtool=no \
+#      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
+#      $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unicode.obj `if test -f '../unicode.cpp'; then $(CYGPATH_W) '../unicode.cpp'; else $(CYGPATH_W) '$(srcdir)/../unicode.cpp'; fi`
+
 .cpp.o:
        $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
        mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
index 167f00b..60e39ba 100755 (executable)
@@ -5,11 +5,15 @@ SRC_DIR=..
 LC_ALL=C
 # SIBDIRS = . 
 
-bin_PROGRAMS = string_reader_test file_reader_test utf8_transcoder_test
+bin_PROGRAMS = string_reader_test file_reader_test utf8_transcoder_test unicode_test \
+       encoding_reader_test
 
 check_PROGRANS = $(bin_PROGRAMS)
 TESTS = $(bin_PROGRAMS)
 
 string_reader_test_SOURCES = string_reader_test.cpp ../string_reader.cpp gtest/gtest-all.cc
 file_reader_test_SOURCES = file_reader_test.cpp ../file_reader.cpp gtest/gtest-all.cc
-utf8_transcoder_test_SOURCES = ../utf8_transcoder.cpp utf8_transcoder_test.cpp  ../string_reader.cpp gtest/gtest-all.cc
\ No newline at end of file
+utf8_transcoder_test_SOURCES = ../utf8_transcoder.cpp utf8_transcoder_test.cpp  ../string_reader.cpp gtest/gtest-all.cc
+unicode_test_SOURCES = unicode_test.cpp ../unicode.cpp ../utf8_transcoder.cpp  ../string_reader.cpp gtest/gtest-all.cc
+encoding_reader_test_SOURCES = ../encoding_reader.cpp ../string_reader.cpp ../utf8_transcoder.cpp \
+       encoding_reader_test.cpp  gtest/gtest-all.cc
\ No newline at end of file
index 638c7b5..bfcdc0f 100644 (file)
@@ -31,7 +31,8 @@ NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 bin_PROGRAMS = string_reader_test$(EXEEXT) file_reader_test$(EXEEXT) \
-       utf8_transcoder_test$(EXEEXT)
+       utf8_transcoder_test$(EXEEXT) unicode_test$(EXEEXT) \
+       encoding_reader_test$(EXEEXT)
 subdir = src/test
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -44,6 +45,11 @@ CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
+am_encoding_reader_test_OBJECTS = encoding_reader.$(OBJEXT) \
+       string_reader.$(OBJEXT) utf8_transcoder.$(OBJEXT) \
+       encoding_reader_test.$(OBJEXT) gtest-all.$(OBJEXT)
+encoding_reader_test_OBJECTS = $(am_encoding_reader_test_OBJECTS)
+encoding_reader_test_LDADD = $(LDADD)
 am_file_reader_test_OBJECTS = file_reader_test.$(OBJEXT) \
        file_reader.$(OBJEXT) gtest-all.$(OBJEXT)
 file_reader_test_OBJECTS = $(am_file_reader_test_OBJECTS)
@@ -52,6 +58,11 @@ am_string_reader_test_OBJECTS = string_reader_test.$(OBJEXT) \
        string_reader.$(OBJEXT) gtest-all.$(OBJEXT)
 string_reader_test_OBJECTS = $(am_string_reader_test_OBJECTS)
 string_reader_test_LDADD = $(LDADD)
+am_unicode_test_OBJECTS = unicode_test.$(OBJEXT) unicode.$(OBJEXT) \
+       utf8_transcoder.$(OBJEXT) string_reader.$(OBJEXT) \
+       gtest-all.$(OBJEXT)
+unicode_test_OBJECTS = $(am_unicode_test_OBJECTS)
+unicode_test_LDADD = $(LDADD)
 am_utf8_transcoder_test_OBJECTS = utf8_transcoder.$(OBJEXT) \
        utf8_transcoder_test.$(OBJEXT) string_reader.$(OBJEXT) \
        gtest-all.$(OBJEXT)
@@ -65,10 +76,12 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 CXXLD = $(CXX)
 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
        -o $@
-SOURCES = $(file_reader_test_SOURCES) $(string_reader_test_SOURCES) \
+SOURCES = $(encoding_reader_test_SOURCES) $(file_reader_test_SOURCES) \
+       $(string_reader_test_SOURCES) $(unicode_test_SOURCES) \
        $(utf8_transcoder_test_SOURCES)
-DIST_SOURCES = $(file_reader_test_SOURCES) \
-       $(string_reader_test_SOURCES) $(utf8_transcoder_test_SOURCES)
+DIST_SOURCES = $(encoding_reader_test_SOURCES) \
+       $(file_reader_test_SOURCES) $(string_reader_test_SOURCES) \
+       $(unicode_test_SOURCES) $(utf8_transcoder_test_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -172,6 +185,10 @@ TESTS = $(bin_PROGRAMS)
 string_reader_test_SOURCES = string_reader_test.cpp ../string_reader.cpp gtest/gtest-all.cc
 file_reader_test_SOURCES = file_reader_test.cpp ../file_reader.cpp gtest/gtest-all.cc
 utf8_transcoder_test_SOURCES = ../utf8_transcoder.cpp utf8_transcoder_test.cpp  ../string_reader.cpp gtest/gtest-all.cc
+unicode_test_SOURCES = unicode_test.cpp ../unicode.cpp ../utf8_transcoder.cpp  ../string_reader.cpp gtest/gtest-all.cc
+encoding_reader_test_SOURCES = ../encoding_reader.cpp ../string_reader.cpp ../utf8_transcoder.cpp \
+       encoding_reader_test.cpp  gtest/gtest-all.cc
+
 all: all-am
 
 .SUFFIXES:
@@ -228,12 +245,18 @@ uninstall-binPROGRAMS:
 
 clean-binPROGRAMS:
        -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+encoding_reader_test$(EXEEXT): $(encoding_reader_test_OBJECTS) $(encoding_reader_test_DEPENDENCIES) 
+       @rm -f encoding_reader_test$(EXEEXT)
+       $(CXXLINK) $(encoding_reader_test_OBJECTS) $(encoding_reader_test_LDADD) $(LIBS)
 file_reader_test$(EXEEXT): $(file_reader_test_OBJECTS) $(file_reader_test_DEPENDENCIES) 
        @rm -f file_reader_test$(EXEEXT)
        $(CXXLINK) $(file_reader_test_OBJECTS) $(file_reader_test_LDADD) $(LIBS)
 string_reader_test$(EXEEXT): $(string_reader_test_OBJECTS) $(string_reader_test_DEPENDENCIES) 
        @rm -f string_reader_test$(EXEEXT)
        $(CXXLINK) $(string_reader_test_OBJECTS) $(string_reader_test_LDADD) $(LIBS)
+unicode_test$(EXEEXT): $(unicode_test_OBJECTS) $(unicode_test_DEPENDENCIES) 
+       @rm -f unicode_test$(EXEEXT)
+       $(CXXLINK) $(unicode_test_OBJECTS) $(unicode_test_LDADD) $(LIBS)
 utf8_transcoder_test$(EXEEXT): $(utf8_transcoder_test_OBJECTS) $(utf8_transcoder_test_DEPENDENCIES) 
        @rm -f utf8_transcoder_test$(EXEEXT)
        $(CXXLINK) $(utf8_transcoder_test_OBJECTS) $(utf8_transcoder_test_LDADD) $(LIBS)
@@ -244,11 +267,15 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoding_reader.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoding_reader_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_reader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_reader_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtest-all.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_reader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_reader_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utf8_transcoder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utf8_transcoder_test.Po@am__quote@
 
@@ -266,33 +293,19 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-file_reader.o: ../file_reader.cpp
-@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.o -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
-@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../file_reader.cpp' object='file_reader.o' libtool=no @AMDEPBACKSLASH@
+encoding_reader.o: ../encoding_reader.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT encoding_reader.o -MD -MP -MF $(DEPDIR)/encoding_reader.Tpo -c -o encoding_reader.o `test -f '../encoding_reader.cpp' || echo '$(srcdir)/'`../encoding_reader.cpp
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/encoding_reader.Tpo $(DEPDIR)/encoding_reader.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../encoding_reader.cpp' object='encoding_reader.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o encoding_reader.o `test -f '../encoding_reader.cpp' || echo '$(srcdir)/'`../encoding_reader.cpp
 
-file_reader.obj: ../file_reader.cpp
-@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.obj -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
-@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../file_reader.cpp' object='file_reader.obj' libtool=no @AMDEPBACKSLASH@
+encoding_reader.obj: ../encoding_reader.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT encoding_reader.obj -MD -MP -MF $(DEPDIR)/encoding_reader.Tpo -c -o encoding_reader.obj `if test -f '../encoding_reader.cpp'; then $(CYGPATH_W) '../encoding_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../encoding_reader.cpp'; fi`
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/encoding_reader.Tpo $(DEPDIR)/encoding_reader.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../encoding_reader.cpp' object='encoding_reader.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
-
-gtest-all.o: gtest/gtest-all.cc
-@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.o -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
-@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='gtest/gtest-all.cc' object='gtest-all.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
-
-gtest-all.obj: gtest/gtest-all.cc
-@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.obj -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
-@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='gtest/gtest-all.cc' object='gtest-all.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o encoding_reader.obj `if test -f '../encoding_reader.cpp'; then $(CYGPATH_W) '../encoding_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../encoding_reader.cpp'; fi`
 
 string_reader.o: ../string_reader.cpp
 @am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT string_reader.o -MD -MP -MF $(DEPDIR)/string_reader.Tpo -c -o string_reader.o `test -f '../string_reader.cpp' || echo '$(srcdir)/'`../string_reader.cpp
@@ -322,6 +335,48 @@ utf8_transcoder.obj: ../utf8_transcoder.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o utf8_transcoder.obj `if test -f '../utf8_transcoder.cpp'; then $(CYGPATH_W) '../utf8_transcoder.cpp'; else $(CYGPATH_W) '$(srcdir)/../utf8_transcoder.cpp'; fi`
 
+gtest-all.o: gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.o -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='gtest/gtest-all.cc' object='gtest-all.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.o `test -f 'gtest/gtest-all.cc' || echo '$(srcdir)/'`gtest/gtest-all.cc
+
+gtest-all.obj: gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gtest-all.obj -MD -MP -MF $(DEPDIR)/gtest-all.Tpo -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/gtest-all.Tpo $(DEPDIR)/gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='gtest/gtest-all.cc' object='gtest-all.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gtest-all.obj `if test -f 'gtest/gtest-all.cc'; then $(CYGPATH_W) 'gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/gtest/gtest-all.cc'; fi`
+
+file_reader.o: ../file_reader.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.o -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../file_reader.cpp' object='file_reader.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.o `test -f '../file_reader.cpp' || echo '$(srcdir)/'`../file_reader.cpp
+
+file_reader.obj: ../file_reader.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT file_reader.obj -MD -MP -MF $(DEPDIR)/file_reader.Tpo -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/file_reader.Tpo $(DEPDIR)/file_reader.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../file_reader.cpp' object='file_reader.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o file_reader.obj `if test -f '../file_reader.cpp'; then $(CYGPATH_W) '../file_reader.cpp'; else $(CYGPATH_W) '$(srcdir)/../file_reader.cpp'; fi`
+
+unicode.o: ../unicode.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unicode.o -MD -MP -MF $(DEPDIR)/unicode.Tpo -c -o unicode.o `test -f '../unicode.cpp' || echo '$(srcdir)/'`../unicode.cpp
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/unicode.Tpo $(DEPDIR)/unicode.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../unicode.cpp' object='unicode.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unicode.o `test -f '../unicode.cpp' || echo '$(srcdir)/'`../unicode.cpp
+
+unicode.obj: ../unicode.cpp
+@am__fastdepCXX_TRUE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT unicode.obj -MD -MP -MF $(DEPDIR)/unicode.Tpo -c -o unicode.obj `if test -f '../unicode.cpp'; then $(CYGPATH_W) '../unicode.cpp'; else $(CYGPATH_W) '$(srcdir)/../unicode.cpp'; fi`
+@am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/unicode.Tpo $(DEPDIR)/unicode.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='../unicode.cpp' object='unicode.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o unicode.obj `if test -f '../unicode.cpp'; then $(CYGPATH_W) '../unicode.cpp'; else $(CYGPATH_W) '$(srcdir)/../unicode.cpp'; fi`
+
 .cpp.o:
 @am__fastdepCXX_TRUE@  $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
 @am__fastdepCXX_TRUE@  mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
diff --git a/src/test/encoding_reader_test.cpp b/src/test/encoding_reader_test.cpp
new file mode 100755 (executable)
index 0000000..be41c31
--- /dev/null
@@ -0,0 +1,67 @@
+#include <algorithm>
+#include <gtest/gtest.h>
+
+#include "src/utf8_transcoder.h"
+#include "src/string_reader.h"
+#include "src/encoding_reader.h"
+
+namespace reader = utakata::reader;
+namespace transcoder = utakata::transcoder;
+
+TEST(UTF8TranscoderTest, EncodingTest) {
+  reader::StringReader sr("UTF8");
+
+  reader::EncodingReader reader(&sr, new transcoder::UTF8Transcoder);
+  unsigned int checker = reader.Read();
+
+  EXPECT_EQ(checker, static_cast<unsigned int>('U'));
+  checker = reader.Peek();
+  EXPECT_EQ(checker, static_cast<unsigned int>('T'));
+  checker = reader.Read();
+  EXPECT_EQ(checker, static_cast<unsigned int>('T'));
+
+  std::vector<unsigned int> t = reader.Peek(2);
+  EXPECT_EQ(t[0], static_cast<unsigned int>('F'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>('8'));
+
+  t = reader.Read(2);
+  EXPECT_EQ(t[0], static_cast<unsigned int>('F'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>('8'));
+
+  EXPECT_NO_THROW(reader.Read());
+  EXPECT_TRUE(reader.IsEof());
+}
+
+TEST(UTF8TranscoderTest, MultiByteTest) {
+  reader::StringReader sr("あいuうえお");
+  reader::EncodingReader reader(&sr, new transcoder::UTF8Transcoder);
+  unsigned int checker = reader.Read();
+
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3042));
+  checker = reader.Peek();
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3044));
+  checker = reader.Read();
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3044));
+
+  std::vector<unsigned int> t = reader.Peek(2);
+  EXPECT_EQ(t[0], static_cast<unsigned int>('u'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>(0x3046));
+
+  t = reader.Read(2);
+  EXPECT_EQ(t[0], static_cast<unsigned int>('u'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>(0x3046));
+
+  checker = reader.Read();
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3048));
+  checker = reader.Read();
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x304A));
+
+  EXPECT_NO_THROW(reader.Read());
+  EXPECT_TRUE(reader.IsEof());
+}
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
index 48c3d69..f3544fd 100755 (executable)
@@ -26,7 +26,7 @@ TEST_F(FileReaderTest, NormalUsega) {
 
   EXPECT_EQ(reader.Peek(), 'o');
   EXPECT_EQ(reader.Read(), 'o');
-  std::vector<unsigned char> t = reader.Read(2);
+  std::vector<unsigned int> t = reader.Read(2);
   EXPECT_EQ(t[0], 'g');
   EXPECT_EQ(t[1], 'e');
 
@@ -61,7 +61,7 @@ TEST_F(FileReaderTest, OpenAndClose) {
 
   EXPECT_EQ(reader.Peek(), 'o');
   EXPECT_EQ(reader.Read(), 'o');
-  std::vector<unsigned char> t = reader.Read(2);
+  std::vector<unsigned int> t = reader.Read(2);
   EXPECT_EQ(t[0], 'g');
   EXPECT_EQ(t[1], 'e');
 
index 4cdb1eb..6b67ef6 100644 (file)
@@ -7,32 +7,32 @@ TEST(StringReaderTest, Test1) {
   // StringReaderを用いた読み出しを行う。
   reader::StringReader reader("hoge");
 
-  EXPECT_EQ(reader.GetSize(), 4);
+  EXPECT_EQ(reader.GetSize(), static_cast<unsigned int>(4));
 
-  EXPECT_EQ(reader.Read(), 'h');
-  EXPECT_EQ(reader.GetPos(), 1);
+  EXPECT_EQ(reader.Read(), static_cast<unsigned int>('h'));
+  EXPECT_EQ(reader.GetPos(), static_cast<unsigned int>(1));
 
-  EXPECT_EQ(reader.Peek(), 'o');
-  EXPECT_EQ(reader.Read(), 'o');
-  std::vector<unsigned char> t = reader.Read(2);
-  EXPECT_EQ(t[0], 'g');
-  EXPECT_EQ(t[1], 'e');
+  EXPECT_EQ(reader.Peek(), static_cast<unsigned int>('o'));
+  EXPECT_EQ(reader.Read(), static_cast<unsigned int>('o'));
+  std::vector<unsigned int> t = reader.Read(2);
+  EXPECT_EQ(t[0], static_cast<unsigned int>('g'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>('e'));
 
-  EXPECT_EQ(reader.GetPos(), 4);
+  EXPECT_EQ(reader.GetPos(), static_cast<unsigned int>(4));
   reader.Begin();
-  EXPECT_EQ(reader.GetPos(), 0);
+  EXPECT_EQ(reader.GetPos(), static_cast<unsigned int>(0));
 
   EXPECT_TRUE(reader.Seek(1, reader::kForward));
-  EXPECT_EQ(reader.Read(), 'o');
+  EXPECT_EQ(reader.Read(), static_cast<unsigned int>('o'));
 
-  size_t seeksize = 0;
+  unsigned int seeksize = 0;
   EXPECT_TRUE(reader.Seek(1, reader::kBackward, &seeksize));
-  EXPECT_EQ(seeksize, 1);
-  EXPECT_EQ(reader.Read(), 'o');
+  EXPECT_EQ(seeksize, static_cast<unsigned int>(1));
+  EXPECT_EQ(reader.Read(), static_cast<unsigned int>('o'));
 
   t = reader.Read(2);
-  EXPECT_EQ(t[0], 'g');
-  EXPECT_EQ(t[1], 'e');
+  EXPECT_EQ(t[0], static_cast<unsigned int>('g'));
+  EXPECT_EQ(t[1], static_cast<unsigned int>('e'));
   EXPECT_TRUE(reader.IsEof());
 
   // すでに末尾であるのに進もうとすると例外が発生する。
index c9daa0d..213191d 100755 (executable)
-#include <ios>
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <functional>
-
-
-#include "../simpletest.h"
+#include <gtest/gtest.h>
 
 #include "../unicode.h"
-#include "../textarrayformat.h"
-#include "../reader.h"
+#include "../string_reader.h"
 #include "../utf8_transcoder.h"
 
+namespace transcoder = utakata::transcoder;
+namespace reader = utakata::reader;
+namespace unicode = utakata::unicode;
 
-using namespace utakata;
+TEST(UnicodeTest, UTF8MultiByteTest) {
 
+  std::string tmp("あいuえお");
+  reader::StringReader reader(tmp);
+  transcoder::UTF8Transcoder trans;
 
-bool utf8_multichar_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
+  unsigned int checker = trans.Encode(&reader);
 
-    std::string tmp("あいuえお");
-    // マルチバイト文字列を正しく読みだせるかどうかのチェックを
-    // 含めたテスト
-    smart_ptr<std::istream> ss(new std::stringstream(tmp));
+  unicode::UniChar ch(checker);
+  // U+3042 = あ
+  EXPECT_EQ(ch.rawcode(), static_cast<unsigned int>(0x3042));
+  unicode::UniChar ch2(trans.Encode(&reader));
+  // U+3044 = い
+  EXPECT_EQ(ch2.rawcode(), static_cast<unsigned int>(0x3044));
+  unicode::UniChar ch3(trans.Encode(&reader));
+  EXPECT_EQ(ch3.rawcode(), static_cast<unsigned int>('u'));
 
-    reader::StreamReader stream(ss,
-                                smart_ptr<transcoder::ITranscoder>(
-                                    new transcoder::UTF8Transcoder()));
-    
-    // 単独のreadを試す。
-    unicode::UniChar ch(stream.read());
-    // U+3042 = あ
-    asserter->check(ch.getRawCode(), 0x3042, "raw-code isn't japanese `a`");
-    // peekが問題なく働いていることのテスト
-    unicode::UniChar ch2(stream.peek());
-    // U+3044 = い
-    asserter->check(ch2.getRawCode(), 0x3044, "raw-code isn't japanese `i`");
-    unicode::UniChar ch3(stream.read());
-    asserter->check(ch3.getRawCode(), 0x3044, "raw-code isn't japanese `i`");
+  // ascii文字の範囲であるかどうかを判定する関数のテスト。
+  EXPECT_TRUE(unicode::IsAscii(ch3));
+  EXPECT_FALSE(unicode::IsAscii(ch));
 
-    // asciiだとしても問題無く読みだせるはず。
-    unicode::UniChar ch4(stream.peek());
-    asserter->check(ch4.getRawCode(), 'u');
+  EXPECT_FALSE(ch == ch2);
+  EXPECT_TRUE(ch != ch2);
+}
 
-    // ascii文字の範囲であるかどうかを判定する関数のテスト。
-    asserter->check(unicode::is_ascii(ch4), true);
-    asserter->check(unicode::is_ascii(ch), false);
 
-    // 同一コードなので比較して同じになるはず。
-    asserter->check(ch == ch2, false, "chとch2が異なる");
-    asserter->check(ch < ch2, true , "chよりch2が大きいはず");
+TEST(UnicodeTest, UnicodeCheck) {
+  reader::StringReader reader("あいうえsssお(");
+  transcoder::UTF8Transcoder trans;
 
-    return asserter->isOk();
-}
+  unicode::UniString str;
 
-bool unicode_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
-    // マルチバイトとascii文字の混在文字も正しく扱うことのできる
-    // CUniStringのテスト
-    
-    std::string tmp("あいうえsssお(");
-
-    smart_ptr<std::istream> ss(new std::stringstream(tmp));
-    reader::StreamReader stream(ss,
-                                smart_ptr<transcoder::ITranscoder>(
-                                    new transcoder::UTF8Transcoder()));
-
-    unicode::UniString str;
-    std::vector<unsigned long> t = stream.read(5);
-    std::vector<unsigned long>::iterator it = t.begin(),
-        end = t.end();
-    for (; it != end; ++it)
-    {
-        str += unicode::UniChar(*it);
-    }
-    
-    asserter->check(str.begin()->getRawCode(), 0x3042);
-    asserter->check(str.size(), 5);
-
-    // 自分自身との加算でも問題ないことを確認する。
-    str += str;
-    asserter->check(str[5].getRawCode(), 0x3042);
-
-    // 本当に基本的なもの以外は、同一の名前空間内に関数が用意されている。
-    // unicodeから返されるのは、UTF8のバイト列を設定した文字列であると
-    // する。
-    asserter->check(unicode::substring(str,0,2)[1].getRawCode(), 0x3044);
-    asserter->check(unicode::substring(str,1,2)[1].getRawCode(), 0x3046);
-
-    return asserter->isOk();
+  for (int i = 0; i < 5; ++i) {
+    str.Append(unicode::UniChar(trans.Encode(&reader)));
+  }
+
+  EXPECT_EQ(str.Begin()->rawcode(), static_cast<unsigned int>(0x3042));
+  EXPECT_EQ(str.GetSize(), static_cast<unsigned int>(5));
+
+  str.Append(str);
+  EXPECT_EQ(str.At(5).rawcode(), static_cast<unsigned int>(0x3042));
+
+  EXPECT_EQ(unicode::Substring(str, 1).At(0).rawcode(),
+            static_cast<unsigned int>(0x3044));
+  EXPECT_EQ(unicode::Substring(str, 2, 2).At(1).rawcode(),
+            static_cast<unsigned int>(0x3048));
 }
 
-bool unicode_util_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
-    // CUniStringと共に利用するためのユーティリティ関数の操作を
-    // 行う。
-    
-    std::string tmp("あいうえsssお");
+TEST(UnicodeTest, UtilTest) {
+  reader::StringReader reader("あいうえsssお");
 
-    smart_ptr<std::istream> ss(new std::stringstream(tmp));
-    reader::StreamReader stream(ss,
-                                smart_ptr<transcoder::ITranscoder>(
-                                    new transcoder::UTF8Transcoder()));
+  transcoder::UTF8Transcoder trans;
+  unicode::UniString str;
 
-    unicode::UniString str(unicode::convert(stream.read(5)));
-    unicode::UniString str2(unicode::convert(stream.read(3)));
-    unicode::UniString str3 = str;
+  for (int i = 0; i < 5; ++i) {
+    str.Append(unicode::UniChar(trans.Encode(&reader)));
+  }
 
-    // 挿入してみる。
-    str.insert(str.begin(), str2.begin(), str2.end());
-    asserter->check(str[0].getRawCode(), 's');
+  unicode::UniString str2;
+  for (int i = 0; i < 3; ++i) {
+    str2.Append(unicode::UniChar(trans.Encode(&reader)));
+  }
+  unicode::UniString str3 = str;
 
-    str3.insert(str3.begin() + 1, str2.begin(), str2.begin() + 1);
-    asserter->check(str3[1].getRawCode(), 's');
+  str.Insert(str.Begin(), str2.Begin(), str2.End());
+  EXPECT_EQ(str.At(0).rawcode(), static_cast<unsigned int>('s'));
 
-    return asserter->isOk();
+  str3.Insert(str3.Begin() + 1, str2.Begin(), str2.Begin() + 1);
+  EXPECT_EQ(str3.At(1).rawcode(), static_cast<unsigned int>('s'));
 }
 
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
 
-int main(int argc, char *argv[])
-{
-    simpletest::SimpleTestSuite suite("UTF-8 文字列テスト");
-    suite.addTester(sfcr::screate(utf8_multichar_test, suite.getAsserter()));
-    suite.addTester(sfcr::screate(unicode_test, suite.getAsserter()));
-    suite.addTester(sfcr::screate(unicode_util_test, suite.getAsserter()));
-    suite.run();
-    return 0;
+  return RUN_ALL_TESTS();
 }
+
index 26bdb3d..8d6057f 100755 (executable)
@@ -13,13 +13,13 @@ TEST(UTF8TranscoderTest, EncodingTest) {
 
   unsigned int checker = trans.Encode(&reader);
 
-  EXPECT_EQ(checker, 'U');
+  EXPECT_EQ(checker, static_cast<unsigned int>('U'));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 'T');
+  EXPECT_EQ(checker, static_cast<unsigned int>('T'));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 'F');
+  EXPECT_EQ(checker, static_cast<unsigned int>('F'));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, '8');
+  EXPECT_EQ(checker, static_cast<unsigned int>('8'));
 
   EXPECT_NO_THROW(trans.Encode(&reader));
   EXPECT_TRUE(reader.IsEof());
@@ -32,19 +32,19 @@ TEST(UTF8TranscoderTest, MultiByteTest) {
 
   unsigned int checker = trans.Encode(&reader);
 
-  EXPECT_EQ(checker, 0x3042);
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3042));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 0x3044);
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3044));
 
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 'u');
+  EXPECT_EQ(checker, static_cast<unsigned int>('u'));
 
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 0x3046);
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3046));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 0x3048);
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x3048));
   checker = trans.Encode(&reader);
-  EXPECT_EQ(checker, 0x304A);
+  EXPECT_EQ(checker, static_cast<unsigned int>(0x304A));
 
   EXPECT_NO_THROW(trans.Encode(&reader));
   EXPECT_TRUE(reader.IsEof());
diff --git a/src/transcoder_interface.h b/src/transcoder_interface.h
new file mode 100755 (executable)
index 0000000..c4925ca
--- /dev/null
@@ -0,0 +1,66 @@
+// IReaderよりバイナリデータを読出し、特定のエンコーディングである
+// と解釈し、結果をunicode文字として返します。
+// ITranscoderインターフェースを実装したクラスは、Encode/Decodeが
+// 失敗した場合の処理を実装する必要があります。
+#ifndef _UTAKATA_SRC_TRANSCODER_INTERFACE_H_
+#define _UTAKATA_SRC_TRANSCODER_INTERFACE_H_
+
+#include <string>
+#include <vector>
+#include "src/exception.h"
+
+namespace utakata {
+
+namespace reader {
+class IReader;
+}
+
+namespace transcoder {
+
+class EncodeException : public exception::Exception {
+  // ITranscoderインターフェースの派生クラスにおいて、Encode時に
+  // 例外が発生した場合に返すことが想定されている例外です。
+ public:
+  // 表示する文字列と、例外が発生した位置を設定します。
+  EncodeException(const std::string& message,
+                  const utakata::exception::ExceptionInfo& info) :
+      Exception(message, info) {}
+  EncodeException(const utakata::exception::Exception& exception,
+                  const std::string& message,
+                  const utakata::exception::ExceptionInfo& info) :
+      Exception(exception, message, info) {}
+};
+
+class DecodeException : public exception::Exception {
+  // ITranscoderインターフェースの派生クラスにおいて、Encode時に
+  // 例外が発生した場合に返すことが想定されている例外です。
+ public:
+  // 表示する文字列と、例外が発生した位置を設定します。
+  DecodeException(const std::string& message,
+                  const utakata::exception::ExceptionInfo& info) :
+      Exception(message, info) {}
+
+  DecodeException(const utakata::exception::Exception& exception,
+                  const std::string& message,
+                  const utakata::exception::ExceptionInfo& info) :
+      Exception(exception, message, info) {}
+};
+
+class ITranscoder {
+  // 入力されたバイト列を、それぞれの判定によってUniCharに
+  // 変換する。
+  // このインターフェースは入力値を変換するためだけのものであり、
+  // schemeのtranscoderとは多少機能が異なる。
+  // これはlexerのインターフェースで利用される。
+ public:
+  virtual ~ITranscoder() {}
+
+  // 渡されたInputPortから一文字分だけ読み出して、unicode値を返す。
+  virtual unsigned int Encode(reader::IReader* reader) = 0;
+  // 渡されたcodeに対応する、自身のエンコードとなるバイト列を返す。
+  virtual std::vector<unsigned int> Decode(unsigned int code) = 0;
+};
+};
+};
+
+#endif /* _UTAKATA_SRC_TRANSCODER_INTERFACE_H_ */
index 714700e..51e5aea 100755 (executable)
@@ -1,56 +1,41 @@
-#include "type.h"
-#include "data_structure.h"
-#include "class.h"
-#include "object.h"
+#include <algorithm>
+#include <string>
+#include "src/type.h"
 
+namespace type = utakata::type;
 
-using namespace utakata::type;
-using namespace utakata;
-
-type::Type::Type(const std::string& str) : hash_(0), hash_string_(str)
-{
-    makeHash();
-}
-
-type::Type::Type(const type::Type& t)
-{
-    hash_ = t.hash_;
-    hash_string_ = t.hash_string_;
+// 宣言のコメントを参照してください。
+type::Type::Type(const std::string& str) : hash_(0), hash_string_(str) {
+  MakeHash();
 }
 
-type::Type& type::Type::operator=(const type::Type& p)
-{
-    hash_ = p.hash_;
-    hash_string_ = p.hash_string_;
-    return *this;
-}
-
-void type::Type::makeHash()
-{
-    // 簡単にハッシュを作成する。
-    std::string::const_iterator beg = hash_string_.begin(), end = hash_string_.end();
+// 宣言のコメントを参照してください。
+type::Type::Type(const type::Type& t) : hash_(t.hash_),
+                                        hash_string_(t.hash_string_) {}
 
-    unsigned char ch = *beg;
-    for (; beg != end; ++beg)
-    {
-        // 各文字毎に簡単なハッシュ値を算出する。
-        hash_ += (ch + (!(ch << 4)));
-        ch = *beg;
-    }
+// 宣言のコメントを参照してください。
+type::Type& type::Type::operator=(const type::Type& p) {
+  type::Type tmp(p);
+  Swap(tmp);
+  return *this;
 }
 
-TypeDescripter::TypeDescripter(const Type& type,
-                               const smart_ptr<data::DataEntity>& entity) :
-    type_(type), entity_(entity)
-{}
-
-const Type& TypeDescripter::getType() const
-{
-    // 実体を返すが、単純に参照を返すのみとする。
-    return type_;
+// ここでのハッシュ値は、次のようなアルゴリズムで生成されます。
+// 渡された文字列 s のn文字目の文字をSnと表したとき、
+// hash = (S1 + !(S1 << 4)) + (S2 + !(S2 << 4))...(Sn + !(Sn << 4))
+// とした結果のハッシュ値となります。
+void type::Type::MakeHash() {
+  std::string::const_iterator beg = hash_string_.begin(),
+      end = hash_string_.end();
+
+  for (; beg != end; ++beg) {
+    // 各文字毎に簡単なハッシュ値を算出する。
+    hash_ += (*beg + (!(*beg << 4)));
+  }
 }
 
-smart_ptr<data::DataEntity> TypeDescripter::getEntity()
-{
-    return entity_;
+// 宣言のコメントを参照してください。
+void type::Type::Swap(type::Type& type) {
+  std::swap(hash_, type.hash_);
+  std::swap(hash_string_, type.hash_string_);
 }
index d30967c..b572438 100755 (executable)
@@ -1,16 +1,10 @@
-#ifndef _TYPE_H_
-#define _TYPE_H_
+#ifndef _UTAKATA_SRC_TYPE_H_
+#define _UTAKATA_SRC_TYPE_H_
 
 #include <string>
-#include "smart_ptr.h"
 
 namespace utakata {
 
-namespace data {
-class DataEntity;
-class Object;
-};
-
 namespace type {
 
 class Type {
@@ -18,25 +12,28 @@ class Type {
   // するクラスです。このクラスはInterpreterからのみ生成される
   // ため、各値の変更は不可能となっています。
  public:
-  explicit Type(const std::string& name);
+  explicit Type(const std::string& name) : hash_(0), hash_string_(name) {
+    MakeHash();
+  }
   Type(const Type& type);
-  virtual ~Type(){}
+  virtual ~Type() {}
 
   // 渡されたTypeをコピーします。
   Type& operator=(const Type& type);
 
-  unsigned long hash() const {return hash_;}
-
-  // 自身のコピーを作成します。
-  Type clone();
+  // 内部で生成されたハッシュ数を返します。
+  unsigned int hash() const {return hash_;}
 
  private:
 
   // 渡された文字列から、型単位で一意なhashを生成します。
-  void makeHash();
+  void MakeHash();
+
+  // 渡されたtypeとそれぞれの値を交換します。
+  void Swap(Type& type);
 
   // 生成されたハッシュ値
-  unsigned long hash_;
+  unsigned int hash_;
   // ハッシュ値の生成元となる文字列
   std::string hash_string_;
 };
@@ -50,35 +47,7 @@ bool operator==(const Type& lh, const Type& rh) {
 bool operator!=(const Type& lh, const Type& rh) {
   return !(lh.hash() == rh.hash());
 }
-
-class TypeDescripter : private utility::Uncopyable {
-  // TypeとIObject派生クラスとを関連付けるためのクラスです。
-  // TypeDescripterは、以下の情報を保持/提供します。
-  // ・保持しているオブジェクトを一意に表すType
-  // ・実体への直接アクセス
-  // Type、及び保持するオブジェクトは、生成時にのみ提供されます。
-  // TypeDescripterは、GC以外からは生成されないことを意図している
-  // ため、通常の方法では生成することができません。
-  //
-  // 各オブジェクトの実体毎に割り当てられるため、TypeDescripter自体はコ
-  // ピー不能です。
-
- public:
-  TypeDescripter(const Type& type,
-                 smart_ptr<interpreter::IObject> object);
-  virtual ~TypeDescripter() {}
-
-  const Type& type() const;
-  interpreter::IObject* object();
-
- private:
-
-  // 各オブジェクトを表す一意な型
-  Type type_;
-  // オブジェクトへの実体を保持するポインタ
-  smart_ptr<interpreter::IObject> object_;
-};
 };
 };
 
-#endif /* _TYPE_H_ */
+#endif /* _UTAKATA_SRC_TYPE_H_ */
index 5fae639..b6983aa 100755 (executable)
-#include <vector>
 #include <string>
-#include <functional>
-#include <algorithm>
-
-#include "unicode.h"
-
-using namespace utakata;
-using namespace utakata::unicode;
-
-//================================================================================
-
-unicode::UniChar::UniChar() : code_(0)
-{
-}
-
-unicode::UniChar::UniChar(const unicode::UniChar& ch)
-{
-    // 単純にそれぞれの値をコピーする。
-    code_ = ch.code_;
-}
-
-unicode::UniChar::UniChar(unicode::unicode_t ch) :
-    code_(ch)
-{
-    // 安全なスワップを利用する。
-
-}
-
-unicode::UniChar& unicode::UniChar::operator=(const unicode::UniChar& ch)
-{
-    // 安全なスワップを利用する。
-    UniChar c(ch);
-    swap(c);
-    return *this;
-}
-
-unicode::UniChar& unicode::UniChar::operator=(unicode::unicode_t ch)
-{
-    code_ = ch;
-    return *this;
-}
-
-bool unicode::UniChar::operator==(const unicode::UniChar& ch) const
-{
-    return ch.code_ == code_;
-}
-
-bool unicode::UniChar::operator!=(const unicode::UniChar& ch) const
-{
-    return !(*this == ch);
-}
-
-bool UniChar::operator<(const UniChar& ch) const
-{
-    return code_ < ch.code_;
-}
-
-bool UniChar::operator>(const UniChar& ch) const
-{
-    return code_ > ch.code_;
-}
-
-bool unicode::UniChar::operator==(unicode::unicode_t ch) const
-{
-    return ch == code_;
-}
-
-bool unicode::UniChar::operator!=(unicode::unicode_t ch) const
-{
-    return !(*this == ch);
-}
-
-bool UniChar::operator<(unicode_t ch) const
-{
-    return code_ < ch;
-}
-
-bool UniChar::operator>(unicode_t ch) const
-{
-    return code_ > ch;
-}
-
-void unicode::UniChar::swap(unicode::UniChar& ch)
-{
-    // 値と標準コンテナなので、特に問題なく動作する。
-    std::swap(code_, ch.code_);
-}
-
-bool unicode::is_ascii(const UniChar& ch)
-{
-    // 0x7f >= ascii >= 0x00 がasciiなので、その範囲で判定を行う。
-    return ch.getRawCode() >= 0 && ch.getRawCode() <= 0x7f ? true : false;
-}
-
-bool unicode::is_numeric(const UniChar& ch)
-{
-    return '0' <= ch.getRawCode() && ch.getRawCode() <= '9' ? true : false;
-}
-
-bool unicode::is_alpha(const UniChar& ch)
-{
-    // 通常のアルファベットであるかどうかを判別する。
-    // 大文字、小文字は問わない。
-    if (('a' <= ch.getRawCode() && ch.getRawCode() <= 'z') ||
-        ('A' <= ch.getRawCode() && ch.getRawCode() <= 'Z'))
-    {
-        return true;
-    }
-    return false;
-}
-
-//================================================================================
-
-unicode::UniString::UniString() : chars_()
-{
-}
-
-unicode::UniString::UniString(const UniChar& ch, int num) : chars_()
-{
-    chars_.assign(num, ch);
-}
-
-unicode::UniString::UniString(
-    const UniString& str) : chars_(str.chars_)
-{
-}
-
-void UniString::assign(const unicode::UniChar& ch, int num)
-{
-    UniString tmp(ch, num);
-    swap(tmp);
-}
-
-void UniString::assign(const UniString& str)
-{
-    //基本的に=で渡した場合と全く同じなので、そのようにする。
-    UniString tmp(str);
-    swap(tmp);
-}
+#include <vector>
+#include "src/unicode.h"
 
-UniString& UniString::operator=(const UniString& str)
-{
-    assign(str);
-    return *this;
-}
+namespace unicode = utakata::unicode;
 
-void UniString::swap(UniString& str)
-{
-    // シンプルにswapを行う。
-    std::swap(chars_, str.chars_);
+// 宣言のコメントを参照してください。
+void unicode::UniString::Assign(const unicode::UniChar& ch, int num) {
+  unicode::UniString tmp(ch, num);
+  Swap(tmp);
 }
 
-UniString& UniString::operator+=(const UniString& str)
-{
-    // 一度コピーと加算してから実際にswapさせる。
-    UniString tmp(str);
-    chars_.insert(chars_.end(), tmp.chars_.begin(), tmp.chars_.end());
-    return *this;
+// 宣言のコメントを参照してください。
+void unicode::UniString::Assign(const UniString& str) {
+  unicode::UniString tmp(str);
+  Swap(tmp);
 }
 
-UniString& UniString::operator+=(const UniChar& ch)
-{
-    // 実際には文字を設定するのに利用される。
-    // また、これを定義しておくことで、streamからの結果を直接設定することができる。
-    UniString tmp(*this);
-    tmp.push_back(ch);
-    swap(tmp);
-    return *this;
+// 宣言のコメントを参照してください。
+unicode::UniString& unicode::UniString::operator=(
+    const unicode::UniString& str) {
+  Assign(str);
+  return *this;
 }
 
-void UniString::insert(UniString::iterator it, UniString::iterator begin,
-                       UniString::iterator last)
-{
-    // 渡されたのは実際にはvectorのイテレータなので、
-    // そのままvectorの実装に任せることができる。
-    chars_.insert(it, begin, last);
+// 宣言のコメントを参照してください。
+void unicode::UniString::Append(const unicode::UniString& str) {
+  unicode::UniString tmp(str);
+  unicode_chars_.insert(unicode_chars_.end(),
+                        tmp.unicode_chars_.begin(), tmp.unicode_chars_.end());
 }
 
-void UniString::insert(UniString::iterator it,
-                       UniString::const_iterator begin,
-                       UniString::const_iterator last)
-{
-    // 渡されたのがconstであるかどうかというだけの違いであるため、
-    // そのまま渡すことができる。
-    chars_.insert(it, begin, last);
+// 宣言のコメントを参照してください。
+void unicode::UniString::Append(const unicode::UniChar& ch) {
+  unicode_chars_.push_back(ch);
 }
 
-void UniString::push_back(const UniChar& ch)
-{
-    // 単純に内部の配列のpush_backを呼びだすのみで完了する。
-    chars_.push_back(ch);
+// 宣言のコメントを参照してください。
+void unicode::UniString::Append(const std::string& str) {
+  std::string::const_iterator it = str.begin(), end = str.end();
+  for (; it != end; ) {
+    unicode_chars_.push_back(unicode::UniChar(*it++));
+  }
 }
 
-bool UniString::operator==(const UniString& str) const
-{
-    return chars_ == str.chars_;
+// 渡されるのはstd::vectorのイテレータとなっていますので、そのまま
+// 設定することができます。
+void unicode::UniString::Insert(unicode::UniString::iterator it,
+                                unicode::UniString::iterator begin,
+                                unicode::UniString::iterator last) {
+  unicode_chars_.insert(it, begin, last);
 }
 
-//================================================================================
-
-unicode::UniString unicode::substring(
-    const unicode::UniString& str, size_t begin, size_t end)
-{
-    if (end == 0)
-    {
-        // 先頭から末尾までを取得する。
-        UniString s;
-        s.insert(s.begin(), str.begin() + begin, str.end());
-        return s;
-    }
-    else if (begin <= end)
-    {
-        UniString s;
-        s.insert(s.begin(), str.begin() + begin, str.begin() + (begin + end));
-        return s;
-    }
-    else
-    {
-        throw range_error("out of range in unicode::substring");
-    }
+void unicode::UniString::Insert(unicode::UniString::iterator it,
+                       unicode::UniString::const_iterator begin,
+                       unicode::UniString::const_iterator last) {
+  unicode_chars_.insert(it, begin, last);
 }
 
-UniString unicode::operator+(const UniString& lh, const UniString& rh)
-{
-    // 双方をコピーして加算して返す。凄い負荷が高い。
-    UniString str(lh);
-    str += rh;
-    return str;
+// 宣言のコメントを参照してください。
+bool unicode::UniString::operator==(const unicode::UniString& str) const {
+  return unicode_chars_ == str.unicode_chars_;
 }
 
-UniString unicode::operator+(const UniString& lh, const UniChar& rh)
-{
-    // 文字と加算する。
-    UniString tmp(lh);
-    tmp += rh;
-    return tmp;
+// 宣言のコメントを参照してください。
+unicode::UniString unicode::Substring(
+    const unicode::UniString& str, unsigned int begin) {
+  unicode::UniString s;
+  s.Insert(s.Begin(), str.Begin() + begin, str.End());
+  return s;
 }
 
-UniString unicode::operator+(const UniChar& lh, const UniString& rh)
-{
-    UniString tmp(lh, 1);
-    tmp += rh;
-    return tmp;
-}
-
-UniString unicode::convert(const std::vector<unsigned long>& c)
-{
-    // 渡されたunsigned longの配列をUniCharの配列であるUniStringに
-    // 変換する。
-    UniString s;
-    std::vector<unsigned long>::const_iterator it = c.begin(), end = c.end();
-    for (; it != end; ++it)
-    {
-        s += UniChar(*it);
-    }
-    return s;
-}
+// 宣言のコメントを参照してください。
+unicode::UniString unicode::Substring(
+    const unicode::UniString& str, unsigned int begin, unsigned int end) {
+  if (begin > end) {
+    return unicode::UniString();
 
-UniString unicode::convert(const std::string& c)
-{
-    // 渡された文字列がasciiであることを前提として、データの設定を行なう。
-    UniString s;
-    std::string::const_iterator it = c.begin(), end = c.end();
-    for (; it != end; ++it)
-    {
-        s += UniChar(*it);
-    }
+  } else {
+    unicode::UniString s;
+    s.Insert(s.Begin(), str.Begin() + begin, str.Begin() + (begin + end));
     return s;
+  }
+}
+
+// 宣言のコメントを参照してください。
+unicode::UniString unicode::Convert(
+    const std::vector<unsigned int>& byte_list) {
+  unicode::UniString s;
+  std::vector<unsigned int>::const_iterator it = byte_list.begin(),
+      end = byte_list.end();
+  for (; it != end;) {
+    s.Append(UniChar(*it++));
+  }
+  return s;
+}
+
+// 宣言のコメントを参照してください。
+unicode::UniString unicode::Convert(const std::string& target) {
+  unicode::UniString s;
+  std::string::const_iterator it = target.begin(), end = target.end();
+  for (; it != end; ++it) {
+    s.Append(UniChar(*it++));
+  }
+  return s;
 }
index 2cc6f64..2287534 100755 (executable)
-#ifndef _UNICODE_H_
-#define _UNICODE_H_
+// utakataで利用される、Unicode文字及び文字列を統合して扱うことが
+// 可能である、Unicodeオブジェクトを定義します。
+// UniCharは、Unicode文字1文字に対応し、各種オペレータオーバロードを
+// 提供し、組込型と同様な利用ができるようになっています。
+// UniStringは、UniCharを集めたUnicode文字列を表現し、UniChar単位での
+// 文字列操作を提供します。
+#ifndef _UTAKATA_SRC_UNICODE_H_
+#define _UTAKATA_SRC_UNICODE_H_
 
 #include <vector>
-#include <functional>
+#include <algorithm>
 #include <string>
-#include <exception>
 
 namespace utakata {
+namespace unicode {
 
-// CUniCharの作成と、CUniCharのコンテナであるCUniStringを定義する。
+typedef unsigned int unicode_t;
 
-    namespace unicode {
-
-        // 内部で利用されるunicodeスカラー値の型。
-        typedef unsigned long unicode_t;
-
-        class range_error : public std::exception
-        {
-        public:
-            range_error(const std::string& str) : str_(str) {}
-            virtual ~range_error() throw() {}
-
-            const char* what() throw() {
-                return str_.c_str();
-            }
-        private:
-
-            std::string str_;
-        };
-    
-        class UniChar
-        {
-            // schemeにおけるunicodeスカラー値一つ分を表す。
-            // スカラー値はunsigned longで保持され、基本的には構造体のように
-            // 振る舞う。
-        public:
-
-            // デフォルトではnul(0x0000)が指定される。
-            UniChar();
-            virtual ~UniChar(){}
-
-            // コピーコンストラクタを宣言したため、同時にoperator=を宣言する。
-            UniChar(const UniChar& ch);
-            UniChar(unicode_t code);
-            UniChar& operator=(const UniChar& ch);
-            UniChar& operator=(unicode_t ch);
-
-            // 各演算子のオーバーロード。
-            // <=と>=は、それぞれ>の結果のnot、<の結果のnotを
-            // 用いることで実装できるため、この二つだけ供えていれば問題ない。
-            bool operator==(const UniChar& code) const;
-            bool operator<(const UniChar& code) const;
-            bool operator>(const UniChar& code) const;
-            bool operator!=(const UniChar& code) const;
-
-            bool operator!=(unicode_t code) const;
-            bool operator==(unicode_t code) const;
-            bool operator<(unicode_t code) const;
-            bool operator>(unicode_t code) const;
-
-            // 内部で保持しているコードを返す。
-            unicode_t getRawCode() const {return this->code_;}
+class UniChar {
+  // Unicode一文字を表現するためのオブジェクトです。
+  // unicodeはunsigned intで表現され、組込型と同様の利用ができるように
+  // 設計されています。
+  // 各operator overloadは、同様の機能を提供する各関数によって機能が
+  // 実装されており、各operator overloadを利用しないことも可能です。
+ public:
 
-        private:
-
-            // 渡されたUniCharの内部と交換する。
-            void swap(UniChar& ch);
-
-            unicode_t code_;
-        };
-
-        // 各unicode用変換用の関数群。
-
-        // 渡されたUniCharがasciiコードの範囲内に収まっているかどうかを返す。
-        bool is_ascii(const UniChar& ch);
-
-        // 渡されたUniCharが、それぞれ数値、アルファベットであるかどうか
-        // を返す。これらはutf8モジュールのユーティリティ関数によって実装される。
-        bool is_numeric(const UniChar& ch);
-        bool is_alpha(const UniChar& ch);
+  UniChar() : rawcode_(0x0000) {}
+  virtual ~UniChar() {}
 
-        //================================================================================
+  UniChar(const UniChar& ch) : rawcode_(ch.rawcode_) {}
+  explicit UniChar(unicode_t code) : rawcode_(code) {}
 
-        class UniString
-        {
-            // UniCharを複数連結して保持するためのコンテナ
-            // 相互での比較などもサポートし、utakataの内部全般で
-            // 標準として使用することが可能なものとし、かつ標準コンテナと
-            // ほぼ同様の処理を行うことができるように定義されている。
-            // というか内部では単純なvectorで定義されているため、
-            // typedefされた型を指定するだけで、イテレータとして利用可能。
+  UniChar& operator=(const UniChar& ch) {
+    UniChar tmp(ch);
+    swap(tmp);
+    return *this;
+  }
 
-        public:
+  // 渡されたUniCharの内部コードと等しければtrueを返します。
+  bool Equal(const UniChar& code) const {return rawcode_ == code.rawcode_;}
 
-            // イテレータとして簡単に利用するためのtypedefマクロ
-            typedef std::vector<UniChar>::iterator iterator;
-            typedef std::vector<UniChar>::const_iterator const_iterator;
+  // 渡されたUniCharの内部コードと異なっていればtrueを返します。
+  bool NotEqual(const UniChar& code) const {return !Equal(code);}
 
-        public:
+  // 渡されたUniCharの内部コードより小さければtrueを返します。
+  bool Less(const UniChar& code) const {return rawcode_ < code.rawcode_;}
 
-            UniString();
-            // 第一引数のchをnum個数分設定する。
-            UniString(const UniChar& ch, int num);
-            UniString(const UniString& str);
-            virtual ~UniString(){}
+  // 渡されたUniCharの内部コード以下であればtrueを返します。
+  bool LessEqual(const UniChar& code) const {return Less(code) || Equal(code);}
 
-            // 実体に代入する。代入が行われなかった場合、元のデータ
-            // は保存される。
-            void assign(const UniChar& ch, int num);
-            void assign(const UniString& str);
+  // 渡されたUniCharの内部コードより大きければtrueを返します。
+  bool Greater(const UniChar& code) const {return code.Less(code);}
 
-            // iteratorを取得する。
-            const_iterator begin() const {return chars_.begin();}
-            iterator begin() {return chars_.begin();}
-
-            // 末尾のイテレータを取得する。
-            const_iterator end() const {return chars_.end();}
-            iterator end() {return chars_.end();}
-
-            // []をオーバーロードする。これは常に境界のチェックを行う。
-            const UniChar& operator[](size_t t) const {return chars_.at(t);}
-            UniChar& operator[](size_t t) {
-                return const_cast<UniChar&>(
-                    static_cast<const UniString*>(this)->chars_[t]);}
-
-            // サイズを取得する。
-            size_t size() const {return chars_.size();}
-            // 空かどうかを調べる。
-            bool empty() const {return chars_.empty();}
-
-            // 安全なswapと共に提供する。
-            UniString& operator=(const UniString& str);
+  // 渡されたUniCharの内部コード以上であればtrueを返します。
+  bool GreaterEqual(const UniChar& code) const {
+    return Greater(code) || Equal(code);
+  }
 
-            // 加算のみをサポートする。
-            UniString& operator+=(const UniString& str);
-            UniString& operator+=(const UniChar& ch);
-            UniString& operator+=(const std::string& str);
+  // Equalのコメントを参照してください。
+  bool operator==(const UniChar& code) const {return Equal(code);}
+  bool operator==(unicode_t code) const {return Equal(UniChar(code));}
 
-            bool operator==(const UniString& str) const;
-            bool operator!=(const UniString& str) const {
-                return !(*this == str);
-            }
+  // NotEqualのコメントを参照してください。
+  bool operator!=(const UniChar& code) const {return NotEqual(code);}
+  bool operator!=(unicode_t code) const {return NotEqual(UniChar(code));}
 
-            // 渡したイテレータの範囲を追加する
-            // beginとlastは同一のUniStringから取得されたものであること。
-            void insert(iterator it, iterator begin, iterator last);
-            void insert(iterator it, const_iterator begin,
-                        const_iterator last);
+  // Lessのコメントを参照してください。
+  bool operator<(const UniChar& code) const {return Less(code);}
+  bool operator<(unicode_t code) const {return Less(UniChar(code));}
 
-            // UniCharを単体で末尾に追加する。
-            void push_back(const UniChar& ch);
+  // LessEqualのコメントを参照してください。
+  bool operator<=(const UniChar& code) const {return LessEqual(code);}
+  bool operator<=(unicode_t code) const {return LessEqual(UniChar(code));}
 
-        private:
+  // Greaterのコメントを参照してください。
+  bool operator>(const UniChar& code) const {return Greater(code);}
+  bool operator>(unicode_t code) const {return Greater(UniChar(code));}
 
-            void swap(UniString& str);
+  // GreaterEqualのコメントを参照してください。
+  bool operator>=(const UniChar& code) const {return GreaterEqual(code);}
+  bool operator>=(unicode_t code) const {return GreaterEqual(UniChar(code));}
 
-            std::vector<UniChar> chars_;
-        };
+  // 内部で保持している、実際のunicodeの値を返します。
+  unicode_t rawcode() const {return rawcode_;}
 
-        UniString operator+(const UniString& lh, const UniString& rh);
-        UniString operator+(const UniString& lh, const UniChar& rh);
-        UniString operator+(const UniChar& lh, const UniString& rh);
+ private:
 
-        // substringの実装を行う
-        // [begin, end)までの文字を文字列として返す。
-        // endが渡されないか、0が渡された場合、beginから末尾までが返される。
-        UniString substring(const UniString& str, size_t begin, size_t end = 0);
+  // 渡されたchのrawcodeを交換します
+  void swap(UniChar& ch) {
+    std::swap(rawcode_, ch.rawcode_);
+  }
 
-        // 渡したunsigned longの配列をUniCharの配列であるUniStringに変換する。
-        UniString convert(const std::vector<unsigned long>& d);
-        // 渡したstringが、全てascii文字列であることを前提として、データの
-        // 設定を行う。
-        UniString convert(const std::string& d);
+  unicode_t rawcode_;
+};
+
+// 渡されたUniCharが、ascii文字の範囲内である場合、trueを返します。
+inline bool IsAscii(const UniChar& unichar) {
+  return unichar.rawcode() >= 0 && unichar.rawcode() <= 0x7F;
+}
+
+// 渡されたUniCharが、数値項目に該当しているかを返します。
+inline bool IsNumeric(const UniChar& unichar) {
+  return '0' <= unichar.rawcode() && unichar.rawcode() <= '9';
+}
+
+// 渡されたUniCharが、アルファベットに該当しているかどうかを返します。
+// 大文字小文字は区別しません。
+inline bool IsAlphabet(const UniChar& unichar) {
+  return ('a' <= unichar.rawcode() && unichar.rawcode() <= 'z') ||
+      ('A' <= unichar.rawcode() && unichar.rawcode() <= 'Z');
+}
+
+class UniString {
+  // UniCharを連結したコンテナのラッパーとして機能し、擬似的な
+  // Unicode文字列を提供します。
+  // 相互での比較などもサポートし、utakataの内部全般で
+  // 標準として使用することが想定されています。
+  // また、内部へのiteratorを取得することができるため、標準
+  // アルゴリズムを利用することができます。
+ public:
+  // 内部で利用されるiteratorを定義します。
+  typedef std::vector<UniChar>::iterator iterator;
+  typedef std::vector<UniChar>::const_iterator const_iterator;
+
+  UniString() : unicode_chars_() {}
+  // 第一引数のchをnum個数分設定する。
+  UniString(const UniChar& ch, int num) : unicode_chars_(num, ch) {}
+  UniString(const UniString& str) : unicode_chars_(str.unicode_chars_) {}
+  virtual ~UniString() {}
+
+  // 渡されたUniCharを、numだけ連続した文字列を代入します。
+  // assignでは、代入前の値は破棄されます。
+  void Assign(const UniChar& ch, int num);
+
+  // 渡したUniStringをコピーします。コピー前の値は破棄されます。
+  void Assign(const UniString& str);
+
+  // 文字列の先頭を指すiteratorを取得します。
+  const_iterator Begin() const {return unicode_chars_.begin();}
+  iterator Begin() {return unicode_chars_.begin();}
+
+  // 文字列の末尾を指すiteratorを取得します。
+  const_iterator End() const {return unicode_chars_.end();}
+  iterator End() {return unicode_chars_.end();}
+
+  // 指定したインデックスのデータを取得します。
+  // インデックスが有効では無い場合、std::range_error例外が
+  // 発生します。
+  const UniChar& At(size_t index) const {return unicode_chars_.at(index);}
+  UniChar& At(size_t index) {
+    return const_cast<UniChar&>(
+        static_cast<const UniString*>(this)->At(index));
+  }
+
+  // 現在の文字列のサイズを取得します。
+  size_t GetSize() const {return unicode_chars_.size();}
+
+  // 文字列が空である場合にtrueを返します。
+  bool IsEmpty() const {return unicode_chars_.empty();}
+
+  // 渡されたUniStringをコピーします。
+  UniString& operator=(const UniString& str);
+
+  // 渡されたデータを、それぞれUniStringの末尾に追加します。
+  void Append(const UniString& str);
+  void Append(const UniChar& ch);
+
+  // 渡されたstd::stringを、UniStringの末尾に追加します。
+  // std::stringは、全てasciiであるとして、一文字がUniChar一つに
+  // 変換されて渡されます。
+  void Append(const std::string& str);
+
+  // 渡されたUniStringと内容が完全に一致している場合trueを返します。
+  // ここでの完全一致とは、文字列長と文字列の内容が完全に一致している
+  // 事を示します。
+  bool operator==(const UniString& str) const;
+
+  // 渡されたUniStringと内容が不一致である場合にtrueを返します。
+  bool operator!=(const UniString& str) const {return !(*this == str);}
+
+  // itの位置に、[begin, last)のデータを挿入します。
+  // beginとlastが異なるUniStringのiteratorであってはなりません。
+  void Insert(iterator It, iterator begin, iterator Last);
+  void Insert(iterator it, const_iterator begin,
+              const_iterator last);
+
+ private:
+
+  // 渡されたUniStringのデータを入れ替えます。
+  void Swap(UniString& str) {std::swap(unicode_chars_, str.unicode_chars_);}
+
+  // UniCharのコンテナです。擬似的な文字列を表現します。
+  std::vector<UniChar> unicode_chars_;
+};
 
+// 渡されたUnicodeから、beginの位置から末尾までの文字列をUniStringで返します。
+// beginが有効範囲外であった場合、std::range_eror例外が発生します。
+UniString Substring(const UniString& str, unsigned int begin);
 
-    };
+// 渡されたUnicodeから、[begin, end)の範囲の文字列を取得します。
+// beginがend以降であったり、endがbegin以前である場合、空のUniStringが
+// 返されます。
+// begin、endのいずれかが有効範囲外であった場合、std::range_error例外が
+// 発生します。
+UniString Substring(const UniString& str, unsigned int begin, unsigned int end);
 
+// 渡されたunicode_tの配列を、一要素が一UniCharであるとしてUniStringを作成
+// して返します。
+UniString Convert(const std::vector<unicode_t>& byte_list);
+
+// 渡したstd::stringを、一文字を一UniCharであるとしてUniStringを作成して
+// 返します。std::stringのエンコードは無視されます。
+UniString Convert(const std::string& target);
+};
 };
 
-#endif /* _UNICODE_H_ */
+#endif /* _UTAKATA_SRC_UNICODE_H_ */
index 0210ffd..82e21d1 100755 (executable)
@@ -1,5 +1,5 @@
 #include <algorithm>
-
+#include <vector>
 #include "src/reader_interface.h"
 #include "src/utf8_transcoder.h"
 
@@ -21,7 +21,6 @@ unsigned int trans::UTF8Transcoder::Encode(reader::IReader* reader) {
       for (int i = 0; i < utf8_size; ++i) {
         utf8_bytes.push_back(reader->Read());
       }
-
       return GenerateUnicode(utf8_bytes);
     }
   }
@@ -74,20 +73,22 @@ std::vector<unsigned int> trans::UTF8Transcoder::Decode(unsigned int unicode) {
 //   y1〜yN = utf8の先頭バイト以降のバイトを順番
 //   N = utf8の先頭バイトを含むバイト数
 // としたとき、Unicodeの文字とした場合、
-//   code = (y1 & ((1 << 7) - 1)) << (6 * n-1) + (y2 & ((1 << 7) -1)) << (6 * (n - 1))...+ x & ((1 << N) -1) << (6 * N-1)
+//   code = (y1 & ((1 << 7) - 1)) << (6 * n-1) +
+//          (y2 & ((1 << 7) -1)) << (6 * (n - 1))
+//          ...+ x & ((1 << N) -1) << (6 * N-1)
 // という形でUnicodeを生成します。
 unsigned int trans::UTF8Transcoder::GenerateUnicode(
     const std::vector<unsigned int>& bytes) {
-  if (bytes.size() == 1){
+  if (bytes.size() == 1) {
     return bytes[0] & kByteMaxValue;
 
   } else {
     std::vector<unsigned int> expecting_first(bytes.begin() + 1, bytes.end());
-    std::vector<unsigned int>::const_reverse_iterator begin = expecting_first.rbegin(),
-        end = expecting_first.rend();
+    std::vector<unsigned int>::const_reverse_iterator begin =
+        expecting_first.rbegin(), end = expecting_first.rend();
 
     unsigned int code = 0;
-    for (int i = 0; begin != end; ++i,++begin) {
+    for (int i = 0; begin != end; ++i, ++begin) {
       code += SamplingUTF8Data(*begin, i);
     }
 
index 5a67bc8..4b03eec 100755 (executable)
@@ -44,7 +44,8 @@ class UTF8Transcoder : public ITranscoder {
   // 1バイトの最大値を表します。16進数で表わした場合、0x7Fとなります。
   const unsigned int kByteMaxValue;
 
-  // Unicodeとして認識可能な最大値を表します。16進数での表現は、0x110000となります。
+  // Unicodeとして認識可能な最大値を表します。16進数での表現は、
+  // 0x110000となります。
   const unsigned int kExternalCodeLimit;
 
   // 先頭バイト以外のUTF8のバイト列からデータを抽出する際のサンプリングを
@@ -71,7 +72,6 @@ class UTF8Transcoder : public ITranscoder {
   // 正しいフォーマットでは無い場合、utf8_sizeは編集されません。
   // utf8_sizeには有効なポインタを渡さなければなりません。
   bool IsUTF8FirstByte(int check_byte, int* utf8_size);
-
 };
 };
 };