LMMS
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) 2021, 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//-------------------------------------------------------------------------------------
47, memSize (0)
48, fillSize (0)
50{}
51
52//-------------------------------------------------------------------------------------
55, memSize (s)
56, fillSize (0)
58{
59 if (memSize == 0)
60 return;
62 if (buffer)
63 memset (buffer, initVal, memSize);
64 else
65 memSize = 0;
66}
67
68//-------------------------------------------------------------------------------------
71, memSize (s)
72, fillSize (0)
74{
75 if (memSize == 0)
76 return;
78 if (!buffer)
79 memSize = 0;
80}
81
82//-------------------------------------------------------------------------------------
83Buffer::Buffer (const void* b , uint32 s)
85, memSize (s)
86, fillSize (s)
88{
89 if (memSize == 0)
90 return;
92 if (buffer)
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
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//-------------------------------------------------------------------------------------
151{
152 uint32 maxGet = memSize - fillSize;
153 if (size > maxGet)
154 size = maxGet;
155 if (size > 0)
157 fillSize += size;
158 return size;
159}
160
161//-------------------------------------------------------------------------------------
163{
164 return put ((const void*)&c, sizeof (c));
165}
166
167//-------------------------------------------------------------------------------------
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//-------------------------------------------------------------------------------------
209{
210 if (!s)
211 return false;
212
213 uint32 len = (uint32) strlen (s);
214 return put (s, len);
215}
216
217//-------------------------------------------------------------------------------------
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//-------------------------------------------------------------------------------------
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//-------------------------------------------------------------------------------------
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//-------------------------------------------------------------------------------------
263{
264 shiftStart (sizeof (char));
265 char* b = (char*)buffer;
266 b [0] = c;
267 return true;
268}
269
270//-------------------------------------------------------------------------------------
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//-------------------------------------------------------------------------------------
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//------------------------------------------------------------------------
376{
377 if (buffer)
378 memset (buffer, value, memSize);
379}
380
381//-------------------------------------------------------------------------------------
383{
384 if (c <= memSize)
385 {
386 fillSize = c;
387 return true;
388 }
389 return false;
390}
391
392//-------------------------------------------------------------------------------------
394{
395 if (fillSize < memSize)
397
398 return true;
399}
400
401//-------------------------------------------------------------------------------------
402bool Buffer::grow (uint32 newSize)
403{
404 if (newSize > memSize)
405 {
406 if (delta == 0)
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//-------------------------------------------------------------------------------------
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)
515 }
516
517 return (newSize > 0) == (buffer != nullptr);
518}
519
520//-------------------------------------------------------------------------------------
522{
523 if (getFree () > 0)
524 memset (buffer + fillSize, value, getFree ());
525}
526
527//-------------------------------------------------------------------------------------
529{
530 if (i < memSize)
531 return buffer + i;
532 else
533 {
534 static int8 eof;
535 eof = 0;
536 return &eof;
537 }
538}
539
540//-------------------------------------------------------------------------------------
542{
543 return swap (buffer, memSize, swapSize);
544}
545
546//-------------------------------------------------------------------------------------
547bool Buffer::swap (void* buffer, uint32 bufferSize, int16 swapSize)
548{
549 if (swapSize != kSwap16 && swapSize != kSwap32 && swapSize != kSwap64)
550 return false;
551
552 if (swapSize == kSwap16)
553 {
554 for (uint32 count = 0 ; count < bufferSize ; count += 2)
555 {
556 SWAP_16 ( * (((int16*)buffer) + count) );
557 }
558 }
559 else if (swapSize == kSwap32)
560 {
561 for (uint32 count = 0 ; count < bufferSize ; count += 4)
562 {
563 SWAP_32 ( * (((int32*)buffer) + count) );
564 }
565 }
566 else if (swapSize == kSwap64)
567 {
568 for (uint32 count = 0 ; count < bufferSize ; count += 8)
569 {
570 SWAP_64 ( * (((int64*)buffer) + count) );
571 }
572 }
573
574 return true;
575}
576
577//-------------------------------------------------------------------------------------
579{
580 setSize (0);
581 memSize = from.memSize;
582 fillSize = from.fillSize;
583 buffer = from.buffer;
584 from.buffer = nullptr;
585 from.memSize = 0;
586 from.fillSize = 0;
587}
588
589//-------------------------------------------------------------------------------------
591{
592 int8* res = buffer;
593 buffer = nullptr;
594 memSize = 0;
595 fillSize = 0;
596 return res;
597}
598
599//-------------------------------------------------------------------------------------
600bool Buffer::toWideString (int32 sourceCodePage)
601{
602 if (getFillSize () > 0)
603 {
604 if (str8 () [getFillSize () - 1] != 0) // multiByteToWideString only works with 0-terminated strings
605 endString8 ();
606
607 Buffer dest (getFillSize () * sizeof (char16));
608 int32 result = String::multiByteToWideString (dest.str16 (), buffer, dest.getFree () / sizeof (char16), sourceCodePage);
609 if (result > 0)
610 {
611 dest.setFillSize ((result - 1) * sizeof (char16));
612 take (dest);
613 return true;
614 }
615 return false;
616 }
617 return true;
618}
619
620//-------------------------------------------------------------------------------------
622{
623 if (getFillSize () > 0)
624 {
625 int32 textLength = getFillSize () / sizeof (char16); // wideStringToMultiByte only works with 0-terminated strings
626 if (str16 () [textLength - 1] != 0)
627 endString16 ();
628
629 Buffer dest (getFillSize ());
630 int32 result = String::wideStringToMultiByte (dest.str8 (), str16 (), dest.getFree (), destCodePage);
631 if (result > 0)
632 {
633 dest.setFillSize (result - 1);
634 take (dest);
635 return true;
636 }
637 return false;
638 }
639 return true;
640}
641
642//------------------------------------------------------------------------
643} // namespace Steinberg
#define nullptr
Definition DistrhoDefines.h:75
#define byte
Definition blargg_source.h:87
uint32 getSize() const
Definition fbuffer.h:101
bool makeHexString(String &result)
Definition fbuffer.cpp:299
void take(Buffer &from)
takes another Buffer's memory, frees the current Buffer's memory
Definition fbuffer.cpp:578
bool appendString8(const char8 *s)
Definition fbuffer.cpp:208
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)
Definition fbuffer.cpp:127
bool truncateToFillSize()
Definition fbuffer.cpp:393
uint32 memSize
Definition fbuffer.h:244
virtual bool toWideString(int32 sourceCodePage)
Definition fbuffer.cpp:600
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
bool fromHexString(const char8 *string)
Definition fbuffer.cpp:337
swapSize
Definition fbuffer.h:216
@ kSwap16
Definition fbuffer.h:217
@ kSwap64
Definition fbuffer.h:219
@ kSwap32
Definition fbuffer.h:218
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)
Definition fbuffer.cpp:621
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
uint32 fillSize
Definition fbuffer.h:245
void endString8()
Definition fbuffer.h:190
char16 * str16() const
conversion
Definition fbuffer.h:200
uint32 getFree() const
Definition fbuffer.h:123
bool operator==(const Buffer &buff) const
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
static const uint32 defaultDelta
Definition fbuffer.h:241
bool prependString16(const char16 *s)
Definition fbuffer.cpp:244
uint8 * uint8Ptr() const
conversion
Definition fbuffer.h:202
int8 * buffer
Definition fbuffer.h:243
Buffer()
Definition fbuffer.cpp:45
char8 * str8() const
conversion
Definition fbuffer.h:199
void endString16()
Definition fbuffer.h:191
virtual ~Buffer()
Definition fbuffer.cpp:119
bool setSize(uint32 newSize)
Definition fbuffer.cpp:470
bool prependString8(const char8 *s)
Definition fbuffer.cpp:228
bool grow(uint32 memSize)
Definition fbuffer.cpp:402
bool appendString16(const char16 *s)
Definition fbuffer.cpp:218
int8 * operator+(uint32 i)
Definition fbuffer.cpp:528
int8 * pass()
pass the current Buffer's memory
Definition fbuffer.cpp:590
void shiftAt(uint32 position, int32 amount)
moves memory starting at the given position
Definition fbuffer.cpp:415
uint32 delta
Definition fbuffer.h:246
bool swap(int16 swapSize)
swap all bytes of this Buffer by the given swapSize
Definition fbuffer.cpp:541
Definition fstring.h:117
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:1924
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:1858
Definition fstring.h:308
unsigned d
Definition inflate.c:940
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
#define SWAP_16(w)
Definition ftypes.h:149
#define SWAP_32(l)
Definition ftypes.h:144
#define SWAP_64(i)
Definition ftypes.h:154
static PuglViewHint int value
Definition pugl.h:1708
JSAMPIMAGE data
Definition jpeglib.h:945
Definition baseiids.cpp:43
short int16
Definition ftypes.h:43
int16 char16
Definition ftypes.h:101
int int32
Definition ftypes.h:50
int32 strlen8(const char8 *str)
Definition fstrdefs.h:125
char char8
Definition ftypes.h:93
char int8
Definition ftypes.h:39
long long int64
Definition ftypes.h:66
char16 tchar
Definition ftypes.h:105
unsigned char uint8
Definition ftypes.h:40
unsigned int uint32
Definition ftypes.h:51
#define true
Definition ordinals.h:82
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
b
Definition crypt.c:628
ulg size
Definition extract.c:2350
int result
Definition process.c:1455
char * malloc()
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263