diff tango/tango/io/model/IBuffer.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tango/tango/io/model/IBuffer.d	Fri Jan 11 17:57:40 2008 +0100
@@ -0,0 +1,622 @@
+/*******************************************************************************
+
+        copyright:      Copyright (c) 2004 Kris Bell. All rights reserved
+
+        license:        BSD style: $(LICENSE)
+
+        version:        Mar 2004: Initial release
+                        Dec 2006: Outback release
+        
+        author:         Kris
+
+*******************************************************************************/
+
+module tango.io.model.IBuffer;
+
+private import tango.io.model.IConduit;
+
+/*******************************************************************************
+
+        Buffer is central concept in Tango I/O. Each buffer acts
+        as a queue (line) where items are removed from the front
+        and new items are added to the back. Buffers are modeled 
+        by this interface and implemented in various ways.
+        
+        Buffer can be read from and written to directly, though 
+        various data-converters and filters are often leveraged 
+        to apply structure to what might otherwise be simple raw 
+        data. 
+
+        Buffers may also be tokenized by applying an Iterator. 
+        This can be handy when one is dealing with text input, 
+        and/or the content suits a more fluid format than most 
+        typical converters support. Iterator tokens are mapped 
+        directly onto buffer content (sliced), making them quite 
+        efficient in practice. Like other types of buffer client, 
+        multiple iterators can be mapped onto one common buffer
+        and access will be serialized.
+
+        Buffers are sometimes memory-only, in which case there
+        is nothing left to do when a client has consumed all the 
+        content. Other buffers are themselves bound to an external
+        device called a conduit. When this is the case, a consumer 
+        will eventually cause a buffer to reload via its associated 
+        conduit and previous buffer content will be lost. 
+        
+        A similar approach is applied to clients which populate a
+        buffer, whereby the content of a full buffer will be flushed
+        to a bound conduit before continuing. Another variation is 
+        that of a memory-mapped buffer, whereby the buffer content 
+        is mapped directly to virtual memory exposed via the OS. This 
+        can be used to address large files as an array of content.
+
+        See tango.io.Buffer for more info.
+
+*******************************************************************************/
+
+abstract class IBuffer : IConduit, Buffered
+{
+        alias append opCall;
+        alias flush  opCall;
+      
+        /***********************************************************************
+                
+                implements Buffered interface
+
+        ***********************************************************************/
+
+        abstract IBuffer buffer ();
+
+        /***********************************************************************
+                
+                Return the backing array
+
+        ***********************************************************************/
+
+        abstract void[] getContent ();
+
+        /***********************************************************************
+        
+                Return a void[] slice of the buffer up to the limit of
+                valid content.
+
+        ***********************************************************************/
+
+        abstract void[] slice ();
+
+        /***********************************************************************
+        
+                Set the backing array with all content readable. Writing
+                to this will either flush it to an associated conduit, or
+                raise an Eof condition. Use IBuffer.clear() to reset the
+                content (make it all writable).
+
+        ***********************************************************************/
+
+        abstract IBuffer setContent (void[] data);
+
+        /***********************************************************************
+        
+                Set the backing array with some content readable. Writing
+                to this will either flush it to an associated conduit, or
+                raise an Eof condition. Use IBuffer.clear() to reset the
+                content (make it all writable).
+
+        ***********************************************************************/
+
+        abstract IBuffer setContent (void[] data, uint readable);
+
+        /***********************************************************************
+
+                Append an array of data into this buffer, and flush to the
+                conduit as necessary. Returns a chaining reference if all 
+                data was written; throws an IOException indicating eof or 
+                eob if not.
+
+                This is often used in lieu of a Writer.
+
+        ***********************************************************************/
+
+        abstract IBuffer append (void* content, uint length);
+
+        /***********************************************************************
+
+                Append an array of data into this buffer, and flush to the
+                conduit as necessary. Returns a chaining reference if all 
+                data was written; throws an IOException indicating eof or 
+                eob if not.
+
+                This is often used in lieu of a Writer.
+
+        ***********************************************************************/
+
+        abstract IBuffer append (void[] content);
+
+        /***********************************************************************
+        
+                Append another buffer to this one, and flush to the
+                conduit as necessary. Returns a chaining reference if all 
+                data was written; throws an IOException indicating eof or 
+                eob if not.
+
+                This is often used in lieu of a Writer.
+
+        ***********************************************************************/
+
+        abstract IBuffer append (IBuffer other);
+
+        /***********************************************************************
+        
+                Consume content from a producer
+
+                Params:
+                The content to consume. This is consumed verbatim, and in
+                raw binary format ~ no implicit conversions are performed.
+
+                Remarks:
+                This is often used in lieu of a Writer, and enables simple
+                classes, such as FilePath and Uri, to emit content directly
+                into a buffer (thus avoiding potential heap activity)
+
+                Examples:
+                ---
+                auto path = new FilePath (somepath);
+
+                path.produce (&buffer.consume);
+                ---
+
+        ***********************************************************************/
+
+        abstract void consume (void[] src);
+
+        /***********************************************************************
+
+                Read a chunk of data from the buffer, loading from the
+                conduit as necessary. The requested number of bytes are
+                loaded into the buffer, and marked as having been read 
+                when the 'eat' parameter is set true. When 'eat' is set
+                false, the read position is not adjusted.
+
+                Returns the corresponding buffer slice when successful, 
+                or null if there's not enough data available (Eof; Eob).
+
+        ***********************************************************************/
+
+        abstract void[] slice (uint size, bool eat = true);
+
+        /***********************************************************************
+
+                Access buffer content
+
+                Params: 
+                dst = destination of the content
+                bytes = size of dst
+
+                Returns:
+                A reference to the populated content
+
+                Remarks:
+                Fill the provided array with content. We try to satisfy 
+                the request from the buffer content, and read directly
+                from an attached conduit where more is required.
+
+        ***********************************************************************/
+
+        abstract void[] readExact (void* dst, uint bytes);
+        
+        /**********************************************************************
+
+                Fill the provided buffer. Returns the number of bytes
+                actually read, which will be less than dst.length when
+                Eof has been reached and IConduit.Eof thereafter.
+
+        **********************************************************************/
+
+        abstract uint fill (void[] dst);
+
+        /***********************************************************************
+
+                Exposes the raw data buffer at the current write position, 
+                The delegate is provided with a void[] representing space
+                available within the buffer at the current write position.
+
+                The delegate should return the approriate number of bytes 
+                if it writes valid content, or IConduit.Eof on error.
+
+                Returns whatever the delegate returns.
+
+        ***********************************************************************/
+
+        abstract uint write (uint delegate (void[]) writer);
+
+        /***********************************************************************
+
+                Exposes the raw data buffer at the current read position. The
+                delegate is provided with a void[] representing the available
+                data, and should return zero to leave the current read position
+                intact. 
+                
+                If the delegate consumes data, it should return the number of 
+                bytes consumed; or IConduit.Eof to indicate an error.
+
+                Returns whatever the delegate returns.
+
+        ***********************************************************************/
+
+        abstract uint read (uint delegate (void[]) reader);
+
+        /***********************************************************************
+
+                If we have some data left after an export, move it to 
+                front-of-buffer and set position to be just after the 
+                remains. This is for supporting certain conduits which 
+                choose to write just the initial portion of a request.
+                            
+                Limit is set to the amount of data remaining. Position 
+                is always reset to zero.
+
+        ***********************************************************************/
+
+        abstract IBuffer compress ();
+
+        /***********************************************************************
+        
+                Skip ahead by the specified number of bytes, streaming from 
+                the associated conduit as necessary.
+        
+                Can also reverse the read position by 'size' bytes. This may
+                be used to support lookahead-type operations.
+
+                Returns true if successful, false otherwise.
+
+        ***********************************************************************/
+
+        abstract bool skip (int size);
+
+        /***********************************************************************
+
+                Support for tokenizing iterators. 
+                
+                Upon success, the delegate should return the byte-based 
+                index of the consumed pattern (tail end of it). Failure
+                to match a pattern should be indicated by returning an
+                IConduit.Eof.
+
+                Each pattern is expected to be stripped of the delimiter.
+                An end-of-file condition causes trailing content to be 
+                placed into the token. Requests made beyond Eof result
+                in empty matches (length == zero).
+
+                Note that additional iterator and/or reader instances
+                will stay in lockstep when bound to a common buffer.
+
+                Returns true if a token was isolated, false otherwise.
+
+        ***********************************************************************/
+
+        abstract bool next (uint delegate (void[]));
+
+        /***********************************************************************
+
+                Try to _fill the available buffer with content from the 
+                specified conduit. We try to read as much as possible 
+                by clearing the buffer when all current content has been 
+                eaten. If there is no space available, nothing will be 
+                read.
+
+                Returns the number of bytes read, or Conduit.Eof.
+        
+        ***********************************************************************/
+
+        abstract uint fill (InputStream src);
+
+        /***********************************************************************
+
+                Write as much of the buffer that the associated conduit
+                can consume.
+
+                Returns the number of bytes written, or Conduit.Eof.
+        
+        ***********************************************************************/
+
+        abstract uint drain (OutputStream dst);
+
+        /***********************************************************************
+        
+                Truncate the buffer within its extent. Returns true if
+                the new 'extent' is valid, false otherwise.
+
+        ***********************************************************************/
+
+        abstract bool truncate (uint extent);
+
+        /***********************************************************************
+        
+                Return count of readable bytes remaining in buffer. This is 
+                calculated simply as limit() - position().
+
+        ***********************************************************************/
+
+        abstract uint readable ();               
+
+        /***********************************************************************
+        
+                Return count of writable bytes available in buffer. This is 
+                calculated simply as capacity() - limit().
+
+        ***********************************************************************/
+
+        abstract uint writable ();
+
+        /***********************************************************************
+        
+                Returns the limit of readable content within this buffer.
+
+        ***********************************************************************/
+
+        abstract uint limit ();               
+
+        /***********************************************************************
+        
+                Returns the total capacity of this buffer.
+
+        ***********************************************************************/
+
+        abstract uint capacity ();               
+
+        /***********************************************************************
+        
+                Returns the current position within this buffer.
+
+        ***********************************************************************/
+
+        abstract uint position ();               
+
+        /***********************************************************************
+        
+                Sets the external conduit associated with this buffer.
+
+                Buffers do not require an external conduit to operate, but 
+                it can be convenient to associate one. For example, methods
+                read and write use it to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract IBuffer setConduit (IConduit conduit);
+
+        /***********************************************************************
+        
+                Set output stream
+
+                Params:
+                sink = the stream to attach to
+
+                Remarks:
+                Sets the external output stream associated with this buffer.
+
+                Buffers do not require an external stream to operate, but 
+                it can be convenient to associate one. For example, methods
+                fill & drain use them to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract IBuffer output (OutputStream sink);
+
+        /***********************************************************************
+        
+                Set input stream
+
+                Params:
+                source = the stream to attach to
+
+                Remarks:
+                Sets the external input stream associated with this buffer.
+
+                Buffers do not require an external stream to operate, but 
+                it can be convenient to associate one. For example, methods
+                fill & drain use them to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract IBuffer input (InputStream source);
+
+        /***********************************************************************
+
+                Transfer content into the provided dst.
+
+                Params: 
+                dst = destination of the content
+
+                Returns:
+                Return the number of bytes read, which may be less than
+                dst.length. Eof is returned when no further content is
+                available.
+
+                Remarks:
+                Populates the provided array with content. We try to 
+                satisfy the request from the buffer content, and read 
+                directly from an attached conduit when the buffer is 
+                empty.
+
+        ***********************************************************************/
+
+        abstract uint read (void[] dst);
+
+        /***********************************************************************
+
+                Emulate OutputStream.write()
+
+                Params: 
+                src = the content to write
+
+                Returns:
+                Return the number of bytes written, which will be Eof when
+                the content cannot be written.
+
+                Remarks:
+                Appends all of dst to the buffer, flushing to an attached
+                conduit as necessary.
+
+        ***********************************************************************/
+
+        abstract uint write (void[] src);
+
+        /***********************************************************************
+        
+                Exposes configured output stream
+
+                Returns:
+                Returns the OutputStream associated with this buffer. Returns 
+                null if the buffer is not attached to an output; that is, it's
+                not backed by some external medium.
+
+                Remarks:
+                Buffers do not require an external stream to operate, but 
+                it can be convenient to associate them. For example, methods
+                fill & drain use them to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract OutputStream output ();
+
+        /***********************************************************************
+        
+                Exposes configured input stream
+
+                Returns:
+                Returns the InputStream associated with this buffer. Returns 
+                null if the buffer is not attached to an input; that is, it's
+                not backed by some external medium.
+
+                Remarks:
+                Buffers do not require an external stream to operate, but 
+                it can be convenient to associate them. For example, methods
+                fill & drain use them to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract InputStream input ();
+
+        /***********************************************************************
+        
+                Throw an exception with the provided message
+
+        ***********************************************************************/
+
+        abstract void error (char[] msg);
+
+        /***********************************************************************
+        
+                Access configured conduit
+
+                Returns:
+                Returns the conduit associated with this buffer. Returns 
+                null if the buffer is purely memory based; that is, it's
+                not backed by some external medium.
+
+                Remarks:
+                Buffers do not require an external conduit to operate, but 
+                it can be convenient to associate one. For example, methods
+                fill() & drain() use it to import/export content as necessary.
+
+        ***********************************************************************/
+
+        abstract IConduit conduit ();
+
+        /***********************************************************************
+        
+                Return a preferred size for buffering conduit I/O.
+
+        ***********************************************************************/
+
+        abstract uint bufferSize (); 
+                     
+        /***********************************************************************
+        
+                Return the name of this conduit.
+
+        ***********************************************************************/
+
+        abstract char[] toString (); 
+                     
+        /***********************************************************************
+
+                Is the conduit alive?
+
+        ***********************************************************************/
+
+        abstract bool isAlive ();
+
+        /***********************************************************************
+        
+                Flush the contents of this buffer to the related conduit.
+                Throws an IOException on premature eof.
+
+        ***********************************************************************/
+
+        abstract OutputStream flush ();
+
+        /***********************************************************************
+        
+                Reset position and limit to zero.
+
+        ***********************************************************************/
+
+        abstract InputStream clear ();               
+
+        /***********************************************************************
+        
+                Copy content via this buffer from the provided src
+                conduit.
+
+                Remarks:
+                The src conduit has its content transferred through 
+                this buffer via a series of fill & drain operations, 
+                until there is no more content available. The buffer
+                content should be explicitly flushed by the caller.
+
+                Throws an IOException on premature Eof.
+
+        ***********************************************************************/
+
+        abstract OutputStream copy (InputStream src);
+
+        /***********************************************************************
+                
+                Release external resources
+
+        ***********************************************************************/
+
+        abstract void detach ();
+
+        /***********************************************************************
+        
+                Close the stream
+
+                Remarks:
+                Propagate request to an attached OutputStream (this is a
+                requirement for the OutputStream interface)
+
+        ***********************************************************************/
+
+        abstract void close ();
+}
+
+
+/*******************************************************************************
+
+        Supported by streams which are prepared to share an internal buffer 
+        instance. This is intended to avoid a situation whereby content is
+        shunted unnecessarily from one buffer to another when "decorator"
+        streams are connected together in arbitrary ways.
+        
+        Do not implement this if the internal buffer should not be accessed 
+        directly by another stream e.g. if wrapper methods manipulate content
+        on the way in or out of the buffer.
+
+*******************************************************************************/
+
+interface Buffered
+{
+        IBuffer buffer();
+}