OpenShot Library | libopenshot-audio  0.2.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  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 
118  MemoryOutputStream mo;
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
juce::MemoryInputStream::~MemoryInputStream
~MemoryInputStream() override
Destructor.
Definition: juce_MemoryInputStream.cpp:49
juce::MemoryInputStream::getTotalLength
int64 getTotalLength() override
Returns the total number of bytes available for reading in this stream.
Definition: juce_MemoryInputStream.cpp:53
juce::CharPointer_UTF16::canRepresent
static bool canRepresent(juce_wchar character) noexcept
Returns true if the given unicode character can be represented in this encoding.
Definition: juce_CharPointer_UTF16.h:434
juce::MemoryInputStream::getPosition
int64 getPosition() override
Returns the offset of the next byte that will be read from the stream.
Definition: juce_MemoryInputStream.cpp:87
juce::MemoryInputStream::setPosition
bool setPosition(int64) override
Tries to move the current read position of the stream.
Definition: juce_MemoryInputStream.cpp:81
juce::MemoryInputStream::MemoryInputStream
MemoryInputStream(const void *sourceData, size_t sourceDataSize, bool keepInternalCopyOfData)
Creates a MemoryInputStream.
Definition: juce_MemoryInputStream.cpp:26
juce::MemoryInputStream::read
int read(void *destBuffer, int maxBytesToRead) override
Reads some data from the stream into a memory buffer.
Definition: juce_MemoryInputStream.cpp:58
juce::MemoryInputStream::skipNextBytes
void skipNextBytes(int64 numBytesToSkip) override
Reads and discards a number of bytes from the stream.
Definition: juce_MemoryInputStream.cpp:92
juce::HeapBlock::malloc
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
Definition: juce_HeapBlock.h:256
juce::MemoryInputStream::isExhausted
bool isExhausted() override
Returns true if the stream has no more data to read.
Definition: juce_MemoryInputStream.cpp:76
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::MemoryBlock
A class to hold a resizable block of raw data.
Definition: juce_MemoryBlock.h:36