/////////////////////////////////////////////////////////////////////////////// // // InputStream / OutputStream の実装例 // // classes.hpp の FileDescriptor を用いた // 単純なファイルストリーム #ifndef KMLIB_FSTREAM_H_ #define KMLIB_FSTREAM_H_ #include "stream.hpp" #include "classes.hpp" /////////////////////////////////////////////////////////////////////////////// #define BAD_ALLOC() "bad alloc" #define NULL_POINTER_EXCEPTION() "null pointer exception" /////////////////////////////////////////////////////////////////////////////// class FileInputStream: public InputStream { FileDescriptor *file_; public: //=========================================================================== /*! コンストラクタ * @param fname ファイル名 * @param ex ファイルが存在する場合の挙動 -- デフォルトは「開く」 * @param ne ファイルが存在しない場合の挙動 -- デフォルトは「エラー」 * @exception bad_alloc new に失敗した場合 * @exception ... 他,FileDescriptor コンストラクタに記述された例外 */ FileInputStream(const char *fname, FileDescriptor::IfExists ex = FileDescriptor::exOPEN, FileDescriptor::IfNotExists ne = FileDescriptor::neERROR) { file_ = 0; try { file_ = new FileDescriptor(fname, FileDescriptor::mdREAD, ex, ne ); if (!file_) throw BAD_ALLOC(); } catch(...) { file_ = 0; throw; } } //=========================================================================== //! オブジェクトが正常なものかどうかを調べる -- overrides InputStream::isValid() const bool isValid() const { return ((file_ != 0) && file_->isValid()); } //=========================================================================== //! デストラクタ ~FileInputStream() { delete file_; } //=========================================================================== //! ファイルを読む unsigned long read(void *buf, unsigned long size) { if (! file_) throw NULL_POINTER_EXCEPTION(); return file_->read(buf, size); } //=========================================================================== /*! ファイルハンドルを得る * FileDescriptor クラスや FileInputStream クラスでサポートしていない API を * 呼び出すために使う */ FileHandle getHandle() { if (!file_) throw NULL_POINTER_EXCEPTION(); return file_->getHandle(); } }; /////////////////////////////////////////////////////////////////////////////// /*! ファイルに書き込む */ class FileOutputStream : public OutputStream { FileDescriptor *file_; public: //=========================================================================== /*! コンストラクタ * @param fname ファイル名 * @param ex ファイルが存在する場合の挙動 -- デフォルトで「開く」 * @param ne ファイルが存在しない場合の挙動 -- デフォルトで「新規作成」 */ FileOutputStream(const char *fname, FileDescriptor::IfExists ex = FileDescriptor::exOPEN, FileDescriptor::IfNotExists ne = FileDescriptor::neCREATE) { file_ = 0; try { file_ = new FileDescriptor(fname, FileDescriptor::mdWRITE, ex, ne); if (!file_) throw BAD_ALLOC(); } catch(...) { file_ = 0; throw; } } //=========================================================================== //! オブジェクトが正常なものかどうかを調べる -- overrides OutputStream::isValid() const bool isValid() const { return ((file_ != 0) && file_->isValid()); } //=========================================================================== //! デストラクタ ~FileOutputStream() { delete file_; } //=========================================================================== //! ファイルに書き込み unsigned long write(const void *buf, unsigned long size ) { if (! file_) throw NULL_POINTER_EXCEPTION(); return file_->write(buf, size); } //=========================================================================== /*! ファイルハンドルを得る * ファイルハンドルを使う API を呼び出すために使う * 中身は HANDLE 型だったり FILE * 型だったり <- FileDescriptor の実装による */ FileHandle getHandle() { if (! file_) throw NULL_POINTER_EXCEPTION(); return file_->getHandle(); } }; #undef BAD_ALLOC #undef NULL_POINTER_EXCEPTION #endif // KMLIB_FSTREAM_H_