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

Generated on Sun Mar 6 00:30:57 2005 for Mango by doxygen 1.3.6