123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
|
/*******************************************************************************
copyright: Copyright (c) 2007 Kris Bell. All rights reserved
license: BSD style: $(LICENSE)
version: Initial release: Oct 2007
author: Kris
*******************************************************************************/
module tango.io.stream.Snoop;
private import tango.io.Console,
tango.io.device.Conduit;
private import tango.text.convert.Format;
version(DigitalMars)
{
private import tango.core.Vararg;
}else version (GNU)
private import tango.core.Vararg;
private alias void delegate(const(char)[]) Snoop;
/*******************************************************************************
Stream to expose call behaviour. By default, activity trace is
sent to Cerr.
*******************************************************************************/
class SnoopInput : InputStream
{
private InputStream host;
private Snoop snoop;
/***********************************************************************
Attach to the provided stream.
***********************************************************************/
this (InputStream host, Snoop snoop = null)
{
assert (host);
this.host = host;
this.snoop = snoop ? snoop : &snooper;
}
/***********************************************************************
Return the upstream host of this filter.
***********************************************************************/
InputStream input ()
{
return host;
}
/***********************************************************************
Return the hosting conduit.
***********************************************************************/
final IConduit conduit ()
{
return host.conduit;
}
/***********************************************************************
Read from conduit into a target array. The provided dst
will be populated with content from the conduit.
Returns the number of bytes read, which may be less than
requested in dst.
***********************************************************************/
final size_t read (void[] dst)
{
auto x = host.read (dst);
trace ("{}: read {} bytes", host.conduit, x is -1 ? 0 : x);
return x;
}
/***********************************************************************
Load the bits from a stream, and return them all in an
array. The dst array can be provided as an option, which
will be expanded as necessary to consume the input.
Returns an array representing the content, and throws
IOException on error.
***********************************************************************/
void[] load (size_t max=-1)
{
auto x = host.load (max);
trace ("{}: loaded {} bytes", x.length);
return x;
}
/***********************************************************************
Clear any buffered content.
***********************************************************************/
final InputStream flush ()
{
host.flush();
trace ("{}: flushed/cleared", host.conduit);
return this;
}
/***********************************************************************
Close the input.
***********************************************************************/
final void close ()
{
host.close();
trace ("{}: closed", host.conduit);
}
/***********************************************************************
Seek on this stream. Target conduits that don't support
seeking will throw an IOException.
***********************************************************************/
final long seek (long offset, Anchor anchor = Anchor.Begin)
{
auto s = host.seek (offset, anchor);
trace ("{}: seek at offset {} from anchor {}", host.conduit, offset, anchor);
return s;
}
/***********************************************************************
Internal trace handler.
***********************************************************************/
private void snooper (const(char)[] x)
{
Cerr(x).newline;
}
/***********************************************************************
Internal trace handler.
***********************************************************************/
private void trace (const(char)[] format, ...)
{
char[256] tmp = void;
snoop (Format.vprint (tmp, format, _arguments, _argptr));
}
}
/*******************************************************************************
Stream to expose call behaviour. By default, activity trace is
sent to Cerr.
*******************************************************************************/
class SnoopOutput : OutputStream
{
private OutputStream host;
private Snoop snoop;
/***********************************************************************
Attach to the provided stream.
***********************************************************************/
this (OutputStream host, Snoop snoop = null)
{
assert (host);
this.host = host;
this.snoop = snoop ? snoop : &snooper;
}
/***********************************************************************
Return the upstream host of this filter.
***********************************************************************/
OutputStream output ()
{
return host;
}
/***********************************************************************
Write to conduit from a source array. The provided src
content will be written to the conduit.
Returns the number of bytes written from src, which may
be less than the quantity provided.
***********************************************************************/
final size_t write (const(void)[] src)
{
auto x = host.write (src);
trace ("{}: wrote {} bytes", host.conduit, x is -1 ? 0 : x);
return x;
}
/***********************************************************************
Return the hosting conduit.
***********************************************************************/
final IConduit conduit ()
{
return host.conduit;
}
/***********************************************************************
Emit/purge buffered content.
***********************************************************************/
final OutputStream flush ()
{
host.flush();
trace ("{}: flushed", host.conduit);
return this;
}
/***********************************************************************
Close the output.
***********************************************************************/
final void close ()
{
host.close();
trace ("{}: closed", host.conduit);
}
/***********************************************************************
Transfer the content of another conduit to this one. Returns
a reference to this class, or throws IOException on failure.
***********************************************************************/
final OutputStream copy (InputStream src, size_t max=-1)
{
host.copy (src, max);
trace("{}: copied from {}", host.conduit, src.conduit);
return this;
}
/***********************************************************************
Seek on this stream. Target conduits that don't support
seeking will throw an IOException.
***********************************************************************/
final long seek (long offset, Anchor anchor = Anchor.Begin)
{
auto s = host.seek (offset, anchor);
trace ("{}: seek at offset {} from anchor {}", host.conduit, offset, anchor);
return s;
}
/***********************************************************************
Internal trace handler.
***********************************************************************/
private void snooper (const(char)[] x)
{
Cerr(x).newline;
}
/***********************************************************************
Internal trace handler.
***********************************************************************/
private void trace (const(char)[] format, ...)
{
char[256] tmp = void;
snoop (Format.vprint (tmp, format, _arguments, _argptr));
}
}
debug (Snoop)
{
void main()
{
auto s = new SnoopInput (null);
auto o = new SnoopOutput (null);
}
}
|