• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

epics/apps/crucible/stream/src/StreamBuffer.h (r4864/r2310)

Go to the documentation of this file.
00001 /***************************************************************
00002 * StreamBuffer                                                 *
00003 *                                                              *
00004 * (C) 2005 Dirk Zimoch (dirk.zimoch@psi.ch)                    *
00005 *                                                              *
00006 * This is a buffer class used in StreamDevice for I/O.         *
00007 * Please refer to the HTML files in ../doc/ for a detailed     *
00008 * documentation.                                               *
00009 *                                                              *
00010 * If you do any changes in this file, you are not allowed to   *
00011 * redistribute it any more. If there is a bug or a missing     *
00012 * feature, send me an email and/or your patch. If I accept     *
00013 * your changes, they will go to the next release.              *
00014 *                                                              *
00015 * DISCLAIMER: If this software breaks something or harms       *
00016 * someone, it's your problem.                                  *
00017 *                                                              *
00018 ***************************************************************/
00019 
00020 #ifndef StreamBuffer_h
00021 #define StreamBuffer_h
00022 
00023 #include <string.h>
00024 #include <stdio.h>
00025 
00026 #ifndef __GNUC__
00027 #define __attribute__(x)
00028 #endif
00029 
00030 class StreamBuffer
00031 {
00032     char local[64];
00033     long len;
00034     long cap;
00035     long offs;
00036     char* buffer;
00037 
00038     void init(const void* s, long minsize);
00039 
00040     void check(long size)
00041         {if (len+offs+size >= cap) grow(len+size);}
00042 
00043     void grow(long minsize);
00044 
00045 public:
00046     // Hints:
00047     // * Any index parameter (long) can be negative
00048     //   meaning "count from end" (-1 is the last byte)
00049     // * Appending negative count deletes from end
00050     // * Any returned char* pointer becomes invalid when
00051     //   the StreamBuffer is modified.
00052     // * End of StreamBuffer always contains 0x00 bytes
00053     // * Deleting from start and clearing is fast
00054 
00055     StreamBuffer()
00056         {init(NULL, 0);}
00057 
00058     StreamBuffer(const void* s, long size)
00059         {init(s, size);}
00060 
00061     StreamBuffer(const char* s)
00062         {init(s, s?strlen(s):0);}
00063 
00064     StreamBuffer(const StreamBuffer& s)
00065         {init(s.buffer+s.offs, s.len);}
00066 
00067     StreamBuffer(long size)
00068         {init(NULL, size);}
00069 
00070     ~StreamBuffer()
00071         {if (buffer != local) delete buffer;}
00072 
00073     // operator (): get char* pointing to index
00074     const char* operator()(long index=0) const
00075         {return buffer+offs+(index<0?index+len:index);}
00076 
00077     char* operator()(long index=0)
00078         {return buffer+offs+(index<0?index+len:index);}
00079 
00080     // operator []: get byte at index
00081     char operator[](long index) const
00082         {return buffer[offs+(index<0?index+len:index)];}
00083 
00084     char& operator[](long index)
00085         {return buffer[offs+(index<0?index+len:index)];}
00086 
00087     // cast to bool: not empty?
00088     operator bool() const
00089         {return len>0;}
00090 
00091     // length: get current data length
00092     long length() const
00093         {return len;}
00094 
00095     // capacity: get current max data length (spare one byte for end)
00096     long capacity() const
00097         {return cap-1;}
00098 
00099     // end: get pointer to byte after last data byte
00100     const char* end() const
00101         {return buffer+offs+len;}
00102 
00103     // clear: set length to 0, don't free or blank memory (fast!)
00104     StreamBuffer& clear()
00105         {offs+=len; len=0; return *this;}
00106 
00107     // reserve: reserve size bytes of memory and return
00108     // pointer to that memory (for copying something to it)
00109     char* reserve(long size)
00110         {check(size); char* p=buffer+offs+len; len+=size; return p;}
00111 
00112     // append: append data at the end of the buffer
00113     StreamBuffer& append(char c)
00114         {check(1); buffer[offs+len++]=c; return *this;}
00115 
00116     StreamBuffer& append(char c, long count)
00117         {if (count < 0) truncate(count);
00118          else {check(count); memset(buffer+offs+len, c, count); len+=count;}
00119          return *this;}
00120 
00121     StreamBuffer& append(const void* s, long size);
00122 
00123     StreamBuffer& append(const char* s)
00124         {return append(s, s?strlen(s):0);}
00125 
00126     StreamBuffer& append(const StreamBuffer& s)
00127         {return append(s.buffer+s.offs, s.len);}
00128         
00129     // operator += alias for set
00130     StreamBuffer& operator+=(char c)
00131         {return append(c);}
00132 
00133     StreamBuffer& operator+=(const char* s)
00134         {return append(s);}
00135 
00136     StreamBuffer& operator+=(const StreamBuffer& s)
00137         {return append(s);}
00138 
00139     // set: clear buffer and fill with new data
00140     StreamBuffer& set(const void* s, long size)
00141         {clear(); return append(s, size);}
00142 
00143     StreamBuffer& set(const char* s)
00144         {clear(); return append(s, s?strlen(s):0);}
00145 
00146     StreamBuffer& set(const StreamBuffer& s)
00147         {clear(); return append(s.buffer+s.offs, s.len);}
00148 
00149     // operator = alias for set
00150     StreamBuffer& operator=(const char* s)
00151         {return set(s);}
00152 
00153     StreamBuffer& operator=(const StreamBuffer& s)
00154         {return set(s);}
00155 
00156     // replace: delete part of buffer (pos/length) and insert new data
00157     StreamBuffer& replace(
00158         long pos, long length, const void* s, long size);
00159 
00160     StreamBuffer& replace(long pos, long length, const char* s)
00161         {return replace(pos, length, s, s?strlen(s):0);}
00162 
00163     StreamBuffer& replace(long pos, long length, const StreamBuffer& s)
00164         {return replace(pos, length, s.buffer+s.offs, s.len);}
00165 
00166     // remove: delete from start/pos
00167     StreamBuffer& remove(long pos, long length)
00168         {return replace(pos, length, NULL, 0);}
00169 
00170     // remove from start: no memset, no function call, fast!
00171     StreamBuffer& remove(long length)
00172         {if (length>len) length=len;
00173          offs+=length; len-=length; return *this;}
00174 
00175     // truncate: delete end of buffer
00176     StreamBuffer& truncate(long pos)
00177         {return replace(pos, len, NULL, 0);}
00178 
00179     // insert: insert new data into buffer
00180     StreamBuffer& insert(long pos, const void* s, long size)
00181         {return replace(pos, 0, s, size);}
00182 
00183     StreamBuffer& insert(long pos, const char* s)
00184         {return replace(pos, 0, s, s?strlen(s):0);}
00185 
00186     StreamBuffer& insert(long pos, const StreamBuffer& s)
00187         {return replace(pos, 0, s.buffer+s.offs, s.len);}
00188 
00189     StreamBuffer& insert(long pos, char c)
00190         {return replace(pos, 0, &c, 1);}
00191 
00192     StreamBuffer& printf(const char* fmt, ...)
00193         __attribute__ ((format(printf,2,3)));
00194 
00195     // find: get index of data in buffer or -1
00196     long find(char c, long start=0) const
00197         {char* p;
00198          return (p = static_cast<char*>(
00199             memchr(buffer+offs+(start<0?start+len:start),
00200                 c, start<0?-start:len-start)))?
00201             p-(buffer+offs) : -1;}
00202 
00203     long find(const void* s, long size, long start=0) const;
00204 
00205     long find(const char* s, long start=0) const
00206         {return find(s, s?strlen(s):0, start);}
00207 
00208     long int find(const StreamBuffer& s, long start=0) const
00209         {return find(s.buffer+s.offs, s.len, start);}
00210 
00211     // startswith: returns true if first size bytes are equal
00212     bool startswith(const void* s, long size) const
00213         {return len>=size ? memcmp(buffer+offs, s, size) == 0 : false;}
00214 
00215     // startswith: returns true if first string is equal (empty string matches)
00216     bool startswith(const char* s) const
00217         {return len ? strcmp(buffer+offs, s) == 0 : !s || !*s;}
00218 
00219 // expand: create copy of StreamBuffer where all nonprintable characters
00220 // are replaced by <xx> with xx being the hex code of the characters
00221     StreamBuffer expand(long start, long length) const;
00222     
00223     StreamBuffer expand(long start=0) const
00224         {return expand(start, len);}
00225 
00226 // dump: debug function, like expand but also show the 'hidden' memory
00227 // before and after the real data. Uses colours.
00228     StreamBuffer dump() const;
00229 };
00230 
00231 #endif

Generated on Tue Dec 10 2013 04:52:22 for ROCsoft by  doxygen 1.7.1