00001 #ifndef hpp_CPP_Streams_CPP_hpp
00002 #define hpp_CPP_Streams_CPP_hpp
00003
00004
00005 #include "../Types/Types.hpp"
00006
00007 #include "../Strings/Strings.hpp"
00008
00009 namespace Stream
00010 {
00012 class BaseStream
00013 {
00014
00015 protected:
00017 BaseStream() {}
00019 virtual ~BaseStream() {}
00020
00021
00022 public:
00027 virtual uint32 fullSize() const = 0;
00029 virtual bool endReached() const = 0;
00031 virtual uint32 currentPosition() const = 0;
00033 virtual bool setPosition(const uint32 & newPos) = 0;
00038 virtual bool goForward(const uint32 & skipAmount) = 0;
00039 };
00040
00042 class InputStream : public BaseStream
00043 {
00044 protected:
00046 InputStream() {}
00047
00048
00049 public:
00053 virtual uint32 read(void * const buffer, const uint32 & size) const throw() = 0;
00054 };
00055
00057 class OutputStream : public BaseStream
00058 {
00059 protected:
00061 OutputStream() {}
00062
00063
00064 public:
00068 virtual uint32 write(const void * const buffer, const uint32 & size) const throw() = 0;
00069 };
00070
00072 template <class String>
00073 class LineSplitStream : public InputStream
00074 {
00075 protected:
00077 LineSplitStream() {}
00078
00079
00080 public:
00084 virtual String readNextLine() const throw()
00085 {
00086 String s;
00087 tchar buffer[256];
00088 tchar ch;
00089 uint32 positionInBuffer = 0;
00090
00091 while (!endReached())
00092 {
00093 if (!read(&ch, sizeof(ch)) != sizeof(ch)) break;
00094 if (ch == '\n') break;
00095
00096 buffer[positionInBuffer++] = ch;
00097
00098 if (positionInBuffer == 256)
00099 {
00100 s += buffer; positionInBuffer = 0;
00101 }
00102 }
00103
00104 if (positionInBuffer)
00105 s += buffer;
00106
00107 return s;
00108 }
00109 };
00110
00112 class InputFileStream : public LineSplitStream<Strings::FastString>
00113 {
00114 protected:
00116 typedef Strings::FastString String;
00117
00118
00119 private:
00121 String fileName;
00123 void * pFile;
00125 uint32 fileSize;
00126
00127
00128 public:
00132 virtual uint32 fullSize() const;
00134 virtual bool endReached() const;
00136 virtual uint32 currentPosition() const;
00138 virtual bool setPosition(const uint32 & newPos);
00143 virtual bool goForward(const uint32 & skipAmount);
00147 virtual uint32 read(void * const buffer, const uint32 & size) const throw();
00148
00149
00150 public:
00152 InputFileStream(const String & name);
00154 ~InputFileStream();
00155
00156 private:
00158 InputFileStream(const InputFileStream &);
00159 };
00160
00162 class MemoryBufferedStream : public InputStream
00163 {
00164
00165
00166 private:
00168 const InputStream & inputStream;
00170 uint8 * buffer;
00171
00172
00173 public:
00177 virtual uint32 fullSize() const { return inputStream.fullSize();}
00179 virtual bool endReached() const { return true; }
00181 virtual uint32 currentPosition() const { return inputStream.fullSize(); }
00183 virtual bool setPosition(const uint32 & newPos) { return false; }
00188 virtual bool goForward(const uint32 & skipAmount) { return false; }
00192 virtual uint32 read(void * const buffer, const uint32 & size) const throw() { return 0; }
00193
00195 inline uint8 * getBuffer() { return buffer; }
00196
00197
00198 public:
00200 MemoryBufferedStream(const InputStream & is) : buffer(0), inputStream(is)
00201 {
00202 if (is.fullSize() < 0xfffffffe)
00203 {
00204 buffer = new uint8[is.fullSize()];
00205 if (!buffer) return;
00206 if (is.read(buffer, is.fullSize()) != is.fullSize())
00207 {
00208 delete buffer;
00209 buffer = 0;
00210 }
00211 }
00212 }
00214 ~MemoryBufferedStream() { if (buffer) delete[] buffer; buffer = 0; }
00215
00216 private:
00218 MemoryBufferedStream(const MemoryBufferedStream &);
00219 };
00220
00222 class MemoryBlockStream : public InputStream
00223 {
00224
00225
00226 private:
00228 const uint8 * buffer;
00230 uint32 length;
00232 uint32 position;
00233
00234
00235 public:
00239 virtual uint32 fullSize() const { return length;}
00241 virtual bool endReached() const { return position >= length; }
00243 virtual uint32 currentPosition() const { return position; }
00245 virtual bool setPosition(const uint32 & newPos) { if (newPos < length) { position = newPos; return true; } return false; }
00250 virtual bool goForward(const uint32 & skipAmount) { if (skipAmount + position > length) return false; position += skipAmount; return true; }
00254 virtual uint32 read(void * const _buffer, const uint32 & size) const throw()
00255 {
00256 uint32 amount = (uint32)( ((int)length - (int)position) < (int)size ? ((int)length - (int)position) : (int)size );
00257 memcpy(_buffer, &buffer[position], amount);
00258 return amount;
00259 }
00260
00262 inline const uint8 * getBuffer() { return buffer; }
00263
00264
00265 public:
00267 MemoryBlockStream(const uint8 * data, const uint32 len) : buffer(data), length(len), position(0)
00268 {
00269 }
00271 ~MemoryBlockStream() { buffer = 0; length = 0; position = 0;}
00272
00273 private:
00275 MemoryBlockStream(const MemoryBlockStream &);
00276 };
00277 }
00278
00279
00280
00281
00282
00283 #endif