lib.c 3.5 KB

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