Mercurial > projects > hoofbaby
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 |