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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/Rakefile +46 -0
- data/bench/both.rb +86 -0
- data/bench/encode.rb +57 -0
- data/bench/encrypt.rb +80 -0
- data/bench/init.rb +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ffi-hydrogen.gemspec +31 -0
- data/lib/ffi/hydrogen.rb +216 -0
- data/vendor/.clang-format +2 -0
- data/vendor/.gitignore +3 -0
- data/vendor/README.md +2 -0
- data/vendor/libhydrogen/.clang-format +95 -0
- data/vendor/libhydrogen/.gitignore +32 -0
- data/vendor/libhydrogen/.travis.yml +22 -0
- data/vendor/libhydrogen/LICENSE +18 -0
- data/vendor/libhydrogen/Makefile +61 -0
- data/vendor/libhydrogen/Makefile.arduino +51 -0
- data/vendor/libhydrogen/README.md +29 -0
- data/vendor/libhydrogen/hydrogen.c +18 -0
- data/vendor/libhydrogen/hydrogen.h +317 -0
- data/vendor/libhydrogen/impl/common.h +316 -0
- data/vendor/libhydrogen/impl/core.h +220 -0
- data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
- data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
- data/vendor/libhydrogen/impl/gimli-core.h +25 -0
- data/vendor/libhydrogen/impl/hash.h +138 -0
- data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
- data/vendor/libhydrogen/impl/kdf.h +20 -0
- data/vendor/libhydrogen/impl/kx.h +441 -0
- data/vendor/libhydrogen/impl/pwhash.h +281 -0
- data/vendor/libhydrogen/impl/random.h +376 -0
- data/vendor/libhydrogen/impl/secretbox.h +236 -0
- data/vendor/libhydrogen/impl/sign.h +207 -0
- data/vendor/libhydrogen/impl/x25519.h +383 -0
- data/vendor/libhydrogen/library.properties +10 -0
- data/vendor/libhydrogen/logo.png +0 -0
- data/vendor/libhydrogen/tests/tests.c +431 -0
- data/vendor/main.c +140 -0
- data/vendor/stringencoders/.gitignore +25 -0
- data/vendor/stringencoders/.travis.yml +13 -0
- data/vendor/stringencoders/AUTHORS +1 -0
- data/vendor/stringencoders/COPYING +2 -0
- data/vendor/stringencoders/ChangeLog +170 -0
- data/vendor/stringencoders/Doxyfile +276 -0
- data/vendor/stringencoders/INSTALL +119 -0
- data/vendor/stringencoders/LICENSE +22 -0
- data/vendor/stringencoders/Makefile.am +3 -0
- data/vendor/stringencoders/NEWS +3 -0
- data/vendor/stringencoders/README +2 -0
- data/vendor/stringencoders/README.md +32 -0
- data/vendor/stringencoders/bootstrap.sh +3 -0
- data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
- data/vendor/stringencoders/configure.ac +44 -0
- data/vendor/stringencoders/doxy/footer.html +34 -0
- data/vendor/stringencoders/doxy/header.html +85 -0
- data/vendor/stringencoders/indent.sh +9 -0
- data/vendor/stringencoders/javascript/base64-speed.html +43 -0
- data/vendor/stringencoders/javascript/base64-test.html +209 -0
- data/vendor/stringencoders/javascript/base64.html +18 -0
- data/vendor/stringencoders/javascript/base64.js +176 -0
- data/vendor/stringencoders/javascript/qunit.css +119 -0
- data/vendor/stringencoders/javascript/qunit.js +1062 -0
- data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
- data/vendor/stringencoders/javascript/urlparse.js +328 -0
- data/vendor/stringencoders/make-ci.sh +13 -0
- data/vendor/stringencoders/makerelease.sh +16 -0
- data/vendor/stringencoders/python/b85.py +176 -0
- data/vendor/stringencoders/src/Makefile.am +134 -0
- data/vendor/stringencoders/src/arraytoc.c +85 -0
- data/vendor/stringencoders/src/arraytoc.h +43 -0
- data/vendor/stringencoders/src/extern_c_begin.h +3 -0
- data/vendor/stringencoders/src/extern_c_end.h +3 -0
- data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
- data/vendor/stringencoders/src/modp_ascii.c +159 -0
- data/vendor/stringencoders/src/modp_ascii.h +162 -0
- data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
- data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
- data/vendor/stringencoders/src/modp_b16.c +125 -0
- data/vendor/stringencoders/src/modp_b16.h +148 -0
- data/vendor/stringencoders/src/modp_b16_data.h +104 -0
- data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
- data/vendor/stringencoders/src/modp_b2.c +69 -0
- data/vendor/stringencoders/src/modp_b2.h +130 -0
- data/vendor/stringencoders/src/modp_b2_data.h +44 -0
- data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
- data/vendor/stringencoders/src/modp_b36.c +108 -0
- data/vendor/stringencoders/src/modp_b36.h +170 -0
- data/vendor/stringencoders/src/modp_b64.c +254 -0
- data/vendor/stringencoders/src/modp_b64.h +236 -0
- data/vendor/stringencoders/src/modp_b64_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
- data/vendor/stringencoders/src/modp_b64r.c +254 -0
- data/vendor/stringencoders/src/modp_b64r.h +242 -0
- data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
- data/vendor/stringencoders/src/modp_b64w.c +254 -0
- data/vendor/stringencoders/src/modp_b64w.h +231 -0
- data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
- data/vendor/stringencoders/src/modp_b85.c +109 -0
- data/vendor/stringencoders/src/modp_b85.h +171 -0
- data/vendor/stringencoders/src/modp_b85_data.h +36 -0
- data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
- data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
- data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
- data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
- data/vendor/stringencoders/src/modp_burl.c +228 -0
- data/vendor/stringencoders/src/modp_burl.h +259 -0
- data/vendor/stringencoders/src/modp_burl_data.h +136 -0
- data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
- data/vendor/stringencoders/src/modp_html.c +128 -0
- data/vendor/stringencoders/src/modp_html.h +53 -0
- data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
- data/vendor/stringencoders/src/modp_json.c +315 -0
- data/vendor/stringencoders/src/modp_json.h +103 -0
- data/vendor/stringencoders/src/modp_json_data.h +57 -0
- data/vendor/stringencoders/src/modp_json_gen.py +60 -0
- data/vendor/stringencoders/src/modp_mainpage.h +120 -0
- data/vendor/stringencoders/src/modp_numtoa.c +350 -0
- data/vendor/stringencoders/src/modp_numtoa.h +100 -0
- data/vendor/stringencoders/src/modp_qsiter.c +76 -0
- data/vendor/stringencoders/src/modp_qsiter.h +71 -0
- data/vendor/stringencoders/src/modp_stdint.h +43 -0
- data/vendor/stringencoders/src/modp_utf8.c +88 -0
- data/vendor/stringencoders/src/modp_utf8.h +38 -0
- data/vendor/stringencoders/src/modp_xml.c +311 -0
- data/vendor/stringencoders/src/modp_xml.h +166 -0
- data/vendor/stringencoders/src/stringencoders.pc +10 -0
- data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
- data/vendor/stringencoders/test/Makefile.am +113 -0
- data/vendor/stringencoders/test/apr_base64.c +262 -0
- data/vendor/stringencoders/test/apr_base64.h +120 -0
- data/vendor/stringencoders/test/cxx_test.cc +482 -0
- data/vendor/stringencoders/test/minunit.h +82 -0
- data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
- data/vendor/stringencoders/test/modp_b16_test.c +288 -0
- data/vendor/stringencoders/test/modp_b2_test.c +250 -0
- data/vendor/stringencoders/test/modp_b64_test.c +266 -0
- data/vendor/stringencoders/test/modp_b85_test.c +130 -0
- data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
- data/vendor/stringencoders/test/modp_burl_test.c +423 -0
- data/vendor/stringencoders/test/modp_html_test.c +296 -0
- data/vendor/stringencoders/test/modp_json_test.c +336 -0
- data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
- data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
- data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
- data/vendor/stringencoders/test/modp_xml_test.c +339 -0
- data/vendor/stringencoders/test/speedtest.c +241 -0
- data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
- data/vendor/stringencoders/test/speedtest_msg.c +78 -0
- data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
- metadata +314 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#include "modp_numtoa.h"
|
|
2
|
+
|
|
3
|
+
#include <math.h>
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
|
|
6
|
+
#include "modp_stdint.h"
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* other interesting references on num to string convesion
|
|
10
|
+
* http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
|
|
11
|
+
* and http://www.ddj.com/dept/cpp/184401596?pgno=6
|
|
12
|
+
*
|
|
13
|
+
* Version 19-Nov-2007
|
|
14
|
+
* Fixed round-to-even rules to match printf
|
|
15
|
+
* thanks to Johannes Otepka
|
|
16
|
+
* Version 22-Sep-2016
|
|
17
|
+
* Fixed rounding error with decimals ending in 5 and low precision
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Powers of 10
|
|
22
|
+
* 10^0 to 10^9
|
|
23
|
+
*/
|
|
24
|
+
static const double powers_of_10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
|
|
25
|
+
10000000, 100000000, 1000000000 };
|
|
26
|
+
|
|
27
|
+
static void strreverse(char* begin, char* end)
|
|
28
|
+
{
|
|
29
|
+
char aux;
|
|
30
|
+
while (end > begin)
|
|
31
|
+
aux = *end, *end-- = *begin, *begin++ = aux;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
size_t modp_itoa10(int32_t value, char* str)
|
|
35
|
+
{
|
|
36
|
+
char* wstr = str;
|
|
37
|
+
/* Take care of sign */
|
|
38
|
+
uint32_t uvalue = (value < 0) ? (uint32_t)(-value) : (uint32_t)(value);
|
|
39
|
+
/* Conversion. Number is reversed. */
|
|
40
|
+
do
|
|
41
|
+
*wstr++ = (char)(48 + (uvalue % 10));
|
|
42
|
+
while (uvalue /= 10);
|
|
43
|
+
if (value < 0)
|
|
44
|
+
*wstr++ = '-';
|
|
45
|
+
*wstr = '\0';
|
|
46
|
+
|
|
47
|
+
/* Reverse string */
|
|
48
|
+
strreverse(str, wstr - 1);
|
|
49
|
+
return (size_t)(wstr - str);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
size_t modp_uitoa10(uint32_t value, char* str)
|
|
53
|
+
{
|
|
54
|
+
char* wstr = str;
|
|
55
|
+
/* Conversion. Number is reversed. */
|
|
56
|
+
do
|
|
57
|
+
*wstr++ = (char)(48 + (value % 10));
|
|
58
|
+
while (value /= 10);
|
|
59
|
+
*wstr = '\0';
|
|
60
|
+
/* Reverse string */
|
|
61
|
+
strreverse(str, wstr - 1);
|
|
62
|
+
return (size_t)(wstr - str);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
size_t modp_litoa10(int64_t value, char* str)
|
|
66
|
+
{
|
|
67
|
+
char* wstr = str;
|
|
68
|
+
uint64_t uvalue = (value < 0) ? (uint64_t)(-value) : (uint64_t)(value);
|
|
69
|
+
|
|
70
|
+
/* Conversion. Number is reversed. */
|
|
71
|
+
do
|
|
72
|
+
*wstr++ = (char)(48 + (uvalue % 10));
|
|
73
|
+
while (uvalue /= 10);
|
|
74
|
+
if (value < 0)
|
|
75
|
+
*wstr++ = '-';
|
|
76
|
+
*wstr = '\0';
|
|
77
|
+
|
|
78
|
+
/* Reverse string */
|
|
79
|
+
strreverse(str, wstr - 1);
|
|
80
|
+
return (size_t)(wstr - str);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
size_t modp_ulitoa10(uint64_t value, char* str)
|
|
84
|
+
{
|
|
85
|
+
char* wstr = str;
|
|
86
|
+
/* Conversion. Number is reversed. */
|
|
87
|
+
do
|
|
88
|
+
*wstr++ = (char)(48 + (value % 10));
|
|
89
|
+
while (value /= 10);
|
|
90
|
+
*wstr = '\0';
|
|
91
|
+
/* Reverse string */
|
|
92
|
+
strreverse(str, wstr - 1);
|
|
93
|
+
return (size_t)(wstr - str);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
size_t modp_dtoa(double value, char* str, int prec)
|
|
97
|
+
{
|
|
98
|
+
/* Hacky test for NaN
|
|
99
|
+
* under -fast-math this won't work, but then you also won't
|
|
100
|
+
* have correct nan values anyways. The alternative is
|
|
101
|
+
* to link with libmath (bad) or hack IEEE double bits (bad)
|
|
102
|
+
*/
|
|
103
|
+
if (!(value == value)) {
|
|
104
|
+
str[0] = 'n';
|
|
105
|
+
str[1] = 'a';
|
|
106
|
+
str[2] = 'n';
|
|
107
|
+
str[3] = '\0';
|
|
108
|
+
return (size_t)3;
|
|
109
|
+
}
|
|
110
|
+
/* if input is larger than thres_max, revert to exponential */
|
|
111
|
+
const double thres_max = (double)(0x7FFFFFFF);
|
|
112
|
+
|
|
113
|
+
double diff = 0.0;
|
|
114
|
+
char* wstr = str;
|
|
115
|
+
|
|
116
|
+
if (prec < 0) {
|
|
117
|
+
prec = 0;
|
|
118
|
+
} else if (prec > 9) {
|
|
119
|
+
/* precision of >= 10 can lead to overflow errors */
|
|
120
|
+
prec = 9;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* we'll work in positive values and deal with the
|
|
124
|
+
negative sign issue later */
|
|
125
|
+
int neg = 0;
|
|
126
|
+
if (value < 0) {
|
|
127
|
+
neg = 1;
|
|
128
|
+
value = -value;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// given 0.05, prec=1
|
|
132
|
+
// whole = 0
|
|
133
|
+
// tmp = (0.05)* 10 = 0.5
|
|
134
|
+
// frac = 0
|
|
135
|
+
// diff = tmp -frac == 0.5 - 0.0 = 0.5
|
|
136
|
+
//
|
|
137
|
+
int whole = (int)value;
|
|
138
|
+
double tmp = (value - whole) * powers_of_10[prec];
|
|
139
|
+
uint32_t frac = (uint32_t)(tmp);
|
|
140
|
+
diff = tmp - frac;
|
|
141
|
+
|
|
142
|
+
if (diff > 0.5) {
|
|
143
|
+
++frac;
|
|
144
|
+
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
|
|
145
|
+
if (frac >= powers_of_10[prec]) {
|
|
146
|
+
frac = 0;
|
|
147
|
+
++whole;
|
|
148
|
+
}
|
|
149
|
+
} else if (diff == 0.5 && prec > 0 && (frac & 1)) {
|
|
150
|
+
/* if halfway, round up if odd, OR
|
|
151
|
+
if last digit is 0. That last part is strange */
|
|
152
|
+
++frac;
|
|
153
|
+
if (frac >= powers_of_10[prec]) {
|
|
154
|
+
frac = 0;
|
|
155
|
+
++whole;
|
|
156
|
+
}
|
|
157
|
+
} else if (diff == 0.5 && prec == 0 && (whole & 1)) {
|
|
158
|
+
++frac;
|
|
159
|
+
if (frac >= powers_of_10[prec]) {
|
|
160
|
+
frac = 0;
|
|
161
|
+
++whole;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* for very large numbers switch back to native sprintf for exponentials.
|
|
166
|
+
anyone want to write code to replace this? */
|
|
167
|
+
/*
|
|
168
|
+
normal printf behavior is to print EVERY whole number digit
|
|
169
|
+
which can be 100s of characters overflowing your buffers == bad
|
|
170
|
+
*/
|
|
171
|
+
if (value > thres_max) {
|
|
172
|
+
sprintf(str, "%e", neg ? -value : value);
|
|
173
|
+
return strlen(str);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
int count = prec;
|
|
177
|
+
while (count > 0) {
|
|
178
|
+
--count;
|
|
179
|
+
*wstr++ = (char)(48 + (frac % 10));
|
|
180
|
+
frac /= 10;
|
|
181
|
+
}
|
|
182
|
+
if (frac > 0) {
|
|
183
|
+
++whole;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* add decimal */
|
|
187
|
+
if (prec > 0) {
|
|
188
|
+
*wstr++ = '.';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* do whole part
|
|
192
|
+
* Take care of sign conversion
|
|
193
|
+
* Number is reversed.
|
|
194
|
+
*/
|
|
195
|
+
do
|
|
196
|
+
*wstr++ = (char)(48 + (whole % 10));
|
|
197
|
+
while (whole /= 10);
|
|
198
|
+
if (neg) {
|
|
199
|
+
*wstr++ = '-';
|
|
200
|
+
}
|
|
201
|
+
*wstr = '\0';
|
|
202
|
+
strreverse(str, wstr - 1);
|
|
203
|
+
return (size_t)(wstr - str);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* This is near identical to modp_dtoa above
|
|
207
|
+
* The differnce is noted below
|
|
208
|
+
*/
|
|
209
|
+
size_t modp_dtoa2(double value, char* str, int prec)
|
|
210
|
+
{
|
|
211
|
+
/* Hacky test for NaN
|
|
212
|
+
* under -fast-math this won't work, but then you also won't
|
|
213
|
+
* have correct nan values anyways. The alternative is
|
|
214
|
+
* to link with libmath (bad) or hack IEEE double bits (bad)
|
|
215
|
+
*/
|
|
216
|
+
if (!(value == value)) {
|
|
217
|
+
str[0] = 'n';
|
|
218
|
+
str[1] = 'a';
|
|
219
|
+
str[2] = 'n';
|
|
220
|
+
str[3] = '\0';
|
|
221
|
+
return (size_t)3;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* if input is larger than thres_max, revert to exponential */
|
|
225
|
+
const double thres_max = (double)(0x7FFFFFFF);
|
|
226
|
+
|
|
227
|
+
double diff = 0.0;
|
|
228
|
+
char* wstr = str;
|
|
229
|
+
|
|
230
|
+
if (prec < 0) {
|
|
231
|
+
prec = 0;
|
|
232
|
+
} else if (prec > 9) {
|
|
233
|
+
/* precision of >= 10 can lead to overflow errors */
|
|
234
|
+
prec = 9;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* we'll work in positive values and deal with the
|
|
238
|
+
negative sign issue later */
|
|
239
|
+
int neg = 0;
|
|
240
|
+
if (value < 0) {
|
|
241
|
+
neg = 1;
|
|
242
|
+
value = -value;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
int whole = (int)value;
|
|
246
|
+
double tmp = (value - whole) * powers_of_10[prec];
|
|
247
|
+
uint32_t frac = (uint32_t)(tmp);
|
|
248
|
+
diff = tmp - frac;
|
|
249
|
+
|
|
250
|
+
if (diff > 0.5) {
|
|
251
|
+
++frac;
|
|
252
|
+
/* handle rollover, e.g. case 0.99 with prec 1 is 1.0 */
|
|
253
|
+
if (frac >= powers_of_10[prec]) {
|
|
254
|
+
frac = 0;
|
|
255
|
+
++whole;
|
|
256
|
+
}
|
|
257
|
+
} else if (diff == 0.5 && prec > 0 && (frac & 1)) {
|
|
258
|
+
/* if halfway, round up if odd, OR
|
|
259
|
+
if last digit is 0. That last part is strange */
|
|
260
|
+
++frac;
|
|
261
|
+
if (frac >= powers_of_10[prec]) {
|
|
262
|
+
frac = 0;
|
|
263
|
+
++whole;
|
|
264
|
+
}
|
|
265
|
+
} else if (diff == 0.5 && prec == 0 && (whole & 1)) {
|
|
266
|
+
++frac;
|
|
267
|
+
if (frac >= powers_of_10[prec]) {
|
|
268
|
+
frac = 0;
|
|
269
|
+
++whole;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* for very large numbers switch back to native sprintf for exponentials.
|
|
274
|
+
anyone want to write code to replace this? */
|
|
275
|
+
/*
|
|
276
|
+
normal printf behavior is to print EVERY whole number digit
|
|
277
|
+
which can be 100s of characters overflowing your buffers == bad
|
|
278
|
+
*/
|
|
279
|
+
if (value > thres_max) {
|
|
280
|
+
sprintf(str, "%e", neg ? -value : value);
|
|
281
|
+
return strlen(str);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
int has_decimal = 0;
|
|
285
|
+
int count = prec;
|
|
286
|
+
|
|
287
|
+
/* Remove ending zeros */
|
|
288
|
+
if (prec > 0) {
|
|
289
|
+
while (count > 0 && ((frac % 10) == 0)) {
|
|
290
|
+
count--;
|
|
291
|
+
frac /= 10;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
while (count > 0) {
|
|
296
|
+
--count;
|
|
297
|
+
*wstr++ = (char)(48 + (frac % 10));
|
|
298
|
+
frac /= 10;
|
|
299
|
+
has_decimal = 1;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (frac > 0) {
|
|
303
|
+
++whole;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* add decimal */
|
|
307
|
+
if (has_decimal) {
|
|
308
|
+
*wstr++ = '.';
|
|
309
|
+
}
|
|
310
|
+
/* do whole part
|
|
311
|
+
* Take care of sign conversion
|
|
312
|
+
* Number is reversed.
|
|
313
|
+
*/
|
|
314
|
+
do
|
|
315
|
+
*wstr++ = (char)(48 + (whole % 10));
|
|
316
|
+
while (whole /= 10);
|
|
317
|
+
if (neg) {
|
|
318
|
+
*wstr++ = '-';
|
|
319
|
+
}
|
|
320
|
+
*wstr = '\0';
|
|
321
|
+
strreverse(str, wstr - 1);
|
|
322
|
+
return (size_t)(wstr - str);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
char* modp_uitoa16(uint32_t value, char* str, int isfinal)
|
|
326
|
+
{
|
|
327
|
+
static const char* hexchars = "0123456789ABCDEF";
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Implementation note:
|
|
331
|
+
* No re-assignment of "value"
|
|
332
|
+
* Each line is independent than the previous, so
|
|
333
|
+
* even dumb compilers can pipeline without loop unrolling
|
|
334
|
+
*/
|
|
335
|
+
str[0] = hexchars[(value >> 28) & 0x0000000F];
|
|
336
|
+
str[1] = hexchars[(value >> 24) & 0x0000000F];
|
|
337
|
+
str[2] = hexchars[(value >> 20) & 0x0000000F];
|
|
338
|
+
str[3] = hexchars[(value >> 16) & 0x0000000F];
|
|
339
|
+
str[4] = hexchars[(value >> 12) & 0x0000000F];
|
|
340
|
+
str[5] = hexchars[(value >> 8) & 0x0000000F];
|
|
341
|
+
str[6] = hexchars[(value >> 4) & 0x0000000F];
|
|
342
|
+
str[7] = hexchars[(value)&0x0000000F];
|
|
343
|
+
|
|
344
|
+
if (isfinal) {
|
|
345
|
+
str[8] = '\0';
|
|
346
|
+
return str;
|
|
347
|
+
} else {
|
|
348
|
+
return str + 8;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* \file modp_numtoa.h
|
|
3
|
+
* \brief Fast integer and floating-point numbers to string conversion
|
|
4
|
+
*
|
|
5
|
+
* This defines signed/unsigned integer, and 'double' to char buffer
|
|
6
|
+
* converters. The standard way of doing this is with "sprintf", however
|
|
7
|
+
* these functions are
|
|
8
|
+
* * guaranteed maximum size output
|
|
9
|
+
* * 5-20x faster!
|
|
10
|
+
* * Won't core-dump
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* <pre>
|
|
16
|
+
* Copyright © 2007, Nick Galbreath -- nickg [at] client9 [dot] com
|
|
17
|
+
* All rights reserved.
|
|
18
|
+
* https://github.com/client9/stringencoders/
|
|
19
|
+
* Released under the MIT license. See LICENSE for details.
|
|
20
|
+
* </pre>
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#ifndef COM_MODP_STRINGENCODERS_NUMTOA_H
|
|
25
|
+
#define COM_MODP_STRINGENCODERS_NUMTOA_H
|
|
26
|
+
|
|
27
|
+
#include "extern_c_begin.h"
|
|
28
|
+
|
|
29
|
+
#include "modp_stdint.h"
|
|
30
|
+
|
|
31
|
+
/** \brief convert an signed integer to char buffer
|
|
32
|
+
*
|
|
33
|
+
* \param[in] value
|
|
34
|
+
* \param[out] buf the output buffer. Should be 16 chars or more.
|
|
35
|
+
*/
|
|
36
|
+
size_t modp_itoa10(int32_t value, char* buf);
|
|
37
|
+
|
|
38
|
+
/** \brief convert an unsigned integer to char buffer
|
|
39
|
+
*
|
|
40
|
+
* \param[in] value
|
|
41
|
+
* \param[out] buf The output buffer, should be 16 chars or more.
|
|
42
|
+
*/
|
|
43
|
+
size_t modp_uitoa10(uint32_t value, char* buf);
|
|
44
|
+
|
|
45
|
+
/** \brief convert an signed long integer to char buffer
|
|
46
|
+
*
|
|
47
|
+
* \param[in] value
|
|
48
|
+
* \param[out] buf the output buffer. Should be 24 chars or more.
|
|
49
|
+
*/
|
|
50
|
+
size_t modp_litoa10(int64_t value, char* buf);
|
|
51
|
+
|
|
52
|
+
/** \brief convert an unsigned long integer to char buffer
|
|
53
|
+
*
|
|
54
|
+
* \param[in] value
|
|
55
|
+
* \param[out] buf The output buffer, should be 24 chars or more.
|
|
56
|
+
*/
|
|
57
|
+
size_t modp_ulitoa10(uint64_t value, char* buf);
|
|
58
|
+
|
|
59
|
+
/** \brief convert a floating point number to char buffer with
|
|
60
|
+
* fixed-precision format
|
|
61
|
+
*
|
|
62
|
+
* This is similar to "%.[0-9]f" in the printf style. It will include
|
|
63
|
+
* trailing zeros
|
|
64
|
+
*
|
|
65
|
+
* If the input value is greater than 1<<31, then the output format
|
|
66
|
+
* will be switched exponential format.
|
|
67
|
+
*
|
|
68
|
+
* \param[in] value
|
|
69
|
+
* \param[out] buf The allocated output buffer. Should be 32 chars or more.
|
|
70
|
+
* \param[in] precision Number of digits to the right of the decimal point.
|
|
71
|
+
* Can only be 0-9.
|
|
72
|
+
*/
|
|
73
|
+
size_t modp_dtoa(double value, char* buf, int precision);
|
|
74
|
+
|
|
75
|
+
/** \brief convert a floating point number to char buffer with a
|
|
76
|
+
* variable-precision format, and no trailing zeros
|
|
77
|
+
*
|
|
78
|
+
* This is similar to "%.[0-9]f" in the printf style, except it will
|
|
79
|
+
* NOT include trailing zeros after the decimal point. This type
|
|
80
|
+
* of format oddly does not exists with printf.
|
|
81
|
+
*
|
|
82
|
+
* If the input value is greater than 1<<31, then the output format
|
|
83
|
+
* will be switched exponential format.
|
|
84
|
+
*
|
|
85
|
+
* \param[in] value
|
|
86
|
+
* \param[out] buf The allocated output buffer. Should be 32 chars or more.
|
|
87
|
+
* \param[in] precision Number of digits to the right of the decimal point.
|
|
88
|
+
* Can only be 0-9.
|
|
89
|
+
*/
|
|
90
|
+
size_t modp_dtoa2(double value, char* buf, int precision);
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* adds a 8-character hexadecimal representation of value
|
|
94
|
+
*
|
|
95
|
+
*/
|
|
96
|
+
char* modp_uitoa16(uint32_t value, char* buf, int final);
|
|
97
|
+
|
|
98
|
+
#include "extern_c_end.h"
|
|
99
|
+
|
|
100
|
+
#endif
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* \file
|
|
3
|
+
* <pre>
|
|
4
|
+
* modp_qs.c query string key-value pair iterator
|
|
5
|
+
* https://github.com/client9/stringencoders
|
|
6
|
+
*
|
|
7
|
+
* Copyright © 2012-2016 Nick Galbreath
|
|
8
|
+
* All rights reserved.
|
|
9
|
+
* Released under MIT license. See LICENSE for details.
|
|
10
|
+
* </PRE>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#include "modp_qsiter.h"
|
|
14
|
+
|
|
15
|
+
void qsiter_reset(struct qsiter_t* qsi, const char* s, size_t len)
|
|
16
|
+
{
|
|
17
|
+
qsi->s = s;
|
|
18
|
+
qsi->len = len;
|
|
19
|
+
qsi->pos = 0;
|
|
20
|
+
|
|
21
|
+
qsi->key = NULL;
|
|
22
|
+
qsi->keylen = 0;
|
|
23
|
+
qsi->val = NULL;
|
|
24
|
+
qsi->vallen = 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
int qsiter_next(struct qsiter_t* qsi)
|
|
28
|
+
{
|
|
29
|
+
const char* eq;
|
|
30
|
+
const char* charstart;
|
|
31
|
+
const char* ends;
|
|
32
|
+
|
|
33
|
+
if (qsi->pos >= qsi->len) {
|
|
34
|
+
qsi->key = NULL;
|
|
35
|
+
qsi->keylen = 0;
|
|
36
|
+
qsi->val = NULL;
|
|
37
|
+
qsi->vallen = 0;
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
charstart = qsi->s + qsi->pos;
|
|
42
|
+
ends = (const char*)memchr(charstart, '&', qsi->len - qsi->pos);
|
|
43
|
+
|
|
44
|
+
if (ends == NULL) {
|
|
45
|
+
eq = (const char*)memchr(charstart, '=', qsi->len - qsi->pos);
|
|
46
|
+
if (eq == NULL) {
|
|
47
|
+
qsi->key = charstart;
|
|
48
|
+
qsi->keylen = (size_t)(qsi->len - qsi->pos);
|
|
49
|
+
qsi->val = NULL;
|
|
50
|
+
qsi->vallen = (size_t)0;
|
|
51
|
+
} else {
|
|
52
|
+
qsi->key = charstart;
|
|
53
|
+
qsi->keylen = (size_t)(eq - charstart);
|
|
54
|
+
qsi->val = eq + 1;
|
|
55
|
+
qsi->vallen = (size_t)((qsi->s + qsi->len) - qsi->val);
|
|
56
|
+
}
|
|
57
|
+
qsi->pos = qsi->len;
|
|
58
|
+
return 1;
|
|
59
|
+
} else {
|
|
60
|
+
/* &&foo=bar */
|
|
61
|
+
eq = (const char*)memchr(charstart, '=', (size_t)(ends - charstart));
|
|
62
|
+
if (eq == NULL) {
|
|
63
|
+
qsi->key = charstart;
|
|
64
|
+
qsi->keylen = (size_t)(ends - charstart);
|
|
65
|
+
qsi->val = NULL;
|
|
66
|
+
qsi->vallen = (size_t)0;
|
|
67
|
+
} else {
|
|
68
|
+
qsi->key = charstart;
|
|
69
|
+
qsi->keylen = (size_t)(eq - charstart);
|
|
70
|
+
qsi->val = eq + 1;
|
|
71
|
+
qsi->vallen = (size_t)(ends - eq - 1);
|
|
72
|
+
}
|
|
73
|
+
qsi->pos = (size_t)((ends - qsi->s) + 1);
|
|
74
|
+
return 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#ifndef COM_MODP_QSITER
|
|
2
|
+
#define COM_MODP_QSITER
|
|
3
|
+
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#include "extern_c_begin.h"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* \file modp_qsiter.h
|
|
10
|
+
* \brief URL Query string key-value pair iterator. Uses no heap, makes
|
|
11
|
+
* no copy, makes no modification of input. Think of this as a
|
|
12
|
+
* super-strtok_r.
|
|
13
|
+
*
|
|
14
|
+
* This also does not do query-string un-escaping.
|
|
15
|
+
*
|
|
16
|
+
* \code
|
|
17
|
+
* qsiiter_t qsi;
|
|
18
|
+
* const char* qs = "foo=bar&ding=bar";
|
|
19
|
+
* qsiter_reset(&qsi, qs, strlen(qs));
|
|
20
|
+
* while (qsiter_next(&qsi)) {
|
|
21
|
+
* // we only get start and length of key,value
|
|
22
|
+
* // up to you how to copy it or not, on heap or stack
|
|
23
|
+
* // with strcpy, strncpy, strndup, memcpy, mempcpy, strlcpy, whatever
|
|
24
|
+
* // callers job to alloc/free memory
|
|
25
|
+
*
|
|
26
|
+
* const char* key = (const char*) malloc(qsi.keylen + 1);
|
|
27
|
+
* strcpy(key, qsi->key, qsi->keylen);
|
|
28
|
+
* const char* val = (const char*) malloc(qsi.vallen + 1);
|
|
29
|
+
* strcpy(val, qsi->val, qsi->vallen);
|
|
30
|
+
* printf("key = %s, value = %s\n", key, val);
|
|
31
|
+
* free(key);
|
|
32
|
+
* free(value);
|
|
33
|
+
* }
|
|
34
|
+
* \endcode
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
struct qsiter_t {
|
|
38
|
+
const char* s;
|
|
39
|
+
size_t pos;
|
|
40
|
+
size_t len;
|
|
41
|
+
|
|
42
|
+
const char* key;
|
|
43
|
+
size_t keylen;
|
|
44
|
+
|
|
45
|
+
const char* val;
|
|
46
|
+
size_t vallen;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Reset a qsiter to an initial start (constructor)
|
|
51
|
+
*
|
|
52
|
+
* This does not modifiy the original string, nor makes a copy.
|
|
53
|
+
*
|
|
54
|
+
* \param[out] qsi data struct used in iterator
|
|
55
|
+
* \param[in] s input string (does not need to be 0-terminated)
|
|
56
|
+
* \param[in] len input string length
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
void qsiter_reset(struct qsiter_t* qsi, const char* s, size_t len);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get next key/value pair in query string
|
|
63
|
+
*
|
|
64
|
+
* \param[out] qsi data struct
|
|
65
|
+
* \return 1 if found a key value pair, 0 if no more data
|
|
66
|
+
*/
|
|
67
|
+
int qsiter_next(struct qsiter_t* qsi);
|
|
68
|
+
|
|
69
|
+
#include "extern_c_end.h"
|
|
70
|
+
|
|
71
|
+
#endif /* MODP_QSITER */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* vi: set ft=c expandtab shiftwidth=4 tabstop=4: */
|
|
2
|
+
#ifndef MODP_STDINT_H_
|
|
3
|
+
#define MODP_STDINT_H_
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* \file modp_stdint.h
|
|
7
|
+
* \brief An attempt to make stringencoders compile under windows
|
|
8
|
+
*
|
|
9
|
+
* This attempts to define various integral types that are normally
|
|
10
|
+
* defined in stdint.h and stdbool.h which oddly don't exit on
|
|
11
|
+
* windows.
|
|
12
|
+
*
|
|
13
|
+
* Please file bugs or patches if it doesn't work!
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include <string.h>
|
|
17
|
+
|
|
18
|
+
#ifndef _WIN32
|
|
19
|
+
#include <stdbool.h>
|
|
20
|
+
#include <stdint.h>
|
|
21
|
+
#else
|
|
22
|
+
/* win64 is llp64 so these are the same for 32/64bit
|
|
23
|
+
so no check for _WIN64 is required.
|
|
24
|
+
*/
|
|
25
|
+
typedef unsigned char uint8_t;
|
|
26
|
+
typedef signed char int8_t;
|
|
27
|
+
typedef unsigned short uint16_t;
|
|
28
|
+
typedef signed short int16_t;
|
|
29
|
+
typedef unsigned int uint32_t;
|
|
30
|
+
typedef signed int int32_t;
|
|
31
|
+
typedef unsigned __int64 uint64_t;
|
|
32
|
+
typedef signed __int64 int64_t;
|
|
33
|
+
|
|
34
|
+
/* windows doesn't do C99 and stdbool */
|
|
35
|
+
|
|
36
|
+
#ifndef __cplusplus
|
|
37
|
+
typedef unsigned char bool;
|
|
38
|
+
#define true 1
|
|
39
|
+
#define false 0
|
|
40
|
+
#endif
|
|
41
|
+
|
|
42
|
+
#endif /* _WIN32 */
|
|
43
|
+
#endif /* MODP_STDINT_H_ */
|