// // // // // Lab. Calcolo II - Esempio di codice // // // // // // // "C++ in a nutshell" basic_networkbuf class tempate #ifndef NETSTREAM_H #define NETSTREAM_H #include <fstream> #include <ios> #include <locale> #include <streambuf> #include <string> #include "basic_networkstream.hpp" template<typename charT, typename traits = ::std::char_traits<char> > class basic_networkbuf : public ::std::basic_streambuf<charT, traits> { public: typedef charT char_type; typedef traits traits_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; basic_networkbuf(); virtual ~basic_networkbuf(); bool is_connected(); const std::string &caller() const; basic_networkbuf* connect(const char* hostname, int port, ::std::ios_base::openmode mode); basic_networkbuf* connect(int listen_fd, ::std::ios_base::openmode mode); basic_networkbuf* disconnect(); protected: virtual ::std::streamsize showmanyc(); virtual int_type underflow(); virtual int_type overflow(int_type c = traits::eof()); virtual basic_networkbuf* setbuf(char_type* buf, ::std::streamsize size); virtual int sync(); virtual void imbue(const ::std::locale&); virtual pos_type seekoff(off_type offset, ::std::ios_base::seekdir dir, ::std::ios_base::openmode mode); virtual pos_type seekpos(pos_type sp, ::std::ios_base::openmode mode); private: char_type* buffer_; ::std::streamsize size_; bool ownbuf_; static const int DEFAULT_BUFSIZ = 1024; basic_networkstream<charT, traits> f; }; template<typename charT, typename traits> basic_networkbuf<charT,traits>::basic_networkbuf() : buffer_(new char_type[DEFAULT_BUFSIZ]), size_(DEFAULT_BUFSIZ), ownbuf_(true) { this->setg(buffer_, buffer_ + size_, buffer_ + size_); this->setp(buffer_, buffer_ + size_); } template<typename charT, typename traits> basic_networkbuf<charT,traits>::~basic_networkbuf() { if (ownbuf_) delete[] buffer_; } template<typename charT, typename traits> basic_networkbuf<charT,traits>* basic_networkbuf<charT,traits>::setbuf(char_type* buf, ::std::streamsize size) { if (ownbuf_) { ownbuf_ = false; delete [] buffer_; } buffer_ = buf; size_ = size; this->setg(buffer_, buffer_ + size_, buffer_ + size_); this->setp(buffer_, buffer_ + size_ - 1); return this; } template<typename charT, typename traits> bool basic_networkbuf<charT,traits>::is_connected() { return f.is_open(); } template<typename charT, typename traits> const std::string &basic_networkbuf<charT,traits>::caller() const { return f.caller(); } template<typename charT, typename traits> basic_networkbuf<charT,traits>* basic_networkbuf<charT,traits>::connect(const char* hostname, int port, ::std::ios_base::openmode mode) { f.open(hostname, port, mode); if (f.good()) return this; else return 0; } template<typename charT, typename traits> basic_networkbuf<charT,traits>* basic_networkbuf<charT,traits>::connect(int listen_fd, ::std::ios_base::openmode mode) { f.open(listen_fd, mode); if (f.good()) return this; else return 0; } template<typename charT, typename traits> basic_networkbuf<charT,traits>* basic_networkbuf<charT,traits>::disconnect() { f.close(); if (f.good()) return this; else return 0; } template<typename charT, typename traits> typename basic_networkbuf<charT,traits>::pos_type basic_networkbuf<charT,traits>::seekoff(off_type offset, ::std::ios_base::seekdir dir, ::std::ios_base::openmode mode) { if (offset == 0 && dir == ::std::ios_base::cur) return f.tellg(); else return static_cast<pos_type>(-1); } template<typename charT, typename traits> typename basic_networkbuf<charT,traits>::pos_type basic_networkbuf<charT,traits>::seekpos(pos_type sp, ::std::ios_base::openmode mode) { return static_cast<pos_type>(-1); } template<typename charT, typename traits> ::std::streamsize basic_networkbuf<charT,traits>::showmanyc() { return this->egptr() - this->gptr(); } template<typename charT, typename traits> typename basic_networkbuf<charT,traits>::int_type basic_networkbuf<charT,traits>::underflow() { f.read(buffer_, size_); this->setg(buffer_, buffer_, buffer_ + f.gcount()); if (this->egptr() == this->gptr()) return traits::eof(); else return traits::to_int_type(*this->gptr()); } template<typename charT, typename traits> typename basic_networkbuf<charT,traits>::int_type basic_networkbuf<charT,traits>::overflow(int_type c) { if (c != traits::eof()) { *(this->pptr()) = c; this->pbump(1); } f.write(this->pbase(), this->pptr() - this->pbase()); this->setp(buffer_, buffer_ + size_ - 1); return traits::not_eof(c); } template<typename charT, typename traits> int basic_networkbuf<charT,traits>::sync() { overflow(traits::eof()); f.sync(); return 0; } template<typename charT, typename traits> void basic_networkbuf<charT,traits>::imbue(const ::std::locale&) {} template<typename charT, typename traits = ::std::char_traits<charT> > class basic_netstream : public ::std::basic_iostream<charT,traits> { public: typedef charT char_type; typedef traits traits_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; basic_netstream(const char* hostname, int port, ::std::ios_base::openmode mode = ::std::ios_base::in) : ::std::basic_iostream<charT,traits>(0) { this->init(&sb); connect(hostname, port, mode); } basic_netstream(int listen_socket, ::std::ios_base::openmode mode = ::std::ios_base::in) : ::std::basic_iostream<charT,traits>(0) { this->init(&sb); connect(listen_socket,mode); } basic_netstream(): ::std::basic_iostream<charT,traits>(0) { this->init(&sb); } ~basic_netstream() { if (is_connected()) disconnect(); } void connect(const char* hostname, int port, ::std::ios_base::openmode mode = ::std::ios_base::in) { sb.connect(hostname, port, mode); } void connect(int listen_socket, ::std::ios_base::openmode mode = ::std::ios_base::in) { sb.connect(listen_socket, mode); } void disconnect() { sb.pubsync(); sb.disconnect(); } bool is_connected() { return sb.is_connected(); } const std::string &caller() { return sb.caller(); } private: basic_networkbuf<char_type, traits_type> sb; }; template<typename charT, typename traits = ::std::char_traits<charT> > class basic_onetstream : public ::std::basic_ostream<charT,traits> { public: typedef charT char_type; typedef traits traits_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; basic_onetstream(const char* hostname, int port) : ::std::basic_ostream<charT,traits>(0) { this->init(&sb); sb.connect(hostname, port, ::std::ios_base::out); } basic_onetstream(): ::std::basic_ostream<charT,traits>(0) { this->init(&sb); } ~basic_onetstream() { if (is_connected()) disconnect(); } void connect(const char* hostname, int port) { sb.connect(hostname, port, ::std::ios_base::out); } void disconnect() { sb.pubsync(); sb.disconnect(); } bool is_connected() { return sb.is_connected(); } private: basic_networkbuf<char_type, traits_type> sb; }; template<typename charT, typename traits = ::std::char_traits<charT> > class basic_inetstream : public ::std::basic_istream<charT,traits> { public: typedef charT char_type; typedef traits traits_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; basic_inetstream(const char* hostname, int port) : ::std::basic_istream<charT,traits>(0) { this->init(&sb); sb.connect(hostname, port, ::std::ios_base::in); } basic_inetstream(int listen_socket) : ::std::basic_istream<charT,traits>(0) { this->init(&sb); sb.connect(listen_socket, ::std::ios_base::in); } basic_inetstream(): ::std::basic_istream<charT,traits>(0) { this->init(&sb); } ~basic_inetstream() { if (is_connected()) disconnect(); } void connect(const char* hostname, int port) { sb.connect(hostname, port, ::std::ios_base::in); } void disconnect() { sb.disconnect(); } bool is_connected() { return sb.is_connected(); } const std::string &caller() { return sb.caller(); } private: basic_networkbuf<char_type, traits_type> sb; }; typedef basic_netstream<char> netstream; typedef basic_netstream<wchar_t> wnetstream; typedef basic_inetstream<char> inetstream; typedef basic_inetstream<wchar_t> winetstream; typedef basic_onetstream<char> onetstream; typedef basic_onetstream<wchar_t> wonetstream; #endif // NETSTREAM_H