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

IConduit.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file IConduit.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.IConduit;
00040 
00041 /*******************************************************************************
00042 
00043         Conduits provide virtualized access to external content, and 
00044         represent things like files or Internet connections. Conduits 
00045         are modelled by mango.io.model.IConduit, and implemented via 
00046         classes FileConduit and SocketConduit. 
00047         
00048         Additional kinds of conduit are easy to construct: one either 
00049         subclasses mango.io.Conduit, or implements mango.io.model.IConduit. 
00050         A conduit typically reads and writes from/to an IBuffer in large 
00051         chunks, typically the entire buffer. Alternatively, one can invoke 
00052         read(dst[]) and/or write(src[]) directly.
00053 
00054 *******************************************************************************/
00055 
00056 interface IConduit
00057 {
00058         /***********************************************************************
00059         
00060                 Declare the End Of File identifer
00061 
00062         ***********************************************************************/
00063 
00064         enum {Eof = uint.max};
00065 
00066         /***********************************************************************
00067                 
00068                 read from conduit into a target array
00069 
00070         ***********************************************************************/
00071 
00072         abstract uint read (void[] dst);               
00073 
00074         /***********************************************************************
00075         
00076                 write to conduit from a source array
00077 
00078         ***********************************************************************/
00079 
00080         abstract uint write (void[] src);               
00081 
00082         /***********************************************************************
00083         
00084                 flush provided content to the conduit
00085 
00086         ***********************************************************************/
00087 
00088         abstract bool flush (void[] src);
00089 
00090         /***********************************************************************
00091         
00092                 Transfer the content of this conduit to another one. 
00093                 Returns true if all content was successfully copied.
00094         
00095         ***********************************************************************/
00096 
00097         abstract IConduit copy (IConduit source);
00098 
00099         /***********************************************************************
00100         
00101                 Attach a filter to this conduit: see IConduitFilter
00102 
00103         ***********************************************************************/
00104 
00105         abstract void attach (IConduitFilter filter);
00106 
00107         /***********************************************************************
00108         
00109                 Return a preferred size for buffering conduit I/O
00110 
00111         ***********************************************************************/
00112 
00113         abstract uint bufferSize (); 
00114                      
00115         /***********************************************************************
00116         
00117                 Returns true is this conduit can be read from
00118 
00119         ***********************************************************************/
00120 
00121         abstract bool isReadable ();
00122 
00123         /***********************************************************************
00124         
00125                 Returns true if this conduit can be written to
00126 
00127         ***********************************************************************/
00128 
00129         abstract bool isWritable ();
00130 
00131         /***********************************************************************
00132         
00133                 Returns true if this conduit is seekable (whether it 
00134                 implements ISeekable)
00135 
00136         ***********************************************************************/
00137 
00138         abstract bool isSeekable ();
00139 
00140         /***********************************************************************
00141         
00142                 Returns true if this conduit is text-based
00143 
00144         ***********************************************************************/
00145 
00146         bool isTextual ();
00147 
00148         /***********************************************************************
00149                 
00150                 Release external resources
00151 
00152         ***********************************************************************/
00153 
00154         abstract void close ();
00155 }
00156 
00157 
00158 /*******************************************************************************
00159         
00160         Define a conduit filter base-class. The filter is invoked
00161         via its reader() method whenever a block of content is 
00162         being read, and by its writer() method whenever content is
00163         being written. 
00164 
00165         The filter should return the number of bytes it has actually
00166         produced: less than or equal to the length of the provided 
00167         array. 
00168 
00169         Filters are chained together such that the last filter added
00170         is the first one invoked. It is the responsibility of each
00171         filter to invoke the next link in the chain; for example:
00172 
00173         @code
00174         class MungingFilter : ConduitFilter
00175         {
00176                 int reader (void[] dst)
00177                 {
00178                         // read the next X bytes
00179                         int count = next.reader (dst);
00180 
00181                         // set everything to '*' !
00182                         dst[0..count] = '*';
00183 
00184                         // say how many we read
00185                         return count;
00186                 }
00187 
00188                 int writer (void[] src)
00189                 {
00190                         byte[] tmp = new byte[src.length];
00191 
00192                         // set everything to '*'
00193                         tmp = '*';
00194 
00195                         // write the munged output
00196                         return next.writer (tmp);
00197                 }
00198         }
00199         @endcode
00200 
00201         Notice how this filter invokes the 'next' instance before 
00202         munging the content ... the far end of the chain is where
00203         the original IConduit reader is attached, so it will get
00204         invoked eventually assuming each filter invokes 'next'. 
00205         If the next reader fails it will return IConduit.Eof, as
00206         should your filter (or throw an IOException). From a client 
00207         perspective, filters are attached like this:
00208 
00209         @code
00210         FileConduit fc = new FileConduit (...);
00211 
00212         fc.attach (new ZipFilter);
00213         fc.attach (new MungingFilter);
00214         @endcode
00215 
00216         Again, the last filter attached is the first one invoked 
00217         when a block of content is actually read. Each filter has
00218         two additional methods that it may use to control behavior:
00219 
00220         @code
00221         class ConduitFilter : IConduitFilter
00222         {
00223                 protected IConduitFilter next;
00224 
00225                 void bind (IConduit conduit, IConduitFilter next)
00226                 {
00227                         this.next = next;
00228                 }
00229 
00230                 void unbind ()
00231                 {
00232                 }
00233         }
00234         @endcode
00235 
00236         The first method is invoked when the filter is attached to a 
00237         conduit, while the second is invoked just before the conduit 
00238         is closed. Both of these may be overridden by the filter for
00239         whatever purpose desired.
00240 
00241         Note that a conduit filter can choose to sidestep reading from 
00242         the conduit (per the usual case), and produce its input from 
00243         somewhere else entirely. This mechanism supports the notion
00244         of 'piping' between multiple conduits, or between a conduit 
00245         and something else entirely; it's a bridging mechanism.
00246 
00247 *******************************************************************************/
00248 
00249 interface IConduitFilter
00250 {
00251         /***********************************************************************
00252         
00253                 filter-specific reader
00254 
00255         ***********************************************************************/
00256 
00257         abstract uint reader (void[] dst);               
00258                              
00259         /***********************************************************************
00260         
00261                 filter-specific writer
00262 
00263         ***********************************************************************/
00264 
00265         abstract uint writer (void[] dst);               
00266                              
00267         /***********************************************************************
00268         
00269         ***********************************************************************/
00270 
00271         abstract void bind (IConduit conduit, IConduitFilter next);                       
00272                               
00273         /***********************************************************************
00274         
00275         ***********************************************************************/
00276 
00277         abstract void unbind ();
00278 }
00279 
00280 
00281 /*******************************************************************************
00282 
00283         Models the ability to seek within a conduit. 
00284 
00285 *******************************************************************************/
00286 
00287 interface ISeekable
00288 {
00289         /***********************************************************************
00290         
00291                 The anchor positions supported by ISeekable
00292 
00293         ***********************************************************************/
00294 
00295         enum SeekAnchor {
00296                         Begin   = 0,
00297                         Current = 1,
00298                         End     = 2,
00299                         };
00300 
00301         /***********************************************************************
00302                         
00303                 Return the current conduit position (such as file position)
00304                 
00305         ***********************************************************************/
00306 
00307         abstract ulong getPosition ();
00308 
00309         /***********************************************************************
00310         
00311                 Move the file position to the given offset from the provided 
00312                 anchor point, and return the adjusted position.
00313 
00314         ***********************************************************************/
00315 
00316         abstract ulong seek (ulong offset, SeekAnchor anchor=SeekAnchor.Begin);
00317 }
00318 
00319 
00320 /*******************************************************************************
00321 
00322         Defines how a Conduit should be opened. This is typically subsumed
00323         by another structure     
00324 
00325 *******************************************************************************/
00326 
00327 struct ConduitStyle
00328 {
00329         align(1):
00330 
00331         struct Bits
00332         {
00333                 Access access;                          // access rights
00334         }
00335 
00336         /***********************************************************************
00337         
00338         ***********************************************************************/
00339 
00340         enum Access : ubyte     {
00341                                 Read      = 0x01,       // is readable
00342                                 Write     = 0x02,       // is writable 
00343                                 ReadWrite = 0x03,       // both 
00344                                 Mask      = 0x7f,       // ignore Text flag!
00345                                 Text      = 0x80,
00346                                 };
00347 
00348         /***********************************************************************
00349         
00350                 Setup common instances of conduit styles
00351 
00352         ***********************************************************************/
00353 
00354         const Bits Read = {Access.Read};
00355         const Bits Write = {Access.Write};
00356         const Bits ReadWrite = {Access.ReadWrite}; 
00357 
00358         const Bits ReadText = {Access.Read + Access.Text};
00359         const Bits WriteText = {Access.Write + Access.Text};
00360         const Bits ReadWriteText = {Access.ReadWrite + Access.Text}; 
00361 }
00362 
00363 

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