OpenShot Library | libopenshot-audio  0.2.0
juce_MemoryBlock.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 
28 MemoryBlock::MemoryBlock (size_t initialSize, bool initialiseToZero)
29 {
30  if (initialSize > 0)
31  {
32  size = initialSize;
33  data.allocate (initialSize, initialiseToZero);
34  }
35  else
36  {
37  size = 0;
38  }
39 }
40 
42  : size (other.size)
43 {
44  if (size > 0)
45  {
46  jassert (other.data != nullptr);
47  data.malloc (size);
48  memcpy (data, other.data, size);
49  }
50 }
51 
52 MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const size_t sizeInBytes)
53  : size (sizeInBytes)
54 {
55  jassert (((ssize_t) sizeInBytes) >= 0);
56 
57  if (size > 0)
58  {
59  jassert (dataToInitialiseFrom != nullptr); // non-zero size, but a zero pointer passed-in?
60 
61  data.malloc (size);
62 
63  if (dataToInitialiseFrom != nullptr)
64  memcpy (data, dataToInitialiseFrom, size);
65  }
66 }
67 
69 {
70 }
71 
73 {
74  if (this != &other)
75  {
76  setSize (other.size, false);
77  memcpy (data, other.data, size);
78  }
79 
80  return *this;
81 }
82 
84  : data (std::move (other.data)),
85  size (other.size)
86 {
87 }
88 
90 {
91  data = std::move (other.data);
92  size = other.size;
93  return *this;
94 }
95 
96 //==============================================================================
97 bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept
98 {
99  return matches (other.data, other.size);
100 }
101 
102 bool MemoryBlock::operator!= (const MemoryBlock& other) const noexcept
103 {
104  return ! operator== (other);
105 }
106 
107 bool MemoryBlock::matches (const void* dataToCompare, size_t dataSize) const noexcept
108 {
109  return size == dataSize
110  && memcmp (data, dataToCompare, size) == 0;
111 }
112 
113 //==============================================================================
114 // this will resize the block to this size
115 void MemoryBlock::setSize (const size_t newSize, const bool initialiseToZero)
116 {
117  if (size != newSize)
118  {
119  if (newSize <= 0)
120  {
121  reset();
122  }
123  else
124  {
125  if (data != nullptr)
126  {
127  data.realloc (newSize);
128 
129  if (initialiseToZero && (newSize > size))
130  zeromem (data + size, newSize - size);
131  }
132  else
133  {
134  data.allocate (newSize, initialiseToZero);
135  }
136 
137  size = newSize;
138  }
139  }
140 }
141 
143 {
144  data.free();
145  size = 0;
146 }
147 
148 void MemoryBlock::ensureSize (size_t minimumSize, bool initialiseToZero)
149 {
150  if (size < minimumSize)
151  setSize (minimumSize, initialiseToZero);
152 }
153 
154 void MemoryBlock::swapWith (MemoryBlock& other) noexcept
155 {
156  std::swap (size, other.size);
157  data.swapWith (other.data);
158 }
159 
160 //==============================================================================
161 void MemoryBlock::fillWith (uint8 value) noexcept
162 {
163  memset (data, (int) value, size);
164 }
165 
166 void MemoryBlock::append (const void* srcData, size_t numBytes)
167 {
168  if (numBytes > 0)
169  {
170  jassert (srcData != nullptr); // this must not be null!
171  auto oldSize = size;
172  setSize (size + numBytes);
173  memcpy (data + oldSize, srcData, numBytes);
174  }
175 }
176 
177 void MemoryBlock::replaceWith (const void* srcData, size_t numBytes)
178 {
179  if (numBytes > 0)
180  {
181  jassert (srcData != nullptr); // this must not be null!
182  setSize (numBytes);
183  memcpy (data, srcData, numBytes);
184  }
185 }
186 
187 void MemoryBlock::insert (const void* srcData, size_t numBytes, size_t insertPosition)
188 {
189  if (numBytes > 0)
190  {
191  jassert (srcData != nullptr); // this must not be null!
192  insertPosition = jmin (size, insertPosition);
193  auto trailingDataSize = size - insertPosition;
194  setSize (size + numBytes, false);
195 
196  if (trailingDataSize > 0)
197  memmove (data + insertPosition + numBytes,
198  data + insertPosition,
199  trailingDataSize);
200 
201  memcpy (data + insertPosition, srcData, numBytes);
202  }
203 }
204 
205 void MemoryBlock::removeSection (size_t startByte, size_t numBytesToRemove)
206 {
207  if (startByte + numBytesToRemove >= size)
208  {
209  setSize (startByte);
210  }
211  else if (numBytesToRemove > 0)
212  {
213  memmove (data + startByte,
214  data + startByte + numBytesToRemove,
215  size - (startByte + numBytesToRemove));
216 
217  setSize (size - numBytesToRemove);
218  }
219 }
220 
221 void MemoryBlock::copyFrom (const void* const src, int offset, size_t num) noexcept
222 {
223  auto* d = static_cast<const char*> (src);
224 
225  if (offset < 0)
226  {
227  d -= offset;
228  num += (size_t) -offset;
229  offset = 0;
230  }
231 
232  if ((size_t) offset + num > size)
233  num = size - (size_t) offset;
234 
235  if (num > 0)
236  memcpy (data + offset, d, num);
237 }
238 
239 void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcept
240 {
241  auto* d = static_cast<char*> (dst);
242 
243  if (offset < 0)
244  {
245  zeromem (d, (size_t) -offset);
246  d -= offset;
247  num -= (size_t) -offset;
248  offset = 0;
249  }
250 
251  if ((size_t) offset + num > size)
252  {
253  auto newNum = (size_t) size - (size_t) offset;
254  zeromem (d + newNum, num - newNum);
255  num = newNum;
256  }
257 
258  if (num > 0)
259  memcpy (d, data + offset, num);
260 }
261 
263 {
264  return String::fromUTF8 (data, (int) size);
265 }
266 
267 //==============================================================================
268 int MemoryBlock::getBitRange (size_t bitRangeStart, size_t numBits) const noexcept
269 {
270  int res = 0;
271 
272  auto byte = bitRangeStart >> 3;
273  auto offsetInByte = bitRangeStart & 7;
274  size_t bitsSoFar = 0;
275 
276  while (numBits > 0 && (size_t) byte < size)
277  {
278  auto bitsThisTime = jmin (numBits, 8 - offsetInByte);
279  const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte;
280 
281  res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar);
282 
283  bitsSoFar += bitsThisTime;
284  numBits -= bitsThisTime;
285  ++byte;
286  offsetInByte = 0;
287  }
288 
289  return res;
290 }
291 
292 void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int bitsToSet) noexcept
293 {
294  auto byte = bitRangeStart >> 3;
295  auto offsetInByte = bitRangeStart & 7;
296  uint32 mask = ~((((uint32) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
297 
298  while (numBits > 0 && (size_t) byte < size)
299  {
300  auto bitsThisTime = jmin (numBits, 8 - offsetInByte);
301 
302  const uint32 tempMask = (mask << offsetInByte) | ~((((uint32) 0xffffffff) >> offsetInByte) << offsetInByte);
303  const uint32 tempBits = (uint32) bitsToSet << offsetInByte;
304 
305  data[byte] = (char) (((uint32) data[byte] & tempMask) | tempBits);
306 
307  ++byte;
308  numBits -= bitsThisTime;
309  bitsToSet >>= bitsThisTime;
310  mask >>= bitsThisTime;
311  offsetInByte = 0;
312  }
313 }
314 
315 //==============================================================================
317 {
318  ensureSize ((size_t) hex.length() >> 1);
319  char* dest = data;
320  auto t = hex.text;
321 
322  for (;;)
323  {
324  int byte = 0;
325 
326  for (int loop = 2; --loop >= 0;)
327  {
328  byte <<= 4;
329 
330  for (;;)
331  {
332  auto c = t.getAndAdvance();
333 
334  if (c >= '0' && c <= '9') { byte |= c - '0'; break; }
335  if (c >= 'a' && c <= 'z') { byte |= c - ('a' - 10); break; }
336  if (c >= 'A' && c <= 'Z') { byte |= c - ('A' - 10); break; }
337 
338  if (c == 0)
339  {
340  setSize (static_cast<size_t> (dest - data));
341  return;
342  }
343  }
344  }
345 
346  *dest++ = (char) byte;
347  }
348 }
349 
350 //==============================================================================
351 static const char base64EncodingTable[] = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
352 
354 {
355  auto numChars = ((size << 3) + 5) / 6;
356 
357  String destString ((unsigned int) size); // store the length, followed by a '.', and then the data.
358  auto initialLen = destString.length();
359  destString.preallocateBytes (sizeof (String::CharPointerType::CharType) * (size_t) initialLen + 2 + numChars);
360 
361  auto d = destString.getCharPointer();
362  d += initialLen;
363  d.write ('.');
364 
365  for (size_t i = 0; i < numChars; ++i)
366  d.write ((juce_wchar) (uint8) base64EncodingTable[getBitRange (i * 6, 6)]);
367 
368  d.writeNull();
369  return destString;
370 }
371 
372 static const char base64DecodingTable[] =
373 {
374  63, 0, 0, 0, 0, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0,
375  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
376  0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52
377 };
378 
380 {
381  auto dot = CharacterFunctions::find (s.text, (juce_wchar) '.');
382 
383  if (dot.isEmpty())
384  return false;
385 
386  auto numBytesNeeded = String (s.text, dot).getIntValue();
387 
388  setSize ((size_t) numBytesNeeded, true);
389 
390  auto srcChars = dot + 1;
391  int pos = 0;
392 
393  for (;;)
394  {
395  auto c = (int) srcChars.getAndAdvance();
396 
397  if (c == 0)
398  return true;
399 
400  c -= 43;
401 
402  if (isPositiveAndBelow (c, numElementsInArray (base64DecodingTable)))
403  {
404  setBitRange ((size_t) pos, 6, base64DecodingTable[c]);
405  pos += 6;
406  }
407  }
408 }
409 
410 } // namespace juce
juce::MemoryBlock::toBase64Encoding
String toBase64Encoding() const
Returns a string of characters in a JUCE-specific text encoding that represents the binary contents o...
Definition: juce_MemoryBlock.cpp:353
juce::MemoryBlock::operator!=
bool operator!=(const MemoryBlock &other) const noexcept
Compares two memory blocks.
Definition: juce_MemoryBlock.cpp:102
juce::StringRef
A simple class for holding temporary references to a string literal or String.
Definition: juce_StringRef.h:65
juce::HeapBlock::free
void free() noexcept
Frees any currently-allocated data.
Definition: juce_HeapBlock.h:304
juce::CharacterFunctions::find
static CharPointerType1 find(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Returns a pointer to the first occurrence of a substring in a string.
Definition: juce_CharacterFunctions.h:663
juce::String::getCharPointer
CharPointerType getCharPointer() const noexcept
Returns the character pointer currently being used to store this string.
Definition: juce_String.h:1200
juce::MemoryBlock::copyTo
void copyTo(void *destData, int sourceOffset, size_t numBytes) const noexcept
Copies data from this MemoryBlock to a memory address.
Definition: juce_MemoryBlock.cpp:239
juce::HeapBlock::realloc
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Re-allocates a specified amount of memory.
Definition: juce_HeapBlock.h:294
juce::MemoryBlock::removeSection
void removeSection(size_t startByte, size_t numBytesToRemove)
Chops out a section of the block.
Definition: juce_MemoryBlock.cpp:205
juce::MemoryBlock::replaceWith
void replaceWith(const void *data, size_t numBytes)
Resizes this block to the given size and fills its contents from the supplied buffer.
Definition: juce_MemoryBlock.cpp:177
juce::MemoryBlock::swapWith
void swapWith(MemoryBlock &other) noexcept
Exchanges the contents of this and another memory block.
Definition: juce_MemoryBlock.cpp:154
juce::MemoryBlock::matches
bool matches(const void *data, size_t dataSize) const noexcept
Returns true if the data in this MemoryBlock matches the raw bytes passed-in.
Definition: juce_MemoryBlock.cpp:107
juce::MemoryBlock::fillWith
void fillWith(uint8 valueToUse) noexcept
Fills the entire memory block with a repeated byte value.
Definition: juce_MemoryBlock.cpp:161
juce::StringRef::length
int length() const noexcept
Returns the number of characters in the string.
Definition: juce_StringRef.h:109
juce::StringRef::text
String::CharPointerType text
The text that is referenced.
Definition: juce_StringRef.h:126
juce::HeapBlock::allocate
void allocate(SizeType newNumElements, bool initialiseToZero)
Allocates a specified amount of memory and optionally clears it.
Definition: juce_HeapBlock.h:279
juce::MemoryBlock::toString
String toString() const
Attempts to parse the contents of the block as a zero-terminated UTF8 string.
Definition: juce_MemoryBlock.cpp:262
juce::MemoryBlock::ensureSize
void ensureSize(const size_t minimumSize, bool initialiseNewSpaceToZero=false)
Increases the block's size only if it's smaller than a given size.
Definition: juce_MemoryBlock.cpp:148
juce::MemoryBlock::getBitRange
int getBitRange(size_t bitRangeStart, size_t numBitsToRead) const noexcept
Reads a number of bits from the memory block, treating it as one long binary sequence.
Definition: juce_MemoryBlock.cpp:268
juce::String::preallocateBytes
void preallocateBytes(size_t numBytesNeeded)
Increases the string's internally allocated storage.
Definition: juce_String.cpp:291
juce::String::length
int length() const noexcept
Returns the number of characters in the string.
Definition: juce_String.cpp:518
juce::HeapBlock::malloc
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
Definition: juce_HeapBlock.h:256
juce::MemoryBlock::loadFromHexString
void loadFromHexString(StringRef sourceHexString)
Parses a string of hexadecimal numbers and writes this data into the memory block.
Definition: juce_MemoryBlock.cpp:316
juce::MemoryBlock::operator==
bool operator==(const MemoryBlock &other) const noexcept
Compares two memory blocks.
Definition: juce_MemoryBlock.cpp:97
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::MemoryBlock::append
void append(const void *data, size_t numBytes)
Adds another block of data to the end of this one.
Definition: juce_MemoryBlock.cpp:166
juce::MemoryBlock::MemoryBlock
MemoryBlock() noexcept
Create an uninitialised block with 0 size.
Definition: juce_MemoryBlock.cpp:26
juce::MemoryBlock::operator=
MemoryBlock & operator=(const MemoryBlock &)
Copies another memory block onto this one.
Definition: juce_MemoryBlock.cpp:72
juce::MemoryBlock::setBitRange
void setBitRange(size_t bitRangeStart, size_t numBits, int binaryNumberToApply) noexcept
Sets a number of bits in the memory block, treating it as a long binary sequence.
Definition: juce_MemoryBlock.cpp:292
juce::CharPointer_UTF8::write
void write(const juce_wchar charToWrite) noexcept
Writes a unicode character to this string, and advances this pointer to point to the next position.
Definition: juce_CharPointer_UTF8.h:329
juce::CharPointer_UTF8::getAndAdvance
juce_wchar getAndAdvance() noexcept
Returns the character that this pointer is currently pointing to, and then advances the pointer to po...
Definition: juce_CharPointer_UTF8.h:151
juce::MemoryBlock::fromBase64Encoding
bool fromBase64Encoding(StringRef encodedString)
Takes a string created by MemoryBlock::toBase64Encoding() and extracts the original data.
Definition: juce_MemoryBlock.cpp:379
juce::String::getIntValue
int getIntValue() const noexcept
Reads the value of the string as a decimal number (up to 32 bits in size).
Definition: juce_String.cpp:1869
juce::MemoryBlock::insert
void insert(const void *dataToInsert, size_t numBytesToInsert, size_t insertPosition)
Inserts some data into the block.
Definition: juce_MemoryBlock.cpp:187
juce::MemoryBlock::reset
void reset()
Frees all the blocks data, setting its size to 0.
Definition: juce_MemoryBlock.cpp:142
juce::MemoryBlock::~MemoryBlock
~MemoryBlock() noexcept
Destructor.
Definition: juce_MemoryBlock.cpp:68
juce::String::fromUTF8
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Creates a String from a UTF-8 encoded buffer.
Definition: juce_String.cpp:2123
juce::MemoryBlock
A class to hold a resizable block of raw data.
Definition: juce_MemoryBlock.h:36
juce::MemoryBlock::copyFrom
void copyFrom(const void *srcData, int destinationOffset, size_t numBytes) noexcept
Copies data into this MemoryBlock from a memory address.
Definition: juce_MemoryBlock.cpp:221
juce::MemoryBlock::setSize
void setSize(const size_t newSize, bool initialiseNewSpaceToZero=false)
Resizes the memory block.
Definition: juce_MemoryBlock.cpp:115