lib.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <stdint.h>
  2. #include <stddef.h>
  3. #include "libbase64.h"
  4. #include "codecs.h"
  5. const uint8_t
  6. neon32_base64_table_enc[] =
  7. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  8. "abcdefghijklmnopqrstuvwxyz"
  9. "0123456789+/";
  10. // In the lookup table below, note that the value for '=' (character 61) is
  11. // 254, not 255. This character is used for in-band signaling of the end of
  12. // the datastream, and we will use that later. The characters A-Z, a-z, 0-9
  13. // and + / are mapped to their "decoded" values. The other bytes all map to
  14. // the value 255, which flags them as "invalid input".
  15. const uint8_t
  16. neon32_base64_table_dec[] =
  17. {
  18. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0..15
  19. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 16..31
  20. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 254, 62, 255, 63, // 32..47
  21. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, // 48..63
  22. 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64..79
  23. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, // 80..95
  24. 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96..111
  25. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, // 112..127
  26. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 128..143
  27. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  28. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  29. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  30. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  31. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  32. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  33. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
  34. };
  35. void
  36. neon32_base64_stream_encode_init (struct neon32_base64_state *state)
  37. {
  38. state->eof = 0;
  39. state->bytes = 0;
  40. state->carry = 0;
  41. }
  42. void
  43. neon32_base64_stream_encode_final
  44. ( struct neon32_base64_state *state
  45. , char *out
  46. , size_t *outlen
  47. )
  48. {
  49. uint8_t *o = (uint8_t *)out;
  50. if (state->bytes == 1) {
  51. *o++ = neon32_base64_table_enc[state->carry];
  52. *o++ = '=';
  53. *o++ = '=';
  54. *outlen = 3;
  55. return;
  56. }
  57. if (state->bytes == 2) {
  58. *o++ = neon32_base64_table_enc[state->carry];
  59. *o++ = '=';
  60. *outlen = 2;
  61. return;
  62. }
  63. *outlen = 0;
  64. }
  65. void
  66. neon32_base64_stream_decode_init (struct neon32_base64_state *state)
  67. {
  68. state->eof = 0;
  69. state->bytes = 0;
  70. state->carry = 0;
  71. }
  72. void
  73. neon32_base64_encode
  74. ( const char *src
  75. , size_t srclen
  76. , char *out
  77. , size_t *outlen
  78. )
  79. {
  80. size_t s;
  81. size_t t;
  82. struct neon32_base64_state state;
  83. // Init the stream reader:
  84. neon32_base64_stream_encode_init(&state);
  85. // Feed the whole string to the stream reader:
  86. neon32_base64_stream_encode(&state, src, srclen, out, &s);
  87. // Finalize the stream by writing trailer if any:
  88. neon32_base64_stream_encode_final(&state, out + s, &t);
  89. // Final output length is stream length plus tail:
  90. *outlen = s + t;
  91. }
  92. int
  93. neon32_base64_decode
  94. ( const char *src
  95. , size_t srclen
  96. , char *out
  97. , size_t *outlen
  98. )
  99. {
  100. struct neon32_base64_state state;
  101. // Init the stream reader:
  102. neon32_base64_stream_decode_init(&state);
  103. // Feed the whole string to the stream reader:
  104. return neon32_base64_stream_decode(&state, src, srclen, out, outlen);
  105. }