Drizzled Public API Documentation

CSStream.h

00001 /* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program 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 General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Original Author: Paul McCullagh
00020  * Continued development: Barry Leslie
00021  *
00022  * 2007-06-07
00023  *
00024  * CORE SYSTEM:
00025  * Basic input and output streams.
00026  *
00027  * These objects wrap the system streams, and simplify things.
00028  * I also want to standardize exceptions and implement
00029  * socket based streams.
00030  *
00031  */
00032 
00033 #pragma once
00034 #ifndef __CSSTREAM_H__
00035 #define __CSSTREAM_H__
00036 
00037 #define DEFAULT_BUFFER_SIZE   64000
00038 
00039 #include "CSDefs.h"
00040 #include "CSFile.h"
00041 #include "CSSocket.h"
00042 
00043 class CSInputStream : public CSRefObject {
00044 public:
00045   CSInputStream() { }
00046   virtual ~CSInputStream() { }
00047 
00048   /*
00049    * Closes this input stream and releases any system
00050    * resources associated  with the stream.
00051    */
00052   virtual void close() = 0;
00053 
00054   /*
00055    * Reads up to len bytes of data from the input stream into an
00056    * array of bytes. Return the number of bytes read.
00057    *
00058    * Zero will be returned in the case of EOF.
00059    *
00060    * This call blocks until at least one byte is
00061    * returned.
00062    */
00063   virtual size_t read(char *b, size_t len) = 0;
00064 
00065   /* Reads the next byte of data from the input stream.
00066    * Returns -1 if EOF.
00067    */
00068   virtual int read() = 0;
00069 
00070   /* Read one character ahead. */
00071   virtual int peek() = 0;
00072 
00073   /*
00074    *  Reset this output stream to the start inorder to restart the write.
00075    */
00076   virtual void reset() = 0; 
00077 
00078   /* Return the name of the file, or whatever: */
00079   virtual const char *identify() = 0;
00080 
00081   /*
00082    * Read a line from the input stream. This function
00083    * handles all types of line endings. The function
00084    * return NULL on EOF.
00085    */
00086   CSStringBuffer *readLine();
00087 };
00088 
00089 class CSOutputStream : public CSRefObject {
00090 public:
00091   /*
00092    * Closes this input stream and releases any system
00093    * resources associated  with the stream.
00094    */
00095   virtual void close() = 0;
00096 
00097   /*
00098    * Writes len bytes from the specified byte array starting at
00099    * offset off to this output stream.
00100    */
00101   virtual void write(const char *b, size_t len) = 0;
00102 
00103   /*
00104    * Returns the default EOL indicator.
00105    * Will be \n, \r or \r\n.
00106    */
00107   virtual const char *getEOL() = 0;
00108 
00109   /*
00110    *  Flushes this output stream and forces any buffered output
00111    * bytes to be written out.
00112    */
00113   virtual void flush() = 0;
00114 
00115   /*
00116    * Writes the specified byte to this output stream.
00117    */
00118   virtual void write(char b) = 0; 
00119 
00120   /*
00121    * Reset this output stream to the start inorder to restart the write.
00122    */
00123   virtual void reset() = 0; 
00124 
00125   virtual const char *identify() = 0;
00126 
00127   /*
00128    * Write a line. Terminator is specific to the
00129    * type of output stream and may depend on the
00130    * current platform.
00131    */
00132   void printLine(const char *cstr);
00133 
00134   /*
00135    * Various write types:
00136    */
00137   virtual void print(const char *cstr);
00138   virtual void print(CSString *s);
00139   virtual void print(int value);
00140   virtual void print(uint64_t value);
00141 };
00142 
00143 class CSStream : public CSObject {
00144 public:
00145   static void pipe(CSOutputStream *out, CSInputStream *in);
00146 };
00147 
00148 /* File Stream: */
00149 
00150 class CSFileInputStream : public CSInputStream {
00151 public:
00152   CSFileInputStream(): iFile(NULL), iReadOffset(0) { }
00153   virtual ~CSFileInputStream();
00154 
00155   virtual void close();
00156 
00157   virtual size_t read(char *b, size_t len);
00158 
00159   virtual int read();
00160 
00161   virtual int peek();
00162 
00163   /*
00164    *  Reset this output stream to the start inorder to restart the read.
00165    */
00166   virtual void reset(); 
00167 
00168   virtual const char *identify();
00169 
00170   static CSFileInputStream *newStream(CSFile* f);
00171   static CSFileInputStream *newStream(CSFile* f, off64_t offset);
00172 
00173 private:
00174   CSFile  *iFile;
00175   off64_t iReadOffset;
00176 };
00177 
00178 class CSFileOutputStream : public CSOutputStream {
00179 public:
00180   CSFileOutputStream(): iFile(NULL), iWriteOffset(0) { }
00181   virtual ~CSFileOutputStream();
00182 
00183   virtual void close();
00184 
00185   virtual void write(const char *b, size_t len);
00186 
00187   virtual const char *getEOL();
00188 
00189   virtual void flush();
00190 
00191   virtual void write(char b);
00192 
00193   virtual void reset(); 
00194 
00195   virtual const char *identify();
00196 
00197   static CSFileOutputStream *newStream(CSFile* f);
00198   static CSFileOutputStream *newStream(CSFile* f, off64_t offset);
00199 
00200 private:
00201   CSFile  *iFile;
00202   off64_t iWriteOffset;
00203 };
00204 
00205 /* Socket Stream */
00206 
00207 class CSSocketInputStream : public CSInputStream {
00208 public:
00209   CSSocketInputStream(): iSocket(NULL) { }
00210   virtual ~CSSocketInputStream();
00211 
00212   virtual void close();
00213 
00214   virtual size_t read(char *b, size_t len);
00215 
00216   virtual int read();
00217 
00218   virtual int peek();
00219 
00220   virtual void reset(); 
00221 
00222   virtual const char *identify();
00223 
00224   static CSSocketInputStream *newStream(CSSocket *s);
00225 
00226 private:
00227   CSSocket* iSocket;
00228 };
00229 
00230 class CSSocketOutputStream : public CSOutputStream {
00231 public:
00232   CSSocketOutputStream(): iSocket(NULL) { }
00233   virtual ~CSSocketOutputStream();
00234 
00235   virtual void close();
00236 
00237   virtual void write(const char *b, size_t len);
00238 
00239   virtual const char *getEOL() { return "\n"; };
00240 
00241   virtual void flush();
00242 
00243   virtual void write(char b);
00244 
00245   virtual void reset(); 
00246 
00247   virtual const char *identify();
00248 
00249   static CSSocketOutputStream *newStream(CSSocket *s);
00250 
00251 private:
00252   CSSocket* iSocket;
00253 };
00254 
00255 /* Buffered Stream: */
00256 #ifdef DEBUG_disabled
00257 #define CS_STREAM_BUFFER_SIZE     80
00258 #else
00259 #define CS_STREAM_BUFFER_SIZE     (32 * 1024)
00260 #endif
00261 
00262 class CSBufferedInputStream : public CSInputStream {
00263 public:
00264   CSBufferedInputStream(): iStream(NULL), iBuffTotal(0), iBuffPos(0) { }
00265   virtual ~CSBufferedInputStream();
00266 
00267   virtual void close();
00268 
00269   virtual size_t read(char *b, size_t len);
00270 
00271   virtual int read();
00272 
00273   virtual int peek();
00274 
00275   virtual void reset(); 
00276 
00277   virtual const char *identify();
00278 
00279   static CSBufferedInputStream *newStream(CSInputStream* i);
00280 
00281 private:
00282   CSInputStream* iStream;
00283   u_char iBuffer[CS_STREAM_BUFFER_SIZE];
00284   uint32_t iBuffTotal;
00285   uint32_t iBuffPos;
00286 };
00287 
00288 class CSBufferedOutputStream : public CSOutputStream {
00289 public:
00290   CSBufferedOutputStream(): iStream(NULL), iBuffTotal(0) { }
00291   virtual ~CSBufferedOutputStream();
00292 
00293   virtual void close();
00294 
00295   virtual void write(const char *b, size_t len);
00296 
00297   virtual const char *getEOL() { return "\n"; };
00298 
00299   virtual void flush();
00300 
00301   virtual void write(char b);
00302 
00303   virtual void reset(); 
00304 
00305   virtual const char *identify();
00306 
00307   static CSBufferedOutputStream *newStream(CSOutputStream* i);
00308 
00309 private:
00310   CSOutputStream* iStream;
00311   u_char iBuffer[CS_STREAM_BUFFER_SIZE];
00312   uint32_t iBuffTotal;
00313 };
00314 
00315 /* memory Stream */
00316 class CSMemoryInputStream : public CSInputStream {
00317 public:
00318   CSMemoryInputStream(): iMemory(NULL), iMemTotal(0), iMemPos(0) { }
00319   ~CSMemoryInputStream(){}
00320 
00321   virtual void close() {}
00322 
00323   virtual size_t read(char *b, size_t len)
00324   {
00325     if (len > (iMemTotal - iMemPos))
00326       len = iMemTotal - iMemPos;
00327     
00328     memcpy(b, iMemory + iMemPos, len);
00329     iMemPos += len; 
00330     return len;
00331   }
00332 
00333   virtual int read()
00334   {
00335     int b = -1;
00336     if (iMemPos < iMemTotal) 
00337       b = iMemory[iMemPos++];
00338     return b;
00339   }
00340 
00341   virtual int peek()
00342   {
00343     int b = -1;
00344     if (iMemPos < iMemTotal) 
00345       b = iMemory[iMemPos];
00346     return b;
00347   }
00348 
00349   virtual void reset() {iMemPos = 0;}
00350   
00351   virtual const char *identify() 
00352   {
00353     return "memory stream";
00354   }
00355 
00356   static CSMemoryInputStream *newStream(const u_char* buffer, uint32_t length);
00357 
00358 private:
00359   const u_char *iMemory;
00360   uint32_t iMemTotal;
00361   uint32_t iMemPos;
00362 };
00363 
00364 
00365 class CSMemoryOutputStream : public CSOutputStream {
00366 public:
00367   CSMemoryOutputStream(): iMemory(NULL), iMemTotal(0), iMemSpace(0), iMemMin(0), iMemPos(NULL){ }
00368   virtual ~CSMemoryOutputStream();
00369 
00370   virtual void close() {}
00371 
00372   virtual void write(const char *b, size_t len);
00373   virtual const char *getEOL() { return "\n"; };
00374 
00375   virtual void flush() {}
00376 
00377   virtual void write(char b);
00378 
00379   const u_char *getMemory(size_t *len)
00380   {
00381     *len = iMemPos - iMemory;
00382     return iMemory;
00383   }
00384   
00385   virtual void reset();
00386   
00387   virtual const char *identify();
00388   
00389   static CSMemoryOutputStream *newStream(size_t init_length, size_t min_alloc);
00390 
00391 private:
00392   u_char *iMemory;
00393   uint32_t iMemTotal;
00394   uint32_t iMemSpace;
00395   uint32_t iMemMin;
00396   u_char *iMemPos;
00397 };
00398 
00399 class CSStaticMemoryOutputStream : public CSOutputStream {
00400 public:
00401   CSStaticMemoryOutputStream(u_char *mem, off64_t size): iMemory(mem), iMemSpace(size), iMemSize(size), iMemPos(mem){ }
00402   virtual ~CSStaticMemoryOutputStream() {}
00403 
00404   virtual void close() {}
00405 
00406   virtual void write(const char *b, size_t len);
00407   virtual const char *getEOL() { return "\n"; };
00408 
00409   virtual void flush() {}
00410 
00411   virtual void write(char b);
00412   
00413   virtual void reset() 
00414   {
00415     iMemPos = iMemory;
00416     iMemSpace = iMemSize;
00417   }
00418   
00419   virtual const char *identify() 
00420   {
00421     return "memory stream";
00422   }
00423   
00424   off64_t getSize() { return iMemPos - iMemory; }
00425 
00426 private:
00427   u_char *iMemory;
00428   off64_t iMemSpace;
00429   off64_t iMemSize;
00430   u_char *iMemPos;
00431 };
00432 
00433 typedef size_t (* CSStreamReadCallbackFunc) (void *caller_data, char *buffer, size_t buffer_size, u_char reset);
00434 
00435 class CSCallbackInputStream : public CSInputStream {
00436 public:
00437   CSCallbackInputStream(): callback(NULL), cb_data(NULL), havePeek(false), doReset(false) { }
00438   ~CSCallbackInputStream(){}
00439 
00440   virtual void close() {}
00441 
00442   virtual size_t read(char *b, size_t len)
00443   {
00444     size_t size = 0;
00445     
00446     if (havePeek) {
00447       havePeek = false;
00448       *b =  peek_char;
00449       b++; len--;
00450       if (len) {
00451         size = callback(cb_data, b, len, doReset);
00452       }
00453         
00454       size++;     
00455     } else
00456       size = callback(cb_data, b, len, doReset);
00457       
00458     if (doReset)
00459       doReset = false;
00460       
00461     return size;
00462   }
00463 
00464   virtual int read()
00465   {
00466     char c;
00467     
00468     if (havePeek) {
00469       havePeek = false;
00470       return peek_char;
00471     }
00472     if (!callback(cb_data, &c, 1, doReset))
00473       c = -1;
00474       
00475     if (doReset)
00476       doReset = false;
00477     
00478     return c;
00479   }
00480 
00481   virtual int peek()
00482   {
00483     if (!havePeek) {
00484       if (callback(cb_data, &peek_char, 1, doReset))
00485         havePeek = true;
00486       else
00487         return -1;
00488     }
00489     return peek_char;
00490   }
00491 
00492   virtual void reset() 
00493   {
00494     havePeek = false;
00495     doReset = false;
00496   }
00497 
00498   virtual const char *identify() 
00499   {
00500     return "callback stream";
00501   }
00502 
00503   static CSCallbackInputStream *newStream(CSStreamReadCallbackFunc callback, void *user_data);
00504 
00505 private:
00506   CSStreamReadCallbackFunc callback;
00507   void *cb_data;
00508   char peek_char;
00509   bool havePeek;
00510   bool doReset;
00511 };
00512 
00513 #endif
00514 
00515