LMMS
Loading...
Searching...
No Matches
MemoryBlock.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#include "MemoryBlock.h"
27
28namespace water {
29
34
35MemoryBlock::MemoryBlock (const size_t initialSize, const bool initialiseToZero)
36{
37 if (initialSize > 0)
38 {
39 size = initialSize;
40 data.allocate (initialSize, initialiseToZero);
41 }
42 else
43 {
44 size = 0;
45 }
46}
47
49 : size (other.size)
50{
51 if (size > 0)
52 {
53 wassert (other.data != nullptr);
54 data.malloc (size);
55 memcpy (data, other.data, size);
56 }
57}
58
59MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const size_t sizeInBytes)
60 : size (sizeInBytes)
61{
62 wassert (((ssize_t) sizeInBytes) >= 0);
63
64 if (size > 0)
65 {
66 wassert (dataToInitialiseFrom != nullptr); // non-zero size, but a zero pointer passed-in?
67
68 data.malloc (size);
69
70 if (dataToInitialiseFrom != nullptr)
71 memcpy (data, dataToInitialiseFrom, size);
72 }
73}
74
78
80{
81 if (this != &other)
82 {
83 setSize (other.size, false);
84 memcpy (data, other.data, size);
85 }
86
87 return *this;
88}
89
90//==============================================================================
91bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept
92{
93 return matches (other.data, other.size);
94}
95
96bool MemoryBlock::operator!= (const MemoryBlock& other) const noexcept
97{
98 return ! operator== (other);
99}
100
101bool MemoryBlock::matches (const void* dataToCompare, size_t dataSize) const noexcept
102{
103 return size == dataSize
104 && memcmp (data, dataToCompare, size) == 0;
105}
106
107//==============================================================================
108// this will resize the block to this size
109void MemoryBlock::setSize (const size_t newSize, const bool initialiseToZero)
110{
111 if (size != newSize)
112 {
113 if (newSize <= 0)
114 {
115 reset();
116 }
117 else
118 {
119 if (data != nullptr)
120 {
121 data.realloc (newSize);
122
123 if (initialiseToZero && (newSize > size))
124 zeromem (data + size, newSize - size);
125 }
126 else
127 {
128 data.allocate (newSize, initialiseToZero);
129 }
130
131 size = newSize;
132 }
133 }
134}
135
137{
138 data.free();
139 size = 0;
140}
141
142void MemoryBlock::ensureSize (const size_t minimumSize, const bool initialiseToZero)
143{
144 if (size < minimumSize)
145 setSize (minimumSize, initialiseToZero);
146}
147
148void MemoryBlock::swapWith (MemoryBlock& other) noexcept
149{
150 std::swap (size, other.size);
151 data.swapWith (other.data);
152}
153
154//==============================================================================
156{
157 size = 0;
158 return data.release();
159}
160
161//==============================================================================
162void MemoryBlock::fillWith (const uint8 value) noexcept
163{
164 memset (data, (int) value, size);
165}
166
167void MemoryBlock::append (const void* const srcData, const size_t numBytes)
168{
169 if (numBytes > 0)
170 {
171 wassert (srcData != nullptr); // this must not be null!
172 const size_t oldSize = size;
173 setSize (size + numBytes);
174 memcpy (data + oldSize, srcData, numBytes);
175 }
176}
177
178void MemoryBlock::replaceWith (const void* const srcData, const size_t numBytes)
179{
180 if (numBytes > 0)
181 {
182 wassert (srcData != nullptr); // this must not be null!
183 setSize (numBytes);
184 memcpy (data, srcData, numBytes);
185 }
186}
187
188void MemoryBlock::insert (const void* const srcData, const size_t numBytes, size_t insertPosition)
189{
190 if (numBytes > 0)
191 {
192 wassert (srcData != nullptr); // this must not be null!
193 insertPosition = jmin (size, insertPosition);
194 const size_t trailingDataSize = size - insertPosition;
195 setSize (size + numBytes, false);
196
197 if (trailingDataSize > 0)
198 memmove (data + insertPosition + numBytes,
199 data + insertPosition,
200 trailingDataSize);
201
202 memcpy (data + insertPosition, srcData, numBytes);
203 }
204}
205
206void MemoryBlock::removeSection (const size_t startByte, const size_t numBytesToRemove)
207{
208 if (startByte + numBytesToRemove >= size)
209 {
210 setSize (startByte);
211 }
212 else if (numBytesToRemove > 0)
213 {
214 memmove (data + startByte,
215 data + startByte + numBytesToRemove,
216 size - (startByte + numBytesToRemove));
217
218 setSize (size - numBytesToRemove);
219 }
220}
221
222void MemoryBlock::copyFrom (const void* const src, int offset, size_t num) noexcept
223{
224 const char* d = static_cast<const char*> (src);
225
226 if (offset < 0)
227 {
228 d -= offset;
229 num += (size_t) -offset;
230 offset = 0;
231 }
232
233 if ((size_t) offset + num > size)
234 num = size - (size_t) offset;
235
236 if (num > 0)
237 memcpy (data + offset, d, num);
238}
239
240void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcept
241{
242 char* d = static_cast<char*> (dst);
243
244 if (offset < 0)
245 {
246 zeromem (d, (size_t) -offset);
247 d -= offset;
248 num -= (size_t) -offset;
249 offset = 0;
250 }
251
252 if ((size_t) offset + num > size)
253 {
254 const size_t newNum = (size_t) size - (size_t) offset;
255 zeromem (d + newNum, num - newNum);
256 num = newNum;
257 }
258
259 if (num > 0)
260 memcpy (d, data + offset, num);
261}
262
264{
265 return String::fromUTF8 (data, (int) size);
266}
267
268//==============================================================================
269int MemoryBlock::getBitRange (const size_t bitRangeStart, size_t numBits) const noexcept
270{
271 int res = 0;
272
273 size_t byte = bitRangeStart >> 3;
274 size_t offsetInByte = bitRangeStart & 7;
275 size_t bitsSoFar = 0;
276
277 while (numBits > 0 && (size_t) byte < size)
278 {
279 const size_t bitsThisTime = jmin (numBits, 8 - offsetInByte);
280 const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte;
281
282 res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar);
283
284 bitsSoFar += bitsThisTime;
285 numBits -= bitsThisTime;
286 ++byte;
287 offsetInByte = 0;
288 }
289
290 return res;
291}
292
293void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int bitsToSet) noexcept
294{
295 size_t byte = bitRangeStart >> 3;
296 size_t offsetInByte = bitRangeStart & 7;
297 uint32 mask = ~((((uint32) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
298
299 while (numBits > 0 && (size_t) byte < size)
300 {
301 const size_t bitsThisTime = jmin (numBits, 8 - offsetInByte);
302
303 const uint32 tempMask = (mask << offsetInByte) | ~((((uint32) 0xffffffff) >> offsetInByte) << offsetInByte);
304 const uint32 tempBits = (uint32) bitsToSet << offsetInByte;
305
306 data[byte] = (char) (((uint32) data[byte] & tempMask) | tempBits);
307
308 ++byte;
309 numBits -= bitsThisTime;
310 bitsToSet >>= bitsThisTime;
311 mask >>= bitsThisTime;
312 offsetInByte = 0;
313 }
314}
315
316//==============================================================================
318{
319 ensureSize ((size_t) hex.length() >> 1);
320 char* dest = data;
321 CharPointer_UTF8 t (hex.text);
322
323 for (;;)
324 {
325 int byte = 0;
326
327 for (int loop = 2; --loop >= 0;)
328 {
329 byte <<= 4;
330
331 for (;;)
332 {
333 const water_uchar c = t.getAndAdvance();
334
335 if (c >= '0' && c <= '9') { byte |= c - '0'; break; }
336 if (c >= 'a' && c <= 'z') { byte |= c - ('a' - 10); break; }
337 if (c >= 'A' && c <= 'Z') { byte |= c - ('A' - 10); break; }
338
339 if (c == 0)
340 {
341 setSize (static_cast<size_t> (dest - data));
342 return;
343 }
344 }
345 }
346
347 *dest++ = (char) byte;
348 }
349}
350
351}
#define noexcept
Definition DistrhoDefines.h:72
goto loop
Definition Spc_Cpu.h:155
static const unsigned long mask[]
Definition bitwise.c:31
#define byte
Definition blargg_source.h:87
Definition CharPointer_UTF8.h:45
size_t size
Definition MemoryBlock.h:226
HeapBlock< char > data
Definition MemoryBlock.h:225
bool matches(const void *data, size_t dataSize) const noexcept
Definition MemoryBlock.cpp:101
void insert(const void *dataToInsert, size_t numBytesToInsert, size_t insertPosition)
Definition MemoryBlock.cpp:188
void removeSection(size_t startByte, size_t numBytesToRemove)
Definition MemoryBlock.cpp:206
void setBitRange(size_t bitRangeStart, size_t numBits, int binaryNumberToApply) noexcept
Definition MemoryBlock.cpp:293
void reset()
Definition MemoryBlock.cpp:136
void ensureSize(const size_t minimumSize, bool initialiseNewSpaceToZero=false)
Definition MemoryBlock.cpp:142
void copyFrom(const void *srcData, int destinationOffset, size_t numBytes) noexcept
Definition MemoryBlock.cpp:222
void append(const void *data, size_t numBytes)
Definition MemoryBlock.cpp:167
bool operator==(const MemoryBlock &other) const noexcept
Definition MemoryBlock.cpp:91
void setSize(const size_t newSize, bool initialiseNewSpaceToZero=false)
Definition MemoryBlock.cpp:109
void fillWith(uint8 valueToUse) noexcept
Definition MemoryBlock.cpp:162
MemoryBlock() noexcept
Definition MemoryBlock.cpp:30
void loadFromHexString(StringRef sourceHexString)
Definition MemoryBlock.cpp:317
void swapWith(MemoryBlock &other) noexcept
Definition MemoryBlock.cpp:148
void copyTo(void *destData, int sourceOffset, size_t numBytes) const noexcept
Definition MemoryBlock.cpp:240
void replaceWith(const void *data, size_t numBytes)
Definition MemoryBlock.cpp:178
String toString() const
Definition MemoryBlock.cpp:263
void * release() noexcept
Definition MemoryBlock.cpp:155
~MemoryBlock() noexcept
Definition MemoryBlock.cpp:75
bool operator!=(const MemoryBlock &other) const noexcept
Definition MemoryBlock.cpp:96
int getBitRange(size_t bitRangeStart, size_t numBitsToRead) const noexcept
Definition MemoryBlock.cpp:269
MemoryBlock & operator=(const MemoryBlock &)
Definition MemoryBlock.cpp:79
Definition String.h:48
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Definition String.cpp:1961
Definition StringRef.h:67
int length() const noexcept
Definition StringRef.h:103
CharPointer_UTF8 text
Definition StringRef.h:120
struct huft * t
Definition inflate.c:943
unsigned d
Definition inflate.c:940
static PuglViewHint int value
Definition pugl.h:1708
#define wassert(expression)
Definition AudioSampleBuffer.h:33
unsigned int uint32
Definition water.h:98
bool operator==(const ReferenceCountedObjectPtr< ReferenceCountedObjectClass > &object1, ReferenceCountedObjectClass *const object2) noexcept
Definition ReferenceCountedObject.h:359
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
void zeromem(void *memory, size_t numBytes) noexcept
Definition Memory.h:37
unsigned char uint8
Definition water.h:90
uint32 water_uchar
Definition CharacterFunctions.h:38
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)