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.

184 lines
5.1KB

  1. /*
  2. * Carla base64 utils imported from qemu source code
  3. * Copyright (C) 2009 Michael Brown <mbrown@fensystems.co.uk>
  4. * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * For a full copy of the GNU General Public License see the GPL.txt file
  17. */
  18. #ifndef __CARLA_BASE64_UTILS_HPP__
  19. #define __CARLA_BASE64_UTILS_HPP__
  20. #include "CarlaUtils.hpp"
  21. #include <cctype>
  22. #include <cstdint>
  23. static const char kBase64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  24. /**
  25. * Calculate length of base64-encoded data
  26. *
  27. * @v rawLen Raw data length
  28. * @ret encodedLen Encoded string length (excluding NUL)
  29. */
  30. static inline
  31. size_t carla_base64_encoded_len(const size_t rawLen)
  32. {
  33. return (((rawLen + 3 - 1) / 3) * 4);
  34. }
  35. /**
  36. * Calculate maximum length of base64-decoded string
  37. *
  38. * @v encoded Encoded string
  39. * @v maxRawLen Maximum length of raw data
  40. *
  41. * Note that the exact length of the raw data cannot be known until
  42. * the string is decoded.
  43. */
  44. static inline
  45. size_t carla_base64_decoded_max_len(const char* const encoded)
  46. {
  47. return (((std::strlen(encoded) + 4 - 1) / 4) * 3);
  48. }
  49. /**
  50. * Base64-encode data
  51. *
  52. * @v raw Raw data
  53. * @v len Length of raw data
  54. * @v encoded Buffer for encoded string
  55. *
  56. * The buffer must be the correct length for the encoded string.
  57. * Use something like
  58. *
  59. * char buf[carla_base64_encoded_len(len) + 1];
  60. *
  61. * (the +1 is for the terminating NUL) to provide a buffer of the correct size.
  62. */
  63. static inline
  64. void carla_base64_encode(const uint8_t* const raw, const size_t len, char* const encoded)
  65. {
  66. const uint8_t* rawBytes = raw;
  67. uint8_t* encodedBytes = (uint8_t*)encoded;
  68. size_t rawBitLen = 8*len;
  69. size_t bit, tmp;
  70. for (bit = 0; bit < rawBitLen; bit += 6)
  71. {
  72. tmp = static_cast<size_t>((rawBytes[bit/8] << (bit % 8)) | (rawBytes[bit/8 + 1] >> (8 - (bit % 8))));
  73. tmp = static_cast<size_t>((tmp >> 2) & 0x3f);
  74. CARLA_ASSERT(tmp < 64);
  75. *(encodedBytes++) = static_cast<uint8_t>(kBase64[tmp]);
  76. }
  77. for (; (bit % 8) != 0; bit += 6)
  78. *(encodedBytes++) = '=';
  79. *(encodedBytes++) = '\0';
  80. carla_debug("Base64-encoded to \"%s\"\n", encoded);
  81. CARLA_ASSERT(std::strlen(encoded) == carla_base64_encoded_len(len));
  82. }
  83. /**
  84. * Base64-decode string
  85. *
  86. * @v encoded Encoded string
  87. * @v raw Raw data
  88. * @ret len Length of raw data, or 0
  89. *
  90. * The buffer must be large enough to contain the decoded data.
  91. * Use something like
  92. *
  93. * char buf[carla_base64_decoded_max_len(encoded)];
  94. *
  95. * to provide a buffer of the correct size.
  96. */
  97. static inline
  98. unsigned int carla_base64_decode(const char* const encoded, uint8_t* const raw)
  99. {
  100. const uint8_t* encodedBytes = (const uint8_t*)encoded;
  101. uint8_t* rawBytes = raw;
  102. uint8_t encodedByte;
  103. unsigned int bit = 0;
  104. unsigned int padCount = 0;
  105. /* Zero the raw data */
  106. carla_zeroMem(raw, carla_base64_decoded_max_len(encoded));
  107. /* Decode string */
  108. while ((encodedByte = *(encodedBytes++)) > 0)
  109. {
  110. /* Ignore whitespace characters */
  111. if (std::isspace(encodedByte))
  112. continue;
  113. /* Process pad characters */
  114. if (encodedByte == '=')
  115. {
  116. if (padCount >= 2)
  117. {
  118. carla_debug("Base64-encoded string \"%s\" has too many pad characters", encoded);
  119. return 0;
  120. }
  121. padCount++;
  122. bit -= 2; /* unused_bits = ( 2 * padCount ) */
  123. continue;
  124. }
  125. if (padCount > 0)
  126. {
  127. carla_debug("Base64-encoded string \"%s\" has invalid pad sequence", encoded);
  128. return 0;
  129. }
  130. /* Process normal characters */
  131. const char* const match = std::strchr(kBase64, encodedByte);
  132. if (match == nullptr)
  133. {
  134. carla_debug("Base64-encoded string \"%s\" contains invalid character '%c'", encoded, encodedByte);
  135. return 0;
  136. }
  137. uint8_t decoded = static_cast<uint8_t>(match - kBase64);
  138. /* Add to raw data */
  139. decoded <<= 2;
  140. rawBytes[bit / 8] |= (decoded >> (bit % 8));
  141. rawBytes[bit / 8 + 1] |= (decoded << (8 - (bit % 8)));
  142. bit += 6;
  143. }
  144. /* Check that we decoded a whole number of bytes */
  145. if ((bit % 8) != 0)
  146. {
  147. carla_debug("Base64-encoded string \"%s\" has invalid bit length %d", encoded, bit);
  148. return 0;
  149. }
  150. unsigned int len = bit/8;
  151. carla_debug("Base64-decoded from \"%s\"", encoded);
  152. CARLA_ASSERT(len <= carla_base64_decoded_max_len(encoded));
  153. /* Return length in bytes */
  154. return len;
  155. }
  156. #endif // __CARLA_BASE64_UTILS_HPP__