comparison deps/Platinum/Source/Core/PltStreamPump.cpp @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
1 /*****************************************************************
2 |
3 | Platinum - Stream Pump
4 |
5 | Copyright (c) 2004-2008, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
8 |
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
13 |
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 |
21 | This program is distributed in the hope that it will be useful,
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | GNU General Public License for more details.
25 |
26 | You should have received a copy of the GNU General Public License
27 | along with this program; see the file LICENSE.txt. If not, write to
28 | the Free Software Foundation, Inc.,
29 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 | http://www.gnu.org/licenses/gpl-2.0.html
31 |
32 ****************************************************************/
33
34 /*----------------------------------------------------------------------
35 | includes
36 +---------------------------------------------------------------------*/
37 #include "PltStreamPump.h"
38 #include "NptUtils.h"
39
40 /*----------------------------------------------------------------------
41 | PLT_StreamPump::PLT_StreamPump
42 +---------------------------------------------------------------------*/
43 PLT_StreamPump::PLT_StreamPump(NPT_Size size) :
44 m_TotalBytesRead(0),
45 m_TotalBytesWritten(0)
46 {
47 m_RingBuffer = new NPT_RingBuffer(size);
48 }
49
50 /*----------------------------------------------------------------------
51 | PLT_StreamPump::~PLT_StreamPump
52 +---------------------------------------------------------------------*/
53 PLT_StreamPump::~PLT_StreamPump()
54 {
55 delete m_RingBuffer;
56 }
57 /*----------------------------------------------------------------------+
58 | PLT_StreamPump::PushData
59 +----------------------------------------------------------------------*/
60 NPT_Result
61 PLT_StreamPump::PushData(NPT_OutputStream& output,
62 NPT_Size& bytes_written)
63 {
64 NPT_Result res = NPT_ERROR_WOULD_BLOCK;
65 NPT_Size count = 0;
66 NPT_Size bytes_available = m_RingBuffer->GetContiguousAvailable();
67
68 bytes_written = 0;
69
70 if (bytes_available) {
71 res = output.Write(m_RingBuffer->GetReadPointer(), bytes_available, &count);
72 m_RingBuffer->MoveOut(count);
73 bytes_written += count;
74
75 // check if we wrapped around
76 bytes_available = m_RingBuffer->GetContiguousAvailable();
77 if (NPT_SUCCEEDED(res) && bytes_available) {
78 res = output.Write(m_RingBuffer->GetReadPointer(), bytes_available, &count);
79 m_RingBuffer->MoveOut(count);
80 bytes_written += count;
81 }
82 }
83
84 m_TotalBytesWritten += bytes_written;
85
86 return res;
87 }
88
89 /*----------------------------------------------------------------------+
90 | PLT_StreamPump::PullData
91 +----------------------------------------------------------------------*/
92 NPT_Result
93 PLT_StreamPump::PullData(NPT_InputStream& input,
94 NPT_Size max_bytes_to_read)
95 {
96 NPT_Result res = NPT_ERROR_WOULD_BLOCK;
97 NPT_Size byte_space = m_RingBuffer->GetContiguousSpace();
98
99 // check that there is space left
100 // make sure we don't read more than our contiguous space
101 NPT_Size nb_to_read = (max_bytes_to_read<byte_space)?max_bytes_to_read:byte_space;
102 if (nb_to_read > 0) {
103 NPT_Size count;
104 res = input.Read(m_RingBuffer->GetWritePointer(), nb_to_read, &count);
105 m_RingBuffer->MoveIn(count);
106 max_bytes_to_read -= count;
107 m_TotalBytesRead += count;
108
109 byte_space = m_RingBuffer->GetContiguousSpace();
110 nb_to_read = (max_bytes_to_read<byte_space)?max_bytes_to_read:byte_space;
111 // if we filled our contiguous space, and we wrapped, check if there is more to read
112 if (NPT_SUCCEEDED(res) && (nb_to_read > 0)) {
113 res = input.Read(m_RingBuffer->GetWritePointer(), nb_to_read, &count);
114 m_RingBuffer->MoveIn(count);
115 m_TotalBytesRead += count;
116 }
117 }
118
119 return res;
120 }
121
122 /*----------------------------------------------------------------------
123 | PLT_PipeInputStreamPump::PLT_PipeInputStreamPump
124 +---------------------------------------------------------------------*/
125 PLT_PipeInputStreamPump::PLT_PipeInputStreamPump(NPT_OutputStreamReference& output,
126 NPT_Size size) :
127 PLT_StreamPump(size),
128 m_Output(output),
129 m_LastRes(NPT_SUCCESS)
130 {
131 }
132
133 /*----------------------------------------------------------------------
134 | PLT_PipeInputStreamPump::~PLT_PipeInputStreamPump
135 +---------------------------------------------------------------------*/
136 PLT_PipeInputStreamPump::~PLT_PipeInputStreamPump()
137 {
138 }
139
140 /*----------------------------------------------------------------------
141 | PLT_PipeInputStreamPump::Receive
142 +---------------------------------------------------------------------*/
143 NPT_Result
144 PLT_PipeInputStreamPump::Receive(NPT_InputStream& input,
145 NPT_Size max_bytes_to_read,
146 NPT_Size* bytes_read)
147 {
148 NPT_Size count;
149 NPT_Result res;
150
151 if ((m_LastRes == NPT_SUCCESS) || (m_LastRes == NPT_ERROR_WOULD_BLOCK)) {
152 // look at what we have buffered already from out input
153 // and if have less than what was asked, read more
154 NPT_Size available = m_RingBuffer->GetAvailable();
155 if (available < max_bytes_to_read) {
156 m_LastRes = PullData(input, max_bytes_to_read-available);
157 }
158 } else if (!m_RingBuffer->GetAvailable()) {
159 // if the buffer is now empty, return the input last error
160 return m_LastRes;
161 }
162
163 // write as much as we can on the output stream
164 res = PushData(*m_Output, count);
165
166 if (bytes_read) *bytes_read = count;
167 return res;
168 }
169
170
171 /*----------------------------------------------------------------------
172 | PLT_PipeOutputStreamPump::PLT_PipeOutputStreamPump
173 +---------------------------------------------------------------------*/
174 PLT_PipeOutputStreamPump::PLT_PipeOutputStreamPump(NPT_InputStreamReference& input,
175 NPT_Size size /* 65535 */,
176 NPT_Size max_bytes_to_read /* = 0 */) :
177 PLT_StreamPump(size),
178 m_Input(input),
179 m_MaxBytesToRead(max_bytes_to_read),
180 m_LastRes(NPT_SUCCESS)
181 {
182 }
183
184 /*----------------------------------------------------------------------
185 | PLT_PipeOutputStreamPump::~PLT_PipeOutputStreamPump
186 +---------------------------------------------------------------------*/
187 PLT_PipeOutputStreamPump::~PLT_PipeOutputStreamPump()
188 {
189 }
190
191 /*----------------------------------------------------------------------
192 | PLT_PipeOutputStreamPump::Transmit
193 +---------------------------------------------------------------------*/
194 NPT_Result
195 PLT_PipeOutputStreamPump::Transmit(NPT_OutputStream& output)
196 {
197 NPT_Size count;
198 NPT_Result res;
199
200 if ((m_LastRes == NPT_SUCCESS) || (m_LastRes == NPT_ERROR_WOULD_BLOCK)) {
201 // fill the entire space by default
202 NPT_Size max_space = m_RingBuffer->GetSpace();
203 if (max_space) {
204 NPT_Size max_to_read = max_space;
205 if (m_MaxBytesToRead != 0) {
206 // if a total maximum amount was set, make sure we don't read more
207 max_to_read = ((m_MaxBytesToRead - m_TotalBytesRead) < max_space) ? (m_MaxBytesToRead - m_TotalBytesRead) : max_space;
208 }
209
210 // any data to read
211 if (max_to_read) {
212 m_LastRes = PullData(*m_Input, max_to_read);
213 } else {
214 m_LastRes = NPT_ERROR_EOS;
215 }
216 }
217 } else if (!m_RingBuffer->GetAvailable()) {
218 // if the buffer is now empty, return the input last error
219 return m_LastRes;
220 }
221
222 // write as much as we can on the output stream
223 res = PushData(output, count);
224 return res;
225 }
226