1 /******************************************************************************* 2 3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: Nov 2007 8 9 author: Kris 10 11 Streams to expose simple native types as discrete elements. I/O 12 is buffered and should yield fair performance. 13 14 *******************************************************************************/ 15 16 module tango.io.stream.Typed; 17 18 private import tango.io.device.Conduit; 19 20 private import tango.io.stream.Buffered; 21 22 /******************************************************************************* 23 24 Type T is the target or destination type. 25 26 *******************************************************************************/ 27 28 class TypedInput(T) : InputFilter 29 { 30 /*********************************************************************** 31 32 ***********************************************************************/ 33 34 this (InputStream stream) 35 { 36 super (BufferedInput.create (stream)); 37 } 38 39 /*********************************************************************** 40 41 Override this to give back a useful chaining reference. 42 43 ***********************************************************************/ 44 45 final override TypedInput flush () 46 { 47 super.flush(); 48 return this; 49 } 50 51 /*********************************************************************** 52 53 Read a value from the stream. Returns false when all 54 content has been consumed. 55 56 ***********************************************************************/ 57 58 final bool read (ref T x) 59 { 60 return source.read((&x)[0..1]) is T.sizeof; 61 } 62 63 /*********************************************************************** 64 65 Iterate over all content. 66 67 ***********************************************************************/ 68 69 final int opApply (scope int delegate(ref T x) dg) 70 { 71 T x; 72 int ret; 73 74 while ((source.read((&x)[0..1]) is T.sizeof)) 75 if ((ret = dg (x)) != 0) 76 break; 77 return ret; 78 } 79 } 80 81 82 83 /******************************************************************************* 84 85 Type T is the target or destination type. 86 87 *******************************************************************************/ 88 89 class TypedOutput(T) : OutputFilter 90 { 91 /*********************************************************************** 92 93 ***********************************************************************/ 94 95 this (OutputStream stream) 96 { 97 super (BufferedOutput.create (stream)); 98 } 99 100 /*********************************************************************** 101 102 Append a value to the output stream. 103 104 ***********************************************************************/ 105 106 final void write (ref T x) 107 { 108 sink.write ((&x)[0..1]); 109 } 110 } 111 112 113 /******************************************************************************* 114 115 *******************************************************************************/ 116 117 debug (UnitTest) 118 { 119 import tango.io.Stdout; 120 import tango.io.stream.Utf; 121 import tango.io.device.Array; 122 123 unittest 124 { 125 Array output; 126 127 auto inp = new TypedInput!(char)(new Array("hello world".dup)); 128 auto oot = new TypedOutput!(char)(output = new Array(20)); 129 130 foreach (x; inp) 131 oot.write (x); 132 assert (output.slice() == "hello world"); 133 134 auto xx = new TypedInput!(char)(new UtfInput!(char, dchar)(new Array("hello world"d.dup))); 135 char[] yy; 136 foreach (x; xx) 137 yy ~= x; 138 assert (yy == "hello world"); 139 } 140 }