Mercurial > projects > ldc
comparison tango/tango/io/stream/EndianStream.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 |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
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 for swapping endian-order. The stream is treated as a set | |
12 of same-sized elements. Note that partial elements are not mutated | |
13 | |
14 *******************************************************************************/ | |
15 | |
16 module tango.io.stream.EndianStream; | |
17 | |
18 private import tango.io.Buffer, | |
19 tango.io.Conduit; | |
20 | |
21 private import tango.core.ByteSwap; | |
22 | |
23 /******************************************************************************* | |
24 | |
25 Type T is the element type | |
26 | |
27 *******************************************************************************/ | |
28 | |
29 class EndianInput(T) : InputFilter | |
30 { | |
31 static if ((T.sizeof != 2) && (T.sizeof != 4) && (T.sizeof != 8)) | |
32 pragma (msg, "EndianInput :: type should be of length 2, 4, or 8 bytes"); | |
33 | |
34 | |
35 private IBuffer input; | |
36 | |
37 /*********************************************************************** | |
38 | |
39 ***********************************************************************/ | |
40 | |
41 this (InputStream stream) | |
42 { | |
43 super (input = Buffer.share (stream)); | |
44 } | |
45 | |
46 /*********************************************************************** | |
47 | |
48 Buffered interface | |
49 | |
50 ***********************************************************************/ | |
51 | |
52 final IBuffer buffer () | |
53 { | |
54 return input; | |
55 } | |
56 | |
57 /*********************************************************************** | |
58 | |
59 Read from conduit into a target array. The provided dst | |
60 will be populated with content from the conduit. | |
61 | |
62 Returns the number of bytes read, which may be less than | |
63 requested in dst (or IOStream.Eof for end-of-flow). Note | |
64 that a trailing partial element will be placed into dst, | |
65 but the returned length will effectively ignore it | |
66 | |
67 ***********************************************************************/ | |
68 | |
69 final override uint read (void[] dst) | |
70 { | |
71 uint len = input.fill (dst[0 .. dst.length & ~(T.sizeof-1)]); | |
72 if (len != Eof) | |
73 { | |
74 // the final read may be misaligned ... | |
75 len &= ~(T.sizeof - 1); | |
76 | |
77 static if (T.sizeof == 2) | |
78 ByteSwap.swap16 (dst.ptr, len); | |
79 | |
80 static if (T.sizeof == 4) | |
81 ByteSwap.swap32 (dst.ptr, len); | |
82 | |
83 static if (T.sizeof == 8) | |
84 ByteSwap.swap64 (dst.ptr, len); | |
85 } | |
86 return len; | |
87 } | |
88 } | |
89 | |
90 | |
91 | |
92 /******************************************************************************* | |
93 | |
94 Type T is the element type | |
95 | |
96 *******************************************************************************/ | |
97 | |
98 class EndianOutput (T) : OutputFilter | |
99 { | |
100 static if ((T.sizeof != 2) && (T.sizeof != 4) && (T.sizeof != 8)) | |
101 pragma (msg, "EndianOutput :: type should be of length 2, 4, or 8 bytes"); | |
102 | |
103 private IBuffer output; | |
104 | |
105 /*********************************************************************** | |
106 | |
107 ***********************************************************************/ | |
108 | |
109 this (OutputStream stream) | |
110 { | |
111 super (output = Buffer.share (stream)); | |
112 } | |
113 | |
114 /*********************************************************************** | |
115 | |
116 Write to output stream from a source array. The provided | |
117 src content will be consumed and left intact. | |
118 | |
119 Returns the number of bytes written from src, which may | |
120 be less than the quantity provided. Note that any partial | |
121 elements will not be consumed | |
122 | |
123 ***********************************************************************/ | |
124 | |
125 final override uint write (void[] src) | |
126 { | |
127 uint writer (void[] dst) | |
128 { | |
129 auto len = dst.length; | |
130 if (len > src.length) | |
131 len = src.length; | |
132 | |
133 len &= ~(T.sizeof - 1); | |
134 dst [0..len] = src [0..len]; | |
135 | |
136 static if (T.sizeof == 2) | |
137 ByteSwap.swap16 (dst.ptr, len); | |
138 | |
139 static if (T.sizeof == 4) | |
140 ByteSwap.swap32 (dst.ptr, len); | |
141 | |
142 static if (T.sizeof == 8) | |
143 ByteSwap.swap64 (dst.ptr, len); | |
144 | |
145 return len; | |
146 } | |
147 | |
148 uint bytes = src.length; | |
149 | |
150 // flush if we used all buffer space | |
151 if ((bytes -= output.write (&writer)) >= T.sizeof) | |
152 if (output.output) | |
153 output.drain (output.output); | |
154 else | |
155 return Eof; | |
156 return src.length - bytes; | |
157 } | |
158 } | |
159 | |
160 | |
161 /******************************************************************************* | |
162 | |
163 *******************************************************************************/ | |
164 | |
165 debug (UnitTest) | |
166 { | |
167 import tango.io.Stdout; | |
168 | |
169 unittest | |
170 { | |
171 auto inp = new EndianInput!(dchar)(new Buffer("hello world"d)); | |
172 auto oot = new EndianOutput!(dchar)(new Buffer(64)); | |
173 oot.copy (inp); | |
174 assert (oot.output.slice == "hello world"d); | |
175 } | |
176 } |