Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
14KB

  1. //------------------------------------------------------------------------
  2. // Project : SDK Base
  3. // Version : 1.0
  4. //
  5. // Category : Helpers
  6. // Filename : base/source/fbuffer.h
  7. // Created by : Steinberg, 2008
  8. // Description :
  9. //
  10. //-----------------------------------------------------------------------------
  11. // LICENSE
  12. // (c) 2017, 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. #pragma once
  38. #include "pluginterfaces/base/ftypes.h"
  39. #include <cstring>
  40. namespace Steinberg {
  41. class String;
  42. //------------------------------------------------------------------------
  43. /** Buffer.
  44. @ingroup adt
  45. A Buffer is an object-oriented wrapper for a piece of memory.
  46. It adds several utility functions, e.g. for managing the size of the Buffer,
  47. appending or prepending values or strings to it.
  48. Internally it uses the standard memory functions malloc(), free(), etc. */
  49. //------------------------------------------------------------------------
  50. class Buffer
  51. {
  52. public:
  53. //---------------------------------------------------------------------
  54. /** Default constructor, allocates no memory at all.
  55. */
  56. Buffer ();
  57. /** Constructor - creates a new Buffer with a given size and copies contents from optional memory pointer.
  58. \param[in] b : optional memory pointer with the size of at least the given size
  59. \param[in] size : the size of the new Buffer to be allocated, in bytes.
  60. */
  61. Buffer (const void* b, uint32 size);
  62. /** Constructor - creates a new Buffer with a given size and fills it all with a given value.
  63. \param[in] size : the size of the new Buffer to be allocated, in bytes.
  64. \param[in] initVal : the initial value the Buffer will be completely filled with
  65. */
  66. Buffer (uint32 size, uint8 initVal);
  67. /** Constructor - creates a new Buffer with a given size.
  68. \param[in] size : the size of the new Buffer to be allocated, in bytes.
  69. */
  70. Buffer (uint32 size);
  71. /** Copy constructor - creates a new Buffer from a given Buffer.
  72. \param[in] buff : the Buffer from which all memory will be copied to the new one
  73. */
  74. Buffer (const Buffer& buff);
  75. /** Destructor - deallocates the internal memory.
  76. */
  77. ~Buffer ();
  78. /** Assignment operator - copies contents from a given Buffer and increases the size if necessary.
  79. \param[in] buff : the Buffer from which all memory will be copied
  80. */
  81. void operator = (const Buffer& buff);
  82. /** Comparison operator - copies contents from a given Buffer and increases the size if necessary.
  83. \param[in] buff : the Buffer to be compared to
  84. \return true, if the given Buffer's content is equal to this one, else false
  85. */
  86. bool operator == (const Buffer& buff)const;
  87. uint32 getSize () const {return memSize;} ///< \return the actual size of the Buffer's memory, in bytes.
  88. /** Sets a new size for this Buffer, keeping as much content as possible.
  89. \param[in] newSize : the new size for the Buffer, in bytes, newSize maybe zero
  90. \return true, if the new size could be adapted, else false
  91. */
  92. bool setSize (uint32 newSize);
  93. /** Increases the Buffer to the next block, block size given by delta.
  94. \param[in] memSize : the new minimum size of the Buffer, newSize maybe zero
  95. \return true, if the Buffer could be grown successfully, else false
  96. */
  97. bool grow (uint32 memSize);
  98. bool setMaxSize (uint32 size) {return grow (size);} ///< see \ref grow()
  99. void fillup (uint8 initVal = 0); ///< set from fillSize to end
  100. uint32 getFillSize ()const {return fillSize;} ///< \return the actual fill size
  101. bool setFillSize (uint32 c); ///< sets a new fill size, does not change any memory
  102. inline void flush () {setFillSize (0);} ///< sets fill size to zero
  103. bool truncateToFillSize (); ///< \return always true, truncates the size of the Buffer to the actual fill size
  104. bool isFull () const { return (fillSize == memSize); } ///< \return true, if all memory is filled up, else false
  105. uint32 getFree () const { return (memSize - fillSize); }///< \return remaining memory
  106. inline void shiftStart (int32 amount) {return shiftAt (0, amount);} ///< moves all memory by given amount, grows the Buffer if necessary
  107. void shiftAt (uint32 position, int32 amount); ///< moves memory starting at the given position
  108. void move (int32 amount, uint8 initVal = 0); ///< shifts memory at start without growing the buffer, so data is lost and initialized with init val
  109. bool copy (uint32 from, uint32 to, uint32 bytes); ///< copies a number of bytes from one position to another, the size may be adapted
  110. uint32 get (void* b, uint32 size); ///< copy to buffer from fillSize, and shift fillSize
  111. void setDelta (uint32 d) {delta = d;} ///< define the block size by which the Buffer grows, see \ref grow()
  112. bool put (uint8); ///< append value at end, grows Buffer if necessary
  113. bool put (char16 c); ///< append value at end, grows Buffer if necessary
  114. bool put (char c); ///< append value at end, grows Buffer if necessary
  115. bool put (const void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  116. bool put (void* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  117. bool put (uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  118. bool put (char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  119. bool put (const uint8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  120. bool put (const char8* , uint32 size); ///< append bytes from a given buffer, grows Buffer if necessary
  121. bool put (const String&); ///< append String at end, grows Buffer if necessary
  122. void set (uint8 value); ///< fills complete Buffer with given value
  123. // strings ----------------
  124. bool appendString (const tchar* s);
  125. bool appendString (tchar* s);
  126. bool appendString (tchar c) { return put (c); }
  127. bool appendString8 (const char8* s);
  128. bool appendString16 (const char16* s);
  129. bool appendString8 (char8* s) { return appendString8 ((const char8*)s); }
  130. bool appendString8 (unsigned char* s) { return appendString8 ((const char8*)s); }
  131. bool appendString8 (const unsigned char* s) { return appendString8 ((const char8*)s); }
  132. bool appendString8 (char8 c) { return put ((uint8)c); }
  133. bool appendString8 (unsigned char c) { return put (c); }
  134. bool appendString16 (char16 c) { return put (c); }
  135. bool appendString16 (char16* s) { return appendString16 ((const char16*)s); }
  136. bool prependString (const tchar* s);
  137. bool prependString (tchar* s);
  138. bool prependString (tchar c);
  139. bool prependString8 (const char8* s);
  140. bool prependString16 (const char16* s);
  141. bool prependString8 (char8 c);
  142. bool prependString8 (unsigned char c) { return prependString8 ((char8)c); }
  143. bool prependString8 (char8* s) { return prependString8 ((const char8*)s); }
  144. bool prependString8 (unsigned char* s) { return prependString8((const char8*)s); }
  145. bool prependString8 (const unsigned char* s) { return prependString8 ((const char8*)s); }
  146. bool prependString16 (char16 c);
  147. bool prependString16 (char16* s) { return prependString16 ((const char16*)s); }
  148. bool operator+= (const char* s) { return appendString8 (s); }
  149. bool operator+= (char c) { return appendString8 (c); }
  150. bool operator+= (const char16* s) { return appendString16 (s); }
  151. bool operator+= (char16 c) { return appendString16 (c); }
  152. bool operator= (const char* s) { flush (); return appendString8 (s); }
  153. bool operator= (const char16* s) { flush (); return appendString16 (s); }
  154. bool operator= (char8 c) { flush (); return appendString8 (c); }
  155. bool operator= (char16 c) { flush (); return appendString16 (c); }
  156. void endString () {put (tchar (0));}
  157. void endString8 () {put (char8 (0));}
  158. void endString16 () {put (char16 (0));}
  159. bool makeHexString (String& result);
  160. bool fromHexString (const char8* string);
  161. // conversion
  162. operator void* () const { return (void*)buffer; } ///< conversion
  163. inline tchar* str () const {return (tchar*)buffer;} ///< conversion
  164. inline char8* str8 () const {return (char8*)buffer;} ///< conversion
  165. inline char16* str16 () const {return (char16*)buffer;} ///< conversion
  166. inline int8* int8Ptr () const {return (int8*)buffer;} ///< conversion
  167. inline uint8* uint8Ptr () const {return (uint8*)buffer; } ///< conversion
  168. inline int16* int16Ptr () const {return (int16*)buffer; } ///< conversion
  169. inline uint16* uint16Ptr () const {return (uint16*)buffer; } ///< conversion
  170. inline int32* int32Ptr () const {return (int32*)buffer; } ///< conversion
  171. inline uint32* uint32Ptr () const {return (uint32*)buffer; } ///< conversion
  172. inline float* floatPtr () const {return (float*)buffer; } ///< conversion
  173. inline double* doublePtr () const {return (double*)buffer; } ///< conversion
  174. inline char16* wcharPtr () const {return (char16*)buffer;} ///< conversion
  175. int8* operator + (uint32 i); ///< \return the internal Buffer's address plus the given offset i, zero if offset is out of range
  176. int32 operator ! () { return buffer == 0; }
  177. enum swapSize
  178. {
  179. kSwap16 = 2,
  180. kSwap32 = 4,
  181. kSwap64 = 8
  182. };
  183. bool swap (int16 swapSize); ///< swap all bytes of this Buffer by the given swapSize
  184. static bool swap (void* buffer, uint32 bufferSize, int16 swapSize); ///< utility, swap given number of bytes in given buffer by the given swapSize
  185. void take (Buffer& from); ///< takes another Buffer's memory, frees the current Buffer's memory
  186. int8* pass (); ///< pass the current Buffer's memory
  187. /** Converts a Buffer's content to UTF-16 from a given multi-byte code page, Buffer must contain char8 of given encoding.
  188. \param[in] sourceCodePage : the actual code page of the Buffer's content
  189. \return true, if the conversion was successful, else false
  190. */
  191. virtual bool toWideString (int32 sourceCodePage); // Buffer contains char8 of given encoding -> utf16
  192. /** Converts a Buffer's content from UTF-16 to a given multi-byte code page, Buffer must contain UTF-16 encoded characters.
  193. \param[in] destCodePage : the desired code page to convert the Buffer's content to
  194. \return true, if the conversion was successful, else false
  195. */
  196. virtual bool toMultibyteString (int32 destCodePage); // Buffer contains utf16 -> char8 of given encoding
  197. //------------------------------------------------------------------------
  198. protected:
  199. static const uint32 defaultDelta = 0x1000; // 0x1000
  200. int8* buffer;
  201. uint32 memSize;
  202. uint32 fillSize;
  203. uint32 delta;
  204. };
  205. inline bool Buffer::put (void* p, uint32 count) { return put ((const void*)p , count ); }
  206. inline bool Buffer::put (uint8 * p, uint32 count) { return put ((const void*)p , count ); }
  207. inline bool Buffer::put (char8* p, uint32 count) { return put ((const void*)p , count ); }
  208. inline bool Buffer::put (const uint8* p, uint32 count) { return put ((const void*)p , count ); }
  209. inline bool Buffer::put (const char8* p, uint32 count) { return put ((const void*)p , count ); }
  210. //------------------------------------------------------------------------
  211. inline bool Buffer::appendString (const tchar* s)
  212. {
  213. #ifdef UNICODE
  214. return appendString16 (s);
  215. #else
  216. return appendString8 (s);
  217. #endif
  218. }
  219. //------------------------------------------------------------------------
  220. inline bool Buffer::appendString (tchar* s)
  221. {
  222. #ifdef UNICODE
  223. return appendString16 (s);
  224. #else
  225. return appendString8 (s);
  226. #endif
  227. }
  228. //------------------------------------------------------------------------
  229. inline bool Buffer::prependString (const tchar* s)
  230. {
  231. #ifdef UNICODE
  232. return prependString16 (s);
  233. #else
  234. return prependString8 (s);
  235. #endif
  236. }
  237. //------------------------------------------------------------------------
  238. inline bool Buffer::prependString (tchar* s)
  239. {
  240. #ifdef UNICODE
  241. return prependString16 (s);
  242. #else
  243. return prependString8 (s);
  244. #endif
  245. }
  246. //------------------------------------------------------------------------
  247. inline bool Buffer::prependString (tchar c)
  248. {
  249. #ifdef UNICODE
  250. return prependString16 (c);
  251. #else
  252. return prependString8 (c);
  253. #endif
  254. }
  255. //------------------------------------------------------------------------
  256. } // namespace Steinberg