ucommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00017 00024 #if defined(OLD_STDCPP) || defined(NEW_STDCPP) 00025 #ifndef _UCOMMON_STREAM_H_ 00026 #define _UCOMMON_STREAM_H_ 00027 00028 #ifndef _UCOMMON_CONFIG_H 00029 #include <ucommon/platform.h> 00030 #endif 00031 00032 #ifndef _UCOMMON_PROTOCOLS_H_ 00033 #include <ucommon/protocols.h> 00034 #endif 00035 00036 #ifndef _UCOMMON_THREAD_H_ 00037 #include <ucommon/thread.h> 00038 #endif 00039 00040 #ifndef _UCOMMON_SOCKET_H_ 00041 #include <ucommon/socket.h> 00042 #endif 00043 00044 #ifndef _UCOMMON_FSYS_H_ 00045 #include <ucommon/fsys.h> 00046 #endif 00047 00048 #ifndef _UCOMMON_SHELL_H_ 00049 #include <ucommon/shell.h> 00050 #endif 00051 00052 #include <iostream> 00053 00054 namespace ucommon { 00055 00062 class __EXPORT StreamBuffer : protected std::streambuf, public std::iostream 00063 { 00064 protected: 00065 size_t bufsize; 00066 char *gbuf, *pbuf; 00067 00068 StreamBuffer(); 00069 00078 int uflow(); 00079 00080 void release(void); 00081 00082 void allocate(size_t size); 00083 00084 public: 00089 int sync(void); 00090 00091 inline bool is_open(void) 00092 {return bufsize > 0;} 00093 00094 inline operator bool() 00095 {return bufsize > 0;} 00096 00097 inline bool operator!() 00098 {return bufsize == 0;} 00099 }; 00100 00109 class __EXPORT tcpstream : public StreamBuffer 00110 { 00111 private: 00112 __LOCAL void allocate(unsigned size); 00113 __LOCAL void reset(void); 00114 00115 protected: 00116 socket_t so; 00117 timeout_t timeout; 00118 00119 virtual ssize_t _read(char *buffer, size_t size); 00120 00121 virtual ssize_t _write(const char *buffer, size_t size); 00122 00123 virtual bool _wait(void); 00124 00128 void release(void); 00129 00136 int underflow(void); 00137 00144 int overflow(int ch); 00145 00146 inline socket_t getsocket(void) const 00147 {return so;} 00148 00149 public: 00154 tcpstream(const tcpstream& copy); 00155 00162 tcpstream(const TCPServer *server, unsigned segsize = 536, timeout_t timeout = 0); 00163 00169 tcpstream(int family = PF_INET, timeout_t timeout = 0); 00170 00179 tcpstream(Socket::address& address, unsigned segsize = 536, timeout_t timeout = 0); 00180 00184 virtual ~tcpstream(); 00185 00190 inline operator bool() const 00191 {return so != INVALID_SOCKET && bufsize > 0;} 00192 00197 inline bool operator!() const 00198 {return so == INVALID_SOCKET || bufsize == 0;} 00199 00205 void open(Socket::address& address, unsigned segment = 536); 00206 00213 void open(const char *host, const char *service, unsigned segment = 536); 00214 00219 void close(void); 00220 }; 00221 00230 class __EXPORT pipestream : public StreamBuffer 00231 { 00232 public: 00233 typedef enum { 00234 RDONLY, 00235 WRONLY, 00236 RDWR 00237 } access_t; 00238 00239 private: 00240 __LOCAL void allocate(size_t size, access_t mode); 00241 00242 protected: 00243 fsys_t rd, wr; 00244 shell::pid_t pid; 00245 00249 void release(void); 00250 00257 int underflow(void); 00258 00266 int overflow(int ch); 00267 00268 public: 00272 pipestream(); 00273 00282 pipestream(const char *command, access_t access, char **args, char **env = NULL, size_t size = 512); 00283 00287 virtual ~pipestream(); 00288 00293 inline operator bool() const 00294 {return (bufsize > 0);} 00295 00300 inline bool operator!() const 00301 {return bufsize == 0;} 00302 00311 void open(const char *path, access_t access, char **args, char **env = NULL, size_t buffering = 512); 00312 00317 int close(void); 00318 00322 void terminate(void); 00323 00324 inline void cancel(void) 00325 {terminate();} 00326 }; 00327 00336 class __EXPORT filestream : public StreamBuffer 00337 { 00338 public: 00339 typedef enum { 00340 RDONLY, 00341 WRONLY, 00342 RDWR 00343 } access_t; 00344 00345 private: 00346 __LOCAL void allocate(size_t size, fsys::access_t mode); 00347 00348 protected: 00349 fsys_t fd; 00350 fsys::access_t ac; 00351 00358 int underflow(void); 00359 00367 int overflow(int ch); 00368 00369 public: 00373 filestream(); 00374 00378 filestream(const filestream& copy); 00379 00383 filestream(const char *path, unsigned mode, fsys::access_t access, size_t bufsize = 512); 00384 00388 filestream(const char *path, fsys::access_t access, size_t bufsize = 512); 00389 00393 virtual ~filestream(); 00394 00399 inline operator bool() const 00400 {return (bufsize > 0);} 00401 00406 inline bool operator!() const 00407 {return bufsize == 0;} 00408 00412 void open(const char *filename, fsys::access_t access, size_t buffering = 512); 00413 00417 void open(const char *filename, unsigned mode, fsys::access_t access, size_t buffering = 512); 00418 00422 void close(void); 00423 00427 void seek(fsys::offset_t offset); 00428 00433 inline int err(void) const 00434 {return fd.err();} 00435 }; 00436 00441 class __EXPORT _stream_operators 00442 { 00443 private: 00444 inline _stream_operators() {} 00445 00446 public: 00447 static std::ostream& print(std::ostream& out, const PrintProtocol& format); 00448 00449 static std::istream& input(std::istream& inp, InputProtocol& format); 00450 00451 static std::ostream& print(std::ostream& out, const string_t& str); 00452 00453 static std::istream& input(std::istream& inp, string_t& str); 00454 00455 static std::ostream& print(std::ostream& out, const stringlist_t& list); 00456 00457 static std::istream& input(std::istream& in, stringlist_t& list); 00458 00459 }; 00460 00461 inline std::ostream& operator<< (std::ostream& out, const PrintProtocol& format) 00462 {return _stream_operators::print(out, format);} 00463 00464 inline std::istream& operator>> (std::istream& inp, InputProtocol& format) 00465 {return _stream_operators::input(inp, format);} 00466 00467 inline std::ostream& operator<< (std::ostream& out, const string_t& str) 00468 {return _stream_operators::print(out, str);} 00469 00470 inline std::istream& operator>> (std::istream& inp, string_t& str) 00471 {return _stream_operators::input(inp, str);} 00472 00473 inline std::ostream& operator<< (std::ostream& out, const stringlist_t& list) 00474 {return _stream_operators::print(out, list);} 00475 00476 inline std::istream& operator>> (std::istream& in, stringlist_t& list) 00477 {return _stream_operators::input(in, list);} 00478 00479 inline std::ostream& operator<<(std::ostream& os, Socket::address& addr) { 00480 #ifdef AF_INET6 00481 char buf[INET6_ADDRSTRLEN]; 00482 #else 00483 char buf[INET_ADDRSTRLEN]; 00484 #endif 00485 size_t s = addr.print(buf, sizeof(buf), false, true); 00486 os << std::string(buf, s); 00487 return os; 00488 } 00489 00490 } // namespace ucommon 00491 00492 #endif 00493 #endif