OpenShot Library | OpenShotAudio  0.2.1
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 
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
void skipNextBytes(int64 numBytesToSkip) override
Reads and discards a number of bytes from the stream.
virtual bool writeDoubleBigEndian(double value)
Writes a 64-bit floating point value to the stream in a binary format.
bool setPosition(int64) override
Tries to move the current read position of the stream.
int nextInt() noexcept
Returns the next random 32 bit integer.
Definition: juce_Random.cpp:78
bool nextBool() noexcept
Returns the next random boolean value.
static bool canRepresent(juce_wchar character) noexcept
Returns true if the given unicode character can be represented in this encoding.
const void * getData() const noexcept
Returns a pointer to the source data block from which this stream is reading.
STL namespace.
The JUCE String class!
Definition: juce_String.h:42
MemoryInputStream(const void *sourceData, size_t sourceDataSize, bool keepInternalCopyOfData)
Creates a MemoryInputStream.
int64 nextInt64() noexcept
Returns the next 64-bit random number.
Definition: juce_Random.cpp:96
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
virtual bool writeInt64BigEndian(int64 value)
Writes a 64-bit integer to the stream in a big-endian byte order.
int64 getPosition() override
Returns the offset of the next byte that will be read from the stream.
int read(void *destBuffer, int maxBytesToRead) override
Reads some data from the stream into a memory buffer.
Wraps a pointer to a null-terminated UTF-32 character string, and provides various methods to operate...
const void * getData() const noexcept
Returns a pointer to the data that has been written to the stream.
void * getData() noexcept
Returns a void pointer to the data.
virtual bool writeIntBigEndian(int value)
Writes a 32-bit integer to the stream in a big-endian byte order.
double nextDouble() noexcept
Returns the next random floating-point number.
virtual bool writeInt64(int64 value)
Writes a 64-bit integer to the stream in a little-endian byte order.
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
int64 getNumBytesRemaining()
Returns the number of bytes available for reading, or a negative value if the remaining length is not...
virtual bool writeDouble(double value)
Writes a 64-bit floating point value to the stream in a binary format.
~MemoryInputStream() override
Destructor.
int64 getTotalLength() override
Returns the total number of bytes available for reading in this stream.
virtual bool writeInt(int value)
Writes a 32-bit integer to the stream in a little-endian byte order.
A random number generator.
Definition: juce_Random.h:38
virtual bool writeCompressedInt(int value)
Writes a condensed binary encoding of a 32-bit integer.
Writes data to an internal memory buffer, which grows as required.
virtual bool writeString(const String &text)
Stores a string in the stream in a binary format.
bool isExhausted() override
Returns true if the stream has no more data to read.
A class to hold a resizable block of raw data.
Allows a block of data to be accessed as a stream.