1 /*******************************************************************************
2 
3         copyright:      Copyright (c) 2007 Kris Bell. All rights reserved
4 
5         license:        BSD style: $(LICENSE)
6 
7         version:        Initial release: June 2007
8 
9         author:         Kris
10 
11 *******************************************************************************/
12 
13 module tango.io.stream.Greedy;
14 
15 private import tango.io.device.Conduit;
16 
17 
18 /*******************************************************************************
19 
20         A conduit filter that ensures its input is read in full. There's
21         also an optional readExact() for more explicit requests.
22 
23 *******************************************************************************/
24 
25 class GreedyInput : InputFilter
26 {
27         /***********************************************************************
28 
29                 Propagate ctor to superclass.
30 
31         ***********************************************************************/
32 
33         this (InputStream stream)
34         {
35                 super (stream);
36         }
37 
38         /***********************************************************************
39 
40                 Fill the provided array. Returns the number of bytes
41                 actually read, which will be less that dst.length when
42                 Eof has been reached, and then Eof thereafter.
43 
44         ***********************************************************************/
45 
46         final override size_t read (void[] dst)
47         {
48                 size_t len = 0;
49 
50                 while (len < dst.length)
51                       {
52                       auto i = source.read (dst [len .. $]);
53                       if (i is Eof)
54                           return (len ? len : i);
55                       len += i;
56                       }
57                 return len;
58         }
59 
60         /***********************************************************************
61 
62                 Read from a stream into a target array. The provided dst
63                 will be fully populated with content from the input.
64 
65                 This differs from read in that it will throw an exception
66                 where an Eof condition is reached before input has completed.
67 
68         ***********************************************************************/
69 
70         final GreedyInput readExact (void[] dst)
71         {
72                 while (dst.length)
73                       {
74                       auto i = read (dst);
75                       if (i is Eof)
76                           conduit.error ("unexpected Eof while reading: "~conduit.toString());
77                       dst = dst [i .. $];
78                       }
79                 return this;
80         }
81 }
82 
83 
84 
85 /*******************************************************************************
86 
87         A conduit filter that ensures its output is written in full. There's
88         also an optional writeExact() for more explicit requests.
89 
90 *******************************************************************************/
91 
92 class GreedyOutput : OutputFilter
93 {
94         /***********************************************************************
95 
96                 Propagate ctor to superclass.
97 
98         ***********************************************************************/
99 
100         this (OutputStream stream)
101         {
102                 super (stream);
103         }
104 
105         /***********************************************************************
106 
107                 Consume everything we were given. Returns the number of
108                 bytes written which will be less than src.length only
109                 when an Eof condition is reached, and Eof from that point
110                 forward.
111 
112         ***********************************************************************/
113 
114         final override size_t write (const(void)[] src)
115         {
116                 size_t len = 0;
117 
118                 while (len < src.length)
119                       {
120                       auto i = sink.write (src [len .. $]);
121                       if (i is Eof)
122                           return (len ? len : i);
123                       len += i;
124                       }
125                 return len;
126         }
127 
128         /***********************************************************************
129 
130                 Write to stream from a source array. The provided src content
131                 will be written in full to the output.
132 
133                 This differs from write in that it will throw an exception
134                 where an Eof condition is reached before output has completed.
135 
136         ***********************************************************************/
137 
138         final GreedyOutput writeExact (void[] src)
139         {
140                 while (src.length)
141                       {
142                       auto i = write (src);
143                       if (i is Eof)
144                           conduit.error ("unexpected Eof while writing: "~conduit.toString());
145                       src = src [i .. $];
146                       }
147                 return this;
148         }
149 }
150 
151 
152 /*******************************************************************************
153 
154 *******************************************************************************/
155 
156 debug (Greedy)
157 {
158         void main()
159         {
160                 auto s = new GreedyInput (null);
161         }
162 }