ffi-hydrogen 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * \file modp_b64w.c
3
+ * <PRE>
4
+ * MODP_B64 - High performance base64 encoder/decoder
5
+ * https://github.com/client9/stringencoders
6
+ *
7
+ * Copyright &copy; 2005-2016 Nick Galbreath
8
+ * All rights reserved.
9
+ * Released under MIT license. See LICENSE for details.
10
+ * </PRE>
11
+ */
12
+
13
+ /*
14
+ * If you are ripping this out of the library, comment out the next
15
+ * line and uncomment the next lines as approrpiate
16
+ */
17
+ // #include "config.h"
18
+
19
+ /* public header */
20
+ #include "modp_b64w.h"
21
+
22
+ /* if on motorola, sun, ibm; uncomment this */
23
+ /* #define WORDS_BIGENDIAN 1 */
24
+ /* else for Intel, Amd; uncomment this */
25
+ /* #undef WORDS_BIGENDIAN */
26
+
27
+ #include "modp_b64w_data.h"
28
+
29
+ #define BADCHAR 0x01FFFFFF
30
+
31
+ /**
32
+ * you can control if we use padding by commenting out this
33
+ * next line. However, I highly recommend you use padding and not
34
+ * using it should only be for compatibility with a 3rd party.
35
+ * Also, 'no padding' is not tested!
36
+ */
37
+ #define DOPAD 1
38
+
39
+ /*
40
+ * if we aren't doing padding
41
+ * set the pad character to NULL
42
+ */
43
+ #ifndef DOPAD
44
+ #undef CHARPAD
45
+ #define CHARPAD '\0'
46
+ #endif
47
+
48
+ size_t modp_b64w_encode(char* dest, const char* str, size_t len)
49
+ {
50
+ size_t i = 0;
51
+ const uint8_t* s = (const uint8_t*)str;
52
+ uint8_t* p = (uint8_t*)dest;
53
+
54
+ /* unsigned here is important! */
55
+ /* uint8_t is fastest on G4, amd */
56
+ /* uint32_t is fastest on Intel */
57
+ uint32_t t1, t2, t3;
58
+
59
+ if (len > 2) {
60
+ for (i = 0; i < len - 2; i += 3) {
61
+ t1 = s[i];
62
+ t2 = s[i + 1];
63
+ t3 = s[i + 2];
64
+ *p++ = e0[t1];
65
+ *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
66
+ *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)];
67
+ *p++ = e2[t3];
68
+ }
69
+ }
70
+
71
+ switch (len - i) {
72
+ case 0:
73
+ break;
74
+ case 1:
75
+ t1 = s[i];
76
+ *p++ = e0[t1];
77
+ *p++ = e1[(t1 & 0x03) << 4];
78
+ *p++ = CHARPAD;
79
+ *p++ = CHARPAD;
80
+ break;
81
+ default: /* case 2 */
82
+ t1 = s[i];
83
+ t2 = s[i + 1];
84
+ *p++ = e0[t1];
85
+ *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)];
86
+ *p++ = e2[(t2 & 0x0F) << 2];
87
+ *p++ = CHARPAD;
88
+ }
89
+
90
+ *p = '\0';
91
+ return (size_t)(p - (uint8_t*)dest);
92
+ }
93
+
94
+ #ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */
95
+ size_t modp_b64w_decode(char* dest, const char* src, size_t len)
96
+ {
97
+ size_t i;
98
+ if (len == 0)
99
+ return 0;
100
+
101
+ #ifdef DOPAD
102
+ /* if padding is used, then the message must be at least
103
+ 4 chars and be a multiple of 4.
104
+ there can be at most 2 pad chars at the end */
105
+ if (len < 4 || (len % 4 != 0))
106
+ return -1;
107
+ if (src[len - 1] == CHARPAD) {
108
+ len--;
109
+ if (src[len - 1] == CHARPAD) {
110
+ len--;
111
+ }
112
+ }
113
+ #endif /* DOPAD */
114
+
115
+ size_t leftover = len % 4;
116
+ size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
117
+
118
+ uint8_t* p = (uint8_t*)dest;
119
+ uint32_t x = 0;
120
+ uint32_t* destInt = (uint32_t*)p;
121
+ uint32_t* srcInt = (uint32_t*)src;
122
+ uint32_t y = *srcInt++;
123
+ for (i = 0; i < chunks; ++i) {
124
+ x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff];
125
+
126
+ if (x >= BADCHAR)
127
+ return -1;
128
+ *destInt = x << 8;
129
+ p += 3;
130
+ destInt = (uint32_t*)p;
131
+ y = *srcInt++;
132
+ }
133
+
134
+ switch (leftover) {
135
+ case 0:
136
+ x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | d2[y >> 8 & 0xff] | d3[y & 0xff];
137
+ if (x >= BADCHAR)
138
+ return -1;
139
+ *p++ = ((uint8_t*)&x)[1];
140
+ *p++ = ((uint8_t*)&x)[2];
141
+ *p = ((uint8_t*)&x)[3];
142
+ return (chunks + 1) * 3;
143
+ #ifndef DOPAD
144
+ case 1: /* with padding this is an impossible case */
145
+ x = d3[y >> 24];
146
+ *p = (uint8_t)x;
147
+ break;
148
+ #endif
149
+ case 2:
150
+ x = d3[y >> 24] * 64 + d3[(y >> 16) & 0xff];
151
+ *p = (uint8_t)(x >> 4);
152
+ break;
153
+ default: /* case 3 */
154
+ x = (d3[y >> 24] * 64 + d3[(y >> 16) & 0xff]) * 64 + d3[(y >> 8) & 0xff];
155
+ *p++ = (uint8_t)(x >> 10);
156
+ *p = (uint8_t)(x >> 2);
157
+ break;
158
+ }
159
+
160
+ if (x >= BADCHAR)
161
+ return -1;
162
+ return 3 * chunks + (6 * leftover) / 8;
163
+ }
164
+
165
+ #else /* LITTLE ENDIAN -- INTEL AND FRIENDS */
166
+
167
+ size_t modp_b64w_decode(char* dest, const char* src, size_t len)
168
+ {
169
+ size_t i;
170
+ size_t leftover;
171
+ size_t chunks;
172
+
173
+ uint8_t* p;
174
+ uint32_t x;
175
+ uint32_t* destInt;
176
+ const uint32_t* srcInt = (const uint32_t*)src;
177
+ uint32_t y = *srcInt++;
178
+
179
+ if (len == 0)
180
+ return 0;
181
+
182
+ #ifdef DOPAD
183
+ /*
184
+ * if padding is used, then the message must be at least
185
+ * 4 chars and be a multiple of 4
186
+ */
187
+ if (len < 4 || (len % 4 != 0)) {
188
+ return (size_t)-1; /* error */
189
+ }
190
+ /* there can be at most 2 pad chars at the end */
191
+ if (src[len - 1] == CHARPAD) {
192
+ len--;
193
+ if (src[len - 1] == CHARPAD) {
194
+ len--;
195
+ }
196
+ }
197
+ #endif
198
+
199
+ leftover = len % 4;
200
+ chunks = (leftover == 0) ? len / 4 - 1 : len / 4;
201
+
202
+ p = (uint8_t*)dest;
203
+ x = 0;
204
+ destInt = (uint32_t*)p;
205
+ srcInt = (const uint32_t*)src;
206
+ y = *srcInt++;
207
+ for (i = 0; i < chunks; ++i) {
208
+ x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
209
+
210
+ if (x >= BADCHAR) {
211
+ return (size_t)-1;
212
+ }
213
+ *destInt = x;
214
+ p += 3;
215
+ destInt = (uint32_t*)p;
216
+ y = *srcInt++;
217
+ }
218
+
219
+ switch (leftover) {
220
+ case 0:
221
+ x = d0[y & 0xff] | d1[(y >> 8) & 0xff] | d2[(y >> 16) & 0xff] | d3[(y >> 24) & 0xff];
222
+
223
+ if (x >= BADCHAR) {
224
+ return (size_t)-1;
225
+ }
226
+ *p++ = ((uint8_t*)(&x))[0];
227
+ *p++ = ((uint8_t*)(&x))[1];
228
+ *p = ((uint8_t*)(&x))[2];
229
+ return (chunks + 1) * 3;
230
+ #ifndef DOPAD
231
+ case 1: /* with padding this is an impossible case */
232
+ x = d0[y & 0xff];
233
+ *p = *((uint8_t*)(&x)); /* i.e. first char/byte in int */
234
+ break;
235
+ #endif
236
+ case 2: /* case 2, 1 output byte */
237
+ x = d0[y & 0xff] | d1[y >> 8 & 0xff];
238
+ *p = *((uint8_t*)(&x)); /* i.e. first char */
239
+ break;
240
+ default: /* case 3, 2 output bytes */
241
+ x = d0[y & 0xff] | d1[y >> 8 & 0xff] | d2[y >> 16 & 0xff]; /* 0x3c */
242
+ *p++ = ((uint8_t*)(&x))[0];
243
+ *p = ((uint8_t*)(&x))[1];
244
+ break;
245
+ }
246
+
247
+ if (x >= BADCHAR) {
248
+ return (size_t)-1;
249
+ }
250
+
251
+ return 3 * chunks + (6 * leftover) / 8;
252
+ }
253
+
254
+ #endif /* if bigendian / else / endif */
@@ -0,0 +1,231 @@
1
+ /**
2
+ * <PRE>
3
+ * High performance WEB-SAFE base64 encoder / decoder
4
+ *
5
+ * Copyright &copy; 2005-2016 Nick Galbreath -- nickg [at] client9 [dot] com
6
+ * All rights reserved.
7
+ *
8
+ * https://github.com/client9/stringencoders/
9
+ *
10
+ * Released under MIT license. See LICENSE for details.
11
+ * </pre>
12
+ *
13
+ * This uses a "URL-safe" or "WEB-safe" encoding. The standard
14
+ * base 64 encoding uses the characters '+', '/' and '=' have special
15
+ * restrictions when used inside a URL.
16
+ *
17
+ * This uses "+" to "-", "/" to "_", and "=" to "." as the replacement
18
+ * alphabet.
19
+ *
20
+ * It's easy to change this to use "URL safe" characters and to remove
21
+ * padding. See the modp_b64.c source code for details.
22
+ *
23
+ */
24
+
25
+ #ifndef COM_MODP_STRINGENCODERS_B64W
26
+ #define COM_MODP_STRINGENCODERS_B64W
27
+
28
+ #include "extern_c_begin.h"
29
+ #include "modp_stdint.h"
30
+
31
+ /**
32
+ * \brief Encode a raw binary string into web-safe base 64.
33
+ * \param[out] dest should be allocated by the caller to contain
34
+ * at least modp_b64w_encode_len(len) bytes (see below)
35
+ * This will contain the null-terminated b64w encoded result
36
+ * \param[in] src contains the bytes
37
+ * \param[in] len contains the number of bytes in the src
38
+ * \return length of the destination string plus the ending null byte
39
+ * i.e. the result will be equal to strlen(dest) + 1
40
+ *
41
+ * Example
42
+ *
43
+ * \code
44
+ * char* src = ...;
45
+ * int srclen = ...; //the length of number of bytes in src
46
+ * char* dest = (char*) malloc(modp_b64w_encode_len);
47
+ * int len = modp_b64w_encode(dest, src, sourcelen);
48
+ * if (len == -1) {
49
+ * printf("Error\n");
50
+ * } else {
51
+ * printf("b64w = %s\n", dest);
52
+ * }
53
+ * \endcode
54
+ *
55
+ */
56
+ size_t modp_b64w_encode(char* dest, const char* src, size_t len);
57
+
58
+ /**
59
+ * \brief Decode a web-safe base64 encoded string
60
+ *
61
+ * \param[out] dest should be allocated by the caller to contain at least
62
+ * len * 3 / 4 bytes.
63
+ * \param[in] src should contain exactly len bytes of b64w characters.
64
+ * if src contains -any- non-base characters (such as white
65
+ * space, -1 is returned.
66
+ * \param[in] len is the length of src
67
+ *
68
+ * \return the length (strlen) of the output, or -1 if unable to
69
+ * decode
70
+ *
71
+ * \code
72
+ * char* src = ...;
73
+ * int srclen = ...; // or if you don't know use strlen(src)
74
+ * char* dest = (char*) malloc(modp_b64w_decode_len(srclen));
75
+ * int len = modp_b64w_decode(dest, src, sourcelen);
76
+ * if (len == -1) { error }
77
+ * \endcode
78
+ */
79
+ size_t modp_b64w_decode(char* dest, const char* src, size_t len);
80
+
81
+ /**
82
+ * Given a source string of length len, this returns the amount of
83
+ * memory the destination string should have.
84
+ *
85
+ * remember, this is integer math
86
+ * 3 bytes turn into 4 chars
87
+ * ceiling[len / 3] * 4 + 1
88
+ *
89
+ * +1 is for any extra null.
90
+ */
91
+ #define modp_b64w_encode_len(A) ((A + 2) / 3 * 4 + 1)
92
+
93
+ /**
94
+ * Given a base64 string of length len,
95
+ * this returns the amount of memory required for output string
96
+ * It maybe be more than the actual number of bytes written.
97
+ * NOTE: remember this is integer math
98
+ * this allocates a bit more memory than traditional versions of b64w
99
+ * decode 4 chars turn into 3 bytes
100
+ * floor[len * 3/4] + 2
101
+ */
102
+ #define modp_b64w_decode_len(A) (A / 4 * 3 + 2)
103
+
104
+ /**
105
+ * Will return the strlen of the output from encoding.
106
+ * This may be less than the required number of bytes allocated.
107
+ *
108
+ * This allows you to 'deserialized' a struct:
109
+ * \code
110
+ * char* b64wencoded = "...";
111
+ * int len = strlen(b64wencoded);
112
+ *
113
+ * struct datastuff foo;
114
+ * if (modp_b64w_encode_strlen(sizeof(struct datastuff)) != len) {
115
+ * // wrong size
116
+ * return false;
117
+ * } else {
118
+ * // safe to do;
119
+ * if (modp_b64w_decode((char*) &foo, b64wencoded, len) == -1) {
120
+ * // bad characters
121
+ * return false;
122
+ * }
123
+ * }
124
+ * // foo is filled out now
125
+ * \endcode
126
+ */
127
+ #define modp_b64w_encode_strlen(A) ((A + 2) / 3 * 4)
128
+
129
+ #include "extern_c_end.h"
130
+
131
+ #ifdef __cplusplus
132
+ #include <cstring>
133
+ #include <string>
134
+
135
+ namespace modp {
136
+
137
+ /** \brief b64w encode a cstr with len
138
+ *
139
+ * \param[in] s the input string to encode
140
+ * \param[in] len the length of the input string
141
+ * \return a newly allocated b64w string. Empty if failed.
142
+ */
143
+ inline std::string b64w_encode(const char* s, size_t len)
144
+ {
145
+ std::string x(modp_b64w_encode_len(len), '\0');
146
+ size_t d = modp_b64w_encode(const_cast<char*>(x.data()), s, len);
147
+ if (d == (size_t)-1) {
148
+ x.clear();
149
+ } else {
150
+ x.erase(d, std::string::npos);
151
+ }
152
+ return x;
153
+ }
154
+
155
+ /** \brief b64w encode a cstr
156
+ *
157
+ * \param[in] s the input string to encode
158
+ * \return a newly allocated b64w string. Empty if failed.
159
+ */
160
+ inline std::string b64w_encode(const char* s)
161
+ {
162
+ return b64w_encode(s, strlen(s));
163
+ }
164
+
165
+ /** \brief b64w encode a const std::string
166
+ *
167
+ * \param[in] s the input string to encode
168
+ * \return a newly allocated b64w string. Empty if failed.
169
+ */
170
+ inline std::string b64w_encode(const std::string& s)
171
+ {
172
+ return b64w_encode(s.data(), s.size());
173
+ }
174
+
175
+ /** \brief self-modifing b64w encode
176
+ *
177
+ * web-safe base 64 decode a string (self-modifing)
178
+ * On failure, the string is empty.
179
+ *
180
+ * \param[in,out] s the string to be decoded
181
+ * \return a reference to the input string
182
+ */
183
+ inline std::string& b64w_encode(std::string& s)
184
+ {
185
+ std::string x(b64w_encode(s.data(), s.size()));
186
+ s.swap(x);
187
+ return s;
188
+ }
189
+
190
+ inline std::string b64w_decode(const char* src, size_t len)
191
+ {
192
+ std::string x(modp_b64w_decode_len(len) + 1, '\0');
193
+ size_t d = modp_b64w_decode(const_cast<char*>(x.data()), src, len);
194
+ if (d == (size_t)-1) {
195
+ x.clear();
196
+ } else {
197
+ x.erase(d, std::string::npos);
198
+ }
199
+ return x;
200
+ }
201
+
202
+ inline std::string b64w_decode(const char* src)
203
+ {
204
+ return b64w_decode(src, strlen(src));
205
+ }
206
+
207
+ /**
208
+ * base 64 decode a string (self-modifing)
209
+ * On failure, the string is empty.
210
+ *
211
+ * This function is for C++ only (duh)
212
+ *
213
+ * \param[in,out] s the string to be decoded
214
+ * \return a reference to the input string
215
+ */
216
+ inline std::string& b64w_decode(std::string& s)
217
+ {
218
+ std::string x(b64w_decode(s.data(), s.size()));
219
+ s.swap(x);
220
+ return s;
221
+ }
222
+
223
+ inline std::string b64w_decode(const std::string& s)
224
+ {
225
+ return b64w_decode(s.data(), s.size());
226
+ }
227
+ }
228
+
229
+ #endif /* __cplusplus */
230
+
231
+ #endif /* MODP_B64W */