diff options
Diffstat (limited to 'ml/dlib/dlib/iosockstream/iosockstream.h')
-rw-r--r-- | ml/dlib/dlib/iosockstream/iosockstream.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/ml/dlib/dlib/iosockstream/iosockstream.h b/ml/dlib/dlib/iosockstream/iosockstream.h new file mode 100644 index 00000000..e49d2e37 --- /dev/null +++ b/ml/dlib/dlib/iosockstream/iosockstream.h @@ -0,0 +1,171 @@ +// Copyright (C) 2012 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_IOSOCKSTrEAM_Hh_ +#define DLIB_IOSOCKSTrEAM_Hh_ + +#include "iosockstream_abstract.h" + +#include <iostream> +#include <memory> + +#include "../sockstreambuf.h" +#include "../timeout.h" + +#ifdef _MSC_VER +// Disable the warning about inheriting from std::iostream 'via dominance' since this warning is a warning about +// visual studio conforming to the standard and is ignorable. +// See http://connect.microsoft.com/VisualStudio/feedback/details/733720/inheriting-from-std-fstream-produces-c4250-warning +// for further details if interested. +#pragma warning(disable : 4250) +#endif // _MSC_VER + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + class iosockstream : public std::iostream + { + public: + + iosockstream( + ) : + std::iostream(0) + { + } + + iosockstream( + const network_address& addr + ) : + std::iostream(0) + { + open(addr); + } + + iosockstream( + const network_address& addr, + unsigned long timeout + ) : + std::iostream(0) + { + open(addr, timeout); + } + + ~iosockstream() + { + close(); + } + + void open ( + const network_address& addr + ) + { + auto_mutex lock(class_mutex); + close(); + con.reset(connect(addr)); + buf.reset(new sockstreambuf(con.get())); + // Note that we use the sockstreambuf's ability to autoflush instead of + // telling the iostream::tie() function to tie the stream to itself even though + // that should work fine. The reason we do it this way is because there is a + // bug in visual studio 2012 that causes a program to crash when a stream is + // tied to itself and then used. See + // http://connect.microsoft.com/VisualStudio/feedback/details/772293/tying-a-c-iostream-object-to-itself-causes-a-stack-overflow-in-visual-studio-2012 + // for further details. + buf->flush_output_on_read(); + rdbuf(buf.get()); + clear(); + } + + void open ( + const network_address& addr, + unsigned long timeout + ) + { + auto_mutex lock(class_mutex); + close(timeout); + con.reset(connect(addr.host_address, addr.port, timeout)); + buf.reset(new sockstreambuf(con.get())); + buf->flush_output_on_read(); + rdbuf(buf.get()); + clear(); + } + + void close( + unsigned long timeout = 10000 + ) + { + auto_mutex lock(class_mutex); + rdbuf(0); + try + { + if (buf) + { + dlib::timeout t(*con,&connection::shutdown,timeout); + + // This will flush the sockstreambuf and also destroy it. + buf.reset(); + + if(con->shutdown_outgoing()) + { + // there was an error so just close it now and return + con->shutdown(); + } + else + { + char junk[100]; + // wait for the other end to close their side + while (con->read(junk,sizeof(junk)) > 0); + } + } + } + catch (...) + { + con.reset(); + throw; + } + con.reset(); + } + + void terminate_connection_after_timeout ( + unsigned long timeout + ) + { + auto_mutex lock(class_mutex); + if (con) + { + con_timeout.reset(new dlib::timeout(*this,&iosockstream::terminate_connection,timeout,con)); + } + } + + void shutdown ( + ) + { + auto_mutex lock(class_mutex); + if (con) + con->shutdown(); + } + + private: + + void terminate_connection( + std::shared_ptr<connection> thecon + ) + { + thecon->shutdown(); + } + + std::unique_ptr<timeout> con_timeout; + rmutex class_mutex; + std::shared_ptr<connection> con; + std::unique_ptr<sockstreambuf> buf; + + }; + +// ---------------------------------------------------------------------------------------- + +} + + +#endif // DLIB_IOSOCKSTrEAM_Hh_ + + |