00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef CXXTOOLS_IODevice_h
00031 #define CXXTOOLS_IODevice_h
00032
00033 #include <cxxtools/types.h>
00034 #include <cxxtools/signal.h>
00035 #include <cxxtools/api.h>
00036 #include <cxxtools/ioerror.h>
00037 #include <cxxtools/selectable.h>
00038 #include <limits>
00039 #include <ios>
00040
00041 namespace cxxtools {
00042
00043 enum IOS_OpenMode
00044 {
00045 IOS_Sync = 0,
00046 IOS_Async = 1L << 0,
00047 IOS_Read = 1L << 1,
00048 IOS_Write = 1L << 2,
00049 IOS_AtEnd = 1L << 3,
00050 IOS_Append = 1L << 4,
00051 IOS_Trunc = 1L << 5,
00052 IOS_OpenModeEnd = 1L << 16
00053 };
00054
00055 inline IOS_OpenMode operator&(IOS_OpenMode a, IOS_OpenMode b)
00056 { return IOS_OpenMode(static_cast<int>(a) & static_cast<int>(b)); }
00057
00058 inline IOS_OpenMode operator|(IOS_OpenMode a, IOS_OpenMode b)
00059 { return IOS_OpenMode(static_cast<int>(a) | static_cast<int>(b)); }
00060
00061 inline IOS_OpenMode operator^(IOS_OpenMode a, IOS_OpenMode b)
00062 { return IOS_OpenMode(static_cast<int>(a) ^ static_cast<int>(b)); }
00063
00064 inline IOS_OpenMode& operator|=(IOS_OpenMode& a, IOS_OpenMode b)
00065 { return a = a | b; }
00066
00067 inline IOS_OpenMode& operator&=(IOS_OpenMode& a, IOS_OpenMode b)
00068 { return a = a & b; }
00069
00070 inline IOS_OpenMode& operator^=(IOS_OpenMode& a, IOS_OpenMode b)
00071 { return a = a ^ b; }
00072
00073 inline IOS_OpenMode operator~(IOS_OpenMode a)
00074 { return IOS_OpenMode(~static_cast<int>(a)); }
00075
00076
00077 class IODeviceImpl;
00078
00091 class CXXTOOLS_API IODevice : public Selectable
00092 {
00093 public:
00094 typedef std::char_traits<char>::pos_type pos_type;
00095
00096 typedef std::char_traits<char>::off_type off_type;
00097
00098 typedef std::ios_base::seekdir SeekDir;
00099
00100 typedef IOS_OpenMode OpenMode;
00101
00102 static const OpenMode Sync = IOS_Sync;
00103 static const OpenMode Async = IOS_Async;
00104 static const OpenMode Read = IOS_Read;
00105 static const OpenMode Write = IOS_Write;
00106 static const OpenMode AtEnd = IOS_AtEnd;
00107 static const OpenMode Append = IOS_Append;
00108 static const OpenMode Trunc = IOS_Trunc;
00109
00110 public:
00112 virtual ~IODevice();
00113
00114 void beginRead(char* buffer, size_t n);
00115
00116 size_t endRead();
00117
00119
00130 size_t read(char* buffer, size_t n);
00131
00132 void beginWrite(const char* buffer, size_t n);
00133
00134 size_t endWrite();
00135
00137
00148 size_t write(const char* buffer, size_t n);
00149
00151
00156 bool seekable() const;
00157
00159
00168 pos_type seek(off_type offset, std::ios::seekdir sd);
00169
00171
00181 size_t peek(char* buffer, size_t n);
00182
00184
00189 void sync();
00190
00192
00199 pos_type position();
00200
00202
00207 bool eof() const;
00208
00211 bool async() const;
00212
00218 Signal<IODevice&> inputReady;
00219
00226 Signal<IODevice&> outputReady;
00227
00234 Signal<IODevice&> errorOccured;
00235
00236 virtual IODeviceImpl& ioimpl() = 0;
00237
00238 bool reading() const
00239 { return _rbuf != 0; }
00240
00241 bool writing() const
00242 { return _wbuf != 0; }
00243
00244 char* rbuf() const
00245 { return _rbuf; }
00246
00247 size_t rbuflen() const
00248 { return _rbuflen; }
00249
00250 const char* wbuf() const
00251 { return _wbuf; }
00252
00253 size_t wbuflen() const
00254 { return _wbuflen; }
00255
00256 protected:
00258 IODevice();
00259
00260 virtual size_t onBeginRead(char* buffer, size_t n, bool& eof) = 0;
00261
00262 virtual size_t onEndRead(bool& eof) = 0;
00263
00265 virtual size_t onRead(char* buffer, size_t count, bool& eof) = 0;
00266
00267 virtual size_t onBeginWrite(const char* buffer, size_t n) = 0;
00268
00269 virtual size_t onEndWrite() = 0;
00270
00272 virtual size_t onWrite(const char* buffer, size_t count) = 0;
00273
00275 virtual size_t onPeek(char*, size_t)
00276 { return 0; }
00277
00279 virtual bool onSeekable() const
00280 { return false; }
00281
00283 virtual pos_type onSeek(off_type, std::ios::seekdir)
00284 { throw IOError("Could not seek on device.", CXXTOOLS_SOURCEINFO); }
00285
00287 virtual void onSync() const
00288 { }
00289
00291 virtual size_t onSize() const
00292 { return 0; }
00293
00295 void setEof(bool eof);
00296
00298 void setAsync(bool async);
00299
00300 private:
00301 bool _eof;
00302 bool _async;
00303
00304 protected:
00305 char* _rbuf;
00306 size_t _rbuflen;
00307 size_t _ravail;
00308 const char* _wbuf;
00309 size_t _wbuflen;
00310 size_t _wavail;
00311 void* _reserved;
00312 };
00313
00314 }
00315
00316 #endif