Main Page | Class Hierarchy | Alphabetical List | Class List | 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 
00027                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00028 
00029 
00030         @version        Initial version, March 2004      
00031         @author         Kris
00032 
00033 
00034 *******************************************************************************/
00035 
00036 module mango.io.model.IConduit;
00037 
00038 private import  mango.io.model.IBuffer;
00039 
00040 private import  mango.io.model.IResource;
00041 
00042 /*******************************************************************************
00043 
00044         Conduits provide virtualized access to external content, and 
00045         represent things like files or Internet connections. Conduits 
00046         are modelled by mango.io.model.IConduit, and implemented via 
00047         classes FileConduit and SocketConduit. 
00048         
00049         Additional kinds of conduit are easy to construct: one either 
00050         subclasses mango.io.Conduit, or implements mango.io.model.IConduit. 
00051         A conduit reads and writes from/to an IBuffer in large chunks, 
00052         typically the entire buffer.
00053 
00054 *******************************************************************************/
00055 
00056 interface IConduit : IResource, IConduitSource, IConduitSink
00057 {
00058         /***********************************************************************
00059         
00060                 Declare the End Of File identifer
00061 
00062         ***********************************************************************/
00063 
00064         enum {Eof = -1};
00065 
00066         /***********************************************************************
00067         
00068                 Attach a filter to the IConduit input. The filter is invoked
00069                 via its reader(void[]) method whenever a block of content is 
00070                 being read; the void[] array represents content destination.
00071                 The filter should return the number of bytes it has actually
00072                 produced: less than or equal to the length of the provided 
00073                 array. 
00074 
00075                 Filters are chained together such that the last filter added
00076                 is the first one invoked. It is the responsibility of each
00077                 filter to invoke the next link in the chain; for example:
00078 
00079                 @code
00080                 class MungingInputFilter : FilterInput
00081                 {
00082                         int reader (void[] dst)
00083                         {
00084                                 // read the next X bytes
00085                                 int count = next.reader (dst);
00086 
00087                                 // set everything to '*' !
00088                                 dst[0..count] = '*';
00089 
00090                                 // say how many we read
00091                                 return count;
00092                         }
00093                 }
00094                 @endcode
00095 
00096                 Notice how this filter invokes the 'next' instance before 
00097                 munging the content ... the far end of the chain is where
00098                 the original IConduit reader is attached, so it will get
00099                 invoked eventually assuming each filter invokes 'next'. 
00100                 If the next reader fails it will return IConduit.Eof, as
00101                 should your filter (or throw an IOException). From a client 
00102                 perspective, filters are attached like this:
00103 
00104                 @code
00105                 FileConduit fc = new FileConduit (...);
00106 
00107                 fc.attach (new ZipInputFilter);
00108                 fc.attach (new MungingInputFilter);
00109                 @endcode
00110 
00111                 Again, the last filter attached is the first one invoked 
00112                 when a block of content is actually read. Each filter has
00113                 two additional methods that it may use to control behavior:
00114 
00115                 @code
00116                 class FilterInput : IFilterInput
00117                 {
00118                         protected IFilterInput next;
00119 
00120                         void bind (IFilterInput next)
00121                         {
00122                                 this.next = next;
00123                         }
00124 
00125                         void unbind ()
00126                         {
00127                         }
00128                 }
00129                 @endcode
00130 
00131                 The first method is invoked when the filter is attached to a 
00132                 conduit, while the second is invoked just before the conduit 
00133                 is closed. Both of these may be overridden by the filter for
00134                 whatever purpose desired.
00135 
00136                 Note that an input filter can choose to sidestep reading from 
00137                 the conduit (per the usual case), and produce its input from 
00138                 somewhere else entirely. This mechanism supports the notion
00139                 of 'piping' between multiple conduits, or between a conduit 
00140                 and something else entirely; it's a bridging mechanism.
00141                 
00142         ***********************************************************************/
00143 
00144         void attach (IConduitSource input);
00145 
00146         /***********************************************************************
00147         
00148                 Attach a filter to the IConduit output. The filter is invoked
00149                 via its writer(void[]) method whenever a block of content is 
00150                 being written; the void[] array supplies writeable content.
00151                 The filter should return the number of bytes it has actually
00152                 consumed: less than or equal to the length of the provided 
00153                 array. 
00154 
00155                 Filters are chained together such that the last filter added
00156                 is the first one invoked. It is the responsibility of each
00157                 filter to invoke the next link in the chain; for example:
00158 
00159                 @code
00160                 class MungingOutputFilter : FilterOutput
00161                 {
00162                         int writer (void[] src)
00163                         {
00164                                 char[src.length] tmp;
00165 
00166                                 // set everything to '*'
00167                                 tmp = '*';
00168 
00169                                 // write the munged output
00170                                 return next.writer (tmp);
00171                         }
00172                 }
00173                 @endcode
00174 
00175                 Notice how the filter invokes the 'next' instance after 
00176                 munging the content ... the far end of the chain is where
00177                 the original IConduit writer is attached, so it will get
00178                 invoked eventually assuming each filter invokes 'next'.
00179                 If the next writer fails it will return IConduit.Eof, as
00180                 should your filter (or throw an IOException). At the client 
00181                 level, filters are attached like this:
00182 
00183                 @code
00184                 FileConduit fc = new FileConduit (...);
00185 
00186                 fc.attach (new ZipOutputFilter);
00187                 fc.attach (new MungingOutputFilter);
00188                 @endcode
00189 
00190                 Again, the last filter attached is the first one invoked 
00191                 when a block of content is actually written. Each filter has
00192                 two additional methods that it may use to control behavior:
00193 
00194                 @code
00195                 class FilterOutput : IFilterOutput
00196                 {
00197                         protected IFilterOutput next;
00198 
00199                         void bind (IFilterOutput next)
00200                         {
00201                                 this.next = next;
00202                         }
00203 
00204                         void unbind ()
00205                         {
00206                         }
00207                 }
00208                 @endcode
00209 
00210                 The first method is invoked when the filter is attached to a 
00211                 conduit, while the second is invoked just before the conduit 
00212                 is closed. Both of these may be overridden by the filter for
00213                 whatever purpose desired.
00214 
00215                 Note that an output filter can choose to sidestep writing to 
00216                 the conduit (per the usual case), and direct its output to 
00217                 somewhere else entirely. This mechanism supports the notion
00218                 of 'piping' between multiple conduits, or between a conduit 
00219                 and something else entirely; as with the input-filter case,
00220                 this is a bridging mechanism.
00221 
00222         ***********************************************************************/
00223 
00224         void attach (IConduitSink output);
00225 
00226         /***********************************************************************
00227                 
00228                 read from conduit into a target buffer
00229 
00230         ***********************************************************************/
00231 
00232         int read (IBuffer target);               
00233 
00234         /***********************************************************************
00235         
00236                 write to conduit from a source buffer
00237 
00238         ***********************************************************************/
00239 
00240         int write (IBuffer source);               
00241 
00242         /***********************************************************************
00243         
00244                 Transfer the content of this conduit to another one. 
00245                 Returns true if all content was successfully copied.
00246         
00247         ***********************************************************************/
00248 
00249         IConduit copy (IConduit source);
00250 
00251         /***********************************************************************
00252         
00253                 Flush buffer content out to this conduit.
00254 
00255                 Returns true if all content is flushed; false if writing 
00256                 results in an Eof condition.
00257                         
00258         ***********************************************************************/
00259 
00260         IConduit flush (IBuffer source);
00261 
00262         /***********************************************************************
00263         
00264                 Create a Buffer of a conduit-specific size
00265 
00266         ***********************************************************************/
00267 
00268         IBuffer createBuffer (); 
00269                      
00270         /***********************************************************************
00271         
00272                 Returns true is this conduit can be read from
00273 
00274         ***********************************************************************/
00275 
00276         bool isReadable ();
00277 
00278         /***********************************************************************
00279         
00280                 Returns true if this conduit can be written to
00281 
00282         ***********************************************************************/
00283 
00284         bool isWritable ();
00285 
00286         /***********************************************************************
00287         
00288                 Returns true if this conduit is seekable (whether it 
00289                 implements ISeekable)
00290 
00291         ***********************************************************************/
00292 
00293         bool isSeekable ();
00294 }
00295 
00296 
00297 
00298 /*******************************************************************************
00299 
00300         Defines an input-filter contract. The filter is invoked
00301         via its reader(void[]) method whenever a block of content is 
00302         being read; the void[] array represents content destination.
00303         The filter should return the number of bytes it has actually
00304         produced: less than or equal to the length of the provided 
00305         array. 
00306 
00307         Filters are chained together such that the last filter added
00308         is the first one invoked. It is the responsibility of each
00309         filter to invoke the next link in the chain; for example:
00310 
00311         @code
00312         class MungingInputFilter : FilterInput
00313         {
00314                 int reader (void[] dst)
00315                 {
00316                         // read the next X bytes
00317                         int count = next.reader (dst);
00318 
00319                         // set everything to '*' !
00320                         dst[0..count] = '*';
00321 
00322                         // say how many we read
00323                         return count;
00324                 }
00325         }
00326         @endcode
00327 
00328         Notice how this filter invokes the 'next' instance before 
00329         munging the content ... the far end of the chain is where
00330         the original IConduit reader is attached, so it will get
00331         invoked eventually assuming each filter invokes 'next'. 
00332         If the next reader fails it will return IConduit.Eof, as
00333         should your filter (or throw an IOException). From a client 
00334         perspective, filters are attached like this:
00335 
00336         @code
00337         FileConduit fc = new FileConduit (...);
00338 
00339         fc.attach (new ZipInputFilter);
00340         fc.attach (new MungingInputFilter);
00341         @endcode
00342 
00343         Again, the last filter attached is the first one invoked 
00344         when a block of content is actually read. Each filter has
00345         two additional methods that it may use to control behavior:
00346 
00347         @code
00348         class FilterInput : IFilterInput
00349         {
00350                 protected IFilterInput next;
00351 
00352                 void bind (IFilterInput next)
00353                 {
00354                         this.next = next;
00355                 }
00356 
00357                 void unbind ()
00358                 {
00359                 }
00360         }
00361         @endcode
00362 
00363         The first method is invoked when the filter is attached to a 
00364         conduit, while the second is invoked just before the conduit 
00365         is closed. Both of these may be overridden by the filter for
00366         whatever purpose desired.
00367 
00368         Note that an input filter can choose to sidestep reading from 
00369         the conduit (per the usual case), and produce its input from 
00370         somewhere else entirely. This mechanism supports the notion
00371         of 'piping' between multiple conduits, or between a conduit 
00372         and something else entirely; it's a bridging mechanism.
00373 
00374 *******************************************************************************/
00375 
00376 interface IConduitSource
00377 {
00378         /***********************************************************************
00379         
00380                 conduit-specific reader
00381 
00382         ***********************************************************************/
00383 
00384         int reader (void[] dst);               
00385                              
00386         /***********************************************************************
00387         
00388         ***********************************************************************/
00389 
00390         void bind (IConduitSource next);                       
00391                               
00392         /***********************************************************************
00393         
00394         ***********************************************************************/
00395 
00396         void unbind ();
00397 }
00398 
00399 
00400 /*******************************************************************************
00401 
00402         Defines an output-filter contract. The filter is invoked
00403         via its writer(void[]) method whenever a block of content is 
00404         being written; the void[] array supplies writeable content.
00405         The filter should return the number of bytes it has actually
00406         consumed: less than or equal to the length of the provided 
00407         array. 
00408 
00409         Filters are chained together such that the last filter added
00410         is the first one invoked. It is the responsibility of each
00411         filter to invoke the next link in the chain; for example:
00412 
00413         @code
00414         class MungingOutputFilter : FilterOutput
00415         {
00416                 int writer (void[] src)
00417                 {
00418                         char[src.length] tmp;
00419 
00420                         // set everything to '*'
00421                         tmp = '*';
00422 
00423                         // write the munged output
00424                         return next.writer (tmp);
00425                 }
00426         }
00427         @endcode
00428 
00429         Notice how the filter invokes the 'next' instance after 
00430         munging the content ... the far end of the chain is where
00431         the original IConduit writer is attached, so it will get
00432         invoked eventually assuming each filter invokes 'next'.
00433         If the next writer fails it will return IConduit.Eof, as
00434         should your filter (or throw an IOException). At the client 
00435         level, filters are attached like this:
00436 
00437         @code
00438         FileConduit fc = new FileConduit (...);
00439 
00440         fc.attach (new ZipOutputFilter);
00441         fc.attach (new MungingOutputFilter);
00442         @endcode
00443 
00444         Again, the last filter attached is the first one invoked 
00445         when a block of content is actually written. Each filter has
00446         two additional methods that it may use to control behavior:
00447 
00448         @code
00449         class FilterOutput : IFilterOutput
00450         {
00451                 protected IFilterOutput next;
00452 
00453                 void bind (IFilterOutput next)
00454                 {
00455                         this.next = next;
00456                 }
00457 
00458                 void unbind ()
00459                 {
00460                 }
00461         }
00462         @endcode
00463 
00464         The first method is invoked when the filter is attached to a 
00465         conduit, while the second is invoked just before the conduit 
00466         is closed. Both of these may be overridden by the filter for
00467         whatever purpose desired.
00468 
00469         Note that an output filter can choose to sidestep writing to 
00470         the conduit (per the usual case), and direct its output to 
00471         somewhere else entirely. This mechanism supports the notion
00472         of 'piping' between multiple conduits, or between a conduit 
00473         and something else entirely; as with the input-filter case,
00474         this is a bridging mechanism.
00475 
00476 *******************************************************************************/
00477 
00478 interface IConduitSink
00479 {
00480         /***********************************************************************
00481         
00482                 conduit-specific writer
00483 
00484         ***********************************************************************/
00485 
00486         int writer (void[] src);  
00487                              
00488         /***********************************************************************
00489         
00490         ***********************************************************************/
00491 
00492         void bind (IConduitSink next);                       
00493                               
00494         /***********************************************************************
00495         
00496         ***********************************************************************/
00497 
00498         void unbind ();
00499 }
00500 
00501 
00502 
00503 
00504 /*******************************************************************************
00505 
00506         Models the ability to seek within a conduit. 
00507 
00508 *******************************************************************************/
00509 
00510 interface ISeekable
00511 {
00512         /***********************************************************************
00513         
00514                 The anchor positions supported by ISeekable
00515 
00516         ***********************************************************************/
00517 
00518         enum SeekAnchor {
00519                         Begin   = 0,
00520                         Current = 1,
00521                         End     = 2,
00522                         };
00523 
00524         /***********************************************************************
00525                         
00526                 Return the current conduit position (such as file position)
00527                 
00528         ***********************************************************************/
00529 
00530         long getPosition ();
00531 
00532         /***********************************************************************
00533         
00534                 Move the file position to the given offset (from the conduit 
00535                 start) and return the adjusted position.
00536 
00537         ***********************************************************************/
00538 
00539         long seek (long offset);
00540 
00541         /***********************************************************************
00542         
00543                 Move the file position to the given offset from the provided 
00544                 anchor point, and return the adjusted position.
00545 
00546         ***********************************************************************/
00547 
00548         long seek (long offset, SeekAnchor anchor);
00549 }
00550 

Generated on Sun Nov 7 19:06:52 2004 for Mango by doxygen 1.3.6