--- /dev/null
+// 渡されたファイルから1バイト単位での読み出しを行うクラスを定義します。
+// FileReaderは、渡されたファイルからの1バイト単位での読み出し機能を
+// 提供します。
+//
+// example
+// -------
+// FileReader reader("hoge.txt");
+// reader.read(); // == 'h'
+// reader.peek(); // == 'o'
+// reader.read(); // == 'o'
+// reader.read(2); // == "ge"
+//
+// reader.begin(); reader.seek(1, IReader::kForward);
+// reader.read(); // == 'o'
+// reader.read(2);
+// reader.eof(); // == true
+#ifndef _UTAKATA_SRC_FILE_READER_H_
+#define _UTAKATA_SRC_FILE_READER_H_
+
+#include <string>
+#include "src/reader_interface.h"
+#include "src/common/uncopyable.h"
+
+namespace utakata {
+
+namespace reader {
+
+class FileReader : public IReader, private utility::Uncopyable {
+ // 指定されたファイルを開き、データの読出を行います。
+ // 読み出すデータはコンストラクタでのみ指定することができます。
+ // FileReaderのインスタンス1つにつき、1つのファイルが対応します。
+ //
+ // コンストラクタでファイルがオープンされ、デストラクタでクローズ
+ // されます。
+ // 一度Closeされたファイルは、再度明示的にOpenしない限り再度Read
+ // などを行うことはできません。
+ // CloseされているFileReaderに対してRead、Peek、Seekを行うと、
+ // それぞれreader::IOException例外が発生します。
+ public:
+
+ FileReader() : file_pointer_(NULL), filename_(),
+ pos_(0), file_size_(0) {}
+ explicit FileReader(const std::string& filename)
+ : file_pointer_(NULL), filename_(filename),
+ pos_(0), file_size_(0) {
+ Open();
+ }
+
+ virtual ~FileReader();
+
+ // 現在関連付けられているファイルをOpenします。
+ // すでにオープンされている場合、一度Closeしてから再度開かれます。
+ // 再オープンされた場合、GetPos、GetSizeで返される値は初期化されます。
+ // 正常にファイルをオープンした場合にtrueが返されます。
+ // 正常にファイルがオープンされない場合でも例外は送出されません。
+ bool Open();
+
+ // filenameで指定されたファイルを開きます。
+ // すでにオープンされている場合、前に開かれているファイルをClose
+ // してから、新しいファイルを再度開きます。
+ // 正常にファイルをオープンした場合にtrueが返されます。
+ // 正常にファイルがオープンされない場合でも例外は送出されません。
+ bool Open(const std::string& filename);
+
+ // 現在開いているファイルを閉じます。
+ // ファイルが閉じられている場合、Read、Peek、Seek、Beginを実行すると
+ // 例外が送出されます。
+ void Close();
+
+ // 各種デバイスから一文字読出します。
+ // 末尾に到達してなお読み出しが行われた場合、reader::EndOfDeviceException
+ // 例外を投げなければなりません。
+ // readでは、読み出し位置を更新します。
+ // ファイルがオープンされていない場合には、常に例外が発生します。
+ unsigned char Read();
+ std::vector<unsigned char> Read(size_t num);
+
+ // デバイスから1バイトの読出しを行いますが、内部の読み出し位置は変化
+ // しません。
+ // peekした後、readを行うと、全く同一のバイトが得られます。
+ // ファイルがオープンされていない場合には、常に例外が発生します。
+ unsigned char Peek();
+ std::vector<unsigned char> Peek(size_t num);
+
+ // 現在の読み出し位置を返します。
+ // ファイルがオープンされていない場合、常に0が返されます。
+ size_t GetPos() const;
+
+ // 現在位置から、指定された方向に指定された量だけ読み出し位置を進めます。
+ // 指定された移動量のうち、実際に移動した量を返します。
+ // ファイルがオープンされていない場合には、常に例外が発生します。
+ bool Seek(int seekpos, SeekDirection direciton);
+ bool Seek(int seekpos, SeekDirection direciton, size_t* seek_difference);
+
+ // 読み出し位置を先頭に戻します。
+ // ファイルがオープンされていない場合には、常に例外が発生します。
+ void Begin();
+
+ // 読み出し対象のサイズを返します。
+ // ファイルがオープンされていない場合には、常に0が返されます。
+ size_t GetSize() const;
+
+ // 読み出し位置が末尾であるかどうかを返します。
+ // ファイルがオープンされていない場合には、常にfalseが返されます。
+ bool IsEof() const;
+
+ // FileReaderに関連付けられたファイル名を返します。
+ std::string filename() const {return filename_;}
+
+ // filenameが開かれているか場合、trueを返します。
+ bool IsOpened() const {return file_pointer_ != NULL;}
+
+ private:
+
+ // ファイルの終端であるかどうかのチェックを行い、終端である場合には
+ // 例外を発生させます。
+ void CheckEOF();
+
+ // IsOpened() = trueである場合に、reader::IOExceptionを送出します。
+ void CheckOpened();
+
+
+ // 読出ファイルへのファイルポインタです。
+ // 常にバイナリ読出("wb")でファイルはオープンされます。
+ FILE* file_pointer_;
+
+ // 関連付けられたファイル名を保持します。
+ std::string filename_;
+
+ // ファイルにおける現在の位置を表します。
+ size_t pos_;
+
+ // 渡されたファイルサイズを取得します。最初に一度だけ初期化されます。
+ size_t file_size_;
+};
+};
+};
+
+#endif /* _UTAKATA_SRC_FILE_READER_H_ */