UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/stream.h
Go to the documentation of this file.
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