31 requestedSize =
jmax (256, requestedSize);
32 auto sourceSize = source->getTotalLength();
34 if (sourceSize >= 0 && sourceSize < requestedSize)
35 return jmax (32, (
int) sourceSize);
42 :
source (sourceStream, takeOwnership),
68 return source->getTotalLength();
109 bytesRead += bytesToKeep;
135 const auto initialPosition =
position;
137 const auto getBufferedRange = [
this] {
return bufferedRange; };
139 const auto readFromReservoir = [
this, &destBuffer, &initialPosition] (
const Range<int64> rangeToRead)
141 memcpy (
static_cast<char*
> (destBuffer) + (rangeToRead.getStart() - initialPosition),
143 (
size_t) rangeToRead.getLength());
146 const auto fillReservoir = [
this] (
int64 requestedStart)
157 const auto bytesRead = maxBytesToRead - remaining.getLength();
159 return (
int) bytesRead;
170 for (
int i = 0;
i < maxChars; ++
i)
188struct BufferedInputStreamTests :
public UnitTest
190 template <
typename Fn,
size_t... Ix,
typename Values>
191 static void applyImpl (Fn&&
fn, std::index_sequence<Ix...>, Values&& values)
193 fn (std::get<Ix> (values)...);
196 template <
typename Fn,
typename... Values>
197 static void apply (Fn&&
fn, std::tuple<Values...> values)
199 applyImpl (
fn, std::make_index_sequence<
sizeof... (Values)>(), values);
202 template <
typename Fn,
typename Values>
203 static void allCombinationsImpl (Fn&&
fn, Values&& values)
208 template <
typename Fn,
typename Values,
typename Range,
typename... Ranges>
209 static void allCombinationsImpl (Fn&&
fn, Values&& values, Range&& range, Ranges&&... ranges)
211 for (
auto& item : range)
212 allCombinationsImpl (
fn, std::tuple_cat (values, std::tie (item)), ranges...);
215 template <
typename Fn,
typename... Ranges>
216 static void allCombinations (Fn&&
fn, Ranges&&... ranges)
218 allCombinationsImpl (
fn, std::tie(), ranges...);
221 BufferedInputStreamTests()
222 : UnitTest (
"BufferedInputStream", UnitTestCategories::streams)
225 void runTest()
override
227 const MemoryBlock testBufferA (
"abcdefghijklmnopqrstuvwxyz", 26);
229 const auto testBufferB = [&]
231 MemoryBlock mb { 8192 };
232 auto r = getRandom();
234 std::for_each (mb.begin(), mb.end(), [&] (
char& item)
236 item = (char) r.nextInt (std::numeric_limits<char>::max());
242 const MemoryBlock buffers[] { testBufferA, testBufferB };
243 const int readSizes[] { 3, 10, 50 };
244 const bool shouldPeek[] {
false,
true };
246 const auto runTest = [
this] (
const MemoryBlock&
data,
const int readSize,
const bool peek)
248 MemoryInputStream mi (
data,
true);
250 BufferedInputStream stream (mi,
jmin (200, (
int)
data.getSize()));
254 expectEquals (stream.getPosition(), (
int64) 0);
255 expectEquals (stream.getTotalLength(), (
int64)
data.getSize());
256 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
257 expect (! stream.isExhausted());
259 size_t numBytesRead = 0;
260 MemoryBlock readBuffer (
data.getSize());
262 while (numBytesRead <
data.getSize())
265 expectEquals (stream.peekByte(), *(
char*) (
data.begin() + numBytesRead));
267 const auto startingPos = numBytesRead;
268 numBytesRead += (size_t) stream.read (readBuffer.begin() + numBytesRead, readSize);
270 expect (std::equal (readBuffer.begin() + startingPos,
271 readBuffer.begin() + numBytesRead,
272 data.begin() + startingPos,
273 data.begin() + numBytesRead));
274 expectEquals (stream.getPosition(), (
int64) numBytesRead);
275 expectEquals (stream.getNumBytesRemaining(), (
int64) (
data.getSize() - numBytesRead));
276 expect (stream.isExhausted() == (numBytesRead ==
data.getSize()));
279 expectEquals (stream.getPosition(), (
int64)
data.getSize());
280 expectEquals (stream.getNumBytesRemaining(), (
int64) 0);
281 expect (stream.isExhausted());
283 expect (readBuffer ==
data);
287 stream.setPosition (0);
288 expectEquals (stream.getPosition(), (
int64) 0);
289 expectEquals (stream.getTotalLength(), (
int64)
data.getSize());
290 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
291 expect (! stream.isExhausted());
294 const int numBytesToSkip = 5;
296 while (numBytesRead <
data.getSize())
298 expectEquals (stream.peekByte(), *(
char*) (
data.begin() + numBytesRead));
300 stream.skipNextBytes (numBytesToSkip);
301 numBytesRead += numBytesToSkip;
302 numBytesRead = std::min (numBytesRead,
data.getSize());
304 expectEquals (stream.getPosition(), (
int64) numBytesRead);
305 expectEquals (stream.getNumBytesRemaining(), (
int64) (
data.getSize() - numBytesRead));
306 expect (stream.isExhausted() == (numBytesRead ==
data.getSize()));
309 expectEquals (stream.getPosition(), (
int64)
data.getSize());
310 expectEquals (stream.getNumBytesRemaining(), (
int64) 0);
311 expect (stream.isExhausted());
314 allCombinations (runTest, buffers, readSizes, shouldPeek);
318static BufferedInputStreamTests bufferedInputStreamTests;
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
int64_t int64
Definition basics.h:91
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Definition String.cpp:1961
Definition juce_Range.h:40
Definition juce_String.h:53
Definition juce_UnitTest.h:70
register unsigned i
Definition inflate.c:1575
JSAMPIMAGE data
Definition jpeglib.h:945
Definition carla_juce.cpp:31
long long int64
Definition juce_MathsFunctions.h:54
static int calcBufferStreamBufferSize(int requestedSize, InputStream *source) noexcept
Definition juce_BufferedInputStream.cpp:26
#define false
Definition ordinals.h:83
static Range< Index > doBufferedRead(Range< Index > rangeToRead, GetBufferedRange &&getBufferedRange, ReadFromReservoir &&readFromReservoir, FillReservoir &&fillReservoir)
Definition juce_Reservoir.h:67
const char const char const char const char char * fn
Definition swell-functions.h:168
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
typedef int(UZ_EXP MsgFn)()