#ifndef __WIN32_STREAM_HANDLE_HEADER__INCLUDED__ #define __WIN32_STREAM_HANDLE_HEADER__INCLUDED__ #include #include namespace win32 { template > class basic_win32handle_streambuf : public std::basic_streambuf { public: explicit basic_win32handle_streambuf(HANDLE h) : handle(h), bufferSize(1024) { init(); } basic_win32handle_streambuf(HANDLE h, int buffer) : handle(h), bufferSize(buffer) { init(); } virtual ~basic_win32handle_streambuf(); protected: const int bufferSize; void init(); HANDLE handle; }; template > class basic_win32handle_ostreambuf : public basic_win32handle_streambuf { public: explicit basic_win32handle_ostreambuf(HANDLE h) : basic_win32handle_streambuf(h) { init(); } basic_win32handle_ostreambuf(HANDLE h, int buffer) : basic_win32handle_streambuf(h, buffer) { init(); } virtual ~basic_win32handle_ostreambuf(); protected: virtual int_type overflow(int_type c=Tr::eof()) { // バッファがあふれたので書き込みを行う write(); // 下はお決まりらしい。よく知らないw if(c!=Tr::eof()){ // 受け取った文字をバッファに挿入 *pptr()=Tr::to_char_type(c); // バッファの書き込み位置をインクリメント pbump(1); return Tr::not_eof(c); } else { return Tr::eof(); } } virtual int_type sync() { flush(); return 0; } private: Ch* writeBuffer; void write(); void flush(); void init(); }; template > class basic_win32handle_istreambuf : public basic_win32handle_streambuf { public: explicit basic_win32handle_istreambuf(HANDLE h) : basic_win32handle_streambuf(h) { init(); } basic_win32handle_istreambuf(HANDLE h, int buffer) : basic_win32handle_streambuf(h, buffer) { init(); } virtual ~basic_win32handle_istreambuf(); protected: virtual int_type underflow(void) { if(egptr()<=gptr()){ // バッファを使い果たしたので読み込みを行う read(); if(egptr()<=gptr()){ // 結局1バイトも読めなかった return Tr::eof(); } } // 読めたので最初の一個を返す return Tr::to_int_type(*gptr()); } private: Ch* readBuffer; void read(); void init(); }; /** * Win32 HANDLE 版 iostream */ template > class basic_win32handle_istream : public std::basic_istream { public: /** * HANDLE から iostream を構築する */ basic_win32handle_istream(HANDLE h) : std::basic_istream(new basic_win32handle_istreambuf(h)) { } ~basic_win32handle_istream(void) { delete rdbuf(); } private: }; /** * Win32 HANDLE 版 iostream */ template > class basic_win32handle_ostream : public std::basic_ostream { public: /** * HANDLE から iostream を構築する */ basic_win32handle_ostream(HANDLE h) : std::basic_ostream(new basic_win32handle_ostreambuf(h)) { } ~basic_win32handle_ostream(void) { delete rdbuf(); } private: }; template inline void basic_win32handle_ostreambuf::init() { writeBuffer = new Ch[bufferSize]; // 書き込みポインタの設定 // バッファ終端までかけるように setp( writeBuffer, writeBuffer + bufferSize ); } template inline void basic_win32handle_istreambuf::init() { readBuffer = new Ch[bufferSize]; // 読み取りポインタの設定 // 最初は何も読み込んでいない状態 setg( readBuffer, readBuffer + bufferSize, readBuffer + bufferSize ); } /** * basic_win32handle_streambufの初期化を行う */ template inline void basic_win32handle_streambuf::init() { } template inline basic_win32handle_ostreambuf::~basic_win32handle_ostreambuf() { flush(); delete [] writeBuffer; } template inline basic_win32handle_istreambuf::~basic_win32handle_istreambuf() { delete [] readBuffer; } template inline basic_win32handle_streambuf::~basic_win32handle_streambuf() { } /** * 実際にハンドルを使ってバッファを書き出す */ template inline void basic_win32handle_ostreambuf::write() { DWORD ws = (pptr() - pbase()) * sizeof(Ch); DWORD written; BOOL rc = WriteFile(handle, pbase(), ws, &written, NULL); if (FALSE == rc) throw Win32Exception(::GetLastError()); setp(pbase(), epptr()); } /** * 実際にハンドルを使ってバッファに読み込む */ template inline void basic_win32handle_istreambuf::read() { DWORD rs = bufferSize * sizeof(Ch); DWORD readed; BOOL rc = ReadFile(handle, readBuffer, rs, &readed, NULL); if (FALSE == rc) throw Win32Exception(::GetLastError()); setg(readBuffer, readBuffer, readBuffer + readed); } /** * バッファをフラッシュする */ template inline void basic_win32handle_ostreambuf::flush() { // flush する write(); } }; // namespace win32 #endif //__WIN32_STREAM_HANDLE_HEADER__INCLUDED__