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.

CarlaBase64Utils.hpp 5.1KB

11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 = (const uint8_t*)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. *(encodedBytes++) = static_cast<uint8_t>(kBase64[tmp]);
  75. }
  76. for (; (bit % 8) != 0; bit += 6)
  77. *(encodedBytes++) = '=';
  78. *(encodedBytes++) = '\0';
  79. carla_debug("Base64-encoded to \"%s\":\n", encoded);
  80. CARLA_ASSERT(std::strlen(encoded) == carla_base64_encoded_len(len));
  81. }
  82. /**
  83. * Base64-decode string
  84. *
  85. * @v encoded Encoded string
  86. * @v raw Raw data
  87. * @ret len Length of raw data, or 0
  88. *
  89. * The buffer must be large enough to contain the decoded data.
  90. * Use something like
  91. *
  92. * char buf[carla_base64_decoded_max_len(encoded)];
  93. *
  94. * to provide a buffer of the correct size.
  95. */
  96. static inline
  97. unsigned int carla_base64_decode(const char* const encoded, uint8_t* const raw)
  98. {
  99. const uint8_t* encodedBytes = (const uint8_t*)encoded;
  100. uint8_t* rawBytes = (uint8_t*)raw;
  101. uint8_t encodedByte;
  102. unsigned int bit = 0;
  103. unsigned int padCount = 0;
  104. /* Zero the raw data */
  105. std::memset(raw, 0, carla_base64_decoded_max_len(encoded));
  106. /* Decode string */
  107. while ((encodedByte = *(encodedBytes++)) > 0)
  108. {
  109. /* Ignore whitespace characters */
  110. if (std::isspace(encodedByte))
  111. continue;
  112. /* Process pad characters */
  113. if (encodedByte == '=')
  114. {
  115. if (padCount >= 2)
  116. {
  117. carla_debug("Base64-encoded string \"%s\" has too many pad characters", encoded);
  118. return 0;
  119. }
  120. padCount++;
  121. bit -= 2; /* unused_bits = ( 2 * padCount ) */
  122. continue;
  123. }
  124. if (padCount)
  125. {
  126. carla_debug("Base64-encoded string \"%s\" has invalid pad sequence", encoded);
  127. return 0;
  128. }
  129. /* Process normal characters */
  130. const char* match = std::strchr(kBase64, encodedByte);
  131. if (match == nullptr)
  132. {
  133. carla_debug("Base64-encoded string \"%s\" contains invalid character '%c'", encoded, encodedByte);
  134. return 0;
  135. }
  136. uint8_t decoded = static_cast<uint8_t>(match - kBase64);
  137. /* Add to raw data */
  138. decoded <<= 2;
  139. rawBytes[bit / 8] |= (decoded >> (bit % 8));
  140. rawBytes[bit / 8 + 1] |= (decoded << (8 - (bit % 8)));
  141. bit += 6;
  142. }
  143. /* Check that we decoded a whole number of bytes */
  144. if ((bit % 8) != 0)
  145. {
  146. carla_debug("Base64-encoded string \"%s\" has invalid bit length %d", encoded, bit);
  147. return 0;
  148. }
  149. unsigned int len = bit/8;
  150. carla_debug("Base64-decoded \"%s\" to: \"%s\"\n", encoded, raw);
  151. CARLA_ASSERT(len <= carla_base64_decoded_max_len(encoded));
  152. /* Return length in bytes */
  153. return len;
  154. }
  155. #endif // __CARLA_BASE64_UTILS_HPP__