JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
fbuffer.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------
2// Project : SDK Base
3// Version : 1.0
4//
5// Category : Helpers
6// Filename : base/source/fbuffer.cpp
7// Created by : Steinberg, 2008
8// Description :
9//
10//-----------------------------------------------------------------------------
11// LICENSE
12// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved
13//-----------------------------------------------------------------------------
14// Redistribution and use in source and binary forms, with or without modification,
15// are permitted provided that the following conditions are met:
16//
17// * Redistributions of source code must retain the above copyright notice,
18// this list of conditions and the following disclaimer.
19// * Redistributions in binary form must reproduce the above copyright notice,
20// this list of conditions and the following disclaimer in the documentation
21// and/or other materials provided with the distribution.
22// * Neither the name of the Steinberg Media Technologies nor the names of its
23// contributors may be used to endorse or promote products derived from this
24// software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
34// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35// OF THE POSSIBILITY OF SUCH DAMAGE.
36//-----------------------------------------------------------------------------
37
38#include "base/source/fbuffer.h"
39#include "base/source/fstring.h"
40#include <cstdlib>
41
42namespace Steinberg {
43
44//-------------------------------------------------------------------------------------
46: buffer (nullptr)
47, memSize (0)
48, fillSize (0)
49, delta (defaultDelta)
50{}
51
52//-------------------------------------------------------------------------------------
53Buffer::Buffer (uint32 s, uint8 initVal)
54: buffer (nullptr)
55, memSize (s)
56, fillSize (0)
57, delta (defaultDelta)
58{
59 if (memSize == 0)
60 return;
61 buffer = (int8*)::malloc (memSize);
62 if (buffer)
63 memset (buffer, initVal, memSize);
64 else
65 memSize = 0;
66}
67
68//-------------------------------------------------------------------------------------
70: buffer (nullptr)
71, memSize (s)
72, fillSize (0)
73, delta (defaultDelta)
74{
75 if (memSize == 0)
76 return;
77 buffer = (int8*)::malloc (memSize);
78 if (!buffer)
79 memSize = 0;
80}
81
82//-------------------------------------------------------------------------------------
83Buffer::Buffer (const void* b , uint32 s)
84: buffer (nullptr)
85, memSize (s)
86, fillSize (s)
87, delta (defaultDelta)
88{
89 if (memSize == 0)
90 return;
91 buffer = (int8*)::malloc (memSize);
92 if (buffer)
93 memcpy (buffer, b, memSize);
94 else
95 {
96 memSize = 0;
97 fillSize = 0;
98 }
99}
100
101//-------------------------------------------------------------------------------------
102Buffer::Buffer (const Buffer& bufferR)
103: buffer (nullptr)
104, memSize (bufferR.memSize)
105, fillSize (bufferR.fillSize)
106, delta (bufferR.delta)
107{
108 if (memSize == 0)
109 return;
110
111 buffer = (int8*)::malloc (memSize);
112 if (buffer)
113 memcpy (buffer, bufferR.buffer, memSize);
114 else
115 memSize = 0;
116}
117
118//-------------------------------------------------------------------------------------
120{
121 if (buffer)
122 ::free (buffer);
123 buffer = nullptr;
124}
125
126//-------------------------------------------------------------------------------------
128{
129 if (&b2 != this)
130 {
131 setSize (b2.memSize);
132 if (b2.memSize > 0 && buffer)
133 memcpy (buffer, b2.buffer, b2.memSize);
134 fillSize = b2.fillSize;
135 delta = b2.delta;
136 }
137}
138
139//-------------------------------------------------------------------------------------
140bool Buffer::operator == (const Buffer& b2)const
141{
142 if (&b2 == this)
143 return true;
144 if (b2.getSize () != getSize ())
145 return false;
146 return memcmp (this->int8Ptr (), b2.int8Ptr (), getSize ()) == 0 ? true : false;
147}
148
149//-------------------------------------------------------------------------------------
150uint32 Buffer::get (void* b, uint32 size)
151{
152 uint32 maxGet = memSize - fillSize;
153 if (size > maxGet)
154 size = maxGet;
155 if (size > 0)
156 memcpy (b, buffer + fillSize, size);
157 fillSize += size;
158 return size;
159}
160
161//-------------------------------------------------------------------------------------
162bool Buffer::put (char16 c)
163{
164 return put ((const void*)&c, sizeof (c));
165}
166
167//-------------------------------------------------------------------------------------
168bool Buffer::put (uint8 byte)
169{
170 if (grow (fillSize + 1) == false)
171 return false;
172
173 buffer [fillSize++] = byte;
174 return true;
175}
176
177//-------------------------------------------------------------------------------------
178bool Buffer::put (char c)
179{
180 if (grow (fillSize + 1) == false)
181 return false;
182
183 buffer [fillSize++] = c;
184 return true;
185}
186
187//-------------------------------------------------------------------------------------
188bool Buffer::put (const void* toPut, uint32 s)
189{
190 if (!toPut)
191 return false;
192
193 if (grow (fillSize + s) == false)
194 return false;
195
196 memcpy (buffer + fillSize, toPut, s);
197 fillSize += s;
198 return true;
199}
200
201//-------------------------------------------------------------------------------------
202bool Buffer::put (const String& str)
203{
204 return put ((const void*)str.text () , (str.length () + 1) * sizeof (tchar));
205}
206
207//-------------------------------------------------------------------------------------
208bool Buffer::appendString8 (const char8* s)
209{
210 if (!s)
211 return false;
212
213 uint32 len = (uint32) strlen (s);
214 return put (s, len);
215}
216
217//-------------------------------------------------------------------------------------
218bool Buffer::appendString16 (const char16* s)
219{
220 if (!s)
221 return false;
222 ConstString str (s);
223 uint32 len = (uint32) str.length () * sizeof (char16);
224 return put (s, len);
225}
226
227//-------------------------------------------------------------------------------------
228bool Buffer::prependString8 (const char8* s)
229{
230 if (!s)
231 return false;
232
233 uint32 len = (uint32) strlen (s);
234 if (len > 0)
235 {
236 shiftStart (len);
237 memcpy (buffer, s, len);
238 return true;
239 }
240 return false;
241}
242
243//-------------------------------------------------------------------------------------
244bool Buffer::prependString16 (const char16* s)
245{
246 if (!s)
247 return false;
248
249 ConstString str (s);
250 uint32 len = (uint32) str.length () * sizeof (char16);
251
252 if (len > 0)
253 {
254 shiftStart (len);
255 memcpy (buffer, s, len);
256 return true;
257 }
258 return false;
259}
260
261//-------------------------------------------------------------------------------------
262bool Buffer::prependString8 (char8 c)
263{
264 shiftStart (sizeof (char));
265 char* b = (char*)buffer;
266 b [0] = c;
267 return true;
268}
269
270//-------------------------------------------------------------------------------------
271bool Buffer::prependString16 (char16 c)
272{
273 shiftStart (sizeof (char16));
274 char16* b = (char16*)buffer;
275 b [0] = c;
276 return true;
277}
278
279//-------------------------------------------------------------------------------------
280bool Buffer::copy (uint32 from, uint32 to, uint32 bytes)
281{
282 if (from + bytes > memSize || bytes == 0)
283 return false;
284
285 if (to + bytes > memSize)
286 setSize (to + bytes);
287
288 if (from + bytes > to && from < to)
289 { // overlap
290 Buffer tmp (buffer + from, bytes);
291 memcpy (buffer + to, tmp, bytes);
292 }
293 else
294 memcpy (buffer + to, buffer + from, bytes);
295 return true;
296}
297
298//-------------------------------------------------------------------------------------
299bool Buffer::makeHexString (String& result)
300{
301 unsigned char* data = uint8Ptr ();
302 uint32 bytes = getSize ();
303
304 if (data == nullptr || bytes == 0)
305 return false;
306
307 char8* stringBuffer = (char8*)malloc ((bytes * 2) + 1);
308 if (!stringBuffer)
309 return false;
310
311 int32 count = 0;
312 while (bytes > 0)
313 {
314 unsigned char t1 = ((*data) >> 4) & 0x0F;
315 unsigned char t2 = (*data) & 0x0F;
316 if (t1 < 10)
317 t1 += '0';
318 else
319 t1 = t1 - 10 + 'A';
320 if (t2 < 10)
321 t2 += '0';
322 else
323 t2 = t2 - 10 + 'A';
324
325 stringBuffer [count++] = t1;
326 stringBuffer [count++] = t2;
327 data++;
328 bytes--;
329 }
330 stringBuffer [count] = 0;
331
332 result.take ((void*)stringBuffer, false);
333 return true;
334}
335
336//-------------------------------------------------------------------------------------
337bool Buffer::fromHexString (const char8* string)
338{
339 flush ();
340 if (string == nullptr)
341 return false;
342
343 int32 len = strlen8 (string);
344 if (len == 0 || ((len & 1) == 1)/*odd number*/ )
345 return false;
346
347 setSize (len / 2);
348 unsigned char* data = uint8Ptr ();
349
350 bool upper = true;
351 int32 count = 0;
352 while (count < len)
353 {
354 char c = string [count];
355
356 unsigned char d = 0;
357 if (c >= '0' && c <= '9') d += c - '0';
358 else if (c >= 'A' && c <= 'F') d += c - 'A' + 10;
359 else if (c >= 'a' && c <= 'f') d += c - 'a' + 10;
360 else return false; // no hex string
361
362 if (upper)
363 data [count >> 1] = static_cast<unsigned char> (d << 4);
364 else
365 data [count >> 1] += d;
366
367 upper = !upper;
368 count++;
369 }
370 setFillSize (len / 2);
371 return true;
372}
373
374//------------------------------------------------------------------------
375void Buffer::set (uint8 value)
376{
377 if (buffer)
378 memset (buffer, value, memSize);
379}
380
381//-------------------------------------------------------------------------------------
382bool Buffer::setFillSize (uint32 c)
383{
384 if (c <= memSize)
385 {
386 fillSize = c;
387 return true;
388 }
389 return false;
390}
391
392//-------------------------------------------------------------------------------------
394{
395 if (fillSize < memSize)
396 setSize (fillSize);
397
398 return true;
399}
400
401//-------------------------------------------------------------------------------------
402bool Buffer::grow (uint32 newSize)
403{
404 if (newSize > memSize)
405 {
406 if (delta == 0)
407 delta = defaultDelta;
408 uint32 s = ((newSize + delta - 1) / delta) * delta;
409 return setSize (s);
410 }
411 return true;
412}
413
414//------------------------------------------------------------------------
415void Buffer::shiftAt (uint32 position, int32 amount)
416{
417 if (amount > 0)
418 {
419 if (grow (fillSize + amount))
420 {
421 if (position < fillSize)
422 memmove (buffer + amount + position, buffer + position, fillSize - position);
423
424 fillSize += amount;
425 }
426 }
427 else if (amount < 0 && fillSize > 0)
428 {
429 uint32 toRemove = -amount;
430
431 if (toRemove < fillSize)
432 {
433 if (position < fillSize)
434 memmove (buffer + position, buffer + toRemove + position, fillSize - position - toRemove);
435 fillSize -= toRemove;
436 }
437 }
438}
439
440//-------------------------------------------------------------------------------------
441void Buffer::move (int32 amount, uint8 initVal)
442{
443 if (memSize == 0)
444 return;
445
446 if (amount > 0)
447 {
448 if ((uint32)amount < memSize)
449 {
450 memmove (buffer + amount, buffer, memSize - amount);
451 memset (buffer, initVal, amount);
452 }
453 else
454 memset (buffer, initVal, memSize);
455 }
456 else
457 {
458 uint32 toRemove = -amount;
459 if (toRemove < memSize)
460 {
461 memmove (buffer, buffer + toRemove, memSize - toRemove);
462 memset (buffer + memSize - toRemove, initVal, toRemove);
463 }
464 else
465 memset (buffer, initVal, memSize);
466 }
467}
468
469//-------------------------------------------------------------------------------------
470bool Buffer::setSize (uint32 newSize)
471{
472 if (memSize != newSize)
473 {
474 if (buffer)
475 {
476 if (newSize > 0)
477 {
478 int8* newBuffer = (int8*) ::realloc (buffer, newSize);
479 if (newBuffer == nullptr)
480 {
481 newBuffer = (int8*)::malloc (newSize);
482 if (newBuffer)
483 {
484 uint32 tmp = newSize;
485 if (tmp > memSize)
486 tmp = memSize;
487 memcpy (newBuffer, buffer, tmp);
488 ::free (buffer);
489 buffer = newBuffer;
490 }
491 else
492 {
493 ::free (buffer);
494 buffer = nullptr;
495 }
496 }
497 else
498 buffer = newBuffer;
499 }
500 else
501 {
502 ::free (buffer);
503 buffer = nullptr;
504 }
505 }
506 else
507 buffer = (int8*)::malloc (newSize);
508
509 if (newSize > 0 && !buffer)
510 memSize = 0;
511 else
512 memSize = newSize;
513 if (fillSize > memSize)
514 fillSize = memSize;
515 }
516
517 return (newSize > 0) == (buffer != nullptr);
518}
519
520//-------------------------------------------------------------------------------------
521void Buffer::fillup (uint8 value)
522{
523 if (getFree () > 0)
524 memset (buffer + fillSize, value, getFree ());
525}
526
527//-------------------------------------------------------------------------------------
528int8* Buffer::operator + (uint32 i)
529{
530 if (i < memSize)
531 return buffer + i;
532
533 static int8 eof;
534 eof = 0;
535 return &eof;
536}
537
538//-------------------------------------------------------------------------------------
539bool Buffer::swap (int16 swapSize)
540{
541 return swap (buffer, memSize, swapSize);
542}
543
544//-------------------------------------------------------------------------------------
545bool Buffer::swap (void* buffer, uint32 bufferSize, int16 swapSize)
546{
547 if (swapSize != kSwap16 && swapSize != kSwap32 && swapSize != kSwap64)
548 return false;
549
550 if (swapSize == kSwap16)
551 {
552 for (uint32 count = 0 ; count < bufferSize ; count += 2)
553 {
554 SWAP_16 ( * (((int16*)buffer) + count) );
555 }
556 }
557 else if (swapSize == kSwap32)
558 {
559 for (uint32 count = 0 ; count < bufferSize ; count += 4)
560 {
561 SWAP_32 ( * (((int32*)buffer) + count) );
562 }
563 }
564 else if (swapSize == kSwap64)
565 {
566 for (uint32 count = 0 ; count < bufferSize ; count += 8)
567 {
568 SWAP_64 ( * (((int64*)buffer) + count) );
569 }
570 }
571
572 return true;
573}
574
575//-------------------------------------------------------------------------------------
577{
578 setSize (0);
579 memSize = from.memSize;
580 fillSize = from.fillSize;
581 buffer = from.buffer;
582 from.buffer = nullptr;
583 from.memSize = 0;
584 from.fillSize = 0;
585}
586
587//-------------------------------------------------------------------------------------
589{
590 int8* res = buffer;
591 buffer = nullptr;
592 memSize = 0;
593 fillSize = 0;
594 return res;
595}
596
597//-------------------------------------------------------------------------------------
598bool Buffer::toWideString (int32 sourceCodePage)
599{
600 if (getFillSize () > 0)
601 {
602 if (str8 () [getFillSize () - 1] != 0) // multiByteToWideString only works with 0-terminated strings
603 endString8 ();
604
605 Buffer dest (getFillSize () * sizeof (char16));
606 int32 result = String::multiByteToWideString (dest.str16 (), str8 (), dest.getFree () / sizeof (char16), sourceCodePage);
607 if (result > 0)
608 {
609 dest.setFillSize ((result - 1) * sizeof (char16));
610 take (dest);
611 return true;
612 }
613 return false;
614 }
615 return true;
616}
617
618//-------------------------------------------------------------------------------------
619bool Buffer::toMultibyteString (int32 destCodePage)
620{
621 if (getFillSize () > 0)
622 {
623 int32 textLength = getFillSize () / sizeof (char16); // wideStringToMultiByte only works with 0-terminated strings
624 if (str16 () [textLength - 1] != 0)
625 endString16 ();
626
627 Buffer dest (getFillSize ());
628 int32 result = String::wideStringToMultiByte (dest.str8 (), str16 (), dest.getFree (), destCodePage);
629 if (result > 0)
630 {
631 dest.setFillSize (result - 1);
632 take (dest);
633 return true;
634 }
635 return false;
636 }
637 return true;
638}
639
640//------------------------------------------------------------------------
641} // namespace Steinberg
uint32 getSize() const
Definition fbuffer.h:101
void take(Buffer &from)
takes another Buffer's memory, frees the current Buffer's memory
Definition fbuffer.cpp:576
void shiftStart(int32 amount)
moves all memory by given amount, grows the Buffer if necessary
Definition fbuffer.h:125
void flush()
sets fill size to zero
Definition fbuffer.h:119
int8 * int8Ptr() const
conversion
Definition fbuffer.h:201
bool put(uint8)
append value at end, grows Buffer if necessary
Definition fbuffer.cpp:168
void operator=(const Buffer &buff)
Assignment operator - copies contents from a given Buffer and increases the size if necessary.
Definition fbuffer.cpp:127
bool truncateToFillSize()
Definition fbuffer.cpp:393
virtual bool toWideString(int32 sourceCodePage)
Converts a Buffer's content to UTF-16 from a given multi-byte code page, Buffer must contain char8 of...
Definition fbuffer.cpp:598
bool setFillSize(uint32 c)
sets a new fill size, does not change any memory
Definition fbuffer.cpp:382
void move(int32 amount, uint8 initVal=0)
shifts memory at start without growing the buffer, so data is lost and initialized with init val
Definition fbuffer.cpp:441
void set(uint8 value)
fills complete Buffer with given value
Definition fbuffer.cpp:375
void fillup(uint8 initVal=0)
set from fillSize to end
Definition fbuffer.cpp:521
virtual bool toMultibyteString(int32 destCodePage)
Converts a Buffer's content from UTF-16 to a given multi-byte code page, Buffer must contain UTF-16 e...
Definition fbuffer.cpp:619
bool copy(uint32 from, uint32 to, uint32 bytes)
copies a number of bytes from one position to another, the size may be adapted
Definition fbuffer.cpp:280
tchar * str() const
conversion
Definition fbuffer.h:198
char16 * str16() const
conversion
Definition fbuffer.h:200
uint32 getFree() const
Definition fbuffer.h:123
bool operator==(const Buffer &buff) const
Comparison operator - copies contents from a given Buffer and increases the size if necessary.
Definition fbuffer.cpp:140
uint32 get(void *b, uint32 size)
copy to buffer from fillSize, and shift fillSize
Definition fbuffer.cpp:150
uint32 getFillSize() const
Definition fbuffer.h:117
uint8 * uint8Ptr() const
conversion
Definition fbuffer.h:202
Buffer()
Default constructor, allocates no memory at all.
Definition fbuffer.cpp:45
char8 * str8() const
conversion
Definition fbuffer.h:199
virtual ~Buffer()
Destructor - deallocates the internal memory.
Definition fbuffer.cpp:119
bool setSize(uint32 newSize)
Sets a new size for this Buffer, keeping as much content as possible.
Definition fbuffer.cpp:470
bool grow(uint32 memSize)
Increases the Buffer to the next block, block size given by delta.
Definition fbuffer.cpp:402
int8 * operator+(uint32 i)
Definition fbuffer.cpp:528
int8 * pass()
pass the current Buffer's memory
Definition fbuffer.cpp:588
void shiftAt(uint32 position, int32 amount)
moves memory starting at the given position
Definition fbuffer.cpp:415
bool swap(int16 swapSize)
swap all bytes of this Buffer by the given swapSize
Definition fbuffer.cpp:539
static int32 wideStringToMultiByte(char8 *dest, const char16 *source, int32 char8Count, uint32 destCodePage=kCP_Default)
If dest is zero, this returns the maximum number of bytes needed to convert source.
Definition fstring.cpp:1889
static int32 multiByteToWideString(char16 *dest, const char8 *source, int32 wcharCount, uint32 sourceCodePage=kCP_Default)
If dest is zero, this returns the maximum number of bytes needed to convert source.
Definition fstring.cpp:1823
void take(String &str)
Take ownership of the string of 'str'.
Definition fstring.cpp:3620
T count(T... args)
T data(T... args)
#define SWAP_32(l)
Byte-order Conversion Macros.
Definition ftypes.h:126
memcmp
memcpy
memmove
memset