OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_MemoryBlock.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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 MemoryBlock::MemoryBlock() noexcept {}
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
41 MemoryBlock::MemoryBlock (const MemoryBlock& other)
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
68 MemoryBlock::~MemoryBlock() noexcept
69{
70}
71
72 MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other)
73{
74 if (this != &other)
75 {
76 setSize (other.size, false);
77 memcpy (data, other.data, size);
78 }
79
80 return *this;
81}
82
83 MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept
84 : data (std::move (other.data)),
85 size (other.size)
86{
87}
88
89 MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept
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
142 void MemoryBlock::reset()
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::replaceAll (const void* srcData, size_t numBytes)
178{
179 if (numBytes <= 0)
180 {
181 reset();
182 return;
183 }
184
185 jassert (srcData != nullptr); // this must not be null!
186 setSize (numBytes);
187 memcpy (data, srcData, numBytes);
188}
189
190 void MemoryBlock::insert (const void* srcData, size_t numBytes, size_t insertPosition)
191{
192 if (numBytes > 0)
193 {
194 jassert (srcData != nullptr); // this must not be null!
195 insertPosition = jmin (size, insertPosition);
196 auto trailingDataSize = size - insertPosition;
197 setSize (size + numBytes, false);
198
199 if (trailingDataSize > 0)
200 memmove (data + insertPosition + numBytes,
201 data + insertPosition,
202 trailingDataSize);
203
204 memcpy (data + insertPosition, srcData, numBytes);
205 }
206}
207
208 void MemoryBlock::removeSection (size_t startByte, size_t numBytesToRemove)
209{
210 if (startByte + numBytesToRemove >= size)
211 {
212 setSize (startByte);
213 }
214 else if (numBytesToRemove > 0)
215 {
216 memmove (data + startByte,
217 data + startByte + numBytesToRemove,
218 size - (startByte + numBytesToRemove));
219
220 setSize (size - numBytesToRemove);
221 }
222}
223
224 void MemoryBlock::copyFrom (const void* const src, int offset, size_t num) noexcept
225{
226 auto* d = static_cast<const char*> (src);
227
228 if (offset < 0)
229 {
230 d -= offset;
231 num += (size_t) -offset;
232 offset = 0;
233 }
234
235 if ((size_t) offset + num > size)
236 num = size - (size_t) offset;
237
238 if (num > 0)
239 memcpy (data + offset, d, num);
240}
241
242 void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcept
243{
244 auto* d = static_cast<char*> (dst);
245
246 if (offset < 0)
247 {
248 zeromem (d, (size_t) -offset);
249 d -= offset;
250 num -= (size_t) -offset;
251 offset = 0;
252 }
253
254 if ((size_t) offset + num > size)
255 {
256 auto newNum = (size_t) size - (size_t) offset;
257 zeromem (d + newNum, num - newNum);
258 num = newNum;
259 }
260
261 if (num > 0)
262 memcpy (d, data + offset, num);
263}
264
265 String MemoryBlock::toString() const
266{
267 return String::fromUTF8 (data, (int) size);
268}
269
270//==============================================================================
271 int MemoryBlock::getBitRange (size_t bitRangeStart, size_t numBits) const noexcept
272{
273 int res = 0;
274
275 auto byte = bitRangeStart >> 3;
276 auto offsetInByte = bitRangeStart & 7;
277 size_t bitsSoFar = 0;
278
279 while (numBits > 0 && (size_t) byte < size)
280 {
281 auto bitsThisTime = jmin (numBits, 8 - offsetInByte);
282 const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte;
283
284 res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar);
285
286 bitsSoFar += bitsThisTime;
287 numBits -= bitsThisTime;
288 ++byte;
289 offsetInByte = 0;
290 }
291
292 return res;
293}
294
295 void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int bitsToSet) noexcept
296{
297 auto byte = bitRangeStart >> 3;
298 auto offsetInByte = bitRangeStart & 7;
299 uint32 mask = ~((((uint32) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
300
301 while (numBits > 0 && (size_t) byte < size)
302 {
303 auto bitsThisTime = jmin (numBits, 8 - offsetInByte);
304
305 const uint32 tempMask = (mask << offsetInByte) | ~((((uint32) 0xffffffff) >> offsetInByte) << offsetInByte);
306 const uint32 tempBits = (uint32) bitsToSet << offsetInByte;
307
308 data[byte] = (char) (((uint32) data[byte] & tempMask) | tempBits);
309
310 ++byte;
311 numBits -= bitsThisTime;
312 bitsToSet >>= bitsThisTime;
313 mask >>= bitsThisTime;
314 offsetInByte = 0;
315 }
316}
317
318//==============================================================================
319 void MemoryBlock::loadFromHexString (StringRef hex)
320{
321 ensureSize ((size_t) hex.length() >> 1);
322 char* dest = data;
323 auto t = hex.text;
324
325 for (;;)
326 {
327 juce_wchar byte = 0;
328
329 for (int loop = 2; --loop >= 0;)
330 {
331 byte <<= 4;
332
333 for (;;)
334 {
335 auto c = t.getAndAdvance();
336
337 if (c >= '0' && c <= '9') { byte |= c - '0'; break; }
338 if (c >= 'a' && c <= 'z') { byte |= c - ('a' - 10); break; }
339 if (c >= 'A' && c <= 'Z') { byte |= c - ('A' - 10); break; }
340
341 if (c == 0)
342 {
343 setSize (static_cast<size_t> (dest - data));
344 return;
345 }
346 }
347 }
348
349 *dest++ = (char) byte;
350 }
351}
352
353//==============================================================================
354 static const char base64EncodingTable[] = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
355
356 String MemoryBlock::toBase64Encoding() const
357{
358 auto numChars = ((size << 3) + 5) / 6;
359
360 String destString ((unsigned int) size); // store the length, followed by a '.', and then the data.
361 auto initialLen = destString.length();
362 destString.preallocateBytes ((size_t) initialLen * sizeof (String::CharPointerType::CharType) + 2 + numChars);
363
364 auto d = destString.getCharPointer();
365 d += initialLen;
366 d.write ('.');
367
368 for (size_t i = 0; i < numChars; ++i)
369 d.write ((juce_wchar) (uint8) base64EncodingTable[getBitRange (i * 6, 6)]);
370
371 d.writeNull();
372 return destString;
373}
374
375 static const char base64DecodingTable[] =
376{
377 63, 0, 0, 0, 0, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0,
378 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,
379 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
380};
381
382 bool MemoryBlock::fromBase64Encoding (StringRef s)
383{
384 auto dot = CharacterFunctions::find (s.text, (juce_wchar) '.');
385
386 if (dot.isEmpty())
387 return false;
388
389 auto numBytesNeeded = String (s.text, dot).getIntValue();
390
391 setSize ((size_t) numBytesNeeded, true);
392
393 auto srcChars = dot + 1;
394 int pos = 0;
395
396 for (;;)
397 {
398 auto c = (int) srcChars.getAndAdvance();
399
400 if (c == 0)
401 return true;
402
403 c -= 43;
404
405 if (isPositiveAndBelow (c, numElementsInArray (base64DecodingTable)))
406 {
407 setBitRange ((size_t) pos, 6, base64DecodingTable[c]);
408 pos += 6;
409 }
410 }
411}
412
413} // namespace juce
juce::CharacterFunctions::find
static CharPointerType1 find(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Definition juce_CharacterFunctions.h:708
juce::HeapBlock::malloc
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Definition juce_HeapBlock.h:249
juce::HeapBlock::allocate
void allocate(SizeType newNumElements, bool initialiseToZero)
Definition juce_HeapBlock.h:270
juce::HeapBlock::realloc
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Definition juce_HeapBlock.h:283
juce::HeapBlock::free
void free() noexcept
Definition juce_HeapBlock.h:291
juce::MemoryBlock
Definition juce_MemoryBlock.h:33
juce::MemoryBlock::copyFrom
void copyFrom(const void *srcData, int destinationOffset, size_t numBytes) noexcept
Definition juce_MemoryBlock.cpp:224
juce::MemoryBlock::~MemoryBlock
~MemoryBlock() noexcept
Definition juce_MemoryBlock.cpp:68
juce::MemoryBlock::fromBase64Encoding
bool fromBase64Encoding(StringRef encodedString)
Definition juce_MemoryBlock.cpp:382
juce::MemoryBlock::toBase64Encoding
String toBase64Encoding() const
Definition juce_MemoryBlock.cpp:356
juce::MemoryBlock::matches
bool matches(const void *data, size_t dataSize) const noexcept
Definition juce_MemoryBlock.cpp:107
juce::MemoryBlock::append
void append(const void *data, size_t numBytes)
Definition juce_MemoryBlock.cpp:166
juce::MemoryBlock::MemoryBlock
MemoryBlock() noexcept
Definition juce_MemoryBlock.cpp:26
juce::MemoryBlock::replaceAll
void replaceAll(const void *data, size_t numBytes)
Definition juce_MemoryBlock.cpp:177
juce::MemoryBlock::toString
String toString() const
Definition juce_MemoryBlock.cpp:265
juce::MemoryBlock::copyTo
void copyTo(void *destData, int sourceOffset, size_t numBytes) const noexcept
Definition juce_MemoryBlock.cpp:242
juce::MemoryBlock::insert
void insert(const void *dataToInsert, size_t numBytesToInsert, size_t insertPosition)
Definition juce_MemoryBlock.cpp:190
juce::MemoryBlock::swapWith
void swapWith(MemoryBlock &other) noexcept
Definition juce_MemoryBlock.cpp:154
juce::MemoryBlock::getBitRange
int getBitRange(size_t bitRangeStart, size_t numBitsToRead) const noexcept
Definition juce_MemoryBlock.cpp:271
juce::MemoryBlock::loadFromHexString
void loadFromHexString(StringRef sourceHexString)
Definition juce_MemoryBlock.cpp:319
juce::MemoryBlock::removeSection
void removeSection(size_t startByte, size_t numBytesToRemove)
Definition juce_MemoryBlock.cpp:208
juce::MemoryBlock::operator=
MemoryBlock & operator=(const MemoryBlock &)
Definition juce_MemoryBlock.cpp:72
juce::MemoryBlock::fillWith
void fillWith(uint8 valueToUse) noexcept
Definition juce_MemoryBlock.cpp:161
juce::MemoryBlock::operator!=
bool operator!=(const MemoryBlock &other) const noexcept
Definition juce_MemoryBlock.cpp:102
juce::MemoryBlock::setSize
void setSize(size_t newSize, bool initialiseNewSpaceToZero=false)
Definition juce_MemoryBlock.cpp:115
juce::MemoryBlock::ensureSize
void ensureSize(size_t minimumSize, bool initialiseNewSpaceToZero=false)
Definition juce_MemoryBlock.cpp:148
juce::MemoryBlock::setBitRange
void setBitRange(size_t bitRangeStart, size_t numBits, int binaryNumberToApply) noexcept
Definition juce_MemoryBlock.cpp:295
juce::MemoryBlock::reset
void reset()
Definition juce_MemoryBlock.cpp:142
juce::MemoryBlock::operator==
bool operator==(const MemoryBlock &other) const noexcept
Definition juce_MemoryBlock.cpp:97
juce::StringRef
Definition juce_StringRef.h:62
juce::StringRef::length
int length() const noexcept
Definition juce_StringRef.h:105
juce::StringRef::text
String::CharPointerType text
Definition juce_StringRef.h:130
juce::String
Definition juce_String.h:53
juce::String::getCharPointer
CharPointerType getCharPointer() const noexcept
Definition juce_String.h:1153
juce::String::length
int length() const noexcept
Definition juce_String.cpp:511
juce::String::preallocateBytes
void preallocateBytes(size_t numBytesNeeded)
Definition juce_String.cpp:284
juce::String::fromUTF8
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Definition juce_String.cpp:2125
juce::String::getIntValue
int getIntValue() const noexcept
Definition juce_String.cpp:1871