OpenShot Audio Library | OpenShotAudio  0.3.0
juce_SubregionStream.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
27  int64 start, int64 length,
28  bool deleteSourceWhenDestroyed)
29  : source (sourceStream, deleteSourceWhenDestroyed),
30  startPositionInSourceStream (start),
31  lengthOfSourceStream (length)
32 {
34 }
35 
37 {
38 }
39 
41 {
42  auto srcLen = source->getTotalLength() - startPositionInSourceStream;
43 
44  return lengthOfSourceStream >= 0 ? jmin (lengthOfSourceStream, srcLen)
45  : srcLen;
46 }
47 
49 {
50  return source->getPosition() - startPositionInSourceStream;
51 }
52 
53 bool SubregionStream::setPosition (int64 newPosition)
54 {
55  return source->setPosition (jmax ((int64) 0, newPosition + startPositionInSourceStream));
56 }
57 
58 int SubregionStream::read (void* destBuffer, int maxBytesToRead)
59 {
60  jassert (destBuffer != nullptr && maxBytesToRead >= 0);
61 
62  if (lengthOfSourceStream < 0)
63  return source->read (destBuffer, maxBytesToRead);
64 
65  maxBytesToRead = (int) jmin ((int64) maxBytesToRead, lengthOfSourceStream - getPosition());
66 
67  if (maxBytesToRead <= 0)
68  return 0;
69 
70  return source->read (destBuffer, maxBytesToRead);
71 }
72 
74 {
75  if (lengthOfSourceStream >= 0 && getPosition() >= lengthOfSourceStream)
76  return true;
77 
78  return source->isExhausted();
79 }
80 
81 
82 //==============================================================================
83 //==============================================================================
84 #if JUCE_UNIT_TESTS
85 
86 struct SubregionInputStreamTests : public UnitTest
87 {
88  SubregionInputStreamTests()
89  : UnitTest ("SubregionInputStream", UnitTestCategories::streams)
90  {}
91 
92  void runTest() override
93  {
94  const MemoryBlock data ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", 52);
95  MemoryInputStream mi (data, true);
96 
97  const int offset = getRandom().nextInt ((int) data.getSize());
98  const size_t subregionSize = data.getSize() - (size_t) offset;
99 
100  SubregionStream stream (&mi, offset, (int) subregionSize, false);
101 
102  beginTest ("Read");
103 
104  expectEquals (stream.getPosition(), (int64) 0);
105  expectEquals (stream.getTotalLength(), (int64) subregionSize);
106  expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
107  expect (! stream.isExhausted());
108 
109  size_t numBytesRead = 0;
110  MemoryBlock readBuffer (subregionSize);
111 
112  while (numBytesRead < subregionSize)
113  {
114  numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
115 
116  expectEquals (stream.getPosition(), (int64) numBytesRead);
117  expectEquals (stream.getNumBytesRemaining(), (int64) (subregionSize - numBytesRead));
118  expect (stream.isExhausted() == (numBytesRead == subregionSize));
119  }
120 
121  expectEquals (stream.getPosition(), (int64) subregionSize);
122  expectEquals (stream.getNumBytesRemaining(), (int64) 0);
123  expect (stream.isExhausted());
124 
125  const MemoryBlock memoryBlockToCheck (data.begin() + (size_t) offset, data.getSize() - (size_t) offset);
126  expect (readBuffer == memoryBlockToCheck);
127 
128  beginTest ("Skip");
129 
130  stream.setPosition (0);
131  expectEquals (stream.getPosition(), (int64) 0);
132  expectEquals (stream.getTotalLength(), (int64) subregionSize);
133  expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
134  expect (! stream.isExhausted());
135 
136  numBytesRead = 0;
137  const int64 numBytesToSkip = 5;
138 
139  while (numBytesRead < subregionSize)
140  {
141  stream.skipNextBytes (numBytesToSkip);
142  numBytesRead += numBytesToSkip;
143  numBytesRead = std::min (numBytesRead, subregionSize);
144 
145  expectEquals (stream.getPosition(), (int64) numBytesRead);
146  expectEquals (stream.getNumBytesRemaining(), (int64) (subregionSize - numBytesRead));
147  expect (stream.isExhausted() == (numBytesRead == subregionSize));
148  }
149 
150  expectEquals (stream.getPosition(), (int64) subregionSize);
151  expectEquals (stream.getNumBytesRemaining(), (int64) 0);
152  expect (stream.isExhausted());
153  }
154 };
155 
156 static SubregionInputStreamTests subregionInputStreamTests;
157 
158 #endif
159 
160 } // namespace juce
size_t getSize() const noexcept
int64 getTotalLength() override
virtual void skipNextBytes(int64 numBytesToSkip)
bool setPosition(int64 newPosition) override
SubregionStream(InputStream *sourceStream, int64 startPositionInSourceStream, int64 lengthOfSourceStream, bool deleteSourceWhenDestroyed)
int read(void *destBuffer, int maxBytesToRead) override
char * begin() noexcept