@file
IBuffer
.d
Copyright (c) 2004 Kris Bell
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for damages
of any kind arising from the use of this software.
Permission is hereby granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and/or
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment within documentation of
said product would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any distribution
of the source.
4. Derivative works are permitted, but they must carry this notice
in full and credit the original source.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@version Initial version, March 2004
@author Kris
- class
IBuffer
;
- the central concept is that of a buffer. The 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 mango.io.Buffer exposes a concrete
implementation.
buffers can be written to directly, but a Reader and/or
Writer are typically used to read & write formatted data.
These readers & writers are bound to a specific buffer;
often the same buffer. It's also perfectly legitimate to
bind multiple writers to the same buffer; they will all
behave serially as one would expect. The same applies to
multiple readers on the same buffer. Readers and writers
support two styles of IO: put/get, and the C++ style <<
and >> operators. All such operations can be chained.
Any class can be made compatable with the reader/writer
framework by implementing the IReadable and/or IWritable
interfaces. Each of these specify just a single method.
Buffers may also be tokenized. This is handy when one is
dealing with text input, and/or the content suits a more
fluid format than most typical readers & writers support.
Tokens are mapped directly onto buffer content, so there
is only minor overhead in using them. Tokens can be read
and written by reader/writers also, using a more relaxed
set of rules than those applied to integral IO.
buffers are sometimes memory-only, in which case there
is nothing left to do when a reader (or tokenizer) hits
end of buffer conditions. Other buffers are themselves
bound to a Conduit. When this is the case, a reader will
eventually cause the buffer to reload via its associated
conduit. Previous buffer content will thus be lost. The
same concept is applied to writers, whereby they flush
the content of a full buffer to a bound conduit before
continuing.
conduits provide virtualized access to external content,
and represent things like files or Internet connections.
They are just a different kind of stream. Conduits are
modelled by mango.io.model.IConduit, and implemented via
classes FileConduit and SocketConduit. Additional kinds
of conduit are easy to construct: one either subclasses
mango.io.Conduit, or implements mango.io.model.IConduit. A
conduit reads and writes from/to a buffer in big chunks
(typically the entire buffer).
- void[]
getContent
();
- Return the backing array
- char[]
toString
();
- Return a char[] slice of the buffer up to the limit of
valid content.
- IBuffer
setValidContent
(void[] data);
- 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).
- IBuffer
setContent
(void[] data, uint readable);
- 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).
- IBuffer
append
(void[] content);
- 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.
- IBuffer
append
(IBuffer other);
- 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.
- void[]
get
(uint size, bool eat = true);
- 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).
- uint
write
(uint delegate(void[]) writer);
- 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.
- uint
read
(uint delegate(void[]) reader);
- 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.
- IBuffer
compress
();
- 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.
- bool
skip
(int size);
- 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.
- bool
next
(uint delegate(void[]));
- 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.
- uint
fill
();
- Try to
fill
the available buffer with content from the
specified conduit. In particular, we will never ask to
read less than 32 bytes. This permits conduit-filters
to operate within a known environment.
Returns the number of bytes read, or throws an underflow
error if there nowhere to read from
- uint
fill
(IConduit conduit);
- Try to
fill
the available buffer with content from the
specified conduit. In particular, we will never ask to
read less than 32 bytes. This permits conduit-filters
to operate within a known environment.
Returns the number of bytes read, or Conduit.Eof
- uint
drain
();
- Write as much of the buffer that the associated conduit
can consume.
Returns the number of bytes written, or Conduit.Eof
- void
flush
();
-
flush
the contents of this buffer to the related conduit.
Throws an IOException on premature eof.
- IBuffer
clear
();
- Reset position and limit to zero.
- bool
truncate
(uint extent);
- Truncate the buffer within its extend. Returns true if
the new 'extent' is valid, false otherwise.
- uint
readable
();
- return count of
readable
bytes remaining in buffer. This is
calculated simply as limit() - position()
- uint
writable
();
- Return count of
writable
bytes available in buffer. This is
calculated simply as capacity() - limit()
- uint
getLimit
();
- returns the limit of readable content within this buffer
- uint
getCapacity
();
- returns the total capacity of this buffer
- uint
getPosition
();
- returns the current position within this buffer
- void
makeRoom
(uint space);
- make some room in the buffer
- IConduit
getConduit
();
- 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 conduit.
Buffers do not require a conduit to operate, but it can
be convenient to associate one. For example, the IReader
and IWriter classes use this to import/export content as
necessary.
- void
setConduit
(IConduit conduit);
- 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.
- Style
getStyle
();
- Return style of buffer
- void
error
(char[] msg);
- Throw an exception with the provided message
- class
AbstractDecoder
;
- Any class implementing IDecoder can be bound to a reader using
the setDecoder() method.
- class
AbstractEncoder
;
- Any class implementing IEncoder can be bound to a writer using
the bind() method.
|