Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

IBuffer.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file IBuffer.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032 
00033         @version        Initial version, March 2004      
00034         @author         Kris
00035 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.io.model.IBuffer;
00040 
00041 private import mango.io.model.IConduit;
00042 
00043 /*******************************************************************************
00044 
00045         The basic premise behind this IO package is as follows:
00046 
00047         1) the central concept is that of a buffer. The buffer acts
00048            as a queue (line) where items are removed from the front
00049            and new items are added to the back. Buffers are modeled 
00050            by this interface, and mango.io.Buffer exposes a concrete 
00051            implementation.
00052 
00053         2) buffers can be written to directly, but a Reader and/or
00054            Writer are typically used to read & write formatted data.
00055            These readers & writers are bound to a specific buffer;
00056            often the same buffer. It's also perfectly legitimate to 
00057            bind multiple writers to the same buffer; they will all
00058            behave serially as one would expect. The same applies to
00059            multiple readers on the same buffer. Readers and writers
00060            support two styles of IO: put/get, and the C++ style << 
00061            and >> operators. All such operations can be chained.
00062 
00063         3) Any class can be made compatable with the reader/writer
00064            framework by implementing the IReadable and/or IWritable 
00065            interfaces. Each of these specify just a single method.
00066 
00067         4) Buffers may also be tokenized. This is handy when one is
00068            dealing with text input, and/or the content suits a more
00069            fluid format than most typical readers & writers support.
00070            Tokens are mapped directly onto buffer content, so there
00071            is only minor overhead in using them. Tokens can be read
00072            and written by reader/writers also, using a more relaxed
00073            set of rules than those applied to integral IO.
00074 
00075         5) buffers are sometimes memory-only, in which case there
00076            is nothing left to do when a reader (or tokenizer) hits
00077            end of buffer conditions. Other buffers are themselves 
00078            bound to a Conduit. When this is the case, a reader will 
00079            eventually cause the buffer to reload via its associated 
00080            conduit. Previous buffer content will thus be lost. The
00081            same concept is applied to writers, whereby they flush 
00082            the content of a full buffer to a bound conduit before 
00083            continuing. 
00084 
00085         6) conduits provide virtualized access to external content,
00086            and represent things like files or Internet connections.
00087            They are just a different kind of stream. Conduits are
00088            modelled by mango.io.model.IConduit, and implemented via
00089            classes FileConduit and SocketConduit. Additional kinds
00090            of conduit are easy to construct: one either subclasses
00091            mango.io.Conduit, or implements mango.io.model.IConduit. A
00092            conduit reads and writes from/to a buffer in big chunks
00093            (typically the entire buffer).
00094 
00095 *******************************************************************************/
00096 
00097 abstract class IBuffer // could be an interface, but that causes poor codegen
00098 {
00099         typedef uint delegate (void* dst, uint count, uint type) Converter;
00100 
00101         private typedef byte Style;
00102 
00103         const Style     Mixed  = 0, 
00104                         Binary = 1,
00105                         Text   = 2;
00106 
00107         /***********************************************************************
00108                 
00109                 Return the backing array
00110 
00111         ***********************************************************************/
00112 
00113         abstract void[] getContent ();
00114 
00115         /***********************************************************************
00116         
00117                 Return a char[] slice of the buffer up to the limit of
00118                 valid content.
00119 
00120         ***********************************************************************/
00121 
00122         abstract char[] toString ();
00123 
00124         /***********************************************************************
00125         
00126                 Set the backing array with all content readable. Writing
00127                 to this will either flush it to an associated conduit, or
00128                 raise an Eof condition. Use IBuffer.clear() to reset the
00129                 content (make it all writable).
00130 
00131         ***********************************************************************/
00132 
00133         abstract IBuffer setValidContent (void[] data);
00134 
00135         /***********************************************************************
00136         
00137                 Set the backing array with some content readable. Writing
00138                 to this will either flush it to an associated conduit, or
00139                 raise an Eof condition. Use IBuffer.clear() to reset the
00140                 content (make it all writable).
00141 
00142         ***********************************************************************/
00143 
00144         abstract IBuffer setContent (void[] data, uint readable);
00145 
00146         /***********************************************************************
00147 
00148                 Write an array of data into this buffer, and flush to the
00149                 conduit as necessary. Returns a chaining reference if all 
00150                 data was written; throws an IOException indicating eof or 
00151                 eob if not.
00152 
00153                 This is often used in lieu of a Writer.
00154 
00155         ***********************************************************************/
00156 
00157         abstract IBuffer append (void[] content);
00158 
00159         /***********************************************************************
00160 
00161                 Read a chunk of data from the buffer, loading from the
00162                 conduit as necessary. The requested number of bytes are
00163                 loaded into the buffer, and marked as having been read 
00164                 when the 'eat' parameter is set true. When 'eat' is set
00165                 false, the read position is not adjusted.
00166 
00167                 Returns the corresponding buffer slice when successful, 
00168                 or null if there's not enough data available (Eof; Eob).
00169 
00170         ***********************************************************************/
00171 
00172         abstract void[] get (uint size, bool eat = true);
00173 
00174         /***********************************************************************
00175 
00176                 Exposes the raw data buffer at the current write position, 
00177                 The delegate is provided with a void[] representing space
00178                 available within the buffer at the current write position.
00179 
00180                 The delegate should return the approriate number of bytes 
00181                 if it writes valid content, or IConduit.Eof on error.
00182 
00183                 Returns whatever the delegate returns.
00184 
00185         ***********************************************************************/
00186 
00187         abstract uint write (uint delegate (void[]) writer);
00188 
00189         /***********************************************************************
00190 
00191                 Exposes the raw data buffer at the current read position. The
00192                 delegate is provided with a void[] representing the available
00193                 data, and should return zero to leave the current read position
00194                 intact. 
00195                 
00196                 If the delegate consumes data, it should return the number of 
00197                 bytes consumed; or IConduit.Eof to indicate an error.
00198 
00199                 Returns whatever the delegate returns.
00200 
00201         ***********************************************************************/
00202 
00203         abstract uint read (uint delegate (void[]) reader);
00204 
00205         /***********************************************************************
00206 
00207                 If we have some data left after an export, move it to 
00208                 front-of-buffer and set position to be just after the 
00209                 remains. This is for supporting certain conduits which 
00210                 choose to write just the initial portion of a request.
00211                             
00212                 Limit is set to the amount of data remaining. Position 
00213                 is always reset to zero.
00214 
00215         ***********************************************************************/
00216 
00217         abstract IBuffer compress ();
00218 
00219         /***********************************************************************
00220         
00221                 Skip ahead by the specified number of bytes, streaming from 
00222                 the associated conduit as necessary.
00223         
00224                 Can also reverse the read position by 'size' bytes. This may
00225                 be used to support lookahead-type operations.
00226 
00227                 Returns true if successful, false otherwise.
00228 
00229         ***********************************************************************/
00230 
00231         abstract bool skip (int size);
00232 
00233         /***********************************************************************
00234 
00235                 Try to fill the available buffer with content from the 
00236                 specified conduit. In particular, we will never ask to 
00237                 read less than 32 bytes. This permits conduit-filters 
00238                 to operate within a known environment.
00239 
00240                 Returns the number of bytes read, or throws an underflow
00241                 error if there nowhere to read from
00242         
00243         ***********************************************************************/
00244 
00245         abstract uint fill ();
00246 
00247         /***********************************************************************
00248 
00249                 Try to fill the available buffer with content from the 
00250                 specified conduit. In particular, we will never ask to 
00251                 read less than 32 bytes. This permits conduit-filters 
00252                 to operate within a known environment.
00253 
00254                 Returns the number of bytes read, or Conduit.Eof
00255         
00256         ***********************************************************************/
00257 
00258         abstract uint fill (IConduit conduit);
00259 
00260         /***********************************************************************
00261 
00262                 Write as much of the buffer that the associated conduit
00263                 can consume.
00264 
00265                 Returns the number of bytes written, or Conduit.Eof
00266         
00267         ***********************************************************************/
00268 
00269         abstract uint drain ();
00270 
00271         /***********************************************************************
00272         
00273                 flush the contents of this buffer to the related conduit.
00274                 Throws an IOException on premature eof.
00275 
00276         ***********************************************************************/
00277 
00278         abstract void flush ();
00279 
00280         /***********************************************************************
00281         
00282                 Reset position and limit to zero.
00283 
00284         ***********************************************************************/
00285 
00286         abstract IBuffer clear ();               
00287 
00288         /***********************************************************************
00289         
00290                 return count of readable bytes remaining in buffer. This is 
00291                 calculated simply as limit() - position()
00292 
00293         ***********************************************************************/
00294 
00295         abstract uint readable ();               
00296 
00297         /***********************************************************************
00298         
00299                 Return count of writable bytes available in buffer. This is 
00300                 calculated simply as capacity() - limit()
00301 
00302         ***********************************************************************/
00303 
00304         abstract uint writable ();
00305 
00306         /***********************************************************************
00307         
00308                 returns the limit of readable content within this buffer
00309 
00310         ***********************************************************************/
00311 
00312         abstract uint getLimit ();               
00313 
00314         /***********************************************************************
00315         
00316                 returns the total capacity of this buffer
00317 
00318         ***********************************************************************/
00319 
00320         abstract uint getCapacity ();               
00321 
00322         /***********************************************************************
00323         
00324                 returns the current position within this buffer
00325 
00326         ***********************************************************************/
00327 
00328         abstract uint getPosition ();               
00329 
00330         /***********************************************************************
00331 
00332                 Overridable method to grow the buffer size when it becomes 
00333                 full. Default is to not grow at all.
00334 
00335         ***********************************************************************/
00336 
00337         abstract bool grow (uint size);
00338 
00339         /***********************************************************************
00340 
00341                 make some room in the buffer
00342                         
00343         ***********************************************************************/
00344 
00345         abstract void makeRoom (int space);
00346 
00347         /***********************************************************************
00348         
00349                 Returns the conduit associated with this buffer. Returns 
00350                 null if the buffer is purely memory based; that is, it's
00351                 not backed by some external conduit.
00352 
00353                 Buffers do not require a conduit to operate, but it can
00354                 be convenient to associate one. For example, the IReader
00355                 and IWriter classes use this to import/export content as
00356                 necessary.
00357 
00358         ***********************************************************************/
00359 
00360         abstract IConduit getConduit ();               
00361 
00362         /***********************************************************************
00363         
00364                 Sets the external conduit associated with this buffer.
00365 
00366                 Buffers do not require an external conduit to operate, but 
00367                 it can be convenient to associate one. For example, methods
00368                 read and write use it to import/export content as necessary.
00369 
00370         ***********************************************************************/
00371 
00372         abstract void setConduit (IConduit conduit);
00373 
00374         /***********************************************************************
00375                 
00376                 Return style of buffer
00377 
00378         ***********************************************************************/
00379 
00380         abstract Style getStyle ();
00381 
00382         /***********************************************************************
00383         
00384                 Throw an exception with the provided message
00385 
00386         ***********************************************************************/
00387 
00388         abstract void error (char[] msg);
00389 }
00390 
00391 
00392 /*******************************************************************************
00393 
00394         Any class implementing IDecoder can be bound to a reader using
00395         the setDecoder() method.
00396         
00397 *******************************************************************************/
00398 
00399 abstract class AbstractDecoder
00400 {       
00401         alias decoder opCall;
00402 
00403         abstract uint type ();
00404 
00405         abstract void bind (IBuffer buffer);
00406 
00407         abstract uint decoder (void* x, uint bytes, uint type);
00408 }
00409 
00410 
00411 /*******************************************************************************
00412 
00413         Any class implementing IEncoder can be bound to a writer using
00414         the bind() method.
00415         
00416 *******************************************************************************/
00417 
00418 abstract class AbstractEncoder
00419 {
00420         alias encoder opCall;
00421 
00422         abstract uint type ();
00423 
00424         abstract void bind (IBuffer buffer);
00425 
00426         abstract uint encoder (void* x, uint bytes, uint type);
00427 }
00428 

Generated on Sat Dec 24 17:28:33 2005 for Mango by  doxygen 1.4.0