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