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.

727 lines
18KB

  1. //------------------------------------------------------------------------
  2. // Project : SDK Base
  3. // Version : 1.0
  4. //
  5. // Category : Helpers
  6. // Filename : base/source/fstreamer.cpp
  7. // Created by : Steinberg, 15.12.2005
  8. // Description : Extract of typed stream i/o methods from FStream
  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. #include "fstreamer.h"
  38. #include "base/source/fstring.h"
  39. #include "base/source/fbuffer.h"
  40. #include "pluginterfaces/base/ibstream.h"
  41. #ifndef UNICODE
  42. #include "pluginterfaces/base/futils.h"
  43. #endif
  44. namespace Steinberg {
  45. //------------------------------------------------------------------------
  46. // IBStreamer
  47. //------------------------------------------------------------------------
  48. IBStreamer::IBStreamer (IBStream* stream, int16 _byteOrder)
  49. : FStreamer (_byteOrder)
  50. , stream (stream)
  51. {}
  52. //------------------------------------------------------------------------
  53. TSize IBStreamer::readRaw (void* buffer, TSize size)
  54. {
  55. int32 numBytesRead = 0;
  56. stream->read (buffer, (int32)size, &numBytesRead);
  57. return numBytesRead;
  58. }
  59. //------------------------------------------------------------------------
  60. TSize IBStreamer::writeRaw (const void* buffer, TSize size)
  61. {
  62. int32 numBytesWritten = 0;
  63. stream->write ((void*)buffer, (int32)size, &numBytesWritten);
  64. return numBytesWritten;
  65. }
  66. //------------------------------------------------------------------------
  67. int64 IBStreamer::seek (int64 pos, FSeekMode mode)
  68. {
  69. int64 result = -1;
  70. stream->seek (pos, mode, &result);
  71. return result;
  72. }
  73. //------------------------------------------------------------------------
  74. int64 IBStreamer::tell ()
  75. {
  76. int64 pos = 0;
  77. stream->tell (&pos);
  78. return pos;
  79. }
  80. //------------------------------------------------------------------------
  81. // FStreamSizeHolder Implementation
  82. //------------------------------------------------------------------------
  83. FStreamSizeHolder::FStreamSizeHolder (FStreamer &s)
  84. : stream (s), sizePos (-1)
  85. {}
  86. //------------------------------------------------------------------------
  87. void FStreamSizeHolder::beginWrite ()
  88. {
  89. sizePos = stream.tell ();
  90. stream.writeInt32 (0L);
  91. }
  92. //------------------------------------------------------------------------
  93. int32 FStreamSizeHolder::endWrite ()
  94. {
  95. if (sizePos < 0)
  96. return 0;
  97. int64 currentPos = stream.tell ();
  98. stream.seek (sizePos, kSeekSet);
  99. int32 size = int32 (currentPos - sizePos - sizeof (int32));
  100. stream.writeInt32 (size);
  101. stream.seek (currentPos, kSeekSet);
  102. return size;
  103. }
  104. //------------------------------------------------------------------------
  105. int32 FStreamSizeHolder::beginRead ()
  106. {
  107. sizePos = stream.tell ();
  108. int32 size = 0;
  109. stream.readInt32 (size);
  110. sizePos += size + sizeof (int32);
  111. return size;
  112. }
  113. //------------------------------------------------------------------------
  114. void FStreamSizeHolder::endRead ()
  115. {
  116. if (sizePos >= 0)
  117. stream.seek (sizePos, kSeekSet);
  118. }
  119. //------------------------------------------------------------------------
  120. // FStreamer
  121. //------------------------------------------------------------------------
  122. FStreamer::FStreamer (int16 _byteOrder)
  123. : byteOrder (_byteOrder)
  124. {}
  125. // int8 / char -----------------------------------------------------------
  126. //------------------------------------------------------------------------
  127. bool FStreamer::writeChar8 (char8 c)
  128. {
  129. return writeRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
  130. }
  131. //------------------------------------------------------------------------
  132. bool FStreamer::readChar8 (char8& c)
  133. {
  134. return readRaw ((void*)&c, sizeof (char8)) == sizeof (char8);
  135. }
  136. //------------------------------------------------------------------------
  137. bool FStreamer::writeUChar8 (unsigned char c)
  138. {
  139. return writeRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
  140. }
  141. //------------------------------------------------------------------------
  142. bool FStreamer::readUChar8 (unsigned char& c)
  143. {
  144. return readRaw ((void*)&c, sizeof (unsigned char)) == sizeof (unsigned char);
  145. }
  146. //------------------------------------------------------------------------
  147. bool FStreamer::writeChar16 (char16 c)
  148. {
  149. if (BYTEORDER != byteOrder)
  150. SWAP_16 (c);
  151. return writeRaw ((void*)&c, sizeof (char16)) == sizeof (char16);
  152. }
  153. //------------------------------------------------------------------------
  154. bool FStreamer::readChar16 (char16& c)
  155. {
  156. if (readRaw ((void*)&c, sizeof (char16)) == sizeof (char16))
  157. {
  158. if (BYTEORDER != byteOrder)
  159. SWAP_16 (c);
  160. return true;
  161. }
  162. c = 0;
  163. return false;
  164. }
  165. // int16 -----------------------------------------------------------------
  166. //------------------------------------------------------------------------
  167. bool FStreamer::writeInt16 (int16 i)
  168. {
  169. if (BYTEORDER != byteOrder)
  170. SWAP_16 (i);
  171. return writeRaw ((void*)&i, sizeof (int16)) == sizeof (int16);
  172. }
  173. //------------------------------------------------------------------------
  174. bool FStreamer::readInt16 (int16& i)
  175. {
  176. if (readRaw ((void*)&i, sizeof (int16)) == sizeof (int16))
  177. {
  178. if (BYTEORDER != byteOrder)
  179. SWAP_16 (i);
  180. return true;
  181. }
  182. i = 0;
  183. return false;
  184. }
  185. //------------------------------------------------------------------------
  186. bool FStreamer::writeInt16Array (const int16* array, int32 count)
  187. {
  188. for (int32 i = 0; i < count; i++)
  189. {
  190. if (!writeInt16 (array[i]))
  191. return false;
  192. }
  193. return true;
  194. }
  195. //------------------------------------------------------------------------
  196. bool FStreamer::readInt16Array (int16* array, int32 count)
  197. {
  198. for (int32 i = 0; i < count; i++)
  199. {
  200. if (!readInt16 (array[i]))
  201. return false;
  202. }
  203. return true;
  204. }
  205. //------------------------------------------------------------------------
  206. bool FStreamer::writeInt16u (uint16 i)
  207. {
  208. if (BYTEORDER != byteOrder)
  209. SWAP_16 (i);
  210. return writeRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16);
  211. }
  212. //------------------------------------------------------------------------
  213. bool FStreamer::readInt16u (uint16& i)
  214. {
  215. if (readRaw ((void*)&i, sizeof (uint16)) == sizeof (uint16))
  216. {
  217. if (BYTEORDER != byteOrder)
  218. SWAP_16 (i);
  219. return true;
  220. }
  221. i = 0;
  222. return false;
  223. }
  224. //------------------------------------------------------------------------
  225. bool FStreamer::writeInt16uArray (const uint16* array, int32 count)
  226. {
  227. for (int32 i = 0; i < count; i++)
  228. {
  229. if (!writeInt16u (array[i]))
  230. return false;
  231. }
  232. return true;
  233. }
  234. //------------------------------------------------------------------------
  235. bool FStreamer::readInt16uArray (uint16* array, int32 count)
  236. {
  237. for (int32 i = 0; i < count; i++)
  238. {
  239. if (!readInt16u (array[i]))
  240. return false;
  241. }
  242. return true;
  243. }
  244. // int32 -----------------------------------------------------------------
  245. //------------------------------------------------------------------------
  246. bool FStreamer::writeInt32 (int32 i)
  247. {
  248. if (BYTEORDER != byteOrder)
  249. SWAP_32 (i);
  250. return writeRaw ((void*)&i, sizeof (int32)) == sizeof (int32);
  251. }
  252. //------------------------------------------------------------------------
  253. bool FStreamer::readInt32 (int32& i)
  254. {
  255. if (readRaw ((void*)&i, sizeof (int32)) == sizeof (int32))
  256. {
  257. if (BYTEORDER != byteOrder)
  258. SWAP_32 (i);
  259. return true;
  260. }
  261. i = 0;
  262. return false;
  263. }
  264. //------------------------------------------------------------------------
  265. bool FStreamer::writeInt32Array (const int32* array, int32 count)
  266. {
  267. for (int32 i = 0; i < count; i++)
  268. {
  269. if (!writeInt32 (array[i]))
  270. return false;
  271. }
  272. return true;
  273. }
  274. //------------------------------------------------------------------------
  275. bool FStreamer::readInt32Array (int32* array, int32 count)
  276. {
  277. for (int32 i = 0; i < count; i++)
  278. {
  279. if (!readInt32 (array[i]))
  280. return false;
  281. }
  282. return true;
  283. }
  284. //------------------------------------------------------------------------
  285. bool FStreamer::writeInt32u (uint32 i)
  286. {
  287. if (BYTEORDER != byteOrder)
  288. SWAP_32 (i);
  289. return writeRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32);
  290. }
  291. //------------------------------------------------------------------------
  292. bool FStreamer::readInt32u (uint32& i)
  293. {
  294. if (readRaw ((void*)&i, sizeof (uint32)) == sizeof (uint32))
  295. {
  296. if (BYTEORDER != byteOrder)
  297. SWAP_32 (i);
  298. return true;
  299. }
  300. i = 0;
  301. return false;
  302. }
  303. //------------------------------------------------------------------------
  304. bool FStreamer::writeInt32uArray (const uint32* array, int32 count)
  305. {
  306. for (int32 i = 0; i < count; i++)
  307. {
  308. if (!writeInt32u (array[i]))
  309. return false;
  310. }
  311. return true;
  312. }
  313. //------------------------------------------------------------------------
  314. bool FStreamer::readInt32uArray (uint32* array, int32 count)
  315. {
  316. for (int32 i = 0; i < count; i++)
  317. {
  318. if (!readInt32u (array[i]))
  319. return false;
  320. }
  321. return true;
  322. }
  323. // int64 -----------------------------------------------------------------
  324. //------------------------------------------------------------------------
  325. bool FStreamer::writeInt64 (int64 i)
  326. {
  327. if (BYTEORDER != byteOrder)
  328. SWAP_64 (i);
  329. return writeRaw ((void*)&i, sizeof (int64)) == sizeof (int64);
  330. }
  331. //------------------------------------------------------------------------
  332. bool FStreamer::readInt64 (int64& i)
  333. {
  334. if (readRaw ((void*)&i, sizeof (int64)) == sizeof (int64))
  335. {
  336. if (BYTEORDER != byteOrder)
  337. SWAP_64 (i);
  338. return true;
  339. }
  340. i = 0;
  341. return false;
  342. }
  343. //------------------------------------------------------------------------
  344. bool FStreamer::writeInt64Array (const int64* array, int32 count)
  345. {
  346. for (int32 i = 0; i < count; i++)
  347. {
  348. if (!writeInt64 (array[i]))
  349. return false;
  350. }
  351. return true;
  352. }
  353. //------------------------------------------------------------------------
  354. bool FStreamer::readInt64Array (int64* array, int32 count)
  355. {
  356. for (int32 i = 0; i < count; i++)
  357. {
  358. if (!readInt64 (array[i]))
  359. return false;
  360. }
  361. return true;
  362. }
  363. //------------------------------------------------------------------------
  364. bool FStreamer::writeInt64u (uint64 i)
  365. {
  366. if (BYTEORDER != byteOrder)
  367. SWAP_64 (i);
  368. return writeRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64);
  369. }
  370. //------------------------------------------------------------------------
  371. bool FStreamer::readInt64u (uint64& i)
  372. {
  373. if (readRaw ((void*)&i, sizeof (uint64)) == sizeof (uint64))
  374. {
  375. if (BYTEORDER != byteOrder)
  376. SWAP_64 (i);
  377. return true;
  378. }
  379. i = 0;
  380. return false;
  381. }
  382. //------------------------------------------------------------------------
  383. bool FStreamer::writeInt64uArray (const uint64* array, int32 count)
  384. {
  385. for (int32 i = 0; i < count; i++)
  386. {
  387. if (!writeInt64u (array[i]))
  388. return false;
  389. }
  390. return true;
  391. }
  392. //------------------------------------------------------------------------
  393. bool FStreamer::readInt64uArray (uint64* array, int32 count)
  394. {
  395. for (int32 i = 0; i < count; i++)
  396. {
  397. if (!readInt64u (array[i]))
  398. return false;
  399. }
  400. return true;
  401. }
  402. // float / double --------------------------------------------------------
  403. //------------------------------------------------------------------------
  404. bool FStreamer::writeFloat (float f)
  405. {
  406. if (BYTEORDER != byteOrder)
  407. SWAP_32 (f);
  408. return writeRaw ((void*)&f, sizeof (float)) == sizeof (float);
  409. }
  410. //------------------------------------------------------------------------
  411. bool FStreamer::readFloat (float& f)
  412. {
  413. if (readRaw ((void*)&f, sizeof (float)) == sizeof (float))
  414. {
  415. if (BYTEORDER != byteOrder)
  416. SWAP_32 (f);
  417. return true;
  418. }
  419. f = 0.f;
  420. return false;
  421. }
  422. //------------------------------------------------------------------------
  423. bool FStreamer::writeFloatArray (const float* array, int32 count)
  424. {
  425. for (int32 i = 0; i < count; i++)
  426. {
  427. if (!writeFloat (array[i]))
  428. return false;
  429. }
  430. return true;
  431. }
  432. //------------------------------------------------------------------------
  433. bool FStreamer::readFloatArray (float* array, int32 count)
  434. {
  435. for (int32 i = 0; i < count; i++)
  436. {
  437. if (!readFloat (array[i]))
  438. return false;
  439. }
  440. return true;
  441. }
  442. //------------------------------------------------------------------------
  443. bool FStreamer::writeDouble (double d)
  444. {
  445. if (BYTEORDER != byteOrder)
  446. SWAP_64 (d);
  447. return writeRaw ((void*)&d, sizeof (double)) == sizeof (double);
  448. }
  449. //------------------------------------------------------------------------
  450. bool FStreamer::readDouble (double& d)
  451. {
  452. if (readRaw ((void*)&d, sizeof (double)) == sizeof (double))
  453. {
  454. if (BYTEORDER != byteOrder)
  455. SWAP_64 (d);
  456. return true;
  457. }
  458. d = 0.0;
  459. return false;
  460. }
  461. //------------------------------------------------------------------------
  462. bool FStreamer::writeDoubleArray (const double* array, int32 count)
  463. {
  464. for (int32 i = 0; i < count; i++)
  465. {
  466. if (!writeDouble (array[i]))
  467. return false;
  468. }
  469. return true;
  470. }
  471. //------------------------------------------------------------------------
  472. bool FStreamer::readDoubleArray (double* array, int32 count)
  473. {
  474. for (int32 i = 0; i < count; i++)
  475. {
  476. if (!readDouble (array[i]))
  477. return false;
  478. }
  479. return true;
  480. }
  481. //------------------------------------------------------------------------
  482. bool FStreamer::readBool (bool& b)
  483. {
  484. int16 v = 0;
  485. bool res = readInt16 (v);
  486. b = (v != 0);
  487. return res;
  488. }
  489. //------------------------------------------------------------------------
  490. bool FStreamer::writeBool (bool b)
  491. {
  492. return writeInt16 ((int16)b);
  493. }
  494. //------------------------------------------------------------------------
  495. TSize FStreamer::writeString8 (const char8* ptr, bool terminate)
  496. {
  497. TSize size = strlen (ptr);
  498. if (terminate) // write \0
  499. size++;
  500. return writeRaw ((void*)ptr, size);
  501. }
  502. //------------------------------------------------------------------------
  503. TSize FStreamer::readString8 (char8* ptr, TSize size)
  504. {
  505. TSize i = 0;
  506. char8 c = 0;
  507. while (i < size)
  508. {
  509. if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
  510. break;
  511. ptr[i] = c;
  512. i++;
  513. if (c == '\n' || c == '\0')
  514. break;
  515. }
  516. if (c == '\n' && ptr[i - 2] == '\r')
  517. ptr[i - 2] = 0;
  518. if (i < size)
  519. ptr[i] = 0;
  520. else
  521. ptr[size - 1] = 0;
  522. return strlen (ptr);
  523. }
  524. //------------------------------------------------------------------------
  525. bool FStreamer::writeStringUtf8 (const tchar* ptr)
  526. {
  527. bool isUtf8 = false;
  528. String str (ptr);
  529. if (str.isAsciiString () == false)
  530. {
  531. str.toMultiByte (kCP_Utf8);
  532. isUtf8 = true;
  533. }
  534. else
  535. {
  536. str.toMultiByte ();
  537. }
  538. if (isUtf8)
  539. if (writeRaw (kBomUtf8, kBomUtf8Length) != kBomUtf8Length)
  540. return false;
  541. TSize size = str.length () + 1;
  542. if (writeRaw (str.text8 (), size) != size)
  543. return false;
  544. return true;
  545. }
  546. //------------------------------------------------------------------------
  547. int32 FStreamer::readStringUtf8 (tchar* ptr, int32 nChars)
  548. {
  549. char8 c = 0;
  550. ptr [0] = 0;
  551. Buffer tmp;
  552. tmp.setDelta (1024);
  553. while (true)
  554. {
  555. if (readRaw ((void*)&c, sizeof (char)) != sizeof (char))
  556. break;
  557. tmp.put (c);
  558. if (c == '\0')
  559. break;
  560. }
  561. char8* source = tmp.int8Ptr ();
  562. uint32 codePage = kCP_Default; // for legacy take default page if no utf8 bom is present...
  563. if (tmp.getFillSize () > 2)
  564. {
  565. if (memcmp (source, kBomUtf8, kBomUtf8Length) == 0)
  566. {
  567. codePage = kCP_Utf8;
  568. source += 3;
  569. }
  570. }
  571. if (tmp.getFillSize () > 1)
  572. {
  573. #ifdef UNICODE
  574. ConstString::multiByteToWideString (ptr, source, nChars, codePage);
  575. #else
  576. if (codePage == kCP_Utf8)
  577. {
  578. Buffer wideBuffer (tmp.getFillSize () * 3);
  579. ConstString::multiByteToWideString (wideBuffer.wcharPtr (), source, wideBuffer.getSize () / 2, kCP_Utf8);
  580. ConstString::wideStringToMultiByte (ptr, wideBuffer.wcharPtr (), nChars);
  581. }
  582. else
  583. {
  584. memcpy (ptr, source, Min<TSize> (nChars, tmp.getFillSize ()));
  585. }
  586. #endif
  587. }
  588. ptr[nChars - 1] = 0;
  589. return ConstString (ptr).length ();
  590. }
  591. //------------------------------------------------------------------------
  592. bool FStreamer::writeStr8 (const char8* s)
  593. {
  594. int32 length = (s) ? (int32) strlen (s) + 1 : 0;
  595. if (!writeInt32 (length))
  596. return false;
  597. if (length > 0)
  598. return writeRaw (s, sizeof (char8) * length) == sizeof (char8) * length;
  599. return true;
  600. }
  601. //------------------------------------------------------------------------
  602. int32 FStreamer::getStr8Size (const char8* s)
  603. {
  604. return sizeof (int32) + (int32)strlen (s) + 1;
  605. }
  606. //------------------------------------------------------------------------
  607. char8* FStreamer::readStr8 ()
  608. {
  609. int32 length;
  610. if (!readInt32 (length))
  611. return 0;
  612. // check corruption
  613. if (length > 262144)
  614. return 0;
  615. char8* s = (length > 0) ? NEWVEC char8[length] : 0;
  616. if (s)
  617. readRaw (s, length * sizeof (char8));
  618. return s;
  619. }
  620. //------------------------------------------------------------------------
  621. bool FStreamer::skip (uint32 bytes)
  622. {
  623. int8 tmp;
  624. while (bytes-- > 0)
  625. {
  626. if (readInt8 (tmp) == false)
  627. return false;
  628. }
  629. return true;
  630. }
  631. //------------------------------------------------------------------------
  632. bool FStreamer::pad (uint32 bytes)
  633. {
  634. while (bytes-- > 0)
  635. {
  636. if (writeInt8 (0) == false)
  637. return false;
  638. }
  639. return true;
  640. }
  641. //------------------------------------------------------------------------
  642. } // namespace Steinberg