Changeset 898

Show
Ignore:
Timestamp:
05/29/06 18:19:25 (2 years ago)
Author:
kris
Message:

updated doc

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/mango/io/Buffer.d

    r798 r898  
    11/******************************************************************************* 
    22 
    3         @file Buffer.d 
    4  
    5         Copyright (c) 2004 Kris Bell 
     3        file:           _Buffer.d 
     4 
     5        copyright:      (c) 2004 Kris Bell; all rights reserved 
     6 
     7        authors:        Kris 
     8 
     9        version:        Initial version; March 2004 
     10 
     11        license:        BSD style 
    612         
    713        This software is provided 'as-is', without any express or implied 
     
    2228 
    2329        3. This notice may not be removed or altered from any distribution 
    24            of the source. 
    25  
    26         4. Derivative works are permitted, but they must carry this notice 
    27            in full and credit the original source. 
    28  
    29  
    30                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    31  
    32        
    33         @version        Initial version; March 2004 
    34  
    35         @author         Kris 
    36  
     30           of the source, and applies to all variations including, but not 
     31           limited to, original source, derived source, and altered source. 
     32 
     33        Copyright (c) 2004 Kris Bell; all rights reserved 
    3734 
    3835*******************************************************************************/ 
     
    5350extern (C) 
    5451{ 
    55         void * memcpy (void *dst, void *src, uint); 
     52        private void * memcpy (void *dst, void *src, uint); 
    5653}        
    5754 
    5855/******************************************************************************* 
    5956 
    60         The basic premise behind this IO package is as follows: 
    61  
    62         @li The central concept is that of a buffer. The buffer acts 
    63            as a queue (line) where items are removed from the front 
    64            and new items are added to the back. Buffers are modeled  
    65            by mango.io.model.IBuffer, and a concrete implementation is  
    66            provided this class. 
    67  
    68         @li Buffers can be written to directly, but a Reader and/or 
    69            Writer are typically used to read & write formatted data. 
    70            These readers & writers are bound to a specific buffer; 
    71            often the same buffer. It's also perfectly legitimate to  
    72            bind multiple writers to the same buffer; they will all 
    73            behave serially as one would expect. The same applies to 
    74            multiple readers on the same buffer. Readers and writers 
    75            support three styles of IO: put/get, the C++ style << & 
    76            >> operators, and the () whisper style. All operations  
    77            can be chained. 
    78  
    79         @li Any class can be made compatable with the reader/writer 
    80            framework by implementing the IReadable and/or IWritable  
    81            interfaces. Each of these specify just a single method. 
    82            Once compatable, the class can simply be passed to the  
    83            reader/writer as if it were native data. 
    84  
    85         @li Buffers may also be tokenized. This is handy when one is 
    86            dealing with text input, and/or the content suits a more 
    87            fluid format than most typical readers & writers support. 
    88            Tokens are mapped directly onto buffer content, so there 
    89            is only minor overhead in using them. Tokens can be read 
    90            and written by reader/writers also, using a more relaxed 
    91            set of rules than those applied to discrete I/O. 
    92  
    93         @li Buffers are sometimes memory-only, in which case there 
    94            is nothing left to do when a reader (or tokenizer) hits 
    95            end of buffer conditions. Other buffers are themselves  
    96            bound to a Conduit. When this is the case, a reader will  
    97            eventually cause the buffer to reload via its associated  
    98            conduit. Previous buffer content will thus be lost. The 
    99            same concept is applied to writers, whereby they flush  
    100            the content of a full buffer to a bound conduit before  
    101            continuing.  
    102  
    103         @li Conduits provide virtualized access to external content, 
    104            and represent things like files or Internet connections. 
    105            They are just a different kind of stream. Conduits are 
    106            modelled by mango.io.model.IConduit, and implemented via 
    107            classes FileConduit and SocketConduit. Additional kinds 
    108            of conduit are easy to construct: one either subclasses 
    109            mango.io.Conduit, or implements mango.io.model.IConduit.  
    110            A conduit reads and writes from/to a buffer in big chunks 
    111            (typically the entire buffer). 
    112  
    113         @li Conduits may have one or more filters attached. These  
    114             will process content as it flows back and forth across 
    115             the conduit. Filter examples include compression, utf 
    116             transcoding, and endian transformation. These filters 
    117             apply to the entire scope of the conduit, rather than 
    118             being specific to one data-type or another. 
    119  
    120         @li Readers & writers may have a transcoder attached. The 
    121            role of a transcoder is to aid in converting between each 
    122            representation of text (utf8, utf16, utf32). They're used 
    123            to normalize string I/O according to a standard text-type. 
    124            By default there is no transcoder attached, and the type 
    125            is therefore considered "raw".            
    126  
    127  
    128         An example of how to append a buffer follows: 
    129  
    130         @code 
    131         char[] foo = "to write some D"; 
    132  
     57        The premise behind this IO package is as follows: 
     58 
     59        The central concept is that of a buffer. The buffer acts 
     60        as a queue (line) where items are removed from the front 
     61        and new items are added to the back. Buffers are modeled  
     62        by mango.io.model.IBuffer, and a concrete implementation  
     63        is provided by this class. 
     64         
     65        Buffers can be read and written directly, but a Reader,  
     66        Iterator, and/or Writer are often leveraged to apply  
     67        structure to what might otherwise be simple raw data.  
     68 
     69        Readers & writers are bound to a buffer; often the same  
     70        buffer. It's also perfectly legitimate to bind multiple  
     71        readers to the same buffer; they will access buffer  
     72        content serially as one would expect. This also applies to 
     73        multiple writers on the same buffer. Readers and writers 
     74        support three styles of IO: put/get, the C++ style << & 
     75        >> operators, and the () whisper style. All operations  
     76        can be chained. 
     77         
     78        Any class can be made compatable with the reader/writer 
     79        framework by implementing the IReadable and/or IWritable  
     80        interfaces. Each of these specify just a single method. 
     81        Once compatable, the class can simply be passed to the  
     82        reader/writer as if it were native data. 
     83         
     84        Buffers may also be tokenized by applying an Iterator.  
     85        This can be handy when one is dealing with text input,  
     86        and/or the content suits a more fluid format than most  
     87        typical readers & writers support. Iterator tokens 
     88        are mapped directly onto buffer content (sliced), making  
     89        them quite efficient in practice. Like Readers, multiple 
     90        iterators can be mapped onto a common buffer; access is 
     91        serialized in a similar fashion. 
     92 
     93        Conduits provide virtualized access to external content, 
     94        and represent things like files or Internet connections. 
     95        They are just a different kind of stream. Conduits are 
     96        modelled by mango.io.model.IConduit, and implemented via 
     97        classes FileConduit, SocketConduit, ConsoleConduit, and  
     98        so on. Additional conduit varieties are easy to construct:  
     99        one either subclasses mango.io.Conduit, or implements  
     100        mango.io.model.IConduit. Each conduit reads and writes  
     101        from/to a buffer in big chunks (typically the entire  
     102        buffer). 
     103 
     104        Conduits may have one or more filters attached. These  
     105        will process content as it flows back and forth across 
     106        the conduit. Examples of filters include compression, utf 
     107        transcoding, and endian transformation. These filters 
     108        apply to the entire scope of the conduit, rather than 
     109        being specific to one data-type or another. Specific  
     110        data-type transformations are applied by readers and  
     111        writers instead, and include operations such as  
     112        endian-conversion. 
     113 
     114        Buffers are sometimes memory-only, in which case there 
     115        is nothing left to do when a reader (or iterator) hits 
     116        end of buffer conditions. Other buffers are themselves  
     117        bound to a Conduit. When this is the case, a reader will  
     118        eventually cause the buffer to reload via its associated  
     119        conduit. Previous buffer content will thus be lost. The 
     120        same approach is applied to writers, whereby they flush  
     121        the content of a full buffer to a bound conduit before  
     122        continuing. Another variation is that of a memory-mapped 
     123        buffer, whereby the buffer content is mapped directly to 
     124        virtual memory exposed via the oS. This can be used to  
     125        address large files as an array of content. 
     126 
     127        Readers & writers may have a transcoder attached. The 
     128        role of a transcoder is to aid in converting between each 
     129        representation of text (utf8, utf16, utf32). They're used 
     130        to normalize string I/O according to a standard text-type. 
     131        By default there is no transcoder attached, and the type 
     132        is therefore considered "raw". 
     133 
     134        Direct buffer manipulation typically involves appending,  
     135        as in the following example: 
     136        --- 
    133137        // create a small buffer 
    134138        auto buf = new Buffer (256); 
    135139 
     140        auto foo = "to write some D"; 
     141 
    136142        // append some text directly to it 
    137143        buf.append("now is the time for all good men ").append(foo); 
    138  
    139         // output the combined string 
    140         Cout (buf.toString); 
    141         @endcode 
    142  
    143         Alternatively, one might use a Writer to append the buffer: 
    144  
    145         @code 
     144        --- 
     145 
     146        Alternatively, one might use a Writer to append the buffer.  
     147        This is an example of the 'whisper' style supported by the 
     148        IO package: 
     149        --- 
    146150        auto write = new Writer (new Buffer(256)); 
    147151        write ("now is the time for all good men "c) (foo); 
    148         @endcode 
    149  
    150         Or, using printf-like formatting: 
    151  
    152         @code 
     152        --- 
     153 
     154        Or, using printf-like formatting via a text oriented DisplayWriter: 
     155        --- 
    153156        auto write = new DisplayWriter (new Buffer(256)); 
    154157        write.print ("now is the time for %d good men %s", 3, foo); 
    155         @endcode 
    156  
    157         You might use a GrowBuffer instead where you wish to  
    158         append beyond a preset limit. One common usage of buffers  
    159         is in conjunction with a conduit, such as FileConduit. Each  
    160         conduit exposes a preferred-size for its associated buffers,  
    161         utilized during Buffer construction: 
    162  
    163         @code 
     158        --- 
     159 
     160        One might use a GrowBuffer instead, where one wishes to append 
     161        beyond the specified size.  
     162         
     163        A common usage of a buffer is in conjunction with a conduit,  
     164        such as FileConduit. Each conduit exposes a preferred-size for  
     165        its associated buffers, utilized during buffer construction: 
     166        --- 
    164167        auto file = new FileConduit ("file.name"); 
    165168        auto buf = new Buffer (file); 
    166         @endcode 
     169        --- 
    167170 
    168171        However, this is typically hidden by higher level constructors  
    169172        such as those of Reader and Writer derivitives. For example: 
    170  
    171         @code 
     173        --- 
    172174        auto file = new FileConduit ("file.name"); 
    173175        auto read = new Reader (file); 
    174         @endcode 
     176        --- 
    175177 
    176178        There is indeed a buffer between the Reader and Conduit, but  
    177         explicit construction is unecessary in most cases. See both  
     179        explicit construction is unecessary in common cases. See both  
    178180        Reader and Writer for examples of formatted IO. 
    179181 
    180182        Stdout is a predefined DisplayWriter, attached to a conduit 
    181183        representing the console. Thus, all conduit operations are 
    182         legitimate on Stdout and Stderr: 
    183  
    184         @code 
     184        legitimate on Stdout and Stderr. For example: 
     185        --- 
    185186        Stdout.conduit.copy (new FileConduit ("readme.txt")); 
    186         @endcode 
    187  
    188         In addition to the standard writer facilities, Stdout also has 
     187        --- 
     188 
     189        Because Stdout is an instance of DisplayWriter, it also has 
    189190        support for formatted output: 
    190  
    191         @code  
     191        --- 
    192192        Stdout.println ("now is the time for %d good men %s", 3, foo); 
    193         @endcode 
     193        --- 
     194 
     195        The Stdout writer is attached to a specific buffer, which in 
     196        turn is attached to a specific conduit. This buffer is known  
     197        as Cout, and it is attached to a conduit representing the  
     198        console. Cout can be used directly, bypassing the writer layer 
     199        if so desired.  
     200         
     201        Cout has relatives named Cerr and Cin, which are attached to  
     202        the corresponding console conduits. Writer Stderr, and reader  
     203        Stdin are mapped onto Cerr and Cin respectively, ensuring  
     204        console IO is buffered in one common area.  
     205        --- 
     206        Cout ("what is your name?"); 
     207        char[] name; 
     208        Cin (name); 
     209        Cout ("hello ") (name) .newline; 
     210        --- 
     211 
     212        An Iterator is constructed in a similar manner to a Reader; you 
     213        provide it with a buffer or a conduit. There's a variety of  
     214        iterators available in the mango.text package, and they are each 
     215        templated for utf8, utf16, and utf32 ~ this example uses a line  
     216        iterator to sweep a text file: 
     217        --- 
     218        auto file = new FileConduit ("file.name"); 
     219        foreach (line; new LineIterator (file)) 
     220                 Cout(line).newline; 
     221        ---                  
    194222 
    195223        Buffers are useful for many purposes within Mango, but there 
    196         are times when it is more straightforward to avoid them. For 
    197         such cases, conduit derivatives (such as FileConduit) support 
    198         direct I/O via a pair of read() and write() methods. These  
    199         alternate methods will also invoke any attached filters. 
     224        are times when it may be more appropriate to sidestep them. For  
     225        such cases, conduit derivatives (such as FileConduit) support  
     226        direct array-based IO via a pair of read() and write() methods.  
     227        These alternate methods will also invoke any attached filters. 
    200228 
    201229 
     
    204232class Buffer : IBuffer 
    205233{ 
    206         protected void[]        data; 
    207         protected Style         style; 
    208         protected uint          limit; 
    209         protected uint          capacity; 
    210         protected uint          position; 
    211         protected IConduit      conduit; 
    212  
     234        protected void[]        data;           // the raw data 
     235        protected Style         style;          // Text, Binary, Raw 
     236        protected uint          limit;          // limit of valid content 
     237        protected uint          capacity;       // maximum of limit 
     238        protected uint          position;       // current read position 
     239        protected IConduit      conduit;        // optional conduit 
     240 
     241         
    213242        protected static char[] overflow  = "output buffer overflow"; 
    214243        protected static char[] underflow = "input buffer underflow"; 
     
    230259        /*********************************************************************** 
    231260         
    232                 Construct a Buffer upon the provided conduit 
     261                Construct a Buffer upon the provided conduit. A relevant  
     262                buffer size is supplied via the provided conduit. 
    233263 
    234264        ***********************************************************************/ 
     
    243273        /*********************************************************************** 
    244274         
    245                 Construct a Buffer with the specified number of bytes. 
    246  
    247         ***********************************************************************/ 
    248  
    249         this (uint capacity=0) 
     275                Construct a Buffer with the specified number of bytes.  
     276 
     277        ***********************************************************************/ 
     278 
     279        this (uint capacity = 0) 
    250280        { 
    251281                this (new ubyte[capacity]);               
     
    291321        /*********************************************************************** 
    292322                 
    293                 Return the backing array 
    294  
    295         ***********************************************************************/ 
    296  
    297         protected void[] getContent () 
    298         { 
    299                 return data; 
    300         } 
    301  
    302         /*********************************************************************** 
    303                  
    304                 Return style of buffer 
     323                Return style of buffer. This is either Text, Binary, or Raw. 
     324                The style is initially set via a constructor 
    305325 
    306326        ***********************************************************************/ 
     
    315335                Set the backing array with all content readable. Writing 
    316336                to this will either flush it to an associated conduit, or 
    317                 raise an Eof condition. Use IBuffer.clear() to reset the 
     337                raise an Eof condition. Use clear() to reset the 
    318338                content (make it all writable). 
    319339 
     
    329349                Set the backing array with some content readable. Writing 
    330350                to this will either flush it to an associated conduit, or 
    331                 raise an Eof condition. Use IBuffer.clear() to reset the 
     351                raise an Eof condition. Use clear() to reset the 
    332352                content (make it all writable). 
    333353 
     
    348368        /*********************************************************************** 
    349369         
    350                 Bulk copy of data from 'src'. Limit is adjusted by 'size' 
    351                 bytes. 
    352  
    353         ***********************************************************************/ 
    354  
    355         protected void copy (void *src, uint size) 
    356         { 
    357                 data[limit..limit+size] = src[0..size]; 
    358                 limit += size; 
    359         } 
    360  
    361         /*********************************************************************** 
    362          
    363                 Read a chunk of data from the buffer, loading from the 
     370                Read a slice of data from the buffer, loading from the 
    364371                conduit as necessary. The specified number of bytes is 
    365372                loaded into the buffer, and marked as having been read  
    366373                when the 'eat' parameter is set true. When 'eat' is set 
    367374                false, the read position is not adjusted. 
     375 
     376                Note that the slice cannot be larger than the size of  
     377                the buffer ~ use method get(void[]) instead where you 
     378                simply want the content copied, or use conduit.read() 
     379                to extract directly from an attached conduit. 
    368380 
    369381                Returns the corresponding buffer slice when successful,  
     
    403415 
    404416        /*********************************************************************** 
    405          
     417 
    406418                Fill the provided array with content. We try to satisfy  
    407419                the request from the buffer content, and read directly 
    408                 from the conduit where more is required. 
     420                from an attached conduit where more is required. 
    409421 
    410422                Returns true if the request was satisfied; false otherwise 
     
    434446                the current thread forever, although usage of SocketConduit  
    435447                will take advantage of the timeout facilities provided there. 
     448 
     449                Note that this is not intended to provide 'barrier' style  
     450                semantics for multi-threaded producer/consumer environments. 
    436451 
    437452        ***********************************************************************/ 
     
    479494        /*********************************************************************** 
    480495         
    481                 Return a char[] slice of the buffer up to the limit of 
    482                 valid content. 
     496                Append another buffer to this one, and flush to the 
     497                conduit as necessary. Returns a chaining reference if all  
     498                data was written; throws an IOException indicating eof or  
     499                eob if not. 
     500 
     501                This is often used in lieu of a Writer. 
     502 
     503        ***********************************************************************/ 
     504 
     505        IBuffer append (IBuffer other)         
     506        {                
     507                return append (other.toString); 
     508        } 
     509 
     510        /*********************************************************************** 
     511         
     512                Return a char[] slice of the buffer, from the current position  
     513                up to the limit of valid content. The content remains in the 
     514                buffer for future extraction. 
    483515 
    484516        ***********************************************************************/ 
     
    494526                the associated conduit as necessary. 
    495527         
    496                 Can also reverse the read position by 'size' bytes. This may 
    497                 be used to support lookahead-type operations. 
     528                Can also reverse the read position by 'size' bytes, when size 
     529                is negative. This may be used to support lookahead operations.  
     530                Note that a negative size will fail where there is not sufficient 
     531                content available in the buffer (can't skip beyond the beginning). 
    498532 
    499533                Returns true if successful, false otherwise. 
     
    715749        /*********************************************************************** 
    716750 
    717                 make some room in the buffer 
     751                Make some room in the buffer. The requested space is simply 
     752                an indicator of how much is desired. A subclass may or may 
     753                not fulfill the request directly.  
     754                 
     755                For example, the base-class simply performs a drain() on the  
     756                buffer. 
    718757                         
    719758        ***********************************************************************/ 
     
    764803        /*********************************************************************** 
    765804         
    766                 Reset 'position' and 'limit' to zero 
     805                Reset 'position' and 'limit' to zero. This effectively clears 
     806                all content from the buffer. 
     807 
    767808 
    768809        ***********************************************************************/ 
     
    793834        /*********************************************************************** 
    794835         
    795                 Returns the limit of readable content within this buffer 
     836                Returns the limit of readable content within this buffer. 
     837 
     838                Each buffer has a capacity, a limit, and a position. The 
     839                capacity is the maximum content a buffer can contain, limit 
     840                represents the extent of valid content, and position marks  
     841                the current read location. 
    796842 
    797843        ***********************************************************************/ 
     
    804850        /*********************************************************************** 
    805851         
    806                 Returns the total capacity of this buffer 
     852                Returns the maximum capacity of this buffer 
     853 
     854                Each buffer has a capacity, a limit, and a position. The 
     855                capacity is the maximum content a buffer can contain, limit 
     856                represents the extent of valid content, and position marks  
     857                the current read location. 
    807858 
    808859        ***********************************************************************/ 
     
    816867         
    817868                Returns the current read-position within this buffer 
     869 
     870                Each buffer has a capacity, a limit, and a position. The 
     871                capacity is the maximum content a buffer can contain, limit 
     872                represents the extent of valid content, and position marks  
     873                the current read location. 
    818874 
    819875        ***********************************************************************/ 
     
    855911                this.conduit = conduit; 
    856912        } 
     913 
     914        /*********************************************************************** 
     915                 
     916                Return the entire backing array. Exposed for subclass usage  
     917                only 
     918 
     919        ***********************************************************************/ 
     920 
     921        protected void[] getContent () 
     922        { 
     923                return data; 
     924        } 
     925 
     926        /*********************************************************************** 
     927         
     928                Bulk copy of data from 'src'. The new content is made  
     929                available for reading. This is exposed for subclass use 
     930                only  
     931 
     932        ***********************************************************************/ 
     933 
     934        protected void copy (void *src, uint size) 
     935        { 
     936                data[limit..limit+size] = src[0..size]; 
     937                limit += size; 
     938        } 
    857939} 
  • trunk/mango/io/model/IBuffer.d

    r853 r898  
    4343/******************************************************************************* 
    4444 
    45         The basic premise behind this IO package is as follows: 
    46  
    47         1) the central concept is that of a buffer. The buffer acts 
    48            as a queue (line) where items are removed from the front 
    49            and new items are added to the back. Buffers are modeled  
    50            by this interface, and mango.io.Buffer exposes a concrete  
    51            implementation. 
    52  
    53         2) buffers can be written to directly, but a Reader and/or 
    54            Writer are typically used to read & write formatted data. 
    55            These readers & writers are bound to a specific buffer; 
    56            often the same buffer. It's also perfectly legitimate to  
    57            bind multiple writers to the same buffer; they will all 
    58            behave serially as one would expect. The same applies to 
    59            multiple readers on the same buffer. Readers and writers 
    60            support two styles of IO: put/get, and the C++ style <<  
    61            and >> operators. All such operations can be chained. 
    62  
    63         3) Any class can be made compatable with the reader/writer 
    64            framework by implementing the IReadable and/or IWritable  
    65            interfaces. Each of these specify just a single method. 
    66  
    67         4) Buffers may also be tokenized. This is handy when one is 
    68            dealing with text input, and/or the content suits a more 
    69            fluid format than most typical readers & writers support. 
    70            Tokens are mapped directly onto buffer content, so there 
    71            is only minor overhead in using them. Tokens can be read 
    72            and written by reader/writers also, using a more relaxed 
    73            set of rules than those applied to integral IO. 
    74  
    75         5) buffers are sometimes memory-only, in which case there 
    76            is nothing left to do when a reader (or tokenizer) hits 
    77            end of buffer conditions. Other buffers are themselves  
    78            bound to a Conduit. When this is the case, a reader will  
    79            eventually cause the buffer to reload via its associated  
    80            conduit. Previous buffer content will thus be lost. The 
    81            same concept is applied to writers, whereby they flush  
    82            the content of a full buffer to a bound conduit before  
    83            continuing.  
    84  
    85         6) conduits provide virtualized access to external content, 
    86            and represent things like files or Internet connections. 
    87            They are just a different kind of stream. Conduits are 
    88            modelled by mango.io.model.IConduit, and implemented via 
    89            classes FileConduit and SocketConduit. Additional kinds 
    90            of conduit are easy to construct: one either subclasses 
    91            mango.io.Conduit, or implements mango.io.model.IConduit. A 
    92            conduit reads and writes from/to a buffer in big chunks 
    93            (typically the entire buffer). 
    94  
     45        the central concept is that of a buffer. The buffer acts 
     46        as a queue (line) where items are removed from the front 
     47        and new items are added to the back. Buffers are modeled  
     48        by this interface, and mango.io.Buffer exposes a concrete  
     49        implementation. 
     50 
     51        buffers can be written to directly, but a Reader and/or 
     52        Writer are typically used to read & write formatted data. 
     53        These readers & writers are bound to a specific buffer; 
     54        often the same buffer. It's also perfectly legitimate to  
     55        bind multiple writers to the same buffer; they will all 
     56        behave serially as one would expect. The same applies to 
     57        multiple readers on the same buffer. Readers and writers 
     58        support two styles of IO: put/get, and the C++ style <<  
     59        and >> operators. All such operations can be chained. 
     60 
     61        Any class can be made compatable with the reader/writer 
     62        framework by implementing the IReadable and/or IWritable  
     63        interfaces. Each of these specify just a single method. 
     64 
     65        Buffers may also be tokenized. This is handy when one is 
     66        dealing with text input, and/or the content suits a more 
     67        fluid format than most typical readers & writers support. 
     68        Tokens are mapped directly onto buffer content, so there 
     69        is only minor overhead in using them. Tokens can be read 
     70        and written by reader/writers also, using a more relaxed 
     71        set of rules than those applied to integral IO. 
     72 
     73        buffers are sometimes memory-only, in which case there 
     74        is nothing left to do when a reader (or tokenizer) hits 
     75        end of buffer conditions. Other buffers are themselves  
     76        bound to a Conduit. When this is the case, a reader will  
     77        eventually cause the buffer to reload via its associated  
     78        conduit. Previous buffer content will thus be lost. The 
     79        same concept is applied to writers, whereby they flush  
     80        the content of a full buffer to a bound conduit before  
     81        continuing.  
     82 
     83        conduits provide virtualized access to external content, 
     84        and represent things like files or Internet connections. 
     85        They are just a different kind of stream. Conduits are 
     86        modelled by mango.io.model.IConduit, and implemented via 
     87        classes FileConduit and SocketConduit. Additional kinds 
     88        of conduit are easy to construct: one either subclasses 
     89        mango.io.Conduit, or implements mango.io.model.IConduit. A 
     90        conduit reads and writes from/to a buffer in big chunks 
     91        (typically the entire buffer). 
     92         
    9593*******************************************************************************/ 
    9694 
    97 abstract class IBuffer // could be an interface, but that causes poor codegen 
     95abstract class IBuffer /// could be an interface, but that causes poor codegen 
    9896{ 
    9997        typedef uint delegate (void* dst, uint count, uint type) Converter; 
     
    146144        /*********************************************************************** 
    147145 
    148                 Write an array of data into this buffer, and flush to the 
     146                Append an array of data into this buffer, and flush to the 
    149147                conduit as necessary. Returns a chaining reference if all  
    150148                data was written; throws an IOException indicating eof or  
     
    156154 
    157155        abstract IBuffer append (void[] content); 
     156 
     157        /*********************************************************************** 
     158         
     159                Append another buffer to this one, and flush to the 
     160                conduit as necessary. Returns a chaining reference if all  
     161                data was written; throws an IOException indicating eof or  
     162                eob if not. 
     163 
     164                This is often used in lieu of a Writer. 
     165 
     166        ***********************************************************************/ 
     167 
     168        IBuffer append (IBuffer other); 
    158169 
    159170        /***********************************************************************