OpenShot Audio Library | OpenShotAudio  0.3.0
juce_MemoryInputStream.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 
26 MemoryInputStream::MemoryInputStream (const void* sourceData, size_t sourceDataSize, bool keepCopy)
27  : data (sourceData),
28  dataSize (sourceDataSize)
29 {
30  if (keepCopy)
31  {
32  internalCopy = MemoryBlock (sourceData, sourceDataSize);
33  data = internalCopy.getData();
34  }
35 }
36 
37 MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData, bool keepCopy)
38  : data (sourceData.getData()),
39  dataSize (sourceData.getSize())
40 {
41  if (keepCopy)
42  {
43  internalCopy = sourceData;
44  data = internalCopy.getData();
45  }
46 }
47 
49  : internalCopy (std::move (source))
50 {
51  data = internalCopy.getData();
52 }
53 
55 {
56 }
57 
59 {
60  return (int64) dataSize;
61 }
62 
63 int MemoryInputStream::read (void* buffer, int howMany)
64 {
65  jassert (buffer != nullptr && howMany >= 0);
66 
67  if (howMany <= 0 || position >= dataSize)
68  return 0;
69 
70  auto num = jmin ((size_t) howMany, dataSize - position);
71 
72  if (num > 0)
73  {
74  memcpy (buffer, addBytesToPointer (data, position), num);
75  position += num;
76  }
77 
78  return (int) num;
79 }
80 
82 {
83  return position >= dataSize;
84 }
85 
86 bool MemoryInputStream::setPosition (const int64 pos)
87 {
88  position = (size_t) jlimit ((int64) 0, (int64) dataSize, pos);
89  return true;
90 }
91 
93 {
94  return (int64) position;
95 }
96 
97 void MemoryInputStream::skipNextBytes (int64 numBytesToSkip)
98 {
99  if (numBytesToSkip > 0)
100  setPosition (getPosition() + numBytesToSkip);
101 }
102 
103 
104 //==============================================================================
105 //==============================================================================
106 #if JUCE_UNIT_TESTS
107 
108 class MemoryStreamTests : public UnitTest
109 {
110 public:
111  MemoryStreamTests()
112  : UnitTest ("MemoryInputStream & MemoryOutputStream", UnitTestCategories::streams)
113  {}
114 
115  void runTest() override
116  {
117  beginTest ("Basics");
118  Random r = getRandom();
119 
120  int randomInt = r.nextInt();
121  int64 randomInt64 = r.nextInt64();
122  double randomDouble = r.nextDouble();
123  String randomString (createRandomWideCharString (r));
124 
125  MemoryOutputStream mo;
126  mo.writeInt (randomInt);
127  mo.writeIntBigEndian (randomInt);
128  mo.writeCompressedInt (randomInt);
129  mo.writeString (randomString);
130  mo.writeInt64 (randomInt64);
131  mo.writeInt64BigEndian (randomInt64);
132  mo.writeDouble (randomDouble);
133  mo.writeDoubleBigEndian (randomDouble);
134 
135  MemoryInputStream mi (mo.getData(), mo.getDataSize(), false);
136  expect (mi.readInt() == randomInt);
137  expect (mi.readIntBigEndian() == randomInt);
138  expect (mi.readCompressedInt() == randomInt);
139  expectEquals (mi.readString(), randomString);
140  expect (mi.readInt64() == randomInt64);
141  expect (mi.readInt64BigEndian() == randomInt64);
142  expect (mi.readDouble() == randomDouble);
143  expect (mi.readDoubleBigEndian() == randomDouble);
144 
145  const MemoryBlock data ("abcdefghijklmnopqrstuvwxyz", 26);
146  MemoryInputStream stream (data, true);
147 
148  beginTest ("Read");
149 
150  expectEquals (stream.getPosition(), (int64) 0);
151  expectEquals (stream.getTotalLength(), (int64) data.getSize());
152  expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
153  expect (! stream.isExhausted());
154 
155  size_t numBytesRead = 0;
156  MemoryBlock readBuffer (data.getSize());
157 
158  while (numBytesRead < data.getSize())
159  {
160  numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
161 
162  expectEquals (stream.getPosition(), (int64) numBytesRead);
163  expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
164  expect (stream.isExhausted() == (numBytesRead == data.getSize()));
165  }
166 
167  expectEquals (stream.getPosition(), (int64) data.getSize());
168  expectEquals (stream.getNumBytesRemaining(), (int64) 0);
169  expect (stream.isExhausted());
170 
171  expect (readBuffer == data);
172 
173  beginTest ("Skip");
174 
175  stream.setPosition (0);
176  expectEquals (stream.getPosition(), (int64) 0);
177  expectEquals (stream.getTotalLength(), (int64) data.getSize());
178  expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
179  expect (! stream.isExhausted());
180 
181  numBytesRead = 0;
182  const int numBytesToSkip = 5;
183 
184  while (numBytesRead < data.getSize())
185  {
186  stream.skipNextBytes (numBytesToSkip);
187  numBytesRead += numBytesToSkip;
188  numBytesRead = std::min (numBytesRead, data.getSize());
189 
190  expectEquals (stream.getPosition(), (int64) numBytesRead);
191  expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
192  expect (stream.isExhausted() == (numBytesRead == data.getSize()));
193  }
194 
195  expectEquals (stream.getPosition(), (int64) data.getSize());
196  expectEquals (stream.getNumBytesRemaining(), (int64) 0);
197  expect (stream.isExhausted());
198  }
199 
200  static String createRandomWideCharString (Random& r)
201  {
202  juce_wchar buffer [50] = { 0 };
203 
204  for (int i = 0; i < numElementsInArray (buffer) - 1; ++i)
205  {
206  if (r.nextBool())
207  {
208  do
209  {
210  buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
211  }
212  while (! CharPointer_UTF16::canRepresent (buffer[i]));
213  }
214  else
215  buffer[i] = (juce_wchar) (1 + r.nextInt (0xff));
216  }
217 
218  return CharPointer_UTF32 (buffer);
219  }
220 };
221 
222 static MemoryStreamTests memoryInputStreamUnitTests;
223 
224 #endif
225 
226 } // namespace juce
static bool canRepresent(juce_wchar character) noexcept
void * getData() noexcept
void skipNextBytes(int64 numBytesToSkip) override
int read(void *destBuffer, int maxBytesToRead) override
bool setPosition(int64) override
MemoryInputStream(const void *sourceData, size_t sourceDataSize, bool keepInternalCopyOfData)