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