Compare commits
1158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d22eb0caa2 | ||
|
|
138cadc01c | ||
|
|
b590e2c96f | ||
|
|
5dd8f28290 | ||
|
|
078436212c | ||
|
|
10521de2fc | ||
|
|
7d11471619 | ||
|
|
434855f500 | ||
|
|
11c4ca00d5 | ||
|
|
f16d701a2c | ||
|
|
34d590d93a | ||
|
|
a87f56448a | ||
|
|
bb61ad2afe | ||
|
|
57b8eb6ccd | ||
|
|
7f52249e40 | ||
|
|
321e2a94fe | ||
|
|
ceb01fb6a3 | ||
|
|
2206d0ef65 | ||
|
|
279c2a6f82 | ||
|
|
d1200224e2 | ||
|
|
fdd1f2ec36 | ||
|
|
7295d7f4bb | ||
|
|
05d98f4380 | ||
|
|
a187750b32 | ||
|
|
55377c12d3 | ||
|
|
cd11f3755e | ||
|
|
289c8c9f09 | ||
|
|
80a9a2bf5d | ||
|
|
1b0b8d7043 | ||
|
|
b81ec3545f | ||
|
|
999e2fa031 | ||
|
|
c060d08767 | ||
|
|
27ca1b2698 | ||
|
|
75af4ed9b5 | ||
|
|
1edc5e5ee0 | ||
|
|
28f90d17ac | ||
|
|
50b5dab5df | ||
|
|
8afdcb9e9f | ||
|
|
7e8f5401b2 | ||
|
|
5a0a47cbae | ||
|
|
bc2642f423 | ||
|
|
cd41a0decd | ||
|
|
803d145a5e | ||
|
|
8303266430 | ||
|
|
44e33121c7 | ||
|
|
8a6ff4803c | ||
|
|
abbf4b82b0 | ||
|
|
9752268308 | ||
|
|
1fe983948f | ||
|
|
39829a09cb | ||
|
|
3de738429f | ||
|
|
fa0ef25ffb | ||
|
|
a9e507da9b | ||
|
|
20dfecd2b6 | ||
|
|
eb7bd6a2f1 | ||
|
|
a570b74038 | ||
|
|
18c82465b2 | ||
|
|
d46db18a31 | ||
|
|
5cf4f4a5e2 | ||
|
|
e3ee23bcfd | ||
|
|
846cbf8c78 | ||
|
|
b14555c742 | ||
|
|
154e90b1ca | ||
|
|
97c89168f7 | ||
|
|
a039e7593a | ||
|
|
acebbf58eb | ||
|
|
84e3184106 | ||
|
|
3a1fa4a552 | ||
|
|
1cf518e82c | ||
|
|
951f479a1b | ||
|
|
a6e408510a | ||
|
|
f2f195f43e | ||
|
|
21c563f83a | ||
|
|
67b1acbf78 | ||
|
|
4ed6cbdd5b | ||
|
|
7e3dbce3d2 | ||
|
|
e38f01d1f4 | ||
|
|
32a01df0e1 | ||
|
|
814a8258fd | ||
|
|
f3b2153ba7 | ||
|
|
651fb45598 | ||
|
|
b5dc8eb9ce | ||
|
|
b12d1570a7 | ||
|
|
cd38492ceb | ||
|
|
411a12693d | ||
|
|
c0952e54db | ||
|
|
09c566a6eb | ||
|
|
97b1ac6eab | ||
|
|
2a8de0fd6b | ||
|
|
8921da91b8 | ||
|
|
2b69831f49 | ||
|
|
e9f924ca31 | ||
|
|
595912f82d | ||
|
|
ec1ffa2945 | ||
|
|
45ff08b6aa | ||
|
|
ab9e0c06b8 | ||
|
|
c549c9dff0 | ||
|
|
d7a778ce6a | ||
|
|
f45e279e06 | ||
|
|
4d19b8be07 | ||
|
|
2ae68923cc | ||
|
|
d197c9780a | ||
|
|
3d063edb72 | ||
|
|
f081e80c28 | ||
|
|
1c3ee48146 | ||
|
|
e499e908d2 | ||
|
|
e0956c36c1 | ||
|
|
2893f8c82a | ||
|
|
036c3098f3 | ||
|
|
24612eba4c | ||
|
|
6512b8894a | ||
|
|
1b44c9a3df | ||
|
|
8499cc9767 | ||
|
|
d49faa0f5c | ||
|
|
258cd2cb87 | ||
|
|
7eed701682 | ||
|
|
e62b9dc4c1 | ||
|
|
36ac1124f4 | ||
|
|
ddb34f1ed1 | ||
|
|
76b761d8e2 | ||
|
|
92b3cdb6f8 | ||
|
|
47eb7fcc2f | ||
|
|
6d8c73cc52 | ||
|
|
9e5e16c18d | ||
|
|
3af4cf0a28 | ||
|
|
d6903efc0c | ||
|
|
9390eb016c | ||
|
|
47dc31d8c2 | ||
|
|
f3c3e0bfff | ||
|
|
fbb5a753b1 | ||
|
|
a1951aff02 | ||
|
|
c28d36b500 | ||
|
|
0efb929898 | ||
|
|
3f84dd8cf9 | ||
|
|
5d9e53a37d | ||
|
|
2e2a7509cd | ||
|
|
7f97b7bc05 | ||
|
|
073ccf2705 | ||
|
|
6d8b25fdf8 | ||
|
|
22f62af9be | ||
|
|
2a014df60d | ||
|
|
6c8b4b2f8d | ||
|
|
8dad543671 | ||
|
|
cf0cea38fd | ||
|
|
db7b65ed42 | ||
|
|
61a8f7f078 | ||
|
|
e4f0b36f61 | ||
|
|
b7c34d8a96 | ||
|
|
b5dbd7942f | ||
|
|
5e5d5fdee4 | ||
|
|
89c05efe22 | ||
|
|
e5bf824c3b | ||
|
|
b509263ef5 | ||
|
|
13ec104154 | ||
|
|
4cfa1d5cd3 | ||
|
|
48396aebd1 | ||
|
|
7cfdab936c | ||
|
|
010444d77a | ||
|
|
1c8c3207fe | ||
|
|
ba7031cb3b | ||
|
|
7e88fdd0f1 | ||
|
|
af3d721f82 | ||
|
|
e09249abad | ||
|
|
0061f03cef | ||
|
|
53c82d54ea | ||
|
|
5602a24b22 | ||
|
|
f4cbb9d8e9 | ||
|
|
df82a734af | ||
|
|
2179ea85f8 | ||
|
|
f5299209d4 | ||
|
|
ca2384f230 | ||
|
|
9c88f76338 | ||
|
|
f07cd8ceb4 | ||
|
|
4469ff4b9a | ||
|
|
54f6f0ceba | ||
|
|
2cb3834bbb | ||
|
|
2e302a43aa | ||
|
|
5e8d028da2 | ||
|
|
8b62c23ab6 | ||
|
|
bcbe22c780 | ||
|
|
3461bafaa2 | ||
|
|
f25b448a49 | ||
|
|
874bbd0b8a | ||
|
|
73ddda4651 | ||
|
|
a433804ee6 | ||
|
|
08171dad5e | ||
|
|
f60eeaf08c | ||
|
|
7b3550c46e | ||
|
|
db8fb177b8 | ||
|
|
203739f7a4 | ||
|
|
735c341fae | ||
|
|
7bb9264c3d | ||
|
|
4b8d227922 | ||
|
|
4124850481 | ||
|
|
637fee5ecc | ||
|
|
47eb4da080 | ||
|
|
79ca82c078 | ||
|
|
d2a787805a | ||
|
|
d2071b7ea7 | ||
|
|
61ba1743ef | ||
|
|
d60426a19f | ||
|
|
a88bc564ee | ||
|
|
a5d5856638 | ||
|
|
4e64e3f1dd | ||
|
|
51850ded05 | ||
|
|
76d7c1c01a | ||
|
|
dabc5567f7 | ||
|
|
5c5ee6f763 | ||
|
|
06bfcad671 | ||
|
|
73e48e6595 | ||
|
|
64a005565d | ||
|
|
aa5098866c | ||
|
|
60ff83f280 | ||
|
|
8dbad62153 | ||
|
|
4a78b343d9 | ||
|
|
ab8102f927 | ||
|
|
fa02409c92 | ||
|
|
3a45ef0e65 | ||
|
|
f2cdeb7d9a | ||
|
|
ff7a2c63f2 | ||
|
|
efe4c9cae3 | ||
|
|
c37261858a | ||
|
|
ef3dc5bb58 | ||
|
|
968327d577 | ||
|
|
eedf724ccd | ||
|
|
bf3f33f8cb | ||
|
|
271feb02b8 | ||
|
|
f254ebb4ca | ||
|
|
c9f1966e08 | ||
|
|
095f85f159 | ||
|
|
fdd2740f8b | ||
|
|
8268162cac | ||
|
|
30eff2b520 | ||
|
|
d3962718aa | ||
|
|
388fd1262a | ||
|
|
7a4bd2278d | ||
|
|
b3f5986c83 | ||
|
|
48d28826d0 | ||
|
|
122a5cdf89 | ||
|
|
f3e93bbbeb | ||
|
|
6d2f7e46dd | ||
|
|
3d9589f010 | ||
|
|
906ef761ba | ||
|
|
6b87a67592 | ||
|
|
e16361826e | ||
|
|
a327cecee6 | ||
|
|
64d9f7c23e | ||
|
|
4f16a1cee9 | ||
|
|
8f83f69325 | ||
|
|
1d0ca51c88 | ||
|
|
ca70f4fab1 | ||
|
|
72cdf3f555 | ||
|
|
1c68fddad7 | ||
|
|
2f3b5f6d0a | ||
|
|
5663c45a0d | ||
|
|
172356d299 | ||
|
|
2323ea4493 | ||
|
|
d6a666f4e0 | ||
|
|
6e70a6c6f5 | ||
|
|
b82be0a9b0 | ||
|
|
94a47569d6 | ||
|
|
73df97f2d0 | ||
|
|
e8b75b80c2 | ||
|
|
f6bec473d5 | ||
|
|
9ab5611c65 | ||
|
|
92391332d7 | ||
|
|
8e26b187be | ||
|
|
79ce5901f3 | ||
|
|
29a4849024 | ||
|
|
0a1731c4c9 | ||
|
|
5cac2befb0 | ||
|
|
be60348f8f | ||
|
|
e6d4436e9d | ||
|
|
c4e9a464e7 | ||
|
|
16b1adfa86 | ||
|
|
404d58d77c | ||
|
|
6c712ff2df | ||
|
|
e3414bf042 | ||
|
|
308aaa6f78 | ||
|
|
eb62959216 | ||
|
|
70d5c4eca7 | ||
|
|
a025d365b8 | ||
|
|
89fa10b40b | ||
|
|
34e85ccb62 | ||
|
|
77a4218a9e | ||
|
|
93bcdf5318 | ||
|
|
d8ee487c19 | ||
|
|
bac303273f | ||
|
|
3605bf1f60 | ||
|
|
7c2e5f3ac8 | ||
|
|
d3b43bfa37 | ||
|
|
bf6079797f | ||
|
|
6366f62f11 | ||
|
|
427c33dbd7 | ||
|
|
675cbb72a6 | ||
|
|
f846b1a88f | ||
|
|
4bfcd12897 | ||
|
|
d736232142 | ||
|
|
9cb02028ed | ||
|
|
0703441ee7 | ||
|
|
2c3128d9ba | ||
|
|
7837eed21b | ||
|
|
db092449f9 | ||
|
|
d321b446db | ||
|
|
78ce7a08c0 | ||
|
|
15adb73a13 | ||
|
|
f15cc6c4f6 | ||
|
|
61e6e5694c | ||
|
|
66bc0bb424 | ||
|
|
25589bacea | ||
|
|
d721d35a2d | ||
|
|
ba84fc2c77 | ||
|
|
0f7dbc7bc0 | ||
|
|
137dd351b8 | ||
|
|
ba38bfad9d | ||
|
|
be71e8afa2 | ||
|
|
076a061997 | ||
|
|
de416adadd | ||
|
|
1fda99ba82 | ||
|
|
9f5b58c8ab | ||
|
|
a5131515ec | ||
|
|
8c11d24454 | ||
|
|
924b6b663e | ||
|
|
688452d971 | ||
|
|
2f94e16359 | ||
|
|
fbf736f169 | ||
|
|
f0624581d1 | ||
|
|
cb23352a35 | ||
|
|
9fea06ad84 | ||
|
|
2beeb9a293 | ||
|
|
1e92ac3cf5 | ||
|
|
acaf91a2f7 | ||
|
|
41125a0a34 | ||
|
|
35ed095dbf | ||
|
|
ce31e26f58 | ||
|
|
2b640532f2 | ||
|
|
94ed5b3a53 | ||
|
|
2eaf211e9b | ||
|
|
ed9f5639a8 | ||
|
|
8e842b5893 | ||
|
|
1b378172b6 | ||
|
|
0dc911c091 | ||
|
|
2be11874e3 | ||
|
|
5ac744ff66 | ||
|
|
57d6ab091c | ||
|
|
f13668371e | ||
|
|
c9486863c3 | ||
|
|
e9e0277b7c | ||
|
|
b69f0356ec | ||
|
|
4d72fc225a | ||
|
|
9786e432f8 | ||
|
|
040d7ebb46 | ||
|
|
f9f2b8124d | ||
|
|
dd5d938aa3 | ||
|
|
7c82adcc84 | ||
|
|
bdb1966573 | ||
|
|
a1582c610e | ||
|
|
2f9f217c11 | ||
|
|
278f679bb1 | ||
|
|
96bc727fcb | ||
|
|
7d2809eb27 | ||
|
|
9b8133f65f | ||
|
|
77c0236cae | ||
|
|
07c4262392 | ||
|
|
10a5421987 | ||
|
|
06beddcee6 | ||
|
|
48f0e1f51d | ||
|
|
6701b7f1d0 | ||
|
|
9063953ee7 | ||
|
|
7315d9c300 | ||
|
|
05c248f297 | ||
|
|
b92a58d11e | ||
|
|
767d253593 | ||
|
|
046a8f443d | ||
|
|
78e59191ed | ||
|
|
958b3a1dc0 | ||
|
|
de4d872b7a | ||
|
|
921b34eafd | ||
|
|
77955c74bc | ||
|
|
555cd59a59 | ||
|
|
b4f8dc7abf | ||
|
|
14dde47173 | ||
|
|
4fb6bf3e67 | ||
|
|
f73c55a922 | ||
|
|
49c86768e6 | ||
|
|
0fca91c6c1 | ||
|
|
749b4adc7c | ||
|
|
a67e4ab9f1 | ||
|
|
e0b2a26805 | ||
|
|
6c5b23b317 | ||
|
|
8da2a724fb | ||
|
|
d5363d1a85 | ||
|
|
8f74ee1d96 | ||
|
|
796ee8e3de | ||
|
|
25f611d0ec | ||
|
|
08e518af73 | ||
|
|
27673c1c3f | ||
|
|
3394129894 | ||
|
|
57625e06ed | ||
|
|
d7935192dd | ||
|
|
dd3e170e08 | ||
|
|
97d5325468 | ||
|
|
8433851652 | ||
|
|
f7b2b84ece | ||
|
|
8be67c1766 | ||
|
|
4d2e7ed404 | ||
|
|
e1018546ac | ||
|
|
44fcab1081 | ||
|
|
6dab1657b1 | ||
|
|
60ad21ae0d | ||
|
|
3974ddd8f7 | ||
|
|
8064e82774 | ||
|
|
e0af6ec567 | ||
|
|
0a96f3a249 | ||
|
|
40363f96a9 | ||
|
|
1c9577a1ac | ||
|
|
a7a30396be | ||
|
|
fee19390f5 | ||
|
|
3c6534dc91 | ||
|
|
95dcdf7ddc | ||
|
|
5423fa25d4 | ||
|
|
8db0094c73 | ||
|
|
7373a26333 | ||
|
|
d4c4a03e42 | ||
|
|
206cd3b529 | ||
|
|
37bf76692d | ||
|
|
26fc812e21 | ||
|
|
4e345b1c8a | ||
|
|
641ab8ddaf | ||
|
|
b783e353c4 | ||
|
|
1883b40083 | ||
|
|
5063839ce5 | ||
|
|
95eaf254c9 | ||
|
|
874b685a83 | ||
|
|
ea5fe35b54 | ||
|
|
3ed1382bbe | ||
|
|
b3749e4d95 | ||
|
|
237b5e704f | ||
|
|
0fcd3da046 | ||
|
|
9930b12d9d | ||
|
|
9cdc06ce43 | ||
|
|
7382a0c142 | ||
|
|
360e3fb81e | ||
|
|
d11510c34c | ||
|
|
845c9f8a51 | ||
|
|
9ad5644a8c | ||
|
|
ef1604a729 | ||
|
|
1185103a3d | ||
|
|
006020aef2 | ||
|
|
22d08b70ec | ||
|
|
ab77e36c70 | ||
|
|
a2530de06a | ||
|
|
c7c7084423 | ||
|
|
30121de963 | ||
|
|
fbf9c86c5c | ||
|
|
233127393f | ||
|
|
4a47ba9b35 | ||
|
|
44932b170f | ||
|
|
0675c2b374 | ||
|
|
bc5fcbbc88 | ||
|
|
da21c77ae3 | ||
|
|
49673c33b4 | ||
|
|
c489975015 | ||
|
|
9bbcbd546b | ||
|
|
7aa6b6b21d | ||
|
|
0a0795328f | ||
|
|
df89999891 | ||
|
|
11c472d701 | ||
|
|
e81d35c4db | ||
|
|
33c5f98824 | ||
|
|
b70cd27bda | ||
|
|
70a27b900a | ||
|
|
18c63a75fb | ||
|
|
d9aec19c87 | ||
|
|
bff5212386 | ||
|
|
3c32d0fbc3 | ||
|
|
4699b17508 | ||
|
|
b8c716a918 | ||
|
|
34f0f9dcf1 | ||
|
|
8d1cfaabe7 | ||
|
|
f78269b02d | ||
|
|
e8c07717fc | ||
|
|
9ca6740db3 | ||
|
|
92c9ebb0d6 | ||
|
|
8432b9e29a | ||
|
|
faf91d6697 | ||
|
|
adc69e72df | ||
|
|
c8ae3d1751 | ||
|
|
79f9cc534d | ||
|
|
5100eadf12 | ||
|
|
1d6721d345 | ||
|
|
c01b4e6baa | ||
|
|
16021591b2 | ||
|
|
a237f9d28c | ||
|
|
f1eb9d4f89 | ||
|
|
1da5e090d5 | ||
|
|
5cde522d5e | ||
|
|
8aa4a027bb | ||
|
|
d9c49386cb | ||
|
|
cd98d1c1f9 | ||
|
|
756ac603db | ||
|
|
933a98b97c | ||
|
|
b14751aad9 | ||
|
|
f3ebd508d6 | ||
|
|
5d33ce352e | ||
|
|
c1e070c042 | ||
|
|
ade26e2c86 | ||
|
|
b668b79341 | ||
|
|
7bc26c5ea0 | ||
|
|
5ece1fa568 | ||
|
|
98ea17f7fc | ||
|
|
8d25cc3c92 | ||
|
|
15c1055ff4 | ||
|
|
c930151a95 | ||
|
|
3d7c6f831c | ||
|
|
ef57b3954c | ||
|
|
878070084e | ||
|
|
ef5adc507a | ||
|
|
ea7013a34d | ||
|
|
eb64a4387d | ||
|
|
68fe1a7c8f | ||
|
|
320897bad6 | ||
|
|
0b692080cd | ||
|
|
eaa021c2e2 | ||
|
|
d352a744a5 | ||
|
|
14b439ce43 | ||
|
|
9e4c4ad8e5 | ||
|
|
f5941041d4 | ||
|
|
9ab4f7bcc6 | ||
|
|
186ca9c235 | ||
|
|
fefdb32d08 | ||
|
|
3cd391daa6 | ||
|
|
88cb0a1f7a | ||
|
|
f0f082d3e3 | ||
|
|
4a8555b3bf | ||
|
|
9d33e4bd7b | ||
|
|
75c8d7aa57 | ||
|
|
f034b02b92 | ||
|
|
96a3a34fa4 | ||
|
|
e965b7c0da | ||
|
|
7847ac3144 | ||
|
|
6708311a66 | ||
|
|
af7f0b5074 | ||
|
|
78dfb6bcf5 | ||
|
|
4640079f55 | ||
|
|
60330da25c | ||
|
|
cd97b5beec | ||
|
|
30eb927ad4 | ||
|
|
579b1e6f79 | ||
|
|
b5384cc964 | ||
|
|
146d706343 | ||
|
|
b69ecfe75c | ||
|
|
02d834e9bb | ||
|
|
e4ecc762c6 | ||
|
|
4f515adafe | ||
|
|
4f0a20ec68 | ||
|
|
b12676f701 | ||
|
|
b968821cc1 | ||
|
|
d81154bf6c | ||
|
|
c7c9a725b8 | ||
|
|
83add658f9 | ||
|
|
cb0e91c602 | ||
|
|
97d87dff09 | ||
|
|
fe9d77734f | ||
|
|
8b59a2f6b6 | ||
|
|
0857c6350d | ||
|
|
bf403a6142 | ||
|
|
5b8bb822ba | ||
|
|
df32f27762 | ||
|
|
ee570a49d0 | ||
|
|
6a1071ccd3 | ||
|
|
11d667c830 | ||
|
|
cc11b498cc | ||
|
|
ca71f18a6d | ||
|
|
6b79b5fc74 | ||
|
|
df24ae0fbb | ||
|
|
b74cdb2f9d | ||
|
|
bb730c00e9 | ||
|
|
7a92ac91d0 | ||
|
|
e68b989af5 | ||
|
|
fd27bcd7ee | ||
|
|
f5eb22253d | ||
|
|
0c5c901222 | ||
|
|
0a93f8db22 | ||
|
|
875f4c87ff | ||
|
|
7b4c705a3f | ||
|
|
b11e857148 | ||
|
|
0568a40d8d | ||
|
|
94dea7c06f | ||
|
|
8cd2ba48fc | ||
|
|
9d819b95bf | ||
|
|
d26dadd9d8 | ||
|
|
55ca9fb090 | ||
|
|
58ec5d5afe | ||
|
|
c00a976ff6 | ||
|
|
97a1af43ed | ||
|
|
558b914c64 | ||
|
|
dda5fd7390 | ||
|
|
ce8f56727e | ||
|
|
d9755d33d0 | ||
|
|
48d4fccc22 | ||
|
|
bfa8dec6f6 | ||
|
|
6e8230e1fb | ||
|
|
587a379b43 | ||
|
|
93021a054b | ||
|
|
bf4dd0cbde | ||
|
|
4ccc380a7b | ||
|
|
9efac86bb7 | ||
|
|
8be17cd60d | ||
|
|
caf5f7579e | ||
|
|
191f4496a7 | ||
|
|
df3f5e442d | ||
|
|
fdfcebd1cb | ||
|
|
8f5b4a6c96 | ||
|
|
a45b532664 | ||
|
|
c0dfbdc910 | ||
|
|
a4ef993282 | ||
|
|
6b0cec1189 | ||
|
|
4a3176e3a0 | ||
|
|
fd9206584f | ||
|
|
2ab7cfbf30 | ||
|
|
6b467e7e59 | ||
|
|
d64f5a387c | ||
|
|
cc6cd0bb8f | ||
|
|
3fbff6e620 | ||
|
|
5eb0aa2765 | ||
|
|
f63cf33118 | ||
|
|
0bb6171a85 | ||
|
|
e92dd73169 | ||
|
|
2d490f6e6a | ||
|
|
761affacc3 | ||
|
|
979c834ee0 | ||
|
|
aff0ec18b0 | ||
|
|
d32b91e0de | ||
|
|
8b659a6d32 | ||
|
|
18486169b3 | ||
|
|
d580e7c694 | ||
|
|
78ec5ccdbc | ||
|
|
d4a5c0353d | ||
|
|
6546c30e17 | ||
|
|
5478c540cb | ||
|
|
b5d81f4f92 | ||
|
|
2a99a8350f | ||
|
|
028935a254 | ||
|
|
6df466c692 | ||
|
|
956f2b98b8 | ||
|
|
4e3dcd1ce6 | ||
|
|
a690690b53 | ||
|
|
b9d0bf8822 | ||
|
|
bb02112752 | ||
|
|
8eddcfd3d5 | ||
|
|
78e1995365 | ||
|
|
c48b9244f2 | ||
|
|
e219008320 | ||
|
|
f603ae175b | ||
|
|
f62d034692 | ||
|
|
deb180cc83 | ||
|
|
17b970a387 | ||
|
|
d060eb498f | ||
|
|
c2bc7e2c30 | ||
|
|
eb5691e8fa | ||
|
|
864b20565b | ||
|
|
3e6818b407 | ||
|
|
aaced060bf | ||
|
|
af77ff3eed | ||
|
|
98162cec33 | ||
|
|
048a2d7bc3 | ||
|
|
307ad244b0 | ||
|
|
0c0fa877cf | ||
|
|
49bd8ac880 | ||
|
|
969ea98fd9 | ||
|
|
bd0f4b95ae | ||
|
|
dda419ddd6 | ||
|
|
1f9e2c920c | ||
|
|
43f38a240e | ||
|
|
705e629001 | ||
|
|
edc60e2e01 | ||
|
|
9f65b26288 | ||
|
|
496b337b27 | ||
|
|
3a895ccfaa | ||
|
|
eb19343f91 | ||
|
|
893b2d4587 | ||
|
|
370d98a858 | ||
|
|
d11983ae32 | ||
|
|
42692abd1c | ||
|
|
d1335a6efd | ||
|
|
61cfa6e37e | ||
|
|
f7aa4f9593 | ||
|
|
1dfd9e3c10 | ||
|
|
2f656e09c6 | ||
|
|
6c9d88bd6d | ||
|
|
045e38314a | ||
|
|
d346e6645a | ||
|
|
760f51910f | ||
|
|
9e5619ce99 | ||
|
|
b38dd98e71 | ||
|
|
71db1dfa06 | ||
|
|
08aa415c66 | ||
|
|
bf87614fa6 | ||
|
|
55045b5fe9 | ||
|
|
56c5c2ebaa | ||
|
|
a2c574fa15 | ||
|
|
b560f5a474 | ||
|
|
206169476f | ||
|
|
30648a1819 | ||
|
|
00575cf847 | ||
|
|
ef94f42b62 | ||
|
|
4ed36da458 | ||
|
|
68b5966fef | ||
|
|
7bae496257 | ||
|
|
dc591f8943 | ||
|
|
31089931d3 | ||
|
|
55dd5b5547 | ||
|
|
1f97a239dc | ||
|
|
8604e216eb | ||
|
|
f4120635e9 | ||
|
|
e8f1dd8421 | ||
|
|
2ec6050959 | ||
|
|
29c38ef0d4 | ||
|
|
74d616ac78 | ||
|
|
504a892887 | ||
|
|
30cf0f8d3a | ||
|
|
d794d7d30b | ||
|
|
b112b333bd | ||
|
|
0e7bac945f | ||
|
|
e5bb90fdfa | ||
|
|
ac0142a49e | ||
|
|
ef6e381de3 | ||
|
|
206e65cf05 | ||
|
|
695cc38b36 | ||
|
|
7b1e03a585 | ||
|
|
49bc04fa48 | ||
|
|
d5954fffa8 | ||
|
|
58da1065d6 | ||
|
|
fe58c1a383 | ||
|
|
2c02580c37 | ||
|
|
24c2315476 | ||
|
|
a3845f54e1 | ||
|
|
7442932b5e | ||
|
|
ed5a98f697 | ||
|
|
fcfa10d508 | ||
|
|
3cf0729878 | ||
|
|
55171f42f6 | ||
|
|
1311ca37e5 | ||
|
|
67d807d8fc | ||
|
|
ebf395ecc4 | ||
|
|
2c3ead339e | ||
|
|
6c7f5d093c | ||
|
|
93e9d8622e | ||
|
|
ca47d72aee | ||
|
|
c864e4d3db | ||
|
|
ff305e63b6 | ||
|
|
01fd05cb4b | ||
|
|
5831a53697 | ||
|
|
b60a7f3363 | ||
|
|
44445ff1b8 | ||
|
|
ac37c38133 | ||
|
|
8b7056b06c | ||
|
|
228b664ecf | ||
|
|
1dfd655959 | ||
|
|
ae22d5dc8a | ||
|
|
c67929ea39 | ||
|
|
2472a902dd | ||
|
|
f3d97c76df | ||
|
|
b0b8660132 | ||
|
|
ae551cde63 | ||
|
|
d0a0dbf430 | ||
|
|
0e46762962 | ||
|
|
a1ec423235 | ||
|
|
4f7dca3e5a | ||
|
|
4394594518 | ||
|
|
e5e0f527fe | ||
|
|
f07515eb88 | ||
|
|
d37dd46f65 | ||
|
|
3f6e7aa05a | ||
|
|
ad0064a310 | ||
|
|
0b7574ba00 | ||
|
|
cc05ce19f9 | ||
|
|
e132aabdae | ||
|
|
026b9268ae | ||
|
|
c807a4e383 | ||
|
|
2ff781b25f | ||
|
|
3acb474795 | ||
|
|
7e4c834c0e | ||
|
|
9c61a6df62 | ||
|
|
94e40dc554 | ||
|
|
38bf40884c | ||
|
|
1ef044d628 | ||
|
|
d5d37466e0 | ||
|
|
5f231d305f | ||
|
|
7b89bf6cc7 | ||
|
|
5c5de57290 | ||
|
|
9e18bb3c31 | ||
|
|
57703acf75 | ||
|
|
fbc247bf53 | ||
|
|
56496d8287 | ||
|
|
9d9c822efb | ||
|
|
1a3cddc002 | ||
|
|
373ca9cef0 | ||
|
|
9534516b42 | ||
|
|
755ab36f0d | ||
|
|
c0ca0373b6 | ||
|
|
7efb6a3ab8 | ||
|
|
69c26a180e | ||
|
|
40aa552489 | ||
|
|
7b1352d9c5 | ||
|
|
68cf7599d8 | ||
|
|
6501dea7a3 | ||
|
|
72fc42b60c | ||
|
|
2a164f0165 | ||
|
|
6a14f251ba | ||
|
|
92fd417962 | ||
|
|
ebbd9ff414 | ||
|
|
874b5240d2 | ||
|
|
14b34fc6ef | ||
|
|
34fffca202 | ||
|
|
4e59ab2261 | ||
|
|
327d7a6524 | ||
|
|
d5ece4e909 | ||
|
|
39f13beaf7 | ||
|
|
37624a7303 | ||
|
|
e82ec68820 | ||
|
|
90551a6eaf | ||
|
|
43ebbb1c70 | ||
|
|
f343941a96 | ||
|
|
001997e088 | ||
|
|
83b9d22ff0 | ||
|
|
77874ee518 | ||
|
|
2a04dcc334 | ||
|
|
50965ca9c0 | ||
|
|
277e32bb1e | ||
|
|
d94e4c2491 | ||
|
|
2dc25cec72 | ||
|
|
207ffdec8e | ||
|
|
1ad8ff9b64 | ||
|
|
1dd2836f1b | ||
|
|
a45fc47682 | ||
|
|
962a95d770 | ||
|
|
ca695fa6e1 | ||
|
|
e96ce99d3d | ||
|
|
550b8e55ee | ||
|
|
8e7e3b7256 | ||
|
|
f3dc7ce52c | ||
|
|
bfdda3212a | ||
|
|
02acf7d6d0 | ||
|
|
84ef06e35c | ||
|
|
f0acc9c901 | ||
|
|
55447b05ac | ||
|
|
41eb8a1e29 | ||
|
|
9eda4bc6fa | ||
|
|
6eda7772eb | ||
|
|
8c522aa758 | ||
|
|
057344e1af | ||
|
|
ee728e3dbc | ||
|
|
ae324fba94 | ||
|
|
43e6d345e4 | ||
|
|
27307fca0c | ||
|
|
8b1b6050e7 | ||
|
|
da925ee5cc | ||
|
|
4676db126a | ||
|
|
d8ea4f9b06 | ||
|
|
d2d946204c | ||
|
|
2b132ae892 | ||
|
|
34b7599df6 | ||
|
|
270ceb7ceb | ||
|
|
200c935228 | ||
|
|
f0c57cf95c | ||
|
|
19d05b8024 | ||
|
|
2a362a99da | ||
|
|
497c8aeabf | ||
|
|
c35843fda5 | ||
|
|
88af355028 | ||
|
|
10958459a3 | ||
|
|
5f6e2ee026 | ||
|
|
7a7514fa0c | ||
|
|
637eafedee | ||
|
|
3f74cb76e9 | ||
|
|
f79b34b2c9 | ||
|
|
85ced3dbf7 | ||
|
|
718569d6a1 | ||
|
|
a56c01d044 | ||
|
|
04a4219a75 | ||
|
|
16113e783f | ||
|
|
63b0a1c9e0 | ||
|
|
a386b458fb | ||
|
|
8017b18039 | ||
|
|
981f6a8972 | ||
|
|
429deb959c | ||
|
|
86793468de | ||
|
|
04d039eddd | ||
|
|
201221253d | ||
|
|
aa2773e483 | ||
|
|
25f29a2287 | ||
|
|
b0503691c5 | ||
|
|
457c3262d7 | ||
|
|
de2c4cc7b8 | ||
|
|
81e5b59060 | ||
|
|
96587dc68c | ||
|
|
d9d291abcb | ||
|
|
38516ef793 | ||
|
|
5acd433080 | ||
|
|
5c2da08c13 | ||
|
|
3c79ebda17 | ||
|
|
46e5dc2f5c | ||
|
|
0aa7e871d1 | ||
|
|
34527fbbe4 | ||
|
|
9fcab37445 | ||
|
|
5c0ee3d9a8 | ||
|
|
f3327e6dca | ||
|
|
0e6e22ac3d | ||
|
|
5002ab2169 | ||
|
|
db05b9ff04 | ||
|
|
04f9270772 | ||
|
|
29feaba22f | ||
|
|
dd3fc7a084 | ||
|
|
c5130e3eb3 | ||
|
|
b4855b6ac9 | ||
|
|
b09e975b4c | ||
|
|
ac9c02f73b | ||
|
|
52ff45549d | ||
|
|
325a265a33 | ||
|
|
918950ba49 | ||
|
|
34dfcee2e8 | ||
|
|
95cb192209 | ||
|
|
c1bef9b35c | ||
|
|
005672e8af | ||
|
|
e52e7d15dc | ||
|
|
dda53a96cc | ||
|
|
35f53516c7 | ||
|
|
14f8ed8dd2 | ||
|
|
21b78adfee | ||
|
|
503b8047b1 | ||
|
|
d959af430e | ||
|
|
4e908d3e96 | ||
|
|
3db2b7d6a6 | ||
|
|
4615297b00 | ||
|
|
6108aca055 | ||
|
|
068cb83803 | ||
|
|
22b4e17fad | ||
|
|
7333d13dd4 | ||
|
|
77268845a6 | ||
|
|
93d490bc8f | ||
|
|
e1d0bc83f4 | ||
|
|
0ac3f826e1 | ||
|
|
2ef937a9dc | ||
|
|
52b0f65bb3 | ||
|
|
0c92204927 | ||
|
|
8632d43748 | ||
|
|
9bf8c3765b | ||
|
|
5b691224f0 | ||
|
|
9cdf27cbf5 | ||
|
|
d1621692dc | ||
|
|
cc133ccc4c | ||
|
|
69f0eb109f | ||
|
|
a3ab23a36a | ||
|
|
5e5b49d4e2 | ||
|
|
377c983ecb | ||
|
|
69b20b52cc | ||
|
|
e4a68d9962 | ||
|
|
21f0d63507 | ||
|
|
e7b008c6d5 | ||
|
|
7735187d36 | ||
|
|
85f4d7d025 | ||
|
|
e0eaa08597 | ||
|
|
43c065c5b6 | ||
|
|
df154e43b1 | ||
|
|
ba21367b40 | ||
|
|
c420f60259 | ||
|
|
b13f35645a | ||
|
|
68560c9ea7 | ||
|
|
1a9019f5f5 | ||
|
|
969eeec717 | ||
|
|
1f59e38dc7 | ||
|
|
b202b82f5a | ||
|
|
d0bdafff71 | ||
|
|
685af493a4 | ||
|
|
e8ad5a0e6b | ||
|
|
000b5a2b7c | ||
|
|
88ffd3cdfb | ||
|
|
98352429c2 | ||
|
|
5171a00569 | ||
|
|
01af51308e | ||
|
|
65d4440d0d | ||
|
|
37276f357c | ||
|
|
e0b6620df2 | ||
|
|
ebabeb6fbd | ||
|
|
ab6c138a7c | ||
|
|
33e7c124a3 | ||
|
|
11ff62e120 | ||
|
|
155a6a09b6 | ||
|
|
74156b6b89 | ||
|
|
9387e7dd2d | ||
|
|
9aaaa6aef0 | ||
|
|
cc9358ee95 | ||
|
|
06ed133ae3 | ||
|
|
75b778924f | ||
|
|
fe902db322 | ||
|
|
0c00335627 | ||
|
|
5e3548fc00 | ||
|
|
c8837d07e7 | ||
|
|
fd14957072 | ||
|
|
1df03b67e7 | ||
|
|
6d9131084f | ||
|
|
66b96b90d5 | ||
|
|
03baeccda5 | ||
|
|
91b0c1cd0e | ||
|
|
6d974daaf2 | ||
|
|
849d0c1c34 | ||
|
|
63dc75fb81 | ||
|
|
f07732a9ca | ||
|
|
9702446d91 | ||
|
|
d3a07234cd | ||
|
|
cf2c43e7ab | ||
|
|
83c3beb2ed | ||
|
|
52133569f5 | ||
|
|
1c39721ff7 | ||
|
|
57b2c3c2e4 | ||
|
|
ed82643faf | ||
|
|
5131752402 | ||
|
|
1b44479311 | ||
|
|
4c987d04d6 | ||
|
|
728ace79c5 | ||
|
|
a937b97a61 | ||
|
|
35d2ea862b | ||
|
|
1c502948f5 | ||
|
|
45f321a3a2 | ||
|
|
85f5672280 | ||
|
|
62c1b02eb1 | ||
|
|
67af5ccda8 | ||
|
|
bd49b0edf8 | ||
|
|
3126654d33 | ||
|
|
1b55d39997 | ||
|
|
51372c01f2 | ||
|
|
7008db7dda | ||
|
|
47456a1723 | ||
|
|
933ba3c7d6 | ||
|
|
08ff5f02b1 | ||
|
|
2bf39203e8 | ||
|
|
d323a84dd9 | ||
|
|
2e402ba654 | ||
|
|
f0afa04037 | ||
|
|
b9290acb85 | ||
|
|
cb47146b3b | ||
|
|
04fadc84a6 | ||
|
|
18333eac29 | ||
|
|
abd3668b65 | ||
|
|
9064af3b1c | ||
|
|
2f7b42b13b | ||
|
|
56755c278b | ||
|
|
7266111b68 | ||
|
|
810954014b | ||
|
|
3248a1b57f | ||
|
|
4edf1fd8fa | ||
|
|
67f22e602e | ||
|
|
114012fab2 | ||
|
|
c50fc88827 | ||
|
|
f5e4b3aeb3 | ||
|
|
76e0d4c770 | ||
|
|
ed8d9b1ed3 | ||
|
|
c825fce0cf | ||
|
|
0f5b35f408 | ||
|
|
ae0cd50840 | ||
|
|
9a7c5b02d4 | ||
|
|
66c5b4ed01 | ||
|
|
f125c3a3c8 | ||
|
|
e36f027a9a | ||
|
|
dc7035ed19 | ||
|
|
d25fe19d87 | ||
|
|
dc52a31814 | ||
|
|
2f45613017 | ||
|
|
8d881d3b6f | ||
|
|
ce6f051551 | ||
|
|
b3b188061a | ||
|
|
49f70c083d | ||
|
|
ed392300b4 | ||
|
|
a3af6404b0 | ||
|
|
312b7352b2 | ||
|
|
23e4bc4f9a | ||
|
|
8208bb25ba | ||
|
|
a90ea340d2 | ||
|
|
e2fd51c282 | ||
|
|
0008193a20 | ||
|
|
5c691c0883 | ||
|
|
e363cbe542 | ||
|
|
d8bec0a43c | ||
|
|
e1c176ceb7 | ||
|
|
a1289eb502 | ||
|
|
4a00e8feed | ||
|
|
60e0e5c38f | ||
|
|
93ef4f2301 | ||
|
|
ccda3068ef | ||
|
|
ebad05a9df | ||
|
|
4f19ea4a8e | ||
|
|
8e2722da95 | ||
|
|
b5fbcfaa8e | ||
|
|
d0ea813515 | ||
|
|
932bc382dc | ||
|
|
bdfb19fe38 | ||
|
|
d798330f44 | ||
|
|
caa3a5d0bb | ||
|
|
d54a5c49c1 | ||
|
|
9e75075dc4 | ||
|
|
6a833e19aa | ||
|
|
941ac2ae5e | ||
|
|
34f4b3cad4 | ||
|
|
03948cd685 | ||
|
|
3c993884cd | ||
|
|
9e99aed182 | ||
|
|
66edf2822c | ||
|
|
9c9ba18619 | ||
|
|
485d048415 | ||
|
|
10a0db9160 | ||
|
|
8260b75586 | ||
|
|
8365ed7408 | ||
|
|
d4298d1bd2 | ||
|
|
75736f547a | ||
|
|
e84b524fc4 | ||
|
|
7eb80615c7 | ||
|
|
030c763549 | ||
|
|
57d0e556d8 | ||
|
|
3fea8a4202 | ||
|
|
ca1eda2df1 | ||
|
|
386fea5e71 | ||
|
|
e7bda30506 | ||
|
|
6dcf61669c | ||
|
|
1832463010 | ||
|
|
a0baaeafd1 | ||
|
|
c5a113ca80 | ||
|
|
e6b3ded33f | ||
|
|
aa66af151a | ||
|
|
ab57495e29 | ||
|
|
afb5d161e3 | ||
|
|
1fdaafb30b | ||
|
|
9328e6fdec | ||
|
|
98ac0697a9 | ||
|
|
b658f82510 | ||
|
|
b50894fa70 | ||
|
|
e002000764 | ||
|
|
9182c1558c | ||
|
|
ded7eca60f | ||
|
|
74e8c881f7 | ||
|
|
f1eac72d20 | ||
|
|
6d13ddd43a | ||
|
|
94e9632234 | ||
|
|
3699b74ebb | ||
|
|
4eeab3bc3e | ||
|
|
0d1ded5278 | ||
|
|
86142ecdf1 | ||
|
|
8cdc00230d | ||
|
|
d3d674ba4b | ||
|
|
6d961d87f8 | ||
|
|
5a28c54505 | ||
|
|
9968101d96 | ||
|
|
d0a309e6da | ||
|
|
f2d84f0a90 | ||
|
|
d81345d8f6 | ||
|
|
97b6260c9a | ||
|
|
48cf78af68 |
2
.gitignore
vendored
@@ -85,3 +85,5 @@ rippled-build.log
|
||||
|
||||
# Profiling data
|
||||
gmon.out
|
||||
|
||||
Builds/VisualStudio2015/*.db
|
||||
|
||||
12
.travis.yml
@@ -8,9 +8,9 @@ env:
|
||||
# Note that for simplicity, BOOST_ROOT's final
|
||||
# namepart must match the folder name internal
|
||||
# to boost's .tar.gz.
|
||||
- BOOST_ROOT=$HOME/boost_1_59_0
|
||||
- BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.59.0%2Fboost_1_59_0.tar.gz%2Fdownload&ts=1441761349&use_mirror=skylineservers'
|
||||
|
||||
- LCOV_ROOT=$HOME/lcov
|
||||
- BOOST_ROOT=$HOME/boost_1_60_0
|
||||
- BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.gz?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.60.0%2Fboost_1_60_0.tar.gz&ts=1460417589&use_mirror=netix'
|
||||
|
||||
packages: &gcc5_pkgs
|
||||
- gcc-5
|
||||
@@ -60,6 +60,12 @@ matrix:
|
||||
env: GCC_VER=5 TARGET=debug.nounity CLANG_VER=3.6
|
||||
addons: *ao_clang36
|
||||
|
||||
# Temporary workaround while the llvm apt repository is down.
|
||||
# TODO: REMOVE THIS if/when clang builds become reliable again.
|
||||
allow_failures:
|
||||
- env: GCC_VER=5 TARGET=debug CLANG_VER=3.6
|
||||
- env: GCC_VER=5 TARGET=debug.nounity CLANG_VER=3.6
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $BOOST_ROOT
|
||||
|
||||
182
Builds/Test.py
@@ -48,18 +48,38 @@ import itertools
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def powerset(iterable):
|
||||
"""powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"""
|
||||
s = list(iterable)
|
||||
return itertools.chain.from_iterable(itertools.combinations(s, r) for r in range(len(s) + 1))
|
||||
|
||||
|
||||
IS_WINDOWS = platform.system().lower() == 'windows'
|
||||
|
||||
if IS_WINDOWS:
|
||||
BINARY_RE = re.compile(r'build\\([^\\]+)\\rippled.exe')
|
||||
|
||||
ALL_TARGETS = [('debug',), ('release',)]
|
||||
else:
|
||||
BINARY_RE = re.compile(r'build/([^/]+)/rippled')
|
||||
ALL_TARGETS = [(cc + "." + target,)
|
||||
for cc in ['gcc', 'clang']
|
||||
for target in ['debug', 'release', 'coverage', 'profile',
|
||||
'debug.nounity', 'release.nounity', 'coverage.nounity', 'profile.nounity']]
|
||||
|
||||
ALL_TARGETS = ['debug', 'release']
|
||||
# list of tuples of all possible options
|
||||
if IS_WINDOWS:
|
||||
ALL_OPTIONS = [tuple(x) for x in powerset(['--assert'])]
|
||||
else:
|
||||
ALL_OPTIONS = list(set(
|
||||
[tuple(x) for x in powerset(['--ninja', '--static', '--assert', '--sanitize=address'])] +
|
||||
[tuple(x) for x in powerset(['--ninja', '--static', '--assert', '--sanitize=thread'])]))
|
||||
|
||||
# list of tuples of all possible options + all possible targets
|
||||
ALL_BUILDS = [options + target
|
||||
for target in ALL_TARGETS
|
||||
for options in ALL_OPTIONS]
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Test.py - run ripple tests'
|
||||
@@ -75,55 +95,74 @@ parser.add_argument(
|
||||
'--keep_going', '-k',
|
||||
action='store_true',
|
||||
help='Keep going after one configuration has failed.',
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--silent', '-s',
|
||||
action='store_true',
|
||||
help='Silence all messages except errors',
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--verbose', '-v',
|
||||
action='store_true',
|
||||
help=('Report more information about which commands are executed and the '
|
||||
'results.'),
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--test', '-t',
|
||||
default='',
|
||||
help='Add a prefix for unit tests',
|
||||
)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--nonpm', '-n',
|
||||
action='store_true',
|
||||
help='Do not run npm tests',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--clean', '-c',
|
||||
action='store_true',
|
||||
help='delete all build artifacts after testing',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'scons_args',
|
||||
default=(),
|
||||
nargs='*'
|
||||
)
|
||||
)
|
||||
|
||||
ARGS = parser.parse_args()
|
||||
|
||||
def shell(*cmd, **kwds):
|
||||
"Execute a shell command and return the output."
|
||||
silent = kwds.pop('silent', ARGS.silent)
|
||||
verbose = not silent and kwds.pop('verbose', ARGS.verbose)
|
||||
|
||||
def shell(cmd, args=(), silent=False):
|
||||
""""Execute a shell command and return the output."""
|
||||
silent = ARGS.silent or silent
|
||||
verbose = not silent and ARGS.verbose
|
||||
if verbose:
|
||||
print('$', ' '.join(cmd))
|
||||
kwds['shell'] = IS_WINDOWS
|
||||
print('$' + cmd, *args)
|
||||
|
||||
command = (cmd,) + args
|
||||
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
command,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
**kwds)
|
||||
shell=IS_WINDOWS)
|
||||
lines = []
|
||||
count = 0
|
||||
for line in process.stdout:
|
||||
lines.append(line)
|
||||
# Python 2 vs. Python 3
|
||||
if isinstance(line, str):
|
||||
decoded = line
|
||||
else:
|
||||
decoded = line.decode()
|
||||
lines.append(decoded)
|
||||
if verbose:
|
||||
print(line, end='')
|
||||
print(decoded, end='')
|
||||
elif not silent:
|
||||
count += 1
|
||||
if count >= 80:
|
||||
@@ -137,27 +176,16 @@ def shell(*cmd, **kwds):
|
||||
process.wait()
|
||||
return process.returncode, lines
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = list(ARGS.scons_args)
|
||||
if ARGS.all:
|
||||
for a in ALL_TARGETS:
|
||||
if a not in args:
|
||||
args.append(a)
|
||||
print('Building:', *(args or ['(default)']))
|
||||
|
||||
# Build everything.
|
||||
resultcode, lines = shell('scons', *args)
|
||||
if resultcode:
|
||||
print('Build FAILED:')
|
||||
if not ARGS.verbose:
|
||||
print(*lines, sep='')
|
||||
exit(1)
|
||||
|
||||
# Now extract the executable names and corresponding targets.
|
||||
def run_tests(args):
|
||||
failed = []
|
||||
_, lines = shell('scons', '-n', '--tree=derived', *args, silent=True)
|
||||
if IS_WINDOWS:
|
||||
binary_re = re.compile(r'build\\([^\\]+)\\rippled.exe')
|
||||
else:
|
||||
binary_re = re.compile(r'build/([^/]+)/rippled')
|
||||
_, lines = shell('scons', ('-n', '--tree=derived',) + args, silent=True)
|
||||
for line in lines:
|
||||
match = BINARY_RE.search(line)
|
||||
match = binary_re.search(line)
|
||||
if match:
|
||||
executable, target = match.group(0, 1)
|
||||
|
||||
@@ -165,8 +193,8 @@ if __name__ == '__main__':
|
||||
testflag = '--unittest'
|
||||
if ARGS.test:
|
||||
testflag += ('=' + ARGS.test)
|
||||
resultcode, lines = shell(executable, (testflag,))
|
||||
|
||||
resultcode, lines = shell(executable, testflag)
|
||||
if resultcode:
|
||||
print('ERROR:', *lines, sep='')
|
||||
failed.append([target, 'unittest'])
|
||||
@@ -174,18 +202,70 @@ if __name__ == '__main__':
|
||||
break
|
||||
ARGS.verbose and print(*lines, sep='')
|
||||
|
||||
print('npm tests for', target)
|
||||
resultcode, lines = shell('npm', 'test', '--rippled=' + executable)
|
||||
if resultcode:
|
||||
print('ERROR:\n', *lines, sep='')
|
||||
failed.append([target, 'npm'])
|
||||
if not ARGS.keep_going:
|
||||
break
|
||||
else:
|
||||
ARGS.verbose and print(*lines, sep='')
|
||||
if not ARGS.nonpm:
|
||||
print('npm tests for', target)
|
||||
resultcode, lines = shell('npm', ('test', '--rippled=' + executable,))
|
||||
if resultcode:
|
||||
print('ERROR:\n', *lines, sep='')
|
||||
failed.append([target, 'npm'])
|
||||
if not ARGS.keep_going:
|
||||
break
|
||||
else:
|
||||
ARGS.verbose and print(*lines, sep='')
|
||||
return failed
|
||||
|
||||
if failed:
|
||||
print('FAILED:', *(':'.join(f) for f in failed))
|
||||
|
||||
def run_build(args=None):
|
||||
print('Building:', *args or ('(default)',))
|
||||
resultcode, lines = shell('scons', args)
|
||||
|
||||
if resultcode:
|
||||
print('Build FAILED:')
|
||||
if not ARGS.verbose:
|
||||
print(*lines, sep='')
|
||||
exit(1)
|
||||
if '--ninja' in args:
|
||||
resultcode, lines = shell('ninja')
|
||||
|
||||
if resultcode:
|
||||
print('Ninja build FAILED:')
|
||||
if not ARGS.verbose:
|
||||
print(*lines, sep='')
|
||||
exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
if ARGS.all:
|
||||
to_build = ALL_BUILDS
|
||||
else:
|
||||
print('Success')
|
||||
to_build = [tuple(ARGS.scons_args)]
|
||||
|
||||
for build in to_build:
|
||||
args = ()
|
||||
# additional arguments come first
|
||||
for arg in list(ARGS.scons_args):
|
||||
if arg not in build:
|
||||
args += (arg,)
|
||||
args += build
|
||||
|
||||
run_build(args)
|
||||
failed = run_tests(args)
|
||||
|
||||
if failed:
|
||||
print('FAILED:', *(':'.join(f) for f in failed))
|
||||
if not ARGS.keep_going:
|
||||
exit(1)
|
||||
else:
|
||||
print('Success')
|
||||
|
||||
if ARGS.clean:
|
||||
shutil.rmtree('build')
|
||||
if '--ninja' in args:
|
||||
os.remove('build.ninja')
|
||||
os.remove('.ninja_deps')
|
||||
os.remove('.ninja_log')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
exit(0)
|
||||
|
||||
82
Builds/Ubuntu/build_clang_libs.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# This scripts installs boost and protobuf built with clang. This is needed on
|
||||
# ubuntu 15.10 when building with clang
|
||||
# It will build these in a 'clang' subdirectory that it creates below the directory
|
||||
# this script is run from. If a clang directory already exists the script will refuse
|
||||
# to run.
|
||||
|
||||
if hash lsb_release 2>/dev/null; then
|
||||
if [ $(lsb_release -si) == "Ubuntu" ]; then
|
||||
ubuntu_release=$(lsb_release -sr)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${ubuntu_release}" ]; then
|
||||
echo "System not supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! hash clang 2>/dev/null; then
|
||||
clang_version=3.7
|
||||
if [ ${ubuntu_release} == "16.04" ]; then
|
||||
clang_version=3.8
|
||||
fi
|
||||
sudo apt-get -y install clang-${clang_version}
|
||||
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clang_version} 99 clang++
|
||||
hash -r
|
||||
if ! hash clang 2>/dev/null; then
|
||||
echo "Please install clang"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${ubuntu_release} != "16.04" ] && [ ${ubuntu_release} != "15.10" ]; then
|
||||
echo "clang specific boost and protobuf not needed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -d clang ]; then
|
||||
echo "clang directory already exists. Cowardly refusing to run"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! hash wget 2>/dev/null; then
|
||||
sudo apt-get -y install wget
|
||||
hash -r
|
||||
if ! hash wget 2>/dev/null; then
|
||||
echo "Please install wget"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # pysical cores
|
||||
|
||||
mkdir clang
|
||||
pushd clang > /dev/null
|
||||
|
||||
# Install protobuf
|
||||
pb=protobuf-2.6.1
|
||||
pb_tar=${pb}.tar.gz
|
||||
wget -O ${pb_tar} https://github.com/google/protobuf/releases/download/v2.6.1/${pb_tar}
|
||||
tar xf ${pb_tar}
|
||||
rm ${pb_tar}
|
||||
pushd ${pb} > /dev/null
|
||||
./configure CC=clang CXX=clang++ CXXFLAGS='-std=c++14 -O3 -g'
|
||||
make -j${num_procs}
|
||||
popd > /dev/null
|
||||
|
||||
# Install boost
|
||||
boost_ver=1.60.0
|
||||
bd=boost_${boost_ver//./_}
|
||||
bd_tar=${bd}.tar.gz
|
||||
wget -O ${bd_tar} http://sourceforge.net/projects/boost/files/boost/${boost_ver}/${bd_tar}
|
||||
tar xf ${bd_tar}
|
||||
rm ${bd_tar}
|
||||
pushd ${bd} > /dev/null
|
||||
./bootstrap.sh
|
||||
./b2 toolset=clang -j${num_procs}
|
||||
popd > /dev/null
|
||||
|
||||
popd > /dev/null
|
||||
@@ -44,7 +44,7 @@ if [ ${ubuntu_release} == "14.04" ] || [ ${ubuntu_release} == "15.04" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ${ubuntu_release} == "15.10" ]; then
|
||||
if [ ${ubuntu_release} == "16.04" ] || [ ${ubuntu_release} == "15.10" ]; then
|
||||
apt-get update
|
||||
apt-get -y upgrade
|
||||
apt-get -y install python-software-properties curl git scons ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties libboost-all-dev nodejs
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug.classic|x64 = debug.classic|x64
|
||||
debug.classic|x86 = debug.classic|x86
|
||||
debug|x64 = debug|x64
|
||||
debug|x86 = debug|x86
|
||||
release.classic|x64 = release.classic|x64
|
||||
release.classic|x86 = release.classic|x86
|
||||
release|x64 = release|x64
|
||||
release|x86 = release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.ActiveCfg = debug.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x64.Build.0 = debug.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug.classic|x86.ActiveCfg = debug.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.ActiveCfg = debug|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x64.Build.0 = debug|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.debug|x86.ActiveCfg = debug|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.ActiveCfg = release.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x64.Build.0 = release.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release.classic|x86.ActiveCfg = release.classic|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.ActiveCfg = release|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x64.Build.0 = release|x64
|
||||
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.release|x86.ActiveCfg = release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
6
Builds/build_all.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # number of physical cores
|
||||
|
||||
cd ..
|
||||
./Builds/Test.py -a -c -- -j${num_procs}
|
||||
178
README.md
@@ -1,129 +1,93 @@
|
||||

|
||||
|
||||
#The World’s Fastest and Most Secure Payment System
|
||||
# What is Ripple?
|
||||
Ripple is a network of computers which use the [Ripple consensus algorithm]
|
||||
(https://www.youtube.com/watch?v=pj1QVb1vlC0) to atomically settle and record
|
||||
transactions on a secure distributed database, the Ripple Consensus Ledger
|
||||
(RCL). Because of its distributed nature, the RCL offers transaction immutability
|
||||
without a central operator. The RCL contains a built-incurrency exchange and its
|
||||
path-finding algorithm finds competitive exchange rates across order books
|
||||
and currency pairs.
|
||||
|
||||
**What is Ripple?**
|
||||
### Key Features
|
||||
- **Distributed**
|
||||
- Direct account-to-account settlement with no central operator
|
||||
- Decentralized global market for competitive FX
|
||||
- **Secure**
|
||||
- Transactions are cryptographically signed using ECDSA or Ed25519
|
||||
- Multi-signing capabilities
|
||||
- **Scalable**
|
||||
- Capacity to process the world’s cross-border payments volume
|
||||
- Easy access to liquidity through a competitive FX marketplace
|
||||
|
||||
Ripple is the open-source, distributed payment protocol that enables instant
|
||||
payments with low fees, no chargebacks, and currency flexibility (for example
|
||||
dollars, yen, euros, bitcoins, or even loyalty points). Businesses of any size
|
||||
can easily build payment solutions such as banking or remittance apps, and
|
||||
accelerate the movement of money. Ripple enables the world to move value the
|
||||
way it moves information on the Internet.
|
||||
## Cross-border payments
|
||||
Ripple enables banks to settle cross-border payments in real-time, with
|
||||
end-to-end transparency, and at lower costs. Banks can provide liquidity
|
||||
for FX themselves or source it from third parties.
|
||||
|
||||

|
||||
As Ripple adoption grows, so do the number of currencies and counterparties.
|
||||
Liquidity providers need to maintain accounts with each counterparty for
|
||||
each currency – a capital- and time-intensive endeavor that spreads liquidity
|
||||
thin. Further, some transactions, such as exotic currency trades, will require
|
||||
multiple trading parties, who each layer costs to the transaction. Thin
|
||||
liquidity and many intermediary trading parties make competitive pricing
|
||||
challenging.
|
||||
|
||||
**What is a Gateway?**
|
||||

|
||||
|
||||
Ripple works with gateways: independent businesses which hold customer
|
||||
deposits in various currencies such as U.S. dollars (USD) or Euros (EUR),
|
||||
in exchange for providing cryptographically-signed issuances that users can
|
||||
send and trade with one another in seconds on the Ripple network. Within the
|
||||
protocol, exchanges between multiple currencies can occur atomically without
|
||||
any central authority to monitor them. Later, customers can withdraw their
|
||||
Ripple balances from the gateways that created those issuances.
|
||||
### XRP as a Bridge Currency
|
||||
Ripple can bridge even exotic currency pairs directly through XRP. Similar to
|
||||
USD in today’s currency market, XRP allows liquidity providers to focus on
|
||||
offering competitive FX rates on fewer pairs and adding depth to order books.
|
||||
Unlike USD, trading through XRP does not require bank accounts, service fees,
|
||||
counterparty risk, or additional operational costs. By using XRP, liquidity
|
||||
providers can specialize in certain currency corridors, reduce operational
|
||||
costs, and ultimately, offer more competitive FX pricing.
|
||||
|
||||
**How do Ripple payments work?**
|
||||

|
||||
|
||||
A sender specifies the amount and currency the recipient should receive and
|
||||
Ripple automatically converts the sender’s available currencies using the
|
||||
distributed order books integrated into the Ripple protocol. Independent third
|
||||
parties acting as market makers provide liquidity in these order books.
|
||||
# rippled - Ripple server
|
||||
`rippled` is the reference server implementation of the Ripple
|
||||
protocol. To learn more about how to build and run a `rippled`
|
||||
server, visit https://ripple.com/build/rippled-setup/
|
||||
|
||||
Ripple uses a pathfinding algorithm that considers currency pairs when
|
||||
converting from the source to the destination currency. This algorithm searches
|
||||
for a series of currency swaps that gives the user the lowest cost. Since
|
||||
anyone can participate as a market maker, market forces drive fees to the
|
||||
lowest practical level.
|
||||
[](https://travis-ci.org/ripple/rippled)
|
||||
[](https://codecov.io/gh/ripple/rippled)
|
||||
|
||||
**What can you do with Ripple?**
|
||||
### License
|
||||
`rippled` is open source and permissively licensed under the
|
||||
ISC license. See the LICENSE file for more details.
|
||||
|
||||
The protocol is entirely open-source and the network’s shared ledger is public
|
||||
information, so no central authority prevents anyone from participating. Anyone
|
||||
can become a market maker, create a wallet or a gateway, or monitor network
|
||||
behavior. Competition drives down spreads and fees, making the network useful
|
||||
to everyone.
|
||||
#### Repository Contents
|
||||
|
||||
| Folder | Contents |
|
||||
|---------|----------|
|
||||
| ./bin | Scripts and data files for Ripple integrators. |
|
||||
| ./build | Intermediate and final build outputs. |
|
||||
| ./Builds| Platform or IDE-specific project files. |
|
||||
| ./doc | Documentation and example configuration files. |
|
||||
| ./src | Source code. |
|
||||
| ./test | Javascript / Mocha tests. |
|
||||
|
||||
|
||||
###Key Protocol Features
|
||||
1. XRP is Ripple’s native [cryptocurrency]
|
||||
(http://en.wikipedia.org/wiki/Cryptocurrency) with a fixed supply that
|
||||
decreases slowly over time, with no mining. XRP acts as a bridge currency, and
|
||||
pays for transaction fees that protect the network against spam.
|
||||

|
||||
Some of the directories under `src` are external repositories inlined via
|
||||
git-subtree. See the corresponding README for more details.
|
||||
|
||||
2. Pathfinding discovers cheap and efficient payment paths through multiple
|
||||
[order books](https://www.ripplecharts.com) allowing anyone to [trade](https://www.rippletrade.com) anything. When two accounts aren’t linked by relationships of trust, the Ripple pathfinding engine considers intermediate links and order books to produce a set of possible paths the transaction can take. When the payment is processed, the liquidity along these paths is iteratively consumed in best-first order.
|
||||

|
||||
##For more information:
|
||||
|
||||
3. [Consensus](https://www.youtube.com/watch?v=pj1QVb1vlC0) confirms
|
||||
transactions in an atomic fashion, without mining, ensuring efficient use of
|
||||
resources.
|
||||
* [Ripple Knowledge Center](https://ripple.com/learn/)
|
||||
* [Ripple Developer Center](https://ripple.com/build/)
|
||||
* [Ripple Whitepapers & Reports](https://ripple.com/whitepapers-reports/)
|
||||
* [Ripple Consensus Whitepaper](https://ripple.com/consensus-whitepaper/)
|
||||
* [Ripple Solutions Guide](https://ripple.com/files/ripple_solutions_guide.pdf)
|
||||
|
||||
[transact]: https://ripple.com/files/ripple-FIs.pdf
|
||||
[build]: https://ripple.com/build/
|
||||
|
||||
[transact.png]: /images/transact.png
|
||||
[build.png]: /images/build.png
|
||||
[contribute.png]: /images/contribute.png
|
||||
|
||||
###Join The Ripple Community
|
||||
|![Transact][transact.png]|![Build][build.png]|![Contribute][contribute.png]|
|
||||
|:-----------------------:|:-----------------:|:---------------------------:|
|
||||
|[Transact on the fastest payment infrastructure][transact]|[Build Imaginative Apps][build]|Contribute to the Ripple Protocol Implementation|
|
||||
|
||||
#rippled - Ripple P2P server
|
||||
|
||||
##[](https://travis-ci.org/ripple/rippled)
|
||||
|
||||
This is the repository for Ripple's `rippled`, reference P2P server.
|
||||
|
||||
###Build instructions:
|
||||
* https://ripple.com/wiki/Rippled_build_instructions
|
||||
|
||||
###Setup instructions:
|
||||
* https://ripple.com/wiki/Rippled_setup_instructions
|
||||
|
||||
###Issues
|
||||
* https://ripplelabs.atlassian.net/browse/RIPD
|
||||
|
||||
### Repository Contents
|
||||
|
||||
#### ./bin
|
||||
Scripts and data files for Ripple integrators.
|
||||
|
||||
#### ./build
|
||||
Intermediate and final build outputs.
|
||||
|
||||
#### ./Builds
|
||||
Platform or IDE-specific project files.
|
||||
|
||||
#### ./doc
|
||||
Documentation and example configuration files.
|
||||
|
||||
#### ./src
|
||||
Source code directory. Some of the directories contained here are
|
||||
external repositories inlined via git-subtree, see the corresponding
|
||||
README for more details.
|
||||
|
||||
#### ./test
|
||||
Javascript / Mocha tests.
|
||||
|
||||
## License
|
||||
Ripple is open source and permissively licensed under the ISC license. See the
|
||||
LICENSE file for more details.
|
||||
|
||||
###For more information:
|
||||
* Ripple Wiki - https://ripple.com/wiki/
|
||||
* Ripple Primer - https://ripple.com/ripple_primer.pdf
|
||||
* Ripple Primer (Market Making) - https://ripple.com/ripple-mm.pdf
|
||||
* Ripple Gateway Primer - https://ripple.com/ripple-gateways.pdf
|
||||
* Consensus - https://wiki.ripple.com/Consensus
|
||||
To learn about how Ripple is transforming global payments visit
|
||||
[https://ripple.com/contact/](https://ripple.com/contact/)
|
||||
|
||||
- - -
|
||||
|
||||
Copyright © 2015, Ripple Labs. All rights reserved.
|
||||
|
||||
Portions of this document, including but not limited to the Ripple logo, images
|
||||
and image templates are the property of Ripple Labs and cannot be copied or
|
||||
used without permission.
|
||||
Portions of this document, including but not limited to the Ripple logo,
|
||||
images and image templates are the property of Ripple Labs and cannot be
|
||||
copied or used without permission.
|
||||
|
||||
2165
RELEASENOTES.md
Normal file
147
SConstruct
@@ -61,10 +61,16 @@ The following environment variables modify the build environment:
|
||||
Path to the boost directory.
|
||||
OPENSSL_ROOT
|
||||
Path to the openssl directory.
|
||||
PROTOBUF_DIR
|
||||
Path to the protobuf directory. This is usually only needed when
|
||||
the installed protobuf library uses a different ABI than clang
|
||||
(as with ubuntu 15.10).
|
||||
PROTOBUF_ROOT
|
||||
Path to the protobuf directory.
|
||||
CLANG_PROTOBUF_ROOT
|
||||
Override the path to the protobuf directory for the clang toolset. This is
|
||||
usually only needed when the installed protobuf library uses a different
|
||||
ABI than clang (as with ubuntu 15.10).
|
||||
CLANG_BOOST_ROOT
|
||||
Override the path to the boost directory for the clang toolset. This is
|
||||
usually only needed when the installed protobuf library uses a different
|
||||
ABI than clang (as with ubuntu 15.10).
|
||||
|
||||
The following extra options may be used:
|
||||
--ninja Generate a `build.ninja` build file for the specified target
|
||||
@@ -73,6 +79,10 @@ The following extra options may be used:
|
||||
|
||||
--static On linux, link protobuf, openssl, libc++, and boost statically
|
||||
|
||||
--sanitize=[address, thread] On gcc & clang, add sanitizer instrumentation
|
||||
|
||||
--assert Enable asserts, even in release builds.
|
||||
|
||||
GCC 5: If the gcc toolchain is used, gcc version 5 or better is required. On
|
||||
linux distros that ship with gcc 4 (ubuntu < 15.10), rippled will force gcc
|
||||
to use gcc4's ABI (there was an ABI change between versions). This allows us
|
||||
@@ -111,7 +121,7 @@ import textwrap
|
||||
import time
|
||||
import SCons.Action
|
||||
|
||||
sys.path.append(os.path.join('src', 'beast', 'site_scons'))
|
||||
sys.path.append(os.path.join('src', 'ripple', 'beast', 'site_scons'))
|
||||
sys.path.append(os.path.join('src', 'ripple', 'site_scons'))
|
||||
|
||||
import Beast
|
||||
@@ -122,9 +132,15 @@ import scons_to_ninja
|
||||
AddOption('--ninja', dest='ninja', action='store_true',
|
||||
help='generate ninja build file build.ninja')
|
||||
|
||||
AddOption('--sanitize', dest='sanitize', choices=['address', 'thread'],
|
||||
help='Build with sanitizer support (gcc and clang only).')
|
||||
|
||||
AddOption('--static', dest='static', action='store_true',
|
||||
help='On linux, link protobuf, openssl, libc++, and boost statically')
|
||||
|
||||
AddOption('--assert', dest='assert', action='store_true',
|
||||
help='Enable asserts, even in release mode')
|
||||
|
||||
def parse_time(t):
|
||||
l = len(t.split())
|
||||
if l==5:
|
||||
@@ -348,24 +364,9 @@ def config_base(env):
|
||||
,{'HAVE_USLEEP' : '1'}
|
||||
,{'SOCI_CXX_C11' : '1'}
|
||||
,'_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS'
|
||||
,'-DBOOST_NO_AUTO_PTR'
|
||||
,'BOOST_NO_AUTO_PTR'
|
||||
])
|
||||
|
||||
try:
|
||||
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
|
||||
env.Append(LIBPATH=[
|
||||
os.path.join(BOOST_ROOT, 'stage', 'lib'),
|
||||
])
|
||||
env['BOOST_ROOT'] = BOOST_ROOT
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
protobuf_dir = os.environ['PROTOBUF_DIR']
|
||||
env.Append(LIBPATH=[protobuf_dir])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if Beast.system.windows:
|
||||
try:
|
||||
OPENSSL_ROOT = os.path.normpath(os.environ['OPENSSL_ROOT'])
|
||||
@@ -400,7 +401,7 @@ def add_static_libs(env, static_libs, dyn_libs=None):
|
||||
for k,l in [('STATICLIBS', static_libs or []), ('DYNAMICLIBS', dyn_libs or [])]:
|
||||
c = env.get(k, '')
|
||||
for f in l:
|
||||
c += ' -l' + f
|
||||
c += ' -l' + f
|
||||
env[k] = c
|
||||
|
||||
def get_libs(lib, static):
|
||||
@@ -425,33 +426,80 @@ def get_libs(lib, static):
|
||||
else:
|
||||
static_libs.append(l)
|
||||
return (static_libs, dynamic_libs)
|
||||
except:
|
||||
raise Exception('pkg-config failed for ' + lib)
|
||||
except Exception as e:
|
||||
raise Exception('pkg-config failed for ' + lib + '; Exception: ' + str(e))
|
||||
|
||||
# Set toolchain and variant specific construction variables
|
||||
def config_env(toolchain, variant, env):
|
||||
if is_debug_variant(variant):
|
||||
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
|
||||
def add_sanitizer (toolchain, env):
|
||||
san = GetOption('sanitize')
|
||||
if not san: return
|
||||
san_to_lib = {'address': 'asan', 'thread': 'tsan'}
|
||||
if toolchain not in Split('clang gcc'):
|
||||
raise Exception("Sanitizers are only supported for gcc and clang")
|
||||
env.Append(CCFLAGS=['-fsanitize='+san, '-fno-omit-frame-pointer'])
|
||||
env.Append(LINKFLAGS=['-fsanitize='+san])
|
||||
add_static_libs(env, [san_to_lib[san]])
|
||||
env.Append(CPPDEFINES=['SANITIZER='+san_to_lib[san].upper()])
|
||||
|
||||
elif variant == 'release' or variant == 'profile':
|
||||
env.Append(CPPDEFINES=['NDEBUG'])
|
||||
def add_boost_and_protobuf(toolchain, env):
|
||||
def get_environ_value(candidates):
|
||||
for c in candidates:
|
||||
try:
|
||||
return os.environ[c]
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError('Environment variable not set')
|
||||
|
||||
if 'BOOST_ROOT' in env:
|
||||
if toolchain == 'gcc':
|
||||
try:
|
||||
br_cands = ['CLANG_BOOST_ROOT'] if toolchain == 'clang' else []
|
||||
br_cands.append('BOOST_ROOT')
|
||||
BOOST_ROOT = os.path.normpath(get_environ_value(br_cands))
|
||||
env.Append(LIBPATH=[
|
||||
os.path.join(BOOST_ROOT, 'stage', 'lib'),
|
||||
])
|
||||
env['BOOST_ROOT'] = BOOST_ROOT
|
||||
if toolchain in ['gcc', 'clang']:
|
||||
env.Append(CCFLAGS=['-isystem' + env['BOOST_ROOT']])
|
||||
else:
|
||||
env.Append(CPPPATH=[
|
||||
env['BOOST_ROOT'],
|
||||
])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
pb_cands = ['CLANG_PROTOBUF_ROOT'] if toolchain == 'clang' else []
|
||||
pb_cands.append('PROTOBUF_ROOT')
|
||||
PROTOBUF_ROOT = os.path.normpath(get_environ_value(pb_cands))
|
||||
env.Append(LIBPATH=[PROTOBUF_ROOT + '/src/.libs'])
|
||||
if not should_link_static() and toolchain in['clang', 'gcc']:
|
||||
env.Append(LINKFLAGS=['-Wl,-rpath,' + PROTOBUF_ROOT + '/src/.libs'])
|
||||
env['PROTOBUF_ROOT'] = PROTOBUF_ROOT
|
||||
env.Append(CPPPATH=[env['PROTOBUF_ROOT'] + '/src',])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def enable_asserts ():
|
||||
return GetOption('assert')
|
||||
|
||||
# Set toolchain and variant specific construction variables
|
||||
def config_env(toolchain, variant, env):
|
||||
add_boost_and_protobuf(toolchain, env)
|
||||
if is_debug_variant(variant):
|
||||
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
|
||||
|
||||
elif (variant == 'release' or variant == 'profile') and (not enable_asserts()):
|
||||
env.Append(CPPDEFINES=['NDEBUG'])
|
||||
|
||||
if should_link_static() and not Beast.system.linux:
|
||||
raise Exception("Static linking is only implemented for linux.")
|
||||
|
||||
add_sanitizer(toolchain, env)
|
||||
|
||||
if toolchain in Split('clang gcc'):
|
||||
if Beast.system.linux:
|
||||
link_static = should_link_static()
|
||||
for l in ['openssl', 'protobuf']:
|
||||
static, dynamic = get_libs(l, link_static)
|
||||
static, dynamic = get_libs(l, link_static)
|
||||
if link_static:
|
||||
add_static_libs(env, static, dynamic)
|
||||
else:
|
||||
@@ -643,6 +691,7 @@ def config_env(toolchain, variant, env):
|
||||
'_SCL_SECURE_NO_WARNINGS',
|
||||
'_CRT_SECURE_NO_WARNINGS',
|
||||
'WIN32_CONSOLE',
|
||||
'NOMINMAX'
|
||||
])
|
||||
if variant == 'debug':
|
||||
env.Append(LIBS=[
|
||||
@@ -710,7 +759,7 @@ root_dir = Dir('#').srcnode().get_abspath() # Path to this SConstruct file
|
||||
build_dir = os.path.join('build')
|
||||
|
||||
base = Environment(
|
||||
toolpath=[os.path.join ('src', 'beast', 'site_scons', 'site_tools')],
|
||||
toolpath=[os.path.join ('src', 'ripple', 'beast', 'site_scons', 'site_tools')],
|
||||
tools=['default', 'Protoc', 'VSProject'],
|
||||
ENV=os.environ,
|
||||
TARGET_ARCH='x86_64')
|
||||
@@ -719,6 +768,8 @@ config_base(base)
|
||||
base.Append(CPPPATH=[
|
||||
'src',
|
||||
os.path.join('src', 'beast'),
|
||||
os.path.join('src', 'beast', 'include'),
|
||||
os.path.join('src', 'beast', 'extras'),
|
||||
os.path.join(build_dir, 'proto'),
|
||||
os.path.join('src','soci','src'),
|
||||
os.path.join('src','soci','include'),
|
||||
@@ -852,6 +903,12 @@ def get_classic_sources(toolchain):
|
||||
'src/soci/src/core',
|
||||
'src/sqlite']
|
||||
)
|
||||
append_sources(result, *list_sources('src/ripple/beast/clock', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/beast/container', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/beast/insight', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/beast/net', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/beast/nudb', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/beast/utility', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/app', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/basics', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/crypto', '.cpp'))
|
||||
@@ -864,8 +921,8 @@ def get_classic_sources(toolchain):
|
||||
append_sources(result, *list_sources('src/ripple/protocol', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/rpc', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/shamap', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/server', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/test', '.cpp'))
|
||||
append_sources(result, *list_sources('src/ripple/unl', '.cpp'))
|
||||
|
||||
if use_shp(toolchain):
|
||||
cc_flags = {'CCFLAGS': ['--system-header-prefix=rocksdb2']}
|
||||
@@ -891,6 +948,12 @@ def get_unity_sources(toolchain):
|
||||
result = []
|
||||
append_sources(
|
||||
result,
|
||||
'src/ripple/beast/unity/beast_clock_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_container_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_insight_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_net_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_nudb_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_utility_unity.cpp',
|
||||
'src/ripple/unity/app_ledger.cpp',
|
||||
'src/ripple/unity/app_main.cpp',
|
||||
'src/ripple/unity/app_misc.cpp',
|
||||
@@ -908,8 +971,8 @@ def get_unity_sources(toolchain):
|
||||
'src/ripple/unity/protocol.cpp',
|
||||
'src/ripple/unity/rpcx.cpp',
|
||||
'src/ripple/unity/shamap.cpp',
|
||||
'src/ripple/unity/server.cpp',
|
||||
'src/ripple/unity/test.cpp',
|
||||
'src/ripple/unity/unl.cpp',
|
||||
)
|
||||
|
||||
if use_shp(toolchain):
|
||||
@@ -1048,19 +1111,18 @@ for tu_style in ['classic', 'unity']:
|
||||
cc_flags = {}
|
||||
|
||||
object_builder.add_source_files(
|
||||
'src/beast/beast/unity/hash_unity.cpp',
|
||||
'src/ripple/beast/unity/beast_hash_unity.cpp',
|
||||
'src/ripple/unity/beast.cpp',
|
||||
'src/ripple/unity/lz4.c',
|
||||
'src/ripple/unity/protobuf.cpp',
|
||||
'src/ripple/unity/ripple.proto.cpp',
|
||||
'src/ripple/unity/resource.cpp',
|
||||
'src/ripple/unity/server.cpp',
|
||||
'src/ripple/unity/websocket02.cpp',
|
||||
**cc_flags
|
||||
)
|
||||
|
||||
object_builder.add_source_files(
|
||||
'src/ripple/unity/beastc.c',
|
||||
'src/sqlite/sqlite_unity.c',
|
||||
CCFLAGS = ([] if toolchain == 'msvc' else ['-Wno-array-bounds']))
|
||||
|
||||
if 'gcc' in toolchain:
|
||||
@@ -1097,11 +1159,6 @@ for tu_style in ['classic', 'unity']:
|
||||
]
|
||||
)
|
||||
|
||||
object_builder.add_source_files(
|
||||
'src/ripple/unity/websocket04.cpp',
|
||||
CPPPATH='src/websocketpp',
|
||||
)
|
||||
|
||||
if toolchain == "clang" and Beast.system.osx:
|
||||
object_builder.add_source_files('src/ripple/unity/beastobjc.mm')
|
||||
|
||||
@@ -1145,7 +1202,7 @@ for key, value in aliases.iteritems():
|
||||
vcxproj = base.VSProject(
|
||||
os.path.join('Builds', 'VisualStudio2015', 'RippleD'),
|
||||
source = [],
|
||||
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
|
||||
VSPROJECT_ROOT_DIRS = ['src/beast', 'src/beast/include', 'src/beast/extras', 'src', '.'],
|
||||
VSPROJECT_CONFIGS = msvc_configs)
|
||||
base.Alias('vcxproj', vcxproj)
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@ install:
|
||||
- python get-pip.py
|
||||
|
||||
# Pip has some problems installing scons on windows so we use easy install.
|
||||
- easy_install scons
|
||||
# - easy_install scons
|
||||
# Workaround
|
||||
- easy_install https://pypi.python.org/packages/source/S/SCons/scons-2.5.0.tar.gz#md5=bda5530a70a41a7831d83c8b191c021e
|
||||
|
||||
# Scons has problems with parallel builds on windows without pywin32.
|
||||
- easy_install pywin32-219.win-amd64-py2.7.exe
|
||||
@@ -83,5 +85,5 @@ test_script:
|
||||
- build\\rippled --unittest
|
||||
|
||||
# Run the integration tests
|
||||
- npm install
|
||||
- npm install --progress=false
|
||||
- npm test
|
||||
|
||||
@@ -20,22 +20,38 @@ rm -f build/rippled
|
||||
|
||||
# See what we've actually built
|
||||
ldd $RIPPLED_PATH
|
||||
|
||||
if [[ $TARGET == "coverage" ]]; then
|
||||
$RIPPLED_PATH --unittest
|
||||
# We pass along -p to keep path segments so as to avoid collisions
|
||||
codecov --gcov-args=-p --gcov-source-match='^src/(ripple|beast)'
|
||||
else
|
||||
if [[ $CC == "clang" ]]; then
|
||||
# gdb segfaults with a clang build
|
||||
$RIPPLED_PATH --unittest
|
||||
else
|
||||
# Run unittests (under gdb)
|
||||
cat $__dirname/unittests.gdb | gdb \
|
||||
--return-child-result \
|
||||
--args $RIPPLED_PATH --unittest
|
||||
fi
|
||||
export PATH=$PATH:$LCOV_ROOT/usr/bin
|
||||
|
||||
# Create baseline coverage data file
|
||||
lcov --no-external -c -i -d . -o baseline.info
|
||||
fi
|
||||
|
||||
# Execute unit tests under gdb, printing a call stack
|
||||
# if we get a crash.
|
||||
gdb -return-child-result -quiet -batch \
|
||||
-ex "set env MALLOC_CHECK_=3" \
|
||||
-ex "set print thread-events off" \
|
||||
-ex run \
|
||||
-ex "thread apply all backtrace full" \
|
||||
-ex "quit" \
|
||||
--args $RIPPLED_PATH --unittest
|
||||
|
||||
if [[ $TARGET == "coverage" ]]; then
|
||||
# Create test coverage data file
|
||||
lcov --no-external -c -d . -o tests.info
|
||||
|
||||
# Combine baseline and test coverage data
|
||||
lcov -a baseline.info -a tests.info -o lcov-all.info
|
||||
|
||||
# Only report on src/ripple files
|
||||
lcov -e "lcov-all.info" "*/src/ripple/*" -o lcov.info
|
||||
|
||||
# Push the results (lcov.info) to codecov
|
||||
codecov -X gcov # don't even try and look for .gcov files ;)
|
||||
fi
|
||||
|
||||
# Run NPM tests
|
||||
npm install
|
||||
npm install --progress=false
|
||||
npm test --rippled=$RIPPLED_PATH
|
||||
|
||||
@@ -28,7 +28,15 @@ fi
|
||||
ls -lah ~/.npm || mkdir ~/.npm
|
||||
# Make sure we own it
|
||||
chown -Rc $USER ~/.npm
|
||||
# We use this so we can filter the subtrees from our coverage report
|
||||
pip install --user https://github.com/sublimator/codecov-python/zipball/source-match
|
||||
pip install --user https://github.com/codecov/codecov-python/archive/master.zip
|
||||
|
||||
bash bin/sh/install-boost.sh
|
||||
|
||||
# Install lcov
|
||||
# Download the archive
|
||||
wget https://github.com/linux-test-project/lcov/releases/download/v1.12/lcov-1.12.tar.gz
|
||||
# Extract to ~/lcov-1.12
|
||||
tar xfvz lcov-1.12.tar.gz -C $HOME
|
||||
# Set install path
|
||||
mkdir -p $LCOV_ROOT
|
||||
cd $HOME/lcov-1.12 && make install PREFIX=$LCOV_ROOT
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
set env MALLOC_CHECK_=3
|
||||
set print thread-events off
|
||||
run
|
||||
backtrace full
|
||||
@@ -4,4 +4,4 @@ import sys
|
||||
from ripple.util import Sign
|
||||
|
||||
result = Sign.run_command(sys.argv[1:])
|
||||
exit(0 if result else -1)
|
||||
sys.exit(0 if result else -1)
|
||||
|
||||
@@ -16,12 +16,18 @@ Usage:
|
||||
create
|
||||
Create a new master public/secret key pair.
|
||||
|
||||
create <master-secret>
|
||||
Generate master key pair using provided secret.
|
||||
|
||||
check <key>
|
||||
Check an existing key for validity.
|
||||
|
||||
sign <sequence> <validator-public> <master-secret>
|
||||
Create a new signed manifest with the given sequence
|
||||
number, validator public key, and master secret key.
|
||||
|
||||
verify <sequence> <validator-public> <signature> <master-public>
|
||||
Verify hex-encoded manifest signature with master public key.
|
||||
"""
|
||||
|
||||
def prepend_length_byte(b):
|
||||
@@ -84,6 +90,15 @@ def create_ed_keys(urandom=os.urandom):
|
||||
Base58.VER_NODE_PRIVATE, private_key)
|
||||
return public_key_human, private_key_human
|
||||
|
||||
def create_ed_public_key(private_key_human):
|
||||
v, private_key = Base58.decode_version(private_key_human)
|
||||
check_master_secret(v, private_key)
|
||||
|
||||
public_key = ed25519.publickey(private_key)
|
||||
public_key_human = Base58.encode_version(
|
||||
Base58.VER_NODE_PUBLIC, ED25519_BYTE + public_key)
|
||||
return public_key_human
|
||||
|
||||
def check_validator_public(v, validator_public_key):
|
||||
Base58.check_version(v, Base58.VER_NODE_PUBLIC)
|
||||
if len(validator_public_key) != 33:
|
||||
@@ -113,12 +128,28 @@ def get_signature(seq, validator_public_key_human, private_key_human):
|
||||
m1 = sign_manifest(m, private_key, pk)
|
||||
return base64.b64encode(m1)
|
||||
|
||||
def verify_signature(seq, validator_public_key_human, public_key_human, signature):
|
||||
v, validator_public_key = Base58.decode_version(validator_public_key_human)
|
||||
check_validator_public(v, validator_public_key)
|
||||
|
||||
v, public_key = Base58.decode_version(public_key_human)
|
||||
|
||||
m = make_manifest(public_key, validator_public_key, seq)
|
||||
public_key = public_key[1:] # Remove ED25519_BYTE
|
||||
sig = signature.decode('hex')
|
||||
ed25519.checkvalid(sig, 'MAN\0' + m, public_key)
|
||||
|
||||
# Testable versions of functions.
|
||||
def perform_create(urandom=os.urandom, print=print):
|
||||
public, private = create_ed_keys(urandom)
|
||||
print('[validator_keys]', public, '', '[master_secret]', private, sep='\n')
|
||||
|
||||
def perform_create_public(private_key_human, print=print):
|
||||
public_key_human = create_ed_public_key(private_key_human)
|
||||
print(
|
||||
'[validator_keys]',public_key_human, '',
|
||||
'[master_secret]', private_key_human, sep='\n')
|
||||
|
||||
def perform_check(s, print=print):
|
||||
version, b = Base58.decode_version(s)
|
||||
print('version = ' + Base58.version_name(version))
|
||||
@@ -131,9 +162,18 @@ def perform_sign(
|
||||
print(wrap(get_signature(
|
||||
int(seq), validator_public_key_human, private_key_human)))
|
||||
|
||||
def perform_verify(
|
||||
seq, validator_public_key_human, public_key_human, signature, print=print):
|
||||
verify_signature(
|
||||
int(seq), validator_public_key_human, public_key_human, signature)
|
||||
print('Signature valid for', public_key_human)
|
||||
|
||||
# Externally visible versions of functions.
|
||||
def create():
|
||||
perform_create()
|
||||
def create(private_key_human=None):
|
||||
if private_key_human:
|
||||
perform_create_public(private_key_human)
|
||||
else:
|
||||
perform_create()
|
||||
|
||||
def check(s):
|
||||
perform_check(s)
|
||||
@@ -141,6 +181,8 @@ def check(s):
|
||||
def sign(seq, validator_public_key_human, private_key_human):
|
||||
perform_sign(seq, validator_public_key_human, private_key_human)
|
||||
|
||||
def verify(seq, validator_public_key_human, public_key_human, signature):
|
||||
perform_verify(seq, validator_public_key_human, public_key_human, signature)
|
||||
|
||||
def usage(*errors):
|
||||
if errors:
|
||||
@@ -148,7 +190,7 @@ def usage(*errors):
|
||||
print(USAGE)
|
||||
return not errors
|
||||
|
||||
_COMMANDS = dict((f.__name__, f) for f in (create, check, sign))
|
||||
_COMMANDS = dict((f.__name__, f) for f in (create, check, sign, verify))
|
||||
|
||||
def run_command(args):
|
||||
if not args:
|
||||
|
||||
@@ -14,6 +14,10 @@ class test_Sign(TestCase):
|
||||
'JAAAABdxIe2DIKUZd9jDjKikknxnDfWCHkSXYZReFenvsmoVCdIw6nMhAnZ2dnZ2'
|
||||
'dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJM'
|
||||
'zqkBJwDz30b2SkxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA')
|
||||
VALIDATOR_KEY_HUMAN = 'n9JijuoCv8ubEy5ag3LiX3hyq27GaLJsitZPbQ6APkwx2MkUXq8E'
|
||||
SIGNATURE_HEX = (
|
||||
'0a1546caa29c887f9fcb5e6143ea101b31fb5895a5cdfa24939301c66ff51794'
|
||||
'a0b729e0ebbf576f2cc7cdb9f68c2366324a53b8e1ecf16f3c17bebbdb8d7102')
|
||||
|
||||
def setUp(self):
|
||||
self.results = []
|
||||
@@ -79,6 +83,12 @@ class test_Sign(TestCase):
|
||||
self.assertEquals(
|
||||
skh, 'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne')
|
||||
|
||||
def test_create_ed_public_key(self):
|
||||
pkh = Sign.create_ed_public_key(
|
||||
'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne')
|
||||
self.assertEquals(
|
||||
pkh, 'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY')
|
||||
|
||||
def get_test_keypair(self):
|
||||
public = (Base58.VER_NODE_PUBLIC, '\x02' + (32 * 'v'))
|
||||
private = (Base58.VER_NODE_PRIVATE, 32 * 'k')
|
||||
@@ -96,6 +106,11 @@ class test_Sign(TestCase):
|
||||
'dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJM'
|
||||
'zqkBJwDz30b2SkxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA')
|
||||
|
||||
def test_verify_signature(self):
|
||||
Sign.verify_signature(self.SEQUENCE, self.VALIDATOR_KEY_HUMAN,
|
||||
'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY',
|
||||
self.SIGNATURE_HEX)
|
||||
|
||||
def test_check(self):
|
||||
public = Base58.encode_version(Base58.VER_NODE_PRIVATE, 32 * 'k')
|
||||
Sign.perform_check(public, self.print)
|
||||
@@ -114,6 +129,18 @@ class test_Sign(TestCase):
|
||||
'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne'],
|
||||
{'sep': '\n'}]])
|
||||
|
||||
def test_create_public(self):
|
||||
Sign.perform_create_public(
|
||||
'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne', self.print)
|
||||
self.assertEquals(
|
||||
self.results,
|
||||
[[['[validator_keys]',
|
||||
'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY',
|
||||
'',
|
||||
'[master_secret]',
|
||||
'pnEp13Zu7xTeKQVQ2RZVaUraE9GXKqFtnXQVUFKXbTE6wsP4wne'],
|
||||
{'sep': '\n'}]])
|
||||
|
||||
def test_sign(self):
|
||||
public, private = self.get_test_keypair()
|
||||
Sign.perform_sign(self.SEQUENCE, public, private, print=self.print)
|
||||
@@ -125,3 +152,8 @@ class test_Sign(TestCase):
|
||||
'Z2dnZ2dkDOjlWtQSvRTjuwe+4iNusg0sJMzqkBJwDz30b2S\n'
|
||||
'kxZ7Fte/Vx4htM/kkfUfJCaxmxE5N4dHSKuiO9iDHsktqIA'],
|
||||
{}]])
|
||||
|
||||
def test_verify(self):
|
||||
Sign.perform_verify(self.SEQUENCE, self.VALIDATOR_KEY_HUMAN,
|
||||
'nHUUaKHpxyRP4TZZ79tTpXuTpoM8pRNs5crZpGVA5jdrjib5easY',
|
||||
self.SIGNATURE_HEX, print=self.print)
|
||||
|
||||
29
circle.yml
@@ -3,13 +3,11 @@ machine:
|
||||
- docker
|
||||
dependencies:
|
||||
pre:
|
||||
- sudo apt-add-repository -y 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.6 main'
|
||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:afrank/boost
|
||||
- wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
- echo "deb [arch=amd64 trusted=yes] https://test-mirrors.ripple.com/ubuntu/ trusty testing" | sudo tee /etc/apt/sources.list.d/ripple.list
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get purge -qq libboost1.48-dev
|
||||
- sudo apt-get install -qq libboost1.57-all-dev
|
||||
- sudo apt-get install -qq libboost1.60-all-dev
|
||||
- sudo apt-get install -qq clang-3.6 gcc-5 g++-5 libobjc-5-dev libgcc-5-dev libstdc++-5-dev libclang1-3.6 libgcc1 libgomp1 libstdc++6 scons protobuf-compiler libprotobuf-dev libssl-dev exuberant-ctags
|
||||
- lsb_release -a
|
||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99
|
||||
@@ -22,26 +20,9 @@ test:
|
||||
pre:
|
||||
- scons clang.debug
|
||||
override:
|
||||
- | # create gdb script
|
||||
echo "set env MALLOC_CHECK_=3" > script.gdb
|
||||
echo "run" >> script.gdb
|
||||
echo "backtrace full" >> script.gdb
|
||||
# gdb --help
|
||||
# gdb segfaults
|
||||
# - cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args build/clang.debug/rippled --unittest
|
||||
- build/clang.debug/rippled --unittest
|
||||
- npm install
|
||||
# Use build/(gcc|clang).debug/rippled
|
||||
# Execute unit tests under gdb
|
||||
- gdb -return-child-result -quiet -batch -ex "set env MALLOC_CHECK_=3" -ex "set print thread-events off" -ex run -ex "thread apply all backtrace full" -ex "quit" --args build/clang.debug/rippled --unittest
|
||||
- npm install --progress=false
|
||||
- |
|
||||
echo "exports.default_server_config = {\"rippled_path\" : \"$HOME/rippled/build/clang.debug/rippled\"};" > test/config.js
|
||||
|
||||
# Run integration tests
|
||||
- npm test
|
||||
post:
|
||||
- ./Builds/Docker/build-ci.sh
|
||||
- docker images
|
||||
deployment:
|
||||
docker:
|
||||
branch: /.*/
|
||||
commands:
|
||||
- ./Builds/Docker/push-to-hub.sh
|
||||
|
||||
@@ -418,16 +418,77 @@
|
||||
#
|
||||
# The queue will be limited to this <number> of average ledgers'
|
||||
# worth of transactions. If the queue fills up, the transactions
|
||||
# with the lowest fees will be dropped from the queue any time a
|
||||
# transaction with a higher fee level is added. Default: 20.
|
||||
# with the lowest fee levels will be dropped from the queue any
|
||||
# time a transaction with a higher fee level is added.
|
||||
# Default: 20.
|
||||
#
|
||||
# retry_sequence_percent = <number>
|
||||
#
|
||||
# If a client resubmits a transaction, the new transaction's fee
|
||||
# must be more than <number> percent higher than the original
|
||||
# transaction's fee, or meet the current open ledger fee to be
|
||||
# considered. Default: 125.
|
||||
# If a client replaces a transaction in the queue (same sequence
|
||||
# number as a transaction already in the queue), the new
|
||||
# transaction's fee must be more than <number> percent higher
|
||||
# than the original transaction's fee, or meet the current open
|
||||
# ledger fee to be considered. Default: 25.
|
||||
#
|
||||
# multi_txn_percent = <number>
|
||||
#
|
||||
# If a client submits multiple transactions (different sequence
|
||||
# numbers), later transactions must pay a fee at least <number>
|
||||
# percent higher than the transaction with the previous sequence
|
||||
# number.
|
||||
# Default: -90.
|
||||
#
|
||||
# minimum_escalation_multiplier = <number>
|
||||
#
|
||||
# At ledger close time, the median fee level of the transactions
|
||||
# in that ledger is used as a multiplier in escalation
|
||||
# calculations of the next ledger. This minimum value ensures that
|
||||
# the escalation is significant. Default: 500.
|
||||
#
|
||||
# minimum_txn_in_ledger = <number>
|
||||
#
|
||||
# Minimum number of transactions that must be allowed into the
|
||||
# ledger at the minimum required fee before the required fee
|
||||
# escalates. Default: 5.
|
||||
#
|
||||
# minimum_txn_in_ledger_standalone = <number>
|
||||
#
|
||||
# Like minimum_txn_in_ledger when rippled is running in standalone
|
||||
# mode. Default: 1000.
|
||||
#
|
||||
# target_txn_in_ledger = <number>
|
||||
#
|
||||
# Number of transactions allowed into the ledger at the minimum
|
||||
# required fee that the queue will "work toward" as long as
|
||||
# consensus stays healthy. The limit will grow quickly until it
|
||||
# reaches or exceeds this number. After that the limit may still
|
||||
# change, but will stay above the target. If consensus is not
|
||||
# healthy, the limit will be clamped to this value or lower.
|
||||
# Default: 50.
|
||||
#
|
||||
# maximum_txn_in_ledger = <number>
|
||||
#
|
||||
# (Optional) Maximum number of transactions that will be allowed
|
||||
# into the ledger at the minimum required fee before the required
|
||||
# fee escalates. Default: no maximum.
|
||||
#
|
||||
# maximum_txn_per_account = <number>
|
||||
#
|
||||
# Maximum number of transactions that one account can have in the
|
||||
# queue at any given time. Default: 10.
|
||||
#
|
||||
# minimum_last_ledger_buffer = <number>
|
||||
#
|
||||
# If a transaction has a LastLedgerSequence, it must be at least
|
||||
# this much larger than the current open ledger sequence number.
|
||||
# Default: 2.
|
||||
#
|
||||
# zero_basefee_transaction_feelevel = <number>
|
||||
#
|
||||
# So we don't deal with infinite fee levels, treat any transaction
|
||||
# with a 0 base fee (ie. SetRegularKey password recovery) as
|
||||
# having this fee level.
|
||||
# Default: 256000.
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -452,14 +513,6 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
# [validation_quorum]
|
||||
#
|
||||
# Sets the minimum number of trusted validations a ledger must have before
|
||||
# the server considers it fully validated. Note that if you are validating,
|
||||
# your validation counts.
|
||||
#
|
||||
#
|
||||
#
|
||||
# [ledger_history]
|
||||
#
|
||||
# The number of past ledgers to acquire on server startup and the minimum to
|
||||
@@ -501,53 +554,36 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
# [validators]
|
||||
#
|
||||
# List of nodes to always accept as validators. Nodes are specified by domain
|
||||
# or public key.
|
||||
#
|
||||
# For domains, rippled will probe for https web servers at the specified
|
||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
||||
#
|
||||
# For public key entries, a comment may optionally be specified after adding
|
||||
# a space to the public key.
|
||||
#
|
||||
# Examples:
|
||||
# ripple.com
|
||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
||||
#
|
||||
#
|
||||
#
|
||||
# [validators_file]
|
||||
#
|
||||
# Path to file contain a list of nodes to always accept as validators. Use
|
||||
# this to specify a file other than this file to manage your validators list.
|
||||
# Path or name of a file that contains the validation public keys of nodes
|
||||
# to always accept as validators as well as the minimum number of validators
|
||||
# needed to accept consensus.
|
||||
#
|
||||
# If this entry is not present or empty and no nodes from previous runs were
|
||||
# found in the database, rippled will look for a validators.txt in the config
|
||||
# directory. If not found there, it will attempt to retrieve the file from
|
||||
# the [validators_site] web site.
|
||||
# The contents of the file should include a [validators] and a
|
||||
# [validation_quorum] entry. [validators] should be followed by
|
||||
# a list of validation public keys of nodes, one per line, optionally
|
||||
# followed by a comment separated by whitespace.
|
||||
# [validation_quorum] should be followed by a number.
|
||||
#
|
||||
# After specifying a different [validators_file] or changing the contents of
|
||||
# the validators file, issue a RPC unl_load command to have rippled load the
|
||||
# file.
|
||||
#
|
||||
# Specify the file by specifying its full path.
|
||||
# Specify the file by its name or path.
|
||||
# Unless an absolute path is specified, it will be considered relative to
|
||||
# the folder in which the rippled.cfg file is located.
|
||||
#
|
||||
# Examples:
|
||||
# C:/home/johndoe/ripple/validators.txt
|
||||
# /home/johndoe/ripple/validators.txt
|
||||
# /home/ripple/validators.txt
|
||||
# C:/home/ripple/validators.txt
|
||||
#
|
||||
# Example content:
|
||||
# [validators]
|
||||
# n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
||||
# n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
||||
# n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
||||
# n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
||||
# n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
||||
#
|
||||
#
|
||||
# [validators_site]
|
||||
#
|
||||
# Specifies where to find validators.txt for UNL boostrapping and RPC
|
||||
# unl_network command.
|
||||
#
|
||||
# Example: ripple.com
|
||||
#
|
||||
# [validation_quorum]
|
||||
# 3
|
||||
#
|
||||
#
|
||||
# [path_search]
|
||||
@@ -938,22 +974,11 @@ pool.ntp.org
|
||||
[ips]
|
||||
r.ripple.com 51235
|
||||
|
||||
# Public keys of the validators that this rippled instance trusts. The latest
|
||||
# list of validators can be obtained from https://ripple.com/ripple.txt
|
||||
#
|
||||
# See also https://wiki.ripple.com/Ripple.txt
|
||||
#
|
||||
[validators]
|
||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
||||
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
||||
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
||||
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
||||
|
||||
# The number of validators rippled needs to accept a consensus.
|
||||
# Don't change this unless you know what you're doing.
|
||||
[validation_quorum]
|
||||
3
|
||||
# File containing validation quorum and trusted validator keys.
|
||||
# Unless an absolute path is specified, it will be considered relative to the
|
||||
# folder in which the rippled.cfg file is located.
|
||||
[validators_file]
|
||||
validators.txt
|
||||
|
||||
# Turn down default logging to save disk space in the long run.
|
||||
# Valid values here are trace, debug, info, warning, error, and fatal
|
||||
|
||||
@@ -8,20 +8,41 @@
|
||||
# Blank lines and lines starting with a '#' are ignored.
|
||||
# All other lines should be hankos or domain names.
|
||||
#
|
||||
# [validators]:
|
||||
# List of nodes to accept as validators specified by public key or domain.
|
||||
#
|
||||
# For domains, rippled will probe for https web servers at the specified
|
||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
||||
#
|
||||
# Examples: redstem.com
|
||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
||||
# [validators]
|
||||
#
|
||||
# List of the validation public keys of nodes to always accept as validators.
|
||||
# A comment may, optionally, be associated with each entry, separated by
|
||||
# whitespace from the validation public key.
|
||||
#
|
||||
# The latest list of recommended validators can be obtained from
|
||||
# https://ripple.com/ripple.txt
|
||||
#
|
||||
# See also https://wiki.ripple.com/Ripple.txt
|
||||
#
|
||||
# Examples:
|
||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
||||
#
|
||||
#
|
||||
#
|
||||
# [validation_quorum]
|
||||
#
|
||||
# Sets the minimum number of trusted validations a ledger must have before
|
||||
# the server considers it fully validated. Note that if you are validating,
|
||||
# your validation counts.
|
||||
#
|
||||
|
||||
# Public keys of the validators that this rippled instance trusts.
|
||||
[validators]
|
||||
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
|
||||
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
|
||||
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
|
||||
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
|
||||
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
|
||||
|
||||
# The number of validators rippled needs to accept a consensus.
|
||||
# Don't change this unless you know what you're doing.
|
||||
[validation_quorum]
|
||||
3
|
||||
|
||||
BIN
images/build.png
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
BIN
images/flow1.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
images/flow2.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 71 KiB |
@@ -149,13 +149,6 @@
|
||||
#define RIPPLE_USE_VALIDATORS 0
|
||||
#endif
|
||||
|
||||
/** Config: RIPPLE_PROPOSE_FEATURES
|
||||
This determines whether to add any features to the proposed transaction set.
|
||||
*/
|
||||
#ifndef RIPPLE_PROPOSE_AMENDMENTS
|
||||
#define RIPPLE_PROPOSE_AMENDMENTS 0
|
||||
#endif
|
||||
|
||||
/** Config: RIPPLE_SINGLE_IO_SERVICE_THREAD
|
||||
When set, restricts the number of threads calling io_service::run to one.
|
||||
This is useful when debugging.
|
||||
|
||||
10
src/beast/.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
Docs
|
||||
docs/
|
||||
._*
|
||||
*.mode1v3
|
||||
*.pbxuser
|
||||
@@ -23,8 +23,8 @@ contents.xcworkspacedata
|
||||
.DS_Store
|
||||
.svn
|
||||
profile
|
||||
Builds/VisualStudio2012/Debug
|
||||
Builds/VisualStudio2012/Release
|
||||
project.xcworkspace
|
||||
modules/beast_cryptopp
|
||||
bin/
|
||||
node_modules/
|
||||
cov-int/
|
||||
nohup.out
|
||||
venv/
|
||||
|
||||
@@ -1,26 +1,93 @@
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
env:
|
||||
global:
|
||||
# Maintenance note: to move to a new version
|
||||
# of boost, update both BOOST_ROOT and BOOST_URL.
|
||||
# Note that for simplicity, BOOST_ROOT's final
|
||||
# namepart must match the folder name internal
|
||||
# to boost's .tar.gz.
|
||||
- LCOV_ROOT=$HOME/lcov
|
||||
- VALGRIND_ROOT=$HOME/valgrind-install
|
||||
- BOOST_ROOT=$HOME/boost_1_60_0
|
||||
- BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.gz?r=https%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.60.0%2Fboost_1_60_0.tar.gz&ts=1460417589&use_mirror=netix'
|
||||
packages: &gcc5_pkgs
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- python-software-properties
|
||||
- libssl-dev
|
||||
- libffi-dev
|
||||
- libstdc++6
|
||||
- binutils-gold
|
||||
# Provides a backtrace if the unittests crash
|
||||
- gdb
|
||||
# Needed for installing valgrind
|
||||
- subversion
|
||||
- automake
|
||||
- autotools-dev
|
||||
- libc6-dbg
|
||||
|
||||
packages: &clang38_pkgs
|
||||
- clang-3.8
|
||||
- g++-5
|
||||
- python-software-properties
|
||||
- libssl-dev
|
||||
- libffi-dev
|
||||
- libstdc++6
|
||||
- binutils-gold
|
||||
# Provides a backtrace if the unittests crash
|
||||
- gdb
|
||||
# Needed for installing valgrind
|
||||
- subversion
|
||||
- automake
|
||||
- autotools-dev
|
||||
- libc6-dbg
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# GCC/Coverage
|
||||
- compiler: gcc
|
||||
env: GCC_VER=5 VARIANT=coverage ADDRESS_MODEL=64
|
||||
addons: &ao_gcc5
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: *gcc5_pkgs
|
||||
|
||||
# # GCC/Debug
|
||||
# - compiler: gcc
|
||||
# env: GCC_VER=5 VARIANT=debug ADDRESS_MODEL=64
|
||||
# addons: *ao_gcc5
|
||||
# branches: # NOTE: this does NOT work, though it SHOULD
|
||||
# - master
|
||||
# - develop
|
||||
|
||||
# Clang/UndefinedBehaviourSanitizer
|
||||
- compiler: clang
|
||||
env: GCC_VER=5 VARIANT=usan CLANG_VER=3.8 ADDRESS_MODEL=64 UBSAN_OPTIONS='print_stacktrace=1'
|
||||
addons: &ao_clang38
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.8']
|
||||
packages: *clang38_pkgs
|
||||
|
||||
# Clang/AddressSanitizer
|
||||
- compiler: clang
|
||||
env: GCC_VER=5 VARIANT=asan CLANG_VER=3.8 ADDRESS_MODEL=64
|
||||
addons: *ao_clang38
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $BOOST_ROOT
|
||||
- $VALGRIND_ROOT
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq python-software-properties
|
||||
- sudo apt-get install -qq g++-4.8
|
||||
- sudo apt-get install -qq libboost1.55-all-dev
|
||||
- sudo apt-get install -qq libssl-dev
|
||||
- sudo apt-get install -qq gcc-4.8
|
||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
|
||||
- sudo update-alternatives --set gcc /usr/bin/gcc-4.8
|
||||
# - sudo apt-get -y install binutils-gold
|
||||
- g++ -v
|
||||
- clang -v
|
||||
- scripts/install-dependencies.sh
|
||||
|
||||
script:
|
||||
# Abort build on failure
|
||||
- set -e
|
||||
- scons
|
||||
- scripts/build-and-test.sh
|
||||
|
||||
after_script:
|
||||
- cat nohup.out || echo "nohup.out already deleted"
|
||||
|
||||
notifications:
|
||||
email:
|
||||
false
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_BEASTCONFIG_H_INCLUDED
|
||||
#define BEAST_BEASTCONFIG_H_INCLUDED
|
||||
|
||||
/** Configuration file for Beast.
|
||||
This sets various configurable options for Beast. In order to compile you
|
||||
must place a copy of this file in a location where your build environment
|
||||
can find it, and then customize its contents to suit your needs.
|
||||
@file BeastConfig.h
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Unit Tests
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Config: BEAST_NO_UNIT_TEST_INLINE
|
||||
Prevents unit test definitions from being inserted into a global table.
|
||||
*/
|
||||
#ifndef BEAST_NO_UNIT_TEST_INLINE
|
||||
#define BEAST_NO_UNIT_TEST_INLINE 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Diagnostics
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Config: BEAST_FORCE_DEBUG
|
||||
Normally, BEAST_DEBUG is set to 1 or 0 based on compiler and project
|
||||
settings, but if you define this value, you can override this to force it
|
||||
to be true or false.
|
||||
*/
|
||||
#ifndef BEAST_FORCE_DEBUG
|
||||
//#define BEAST_FORCE_DEBUG 1
|
||||
#endif
|
||||
|
||||
/** Config: BEAST_CHECK_MEMORY_LEAKS
|
||||
Enables a memory-leak check for certain objects when the app terminates.
|
||||
See the LeakChecked class for more details about enabling leak checking for
|
||||
specific classes.
|
||||
*/
|
||||
#ifndef BEAST_CHECK_MEMORY_LEAKS
|
||||
//#define BEAST_CHECK_MEMORY_LEAKS 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Libraries
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Config: BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||
In a Visual C++ build, this can be used to stop the required system libs
|
||||
being automatically added to the link stage.
|
||||
*/
|
||||
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||
//#define BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
|
||||
#endif
|
||||
|
||||
/** Config: BEAST_INCLUDE_ZLIB_CODE
|
||||
This can be used to disable Beast's embedded 3rd-party zlib code.
|
||||
You might need to tweak this if you're linking to an external zlib library
|
||||
in your app, but for normal apps, this option should be left alone.
|
||||
|
||||
If you disable this, you might also want to set a value for
|
||||
BEAST_ZLIB_INCLUDE_PATH, to specify the path where your zlib headers live.
|
||||
*/
|
||||
#ifndef BEAST_INCLUDE_ZLIB_CODE
|
||||
//#define BEAST_INCLUDE_ZLIB_CODE 1
|
||||
#endif
|
||||
|
||||
/** Config: BEAST_ZLIB_INCLUDE_PATH
|
||||
This is included when BEAST_INCLUDE_ZLIB_CODE is set to zero.
|
||||
*/
|
||||
#ifndef BEAST_ZLIB_INCLUDE_PATH
|
||||
#define BEAST_ZLIB_INCLUDE_PATH <zlib.h>
|
||||
#endif
|
||||
|
||||
/** Config: BEAST_SQLITE_FORCE_NDEBUG
|
||||
Setting this option forces sqlite into release mode even if NDEBUG is not set
|
||||
*/
|
||||
#ifndef BEAST_SQLITE_FORCE_NDEBUG
|
||||
//#define BEAST_SQLITE_FORCE_NDEBUG 1
|
||||
#endif
|
||||
|
||||
/** Config: BEAST_FUNCTIONAL_USES_###
|
||||
<functional> source configuration.
|
||||
Set one of these to manually force a particular implementation of bind().
|
||||
If nothing is chosen then beast will use whatever is appropriate for your
|
||||
environment based on what is available.
|
||||
If you override these, set ONE to 1 and the rest to 0
|
||||
*/
|
||||
#ifndef BEAST_FUNCTIONAL_USES_STD
|
||||
//#define BEAST_FUNCTIONAL_USES_STD 0
|
||||
#endif
|
||||
#ifndef BEAST_FUNCTIONAL_USES_TR1
|
||||
//#define BEAST_FUNCTIONAL_USES_TR1 0
|
||||
#endif
|
||||
#ifndef BEAST_FUNCTIONAL_USES_BOOST
|
||||
//#define BEAST_FUNCTIONAL_USES_BOOST 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Boost
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Config: BEAST_USE_BOOST_FEATURES
|
||||
This activates boost specific features and improvements. If this is
|
||||
turned on, the include paths for your build environment must be set
|
||||
correctly to find the boost headers.
|
||||
*/
|
||||
#ifndef BEAST_USE_BOOST_FEATURES
|
||||
//#define BEAST_USE_BOOST_FEATURES 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
21
src/beast/CHANGELOG
Normal file
@@ -0,0 +1,21 @@
|
||||
1.0.0-b6
|
||||
|
||||
* Use SFINAE on return values
|
||||
* Use beast::error_code instead of nested types
|
||||
* Tidy up use of GENERATING_DOCS
|
||||
* Remove obsolete RFC2616 functions
|
||||
* Add message swap members and free functions
|
||||
* Add HTTP field value parser containers: ext_list, param_list, token_list
|
||||
* Fixes for some corner cases in basic_parser_v1
|
||||
* Configurable limits on headers and body sizes in basic_parser_v1
|
||||
|
||||
API Changes:
|
||||
|
||||
* ci_equal is moved to beast::http namespace, in rfc7230.hpp
|
||||
|
||||
* "DynamicBuffer","dynabuf" renamed from "Streambuf", "streambuf". See:
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4478.html#requirements.dynamic_buffers
|
||||
|
||||
* basic_parser_v1 adheres to rfc7230 as strictly as possible
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
64
src/beast/CMakeLists.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
# Part of Beast
|
||||
|
||||
cmake_minimum_required (VERSION 3.2)
|
||||
|
||||
project (Beast)
|
||||
|
||||
set_property (GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
if (WIN32)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4 /wd4100 /D_SCL_SECURE_NO_WARNINGS=1 /D_CRT_SECURE_NO_WARNINGS=1")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
else()
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
find_package(Boost REQUIRED COMPONENTS coroutine context thread filesystem program_options system)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
link_directories(${Boost_LIBRARY_DIR})
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -g -std=c++11 -Wall -Wpedantic")
|
||||
endif()
|
||||
|
||||
message ("cxx Flags: " ${CMAKE_CXX_FLAGS})
|
||||
|
||||
function(DoGroupSources curdir rootdir folder)
|
||||
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
|
||||
foreach(child ${children})
|
||||
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
DoGroupSources(${curdir}/${child} ${rootdir} ${folder})
|
||||
elseif(${child} STREQUAL "CMakeLists.txt")
|
||||
source_group("" FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
else()
|
||||
string(REGEX REPLACE ^${rootdir} ${folder} groupname ${curdir})
|
||||
#set(groupname ${curdir})
|
||||
string(REPLACE "/" "\\" groupname ${groupname})
|
||||
source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(GroupSources curdir folder)
|
||||
DoGroupSources(${curdir} ${curdir} ${folder})
|
||||
endfunction()
|
||||
|
||||
include_directories (extras)
|
||||
include_directories (include)
|
||||
|
||||
file(GLOB_RECURSE BEAST_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/beast/*.ipp
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/extras/beast/*.ipp
|
||||
)
|
||||
|
||||
add_subdirectory (examples)
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (test/core)
|
||||
add_subdirectory (test/http)
|
||||
add_subdirectory (test/websocket)
|
||||
|
||||
#enable_testing()
|
||||
126
src/beast/Jamroot
Normal file
@@ -0,0 +1,126 @@
|
||||
#
|
||||
# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#
|
||||
|
||||
import os ;
|
||||
import feature ;
|
||||
import boost ;
|
||||
|
||||
boost.use-project ;
|
||||
|
||||
if [ os.name ] = SOLARIS
|
||||
{
|
||||
lib socket ;
|
||||
lib nsl ;
|
||||
}
|
||||
else if [ os.name ] = NT
|
||||
{
|
||||
lib ws2_32 ;
|
||||
lib mswsock ;
|
||||
}
|
||||
else if [ os.name ] = HPUX
|
||||
{
|
||||
lib ipv6 ;
|
||||
}
|
||||
else if [ os.name ] = QNXNTO
|
||||
{
|
||||
lib socket ;
|
||||
}
|
||||
else if [ os.name ] = HAIKU
|
||||
{
|
||||
lib network ;
|
||||
}
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
lib ssl : : <name>ssleay32 ;
|
||||
lib crypto : : <name>libeay32 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lib ssl ;
|
||||
lib crypto ;
|
||||
}
|
||||
|
||||
variant coverage
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fprofile-arcs -ftest-coverage"
|
||||
<linkflags>"-lgcov"
|
||||
;
|
||||
|
||||
variant asan
|
||||
:
|
||||
release
|
||||
:
|
||||
<cxxflags>"-fsanitize=address -fno-omit-frame-pointer"
|
||||
<linkflags>"-fsanitize=address"
|
||||
;
|
||||
|
||||
variant msan
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fsanitize=memory -fno-omit-frame-pointer -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor"
|
||||
<linkflags>"-fsanitize=memory"
|
||||
;
|
||||
|
||||
variant usan
|
||||
:
|
||||
debug
|
||||
:
|
||||
<cxxflags>"-fsanitize=undefined -fno-omit-frame-pointer"
|
||||
<linkflags>"-fsanitize=undefined"
|
||||
;
|
||||
|
||||
project beast
|
||||
: requirements
|
||||
<include>.
|
||||
<include>./extras
|
||||
<include>./include
|
||||
#<use>/boost//headers
|
||||
<library>/boost/system//boost_system
|
||||
<library>/boost/coroutine//boost_coroutine
|
||||
<library>/boost/filesystem//boost_filesystem
|
||||
<library>/boost/program_options//boost_program_options
|
||||
# <library>ssl
|
||||
# <library>crypto
|
||||
<define>BOOST_ALL_NO_LIB=1
|
||||
<define>BOOST_SYSTEM_NO_DEPRECATED=1
|
||||
<threading>multi
|
||||
<link>static
|
||||
<runtime-link>shared
|
||||
<debug-symbols>on
|
||||
<toolset>gcc:<cxxflags>-std=c++11
|
||||
<toolset>gcc:<cxxflags>-Wno-unused-variable
|
||||
<toolset>clang:<cxxflags>-std=c++11
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS=1
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS=1
|
||||
<os>LINUX:<define>_XOPEN_SOURCE=600
|
||||
<os>LINUX:<define>_GNU_SOURCE=1
|
||||
<os>SOLARIS:<define>_XOPEN_SOURCE=500
|
||||
<os>SOLARIS:<define>__EXTENSIONS__
|
||||
<os>SOLARIS:<library>socket
|
||||
<os>SOLARIS:<library>nsl
|
||||
<os>NT:<define>_WIN32_WINNT=0x0601
|
||||
<os>NT,<toolset>cw:<library>ws2_32
|
||||
<os>NT,<toolset>cw:<library>mswsock
|
||||
<os>NT,<toolset>gcc:<library>ws2_32
|
||||
<os>NT,<toolset>gcc:<library>mswsock
|
||||
<os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
|
||||
<os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
|
||||
<os>HPUX:<library>ipv6
|
||||
<os>QNXNTO:<library>socket
|
||||
<os>HAIKU:<library>network
|
||||
: usage-requirements
|
||||
<include>.
|
||||
:
|
||||
build-dir bin
|
||||
;
|
||||
|
||||
build-project test ;
|
||||
build-project examples ;
|
||||
99
src/beast/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Beast
|
||||
|
||||
[](https://gitter.im/vinniefalco/Beast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status]
|
||||
(https://travis-ci.org/vinniefalco/Beast.svg?branch=master)](https://travis-ci.org/vinniefalco/Beast) [![codecov]
|
||||
(https://codecov.io/gh/vinniefalco/Beast/branch/master/graph/badge.svg)](https://codecov.io/gh/vinniefalco/Beast) [![coveralls]
|
||||
(https://coveralls.io/repos/github/vinniefalco/Beast/badge.svg?branch=master)](https://coveralls.io/github/vinniefalco/Beast?branch=master) [![Documentation]
|
||||
(https://img.shields.io/badge/documentation-master-brightgreen.svg)](http://vinniefalco.github.io/beast/) [![License]
|
||||
(https://img.shields.io/badge/license-boost-brightgreen.svg)](LICENSE_1_0.txt)
|
||||
|
||||
Beast provides implementations of the HTTP and WebSocket protocols
|
||||
built on top of Boost.Asio and other parts of boost.
|
||||
|
||||
Requirements:
|
||||
|
||||
* Boost
|
||||
* C++11 or greater
|
||||
* OpenSSL (optional)
|
||||
|
||||
This software is currently in beta: interfaces are subject to change. For
|
||||
recent changes see [CHANGELOG](CHANGELOG).
|
||||
The library has been submitted to the
|
||||
[Boost Library Incubator](http://rrsd.com/blincubator.com/bi_library/beast-2/?gform_post_id=1579)
|
||||
|
||||
Example WebSocket program:
|
||||
```C++
|
||||
#include <beast/to_string.hpp>
|
||||
#include <beast/websocket.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "echo.websocket.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r(ios);
|
||||
boost::asio::ip::tcp::socket sock(ios);
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
|
||||
|
||||
// WebSocket connect and send message using beast
|
||||
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock);
|
||||
ws.handshake(host, "/");
|
||||
ws.write(boost::asio::buffer("Hello, world!"));
|
||||
|
||||
// Receive WebSocket message, print and close using beast
|
||||
beast::streambuf sb;
|
||||
beast::websocket::opcode op;
|
||||
ws.read(op, sb);
|
||||
ws.close(beast::websocket::close_code::normal);
|
||||
std::cout << to_string(sb.data()) << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
Example HTTP program:
|
||||
```C++
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Normal boost::asio setup
|
||||
std::string const host = "boost.org";
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ip::tcp::resolver r(ios);
|
||||
boost::asio::ip::tcp::socket sock(ios);
|
||||
boost::asio::connect(sock,
|
||||
r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
|
||||
|
||||
// Send HTTP request using beast
|
||||
beast::http::request_v1<beast::http::empty_body> req;
|
||||
req.method = "GET";
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
|
||||
req.headers.replace("User-Agent", "Beast");
|
||||
beast::http::prepare(req);
|
||||
beast::http::write(sock, req);
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
beast::http::response_v1<beast::http::streambuf_body> resp;
|
||||
beast::http::read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
```
|
||||
|
||||
Links:
|
||||
|
||||
* [Home](http://vinniefalco.github.io/)
|
||||
* [Repository](https://github.com/vinniefalco/Beast)
|
||||
* [Documentation](http://vinniefalco.github.io/beast/)
|
||||
* [Autobahn.testsuite results](http://vinniefalco.github.io/autobahn/index.html)
|
||||
|
||||
Please report issues or questions here:
|
||||
https://github.com/vinniefalco/Beast/issues
|
||||
@@ -1,31 +0,0 @@
|
||||
# Beast: An amazing cross platform library
|
||||
|
||||
Contains cross platform objects to do a variety of useful things.
|
||||
No external dependencies, no complicated build steps.
|
||||
|
||||
Things people need for building peer to peer, concurrent, cryptographic systems.
|
||||
|
||||
The hope is that this will replace the use of boost and other cumbersome jalopies.
|
||||
|
||||
## JUCE
|
||||
|
||||
Parts of Beast are based on the juce_core module which is provided under the ISC
|
||||
license. More information about JUCE is available at
|
||||
|
||||
http://www.juce.com
|
||||
|
||||
## License
|
||||
|
||||
Beast is provided under the terms of the ISC license:
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -1,139 +0,0 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import copy
|
||||
import itertools
|
||||
import ntpath
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
|
||||
def add_beast_to_path():
|
||||
python_home = os.path.join(os.getcwd(), 'python')
|
||||
if python_home not in sys.path:
|
||||
sys.path.append(python_home)
|
||||
|
||||
add_beast_to_path()
|
||||
|
||||
from beast.env.AddCommonFlags import add_common_flags
|
||||
from beast.env.AddUserEnv import add_user_env
|
||||
from beast.env import Print
|
||||
from beast.platform import GetEnvironment
|
||||
from beast.util import Boost
|
||||
from beast.util import File
|
||||
from beast.util import Tests
|
||||
|
||||
VARIANT_DIRECTORIES = {
|
||||
'beast': ('bin', 'beast'),
|
||||
'modules': ('bin', 'modules'),
|
||||
}
|
||||
|
||||
BOOST_LIBRARIES = '' #boost_system'
|
||||
MAIN_PROGRAM_FILE = 'beast/unit_test/tests/main.cpp'
|
||||
DOTFILE = '~/.scons'
|
||||
|
||||
def main():
|
||||
File.validate_libraries(Boost.LIBPATH, BOOST_LIBRARIES)
|
||||
defaults = GetEnvironment.get_environment(ARGUMENTS)
|
||||
working = copy.deepcopy(defaults)
|
||||
add_common_flags(defaults)
|
||||
|
||||
add_user_env(working, DOTFILE)
|
||||
add_common_flags(working)
|
||||
Print.print_build_config(working, defaults)
|
||||
|
||||
env = Environment(**working)
|
||||
|
||||
for name, path in VARIANT_DIRECTORIES.items():
|
||||
env.VariantDir(os.path.join(*path), name, duplicate=0)
|
||||
env.Replace(PRINT_CMD_LINE_FUNC=Print.print_cmd_line)
|
||||
#Tests.run_tests(env, MAIN_PROGRAM_FILE, '.', '.test.cpp')
|
||||
|
||||
#main()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def is_unity(path):
|
||||
b, e = os.path.splitext(path)
|
||||
return os.path.splitext(b)[1] == '.unity' and e in ['.c', '.cpp']
|
||||
|
||||
def files(base):
|
||||
for parent, _, files in os.walk(base):
|
||||
for path in files:
|
||||
path = os.path.join(parent, path)
|
||||
yield os.path.normpath(path)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
'''
|
||||
/MP /GS /W3 /wd"4018" /wd"4244" /wd"4267" /Gy- /Zc:wchar_t
|
||||
/I"D:\lib\OpenSSL-Win64\include" /I"D:\lib\boost_1_55_0"
|
||||
/I"..\..\src\protobuf\src" /I"..\..\src\protobuf\vsprojects"
|
||||
/I"..\..\src\leveldb" /I"..\..\src\leveldb\include" /I"..\..\build\proto"
|
||||
/Zi /Gm- /Od /Fd"..\..\build\obj\VisualStudio2013\Debug.x64\vc120.pdb"
|
||||
/fp:precise /D "_CRTDBG_MAP_ALLOC" /D "WIN32" /D "_DEBUG" /D "_CONSOLE"
|
||||
/D "_VARIADIC_MAX=10" /D "_WIN32_WINNT=0x0600" /D "_SCL_SECURE_NO_WARNINGS"
|
||||
/D "_CRT_SECURE_NO_WARNINGS" /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope
|
||||
/RTC1 /GR /Gd /MTd /openmp- /Fa"..\..\build\obj\VisualStudio2013\Debug.x64\"
|
||||
/EHa /nologo /Fo"..\..\build\obj\VisualStudio2013\Debug.x64\"
|
||||
/Fp"..\..\build\obj\VisualStudio2013\Debug.x64\rippled.pch"
|
||||
'''
|
||||
|
||||
# Path to this SConstruct file
|
||||
base_dir = Dir('#').srcnode().get_abspath()
|
||||
|
||||
base_env = Environment(
|
||||
tools = ['default', 'VSProject'],
|
||||
CCCOMSTR = '',
|
||||
CMDLINE_QUIET = 1,
|
||||
CPPPATH = [
|
||||
os.environ['BOOST_ROOT'],
|
||||
os.environ['OPENSSL_ROOT']
|
||||
],
|
||||
CPPDEFINES = [
|
||||
'_WIN32_WINNT=0x6000']
|
||||
)
|
||||
|
||||
#base_env.Replace(PRINT_CMD_LINE_FUNC=Print.print_cmd_line)
|
||||
|
||||
env = base_env
|
||||
|
||||
bin_dir = os.path.join(base_dir, 'bin')
|
||||
|
||||
srcs = filter(is_unity, list(files('beast')) + list(files('modules')))
|
||||
for variant in ['Debug']: #, 'Release']:
|
||||
for platform in ['Win32']:
|
||||
#env = base_env.Clone()
|
||||
#env.Replace(PRINT_CMD_LINE_FUNC=Print.print_cmd_line)
|
||||
variant_dir = os.path.join(bin_dir, variant + '.' + platform)
|
||||
env.VariantDir(os.path.join(variant_dir, 'beast'), 'beast', duplicate=0)
|
||||
env.VariantDir(os.path.join(variant_dir, 'modules'), 'modules', duplicate=0)
|
||||
env.Append(CCFLAGS=[
|
||||
'/EHsc',
|
||||
'/bigobj',
|
||||
'/Fd${TARGET}.pdb'
|
||||
])
|
||||
if variant == 'Debug':
|
||||
env.Append(CCFLAGS=[
|
||||
'/MTd',
|
||||
'/Od',
|
||||
'/Zi'
|
||||
])
|
||||
else:
|
||||
env.Append(CCFLAGS=[
|
||||
'/MT',
|
||||
'/Ox'
|
||||
])
|
||||
variant_srcs = [os.path.join(variant_dir, os.path.relpath(f, base_dir)) for f in srcs]
|
||||
|
||||
beast = env.StaticLibrary(
|
||||
target = os.path.join(variant_dir, 'beast.lib'),
|
||||
source = variant_srcs)
|
||||
|
||||
env.VSProject (
|
||||
'out',
|
||||
buildtarget = beast,
|
||||
source = filter(is_unity, list(files('beast')) + list(files('modules'))))
|
||||
|
||||
env.Default ('out.vcxproj')
|
||||
#env.Default (os.path.join(bin_dir,'Debug.Win32', 'beast.lib'))
|
||||
|
||||
56
src/beast/TODO.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
* Add writer::prepare(msg&) interface to set Content-Type
|
||||
|
||||
Boost.Http
|
||||
* Use enum instead of bool in isRequest
|
||||
|
||||
Docs:
|
||||
* Include Example program listings in the docs
|
||||
* Fix index in docs
|
||||
* melpon sandbox?
|
||||
* Implement cleanup-param to remove spaces around template arguments
|
||||
e.g. in basic_streambuf move constructor members
|
||||
* Don't put using namespace at file scope in examples,
|
||||
do something like "using ba = boost::asio" instead.
|
||||
|
||||
Core:
|
||||
* Replace Jamroot with Jamfile
|
||||
* Fix bidirectional buffers iterators operator->()
|
||||
* Complete allocator testing in basic_streambuf
|
||||
|
||||
WebSocket:
|
||||
* more invokable unit test coverage
|
||||
* More control over the HTTP request and response during handshakes
|
||||
* optimized versions of key/masking, choose prepared_key size
|
||||
* Give callers control over the http request/response used during handshake
|
||||
* Investigate poor autobahn results in Debug builds
|
||||
* Fall through composed operation switch cases
|
||||
* Use close_code::no_code instead of close_code::none
|
||||
* Make request_type, response_type public APIs,
|
||||
use in stream member function signatures
|
||||
|
||||
HTTP:
|
||||
* Define Parser concept in HTTP
|
||||
- Need parse version of read() so caller can set parser options
|
||||
like maximum size of headers, maximum body size, etc
|
||||
* add bool should_close(message_v1 const&) to replace the use
|
||||
of eof return value from write and async_write
|
||||
* More fine grained parser errors
|
||||
* HTTP parser size limit with test (configurable?)
|
||||
* HTTP parser trailers with test
|
||||
* Decode chunk encoding parameters
|
||||
* URL parser, strong URL character checking in HTTP parser
|
||||
* Fix prepare() calling content_length() without init()
|
||||
* Complete allocator testing in basic_streambuf, basic_headers
|
||||
* Custom HTTP error codes for various situations
|
||||
* Branch prediction hints in parser
|
||||
* Check basic_parser_v1 against rfc7230 for leading message whitespace
|
||||
* Fix the order of message constructor parameters:
|
||||
body first then headers (since body is constructed with arguments more often)
|
||||
* Unit tests for char tables
|
||||
* Remove status_code() from API when isRequest==true, et. al.
|
||||
* Permit sending trailers and parameters in chunk-encoding chunks
|
||||
|
||||
Future:
|
||||
|
||||
* SOCKS proxy client and server implementations
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ARITHMETIC_H_INCLUDED
|
||||
#define BEAST_ARITHMETIC_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/** Constrains a value to keep it within a given range.
|
||||
|
||||
This will check that the specified value lies between the lower and upper bounds
|
||||
specified, and if not, will return the nearest value that would be in-range. Effectively,
|
||||
it's like calling bmax (lowerLimit, bmin (upperLimit, value)).
|
||||
|
||||
Note that it expects that lowerLimit <= upperLimit. If this isn't true,
|
||||
the results will be unpredictable.
|
||||
|
||||
@param lowerLimit the minimum value to return
|
||||
@param upperLimit the maximum value to return
|
||||
@param valueToConstrain the value to try to return
|
||||
@returns the closest value to valueToConstrain which lies between lowerLimit
|
||||
and upperLimit (inclusive)
|
||||
@see blimit0To, bmin, bmax
|
||||
*/
|
||||
template <typename Type>
|
||||
inline Type blimit (const Type lowerLimit,
|
||||
const Type upperLimit,
|
||||
const Type valueToConstrain) noexcept
|
||||
{
|
||||
// if these are in the wrong order, results are unpredictable.
|
||||
bassert (lowerLimit <= upperLimit);
|
||||
|
||||
return (valueToConstrain < lowerLimit) ? lowerLimit
|
||||
: ((upperLimit < valueToConstrain) ? upperLimit
|
||||
: valueToConstrain);
|
||||
}
|
||||
|
||||
/** Returns true if a value is at least zero, and also below a specified upper limit.
|
||||
This is basically a quicker way to write:
|
||||
@code valueToTest >= 0 && valueToTest < upperLimit
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type>
|
||||
inline bool isPositiveAndBelow (Type valueToTest, Type upperLimit) noexcept
|
||||
{
|
||||
bassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return Type() <= valueToTest && valueToTest < upperLimit;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noexcept
|
||||
{
|
||||
bassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return static_cast <unsigned int> (valueToTest) < static_cast <unsigned int> (upperLimit);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/** Handy function for getting the number of elements in a simple const C array.
|
||||
E.g.
|
||||
@code
|
||||
static int myArray[] = { 1, 2, 3 };
|
||||
|
||||
int numElements = numElementsInArray (myArray) // returns 3
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type, int N>
|
||||
int numElementsInArray (Type (&array)[N])
|
||||
{
|
||||
(void) array; // (required to avoid a spurious warning in MS compilers)
|
||||
(void) sizeof (0[array]); // This line should cause an error if you pass an object with a user-defined subscript operator
|
||||
return N;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONFIG_H_INCLUDED
|
||||
#define BEAST_CONFIG_H_INCLUDED
|
||||
|
||||
// VFALCO NOTE this is analogous to <boost/config.hpp>
|
||||
|
||||
#if !defined(BEAST_COMPILER_CONFIG) && !defined(BEAST_NO_COMPILER_CONFIG) && !defined(BEAST_NO_CONFIG)
|
||||
#include <beast/config/SelectCompilerConfig.h>
|
||||
#endif
|
||||
#ifdef BEAST_COMPILER_CONFIG
|
||||
#include BEAST_COMPILER_CONFIG
|
||||
#endif
|
||||
|
||||
#if !defined(BEAST_STDLIB_CONFIG) && !defined(BEAST_NO_STDLIB_CONFIG) && !defined(BEAST_NO_CONFIG) && defined(__cplusplus)
|
||||
#include <beast/config/SelectStdlibConfig.h>
|
||||
#endif
|
||||
#ifdef BEAST_STDLIB_CONFIG
|
||||
#include BEAST_STDLIB_CONFIG
|
||||
#endif
|
||||
|
||||
#if !defined(BEAST_PLATFORM_CONFIG) && !defined(BEAST_NO_PLATFORM_CONFIG) && !defined(BEAST_NO_CONFIG)
|
||||
#include <beast/config/SelectCompilerConfig.h>
|
||||
#endif
|
||||
#ifdef BEAST_PLATFORM_CONFIG
|
||||
#include BEAST_PLATFORM_CONFIG
|
||||
#endif
|
||||
|
||||
// Legacy
|
||||
#include <beast/Version.h>
|
||||
#include <beast/config/PlatformConfig.h>
|
||||
#include <beast/config/CompilerConfig.h>
|
||||
#include <beast/config/StandardConfig.h>
|
||||
#include <beast/config/ConfigCheck.h>
|
||||
|
||||
// Suffix
|
||||
#include <beast/config/Suffix.h>
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_H_INCLUDED
|
||||
#define BEAST_STRINGS_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
#include <beast/strings/NewLine.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_THREADS_H_INCLUDED
|
||||
#define BEAST_THREADS_H_INCLUDED
|
||||
|
||||
#include <beast/threads/UnlockGuard.h>
|
||||
#include <beast/threads/TryLockGuard.h>
|
||||
#include <beast/threads/SharedLockGuard.h>
|
||||
#include <beast/threads/SharedMutexAdapter.h>
|
||||
#include <beast/threads/SpinLock.h>
|
||||
#include <beast/threads/Stoppable.h>
|
||||
#include <beast/threads/Thread.h>
|
||||
#include <beast/threads/WaitableEvent.h>
|
||||
#include <beast/threads/ScopedWrapperContext.h>
|
||||
|
||||
#include <beast/threads/semaphore.h>
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_VERSION_H_INCLUDED
|
||||
#define BEAST_VERSION_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
/** Current BEAST version number. */
|
||||
unsigned int const BEAST_VERSION_MAJOR = 1;
|
||||
unsigned int const BEAST_VERSION_MINOR = 0;
|
||||
unsigned int const BEAST_VERSION_BUILD = 0;
|
||||
|
||||
unsigned int const BEAST_VERSION =
|
||||
(BEAST_VERSION_MAJOR << 16) +
|
||||
(BEAST_VERSION_MINOR << 8) +
|
||||
BEAST_VERSION_BUILD;
|
||||
|
||||
inline
|
||||
std::string
|
||||
getBeastVersion()
|
||||
{
|
||||
return "Beast v" + std::to_string (BEAST_VERSION_MAJOR) +
|
||||
"." + std::to_string (BEAST_VERSION_MINOR) +
|
||||
"." + std::to_string (BEAST_VERSION_BUILD);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# beast::asio
|
||||
|
||||
Wrappers and utilities to make working with boost::asio easier.
|
||||
|
||||
## Rules for asynchronous objects
|
||||
|
||||
If an object calls asynchronous initiating functions it must either:
|
||||
|
||||
1. Manage its lifetime by being reference counted
|
||||
|
||||
or
|
||||
|
||||
2. Wait for all pending completion handlers to be called before
|
||||
allowing itself to be destroyed.
|
||||
@@ -1,164 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_BIND_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_BIND_HANDLER_H_INCLUDED
|
||||
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** Nullary handler that calls Handler with bound arguments.
|
||||
The rebound handler provides the same io_service execution
|
||||
guarantees as the original handler.
|
||||
*/
|
||||
template <class DeducedHandler, class... Args>
|
||||
class bound_handler
|
||||
{
|
||||
private:
|
||||
using args_type = std::tuple <std::decay_t <Args>...>;
|
||||
|
||||
std::decay_t <DeducedHandler> m_handler;
|
||||
args_type m_args;
|
||||
|
||||
template <class Handler, class Tuple, std::size_t... S>
|
||||
static void invoke (Handler& h, Tuple& args,
|
||||
std::index_sequence <S...>)
|
||||
{
|
||||
h (std::get <S> (args)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
explicit
|
||||
bound_handler (DeducedHandler&& handler, Args&&... args)
|
||||
: m_handler (std::forward <DeducedHandler> (handler))
|
||||
, m_args (std::forward <Args> (args)...)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
operator() ()
|
||||
{
|
||||
invoke (m_handler, m_args,
|
||||
std::index_sequence_for <Args...> ());
|
||||
}
|
||||
|
||||
void
|
||||
operator() () const
|
||||
{
|
||||
invoke (m_handler, m_args,
|
||||
std::index_sequence_for <Args...> ());
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size, bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size, bound_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (bound_handler* h)
|
||||
{
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (h->m_handler);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Binds parameters to a handler to produce a nullary functor.
|
||||
The returned handler provides the same io_service execution guarantees
|
||||
as the original handler. This is designed to use as a replacement for
|
||||
io_service::wrap, to ensure that the handler will not be invoked
|
||||
immediately by the calling function.
|
||||
*/
|
||||
template <class DeducedHandler, class... Args>
|
||||
detail::bound_handler <DeducedHandler, Args...>
|
||||
bind_handler (DeducedHandler&& handler, Args&&... args)
|
||||
{
|
||||
return detail::bound_handler <DeducedHandler, Args...> (
|
||||
std::forward <DeducedHandler> (handler),
|
||||
std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
template <class Handler, class... Args>
|
||||
void bind (beast::asio::detail::bound_handler <
|
||||
Handler, Args...>, ...) = delete;
|
||||
|
||||
#if 0
|
||||
template <class Handler, class... Args>
|
||||
struct is_bind_expression <
|
||||
beast::asio::detail::bound_handler <Handler, Args...>
|
||||
> : std::true_type
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/error.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
// This buffer must be at least 120 bytes, most examples use 256.
|
||||
// https://www.openssl.org/docs/crypto/ERR_error_string.html
|
||||
static std::uint32_t const errorBufferSize (256);
|
||||
|
||||
std::string
|
||||
asio_message (boost::system::error_code const& ec)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (ec.category () == boost::asio::error::get_ssl_category ())
|
||||
{
|
||||
error = " ("
|
||||
+ boost::lexical_cast<std::string> (ERR_GET_LIB (ec.value ()))
|
||||
+ ","
|
||||
+ boost::lexical_cast<std::string> (ERR_GET_FUNC (ec.value ()))
|
||||
+ ","
|
||||
+ boost::lexical_cast<std::string> (ERR_GET_REASON (ec.value ()))
|
||||
+ ") ";
|
||||
|
||||
//
|
||||
char buf[errorBufferSize];
|
||||
::ERR_error_string_n (ec.value (), buf, errorBufferSize);
|
||||
error += buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ec.message ();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_PLACEHOLDERS_H_INCLUDED
|
||||
#define BEAST_ASIO_PLACEHOLDERS_H_INCLUDED
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace placeholders {
|
||||
// asio placeholders that work with std::bind
|
||||
namespace {
|
||||
static auto const error (std::placeholders::_1);
|
||||
static auto const bytes_transferred (std::placeholders::_2);
|
||||
static auto const iterator (std::placeholders::_2);
|
||||
static auto const signal_number (std::placeholders::_2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,679 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_STREAMBUF_H_INCLUDED
|
||||
#define BEAST_ASIO_STREAMBUF_H_INCLUDED
|
||||
|
||||
#include <beast/utility/empty_base_optimization.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <exception>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Implements asio::streambuf interface using multiple buffers. */
|
||||
template <class Allocator>
|
||||
class basic_streambuf
|
||||
: private empty_base_optimization<Allocator>
|
||||
{
|
||||
public:
|
||||
using size_type = typename std::allocator_traits<Allocator>::size_type;
|
||||
using const_buffer = boost::asio::const_buffer;
|
||||
using mutable_buffer = boost::asio::mutable_buffer;
|
||||
|
||||
private:
|
||||
class element;
|
||||
|
||||
using alloc_traits = std::allocator_traits<Allocator>;
|
||||
using list_type = typename boost::intrusive::make_list <element,
|
||||
boost::intrusive::constant_time_size <true>>::type;
|
||||
using iterator = typename list_type::iterator;
|
||||
using const_iterator = typename list_type::const_iterator;
|
||||
|
||||
/* These diagrams illustrate the layout and state variables.
|
||||
|
||||
Input and output contained entirely in one element:
|
||||
|
||||
0 out_
|
||||
|<-------------+------------------------------------------->|
|
||||
in_pos_ out_pos_ out_end_
|
||||
|
||||
|
||||
Output contained in first and second elements:
|
||||
|
||||
out_
|
||||
|<------+----------+------->| |<----------+-------------->|
|
||||
in_pos_ out_pos_ out_end_
|
||||
|
||||
|
||||
Output contained in the second element:
|
||||
|
||||
out_
|
||||
|<------------+------------>| |<----+-------------------->|
|
||||
in_pos_ out_pos_ out_end_
|
||||
|
||||
|
||||
Output contained in second and third elements:
|
||||
|
||||
out_
|
||||
|<-----+-------->| |<-------+------>| |<--------------->|
|
||||
in_pos_ out_pos_ out_end_
|
||||
|
||||
|
||||
Input sequence is empty:
|
||||
|
||||
out_
|
||||
|<------+------------------>| |<-----------+------------->|
|
||||
out_pos_ out_end_
|
||||
in_pos_
|
||||
|
||||
|
||||
Output sequence is empty:
|
||||
|
||||
out_
|
||||
|<------+------------------>| |<------+------------------>|
|
||||
in_pos_ out_pos_
|
||||
out_end_
|
||||
|
||||
|
||||
The end of output can point to the end of an element.
|
||||
But out_pos_ should never point to the end:
|
||||
|
||||
out_
|
||||
|<------+------------------>| |<------+------------------>|
|
||||
in_pos_ out_pos_ out_end_
|
||||
|
||||
|
||||
When the input sequence entirely fills the last element and
|
||||
the output sequence is empty, out_ will point to the end of
|
||||
the list of buffers, and out_pos_ and out_end_ will be 0:
|
||||
|
||||
|
||||
|<------+------------------>| out_ == list_.end()
|
||||
in_pos_ out_pos_ == 0
|
||||
out_end_ == 0
|
||||
*/
|
||||
|
||||
list_type list_;
|
||||
size_type block_size_;
|
||||
size_type block_size_next_;
|
||||
size_type in_size_ = 0; // size of the input sequence
|
||||
iterator out_; // element that contains out_pos_
|
||||
size_type in_pos_ = 0; // input offset in list_.front()
|
||||
size_type out_pos_ = 0; // output offset in *out_
|
||||
size_type out_end_ = 0; // output end offset in list_.back()
|
||||
|
||||
public:
|
||||
class const_buffers_type;
|
||||
class mutable_buffers_type;
|
||||
|
||||
basic_streambuf (basic_streambuf const& other) = delete;
|
||||
basic_streambuf& operator= (basic_streambuf const& other) = delete;
|
||||
basic_streambuf& operator= (basic_streambuf&& other) = delete;
|
||||
|
||||
~basic_streambuf();
|
||||
|
||||
explicit
|
||||
basic_streambuf(std::size_t block_size = 16*1024,
|
||||
Allocator const& alloc = Allocator{});
|
||||
|
||||
basic_streambuf (basic_streambuf&& other);
|
||||
|
||||
/** Get the maximum size of the basic_streambuf. */
|
||||
size_type
|
||||
max_size() const
|
||||
{
|
||||
return std::numeric_limits<std::size_t>::max();
|
||||
}
|
||||
|
||||
/** Get the size of the input sequence. */
|
||||
size_type
|
||||
size() const
|
||||
{
|
||||
return in_size_;
|
||||
}
|
||||
|
||||
/** Get a list of buffers that represents the output sequence, with the given size. */
|
||||
mutable_buffers_type
|
||||
prepare (size_type n);
|
||||
|
||||
/** Move bytes from the output sequence to the input sequence. */
|
||||
void
|
||||
commit (size_type n);
|
||||
|
||||
/** Get a list of buffers that represents the input sequence. */
|
||||
const_buffers_type
|
||||
data() const;
|
||||
|
||||
/** Remove bytes from the input sequence. */
|
||||
void
|
||||
consume (size_type n);
|
||||
|
||||
private:
|
||||
void
|
||||
debug_check() const;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Allocator>
|
||||
class basic_streambuf<Allocator>::element
|
||||
: public boost::intrusive::list_base_hook <
|
||||
boost::intrusive::link_mode <boost::intrusive::normal_link>>
|
||||
{
|
||||
private:
|
||||
size_type const size_; // size of the allocation minus sizeof(element)
|
||||
|
||||
public:
|
||||
element (element const&) = delete;
|
||||
element& operator= (element const&) = delete;
|
||||
|
||||
explicit
|
||||
element (size_type block_size)
|
||||
: size_(block_size)
|
||||
{ }
|
||||
|
||||
size_type
|
||||
size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_type
|
||||
alloc_size() const
|
||||
{
|
||||
return size_ + sizeof(*this);
|
||||
}
|
||||
|
||||
char*
|
||||
data() const
|
||||
{
|
||||
return const_cast<char*>(
|
||||
reinterpret_cast<char const*>(this+1));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Allocator>
|
||||
class basic_streambuf<Allocator>::const_buffers_type
|
||||
{
|
||||
public:
|
||||
using value_type = const_buffer;
|
||||
|
||||
private:
|
||||
struct transform
|
||||
{
|
||||
using argument_type = element;
|
||||
using result_type = value_type;
|
||||
|
||||
basic_streambuf const* streambuf_ = nullptr;
|
||||
|
||||
transform() = default;
|
||||
|
||||
explicit
|
||||
transform (basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
value_type const
|
||||
operator() (element const& e) const;
|
||||
};
|
||||
|
||||
basic_streambuf const* streambuf_ = nullptr;
|
||||
|
||||
public:
|
||||
using const_iterator = boost::transform_iterator<
|
||||
transform, typename list_type::const_iterator,
|
||||
value_type, value_type>;
|
||||
|
||||
const_buffers_type() = default;
|
||||
const_buffers_type (const_buffers_type const&) = default;
|
||||
const_buffers_type& operator= (const_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator (streambuf_->list_.begin(),
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return const_iterator (streambuf_->out_ ==
|
||||
streambuf_->list_.end() ? streambuf_->list_.end() :
|
||||
std::next(streambuf_->out_), transform(*streambuf_));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class basic_streambuf;
|
||||
|
||||
explicit
|
||||
const_buffers_type (basic_streambuf const& streambuf);
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
basic_streambuf<Allocator>::const_buffers_type::const_buffers_type (
|
||||
basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::const_buffers_type::
|
||||
transform::operator() (element const& e) const ->
|
||||
value_type const
|
||||
{
|
||||
return value_type (e.data(),
|
||||
(streambuf_->out_ == streambuf_->list_.end() ||
|
||||
&e != &*streambuf_->out_) ? e.size() : streambuf_->out_pos_) +
|
||||
(&e == &*streambuf_->list_.begin() ?
|
||||
streambuf_->in_pos_ : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Allocator>
|
||||
class basic_streambuf<Allocator>::mutable_buffers_type
|
||||
{
|
||||
public:
|
||||
using value_type = mutable_buffer;
|
||||
|
||||
private:
|
||||
struct transform
|
||||
{
|
||||
using argument_type = element;
|
||||
using result_type = value_type;
|
||||
|
||||
basic_streambuf const* streambuf_ = nullptr;
|
||||
|
||||
transform() = default;
|
||||
|
||||
explicit
|
||||
transform (basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
value_type const
|
||||
operator() (element const& e) const;
|
||||
};
|
||||
|
||||
basic_streambuf const* streambuf_;
|
||||
|
||||
public:
|
||||
using const_iterator = boost::transform_iterator<
|
||||
transform, typename list_type::const_iterator,
|
||||
value_type, value_type>;
|
||||
|
||||
mutable_buffers_type() = default;
|
||||
mutable_buffers_type (mutable_buffers_type const&) = default;
|
||||
mutable_buffers_type& operator= (mutable_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator (streambuf_->out_,
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return const_iterator (streambuf_->list_.end(),
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class basic_streambuf;
|
||||
mutable_buffers_type (basic_streambuf const& streambuf);
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
basic_streambuf<Allocator>::mutable_buffers_type::mutable_buffers_type (
|
||||
basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::mutable_buffers_type::
|
||||
transform::operator() (element const& e) const ->
|
||||
value_type const
|
||||
{
|
||||
return value_type (e.data(), &e == &*std::prev(streambuf_->list_.end()) ?
|
||||
streambuf_->out_end_ : e.size()) + (&e == &*streambuf_->out_ ?
|
||||
streambuf_->out_pos_ : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Allocator>
|
||||
basic_streambuf<Allocator>::~basic_streambuf()
|
||||
{
|
||||
for(auto iter = list_.begin(); iter != list_.end();)
|
||||
{
|
||||
auto& e = *iter++;
|
||||
size_type const n = e.alloc_size();
|
||||
alloc_traits::destroy(this->member(), &e);
|
||||
alloc_traits::deallocate(this->member(),
|
||||
reinterpret_cast<char*>(&e), n);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
basic_streambuf<Allocator>::basic_streambuf(std::size_t block_size,
|
||||
Allocator const& alloc)
|
||||
: empty_base_optimization<Allocator>(alloc)
|
||||
, block_size_ (block_size)
|
||||
, block_size_next_ (block_size)
|
||||
, out_ (list_.end())
|
||||
{
|
||||
if (! (block_size > 0))
|
||||
throw std::invalid_argument(
|
||||
"basic_streambuf: invalid block_size");
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
basic_streambuf<Allocator>::basic_streambuf (basic_streambuf&& other)
|
||||
: empty_base_optimization<Allocator>(other.member())
|
||||
, list_ (std::move(other.list_))
|
||||
, block_size_ (other.block_size_)
|
||||
, block_size_next_ (other.block_size_next_)
|
||||
, in_size_ (other.in_size_)
|
||||
, out_ (other.out_)
|
||||
, in_pos_ (other.in_pos_)
|
||||
, out_pos_ (other.out_pos_)
|
||||
, out_end_ (other.out_end_)
|
||||
{
|
||||
other.in_size_ = 0;
|
||||
other.out_ = other.list_.end();
|
||||
other.in_pos_ = 0;
|
||||
other.out_pos_ = 0;
|
||||
other.out_end_ = 0;
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::prepare (size_type n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
iterator pos = out_;
|
||||
if (pos != list_.end())
|
||||
{
|
||||
auto const avail = pos->size() - out_pos_;
|
||||
if (n > avail)
|
||||
{
|
||||
n -= avail;
|
||||
while (++pos != list_.end())
|
||||
{
|
||||
if (n < pos->size())
|
||||
{
|
||||
out_end_ = n;
|
||||
n = 0;
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
n -= pos->size();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++pos;
|
||||
out_end_ = out_pos_ + n;
|
||||
n = 0;
|
||||
}
|
||||
debug_check();
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
assert(pos == list_.end());
|
||||
for(;;)
|
||||
{
|
||||
auto const avail = block_size_next_;
|
||||
auto& e = *reinterpret_cast<element*>(alloc_traits::allocate(
|
||||
this->member(), avail + sizeof(element)));
|
||||
alloc_traits::construct(this->member(), &e, avail);
|
||||
list_.push_back(e);
|
||||
if (out_ == list_.end())
|
||||
{
|
||||
out_ = list_.iterator_to(e);
|
||||
debug_check();
|
||||
}
|
||||
if (n <= avail)
|
||||
{
|
||||
out_end_ = n;
|
||||
debug_check();
|
||||
break;
|
||||
}
|
||||
n -= avail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (pos != list_.end())
|
||||
{
|
||||
auto& e = *pos++;
|
||||
list_.erase(list_.iterator_to(e));
|
||||
auto const len = e.alloc_size();
|
||||
alloc_traits::destroy(this->member(), &e);
|
||||
alloc_traits::deallocate(this->member(),
|
||||
reinterpret_cast<char*>(&e), len);
|
||||
}
|
||||
debug_check();
|
||||
}
|
||||
|
||||
return mutable_buffers_type (*this);
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::commit (size_type n)
|
||||
{
|
||||
if (list_.empty())
|
||||
return;
|
||||
if (out_ == list_.end())
|
||||
return;
|
||||
auto const last = std::prev(list_.end());
|
||||
while (out_ != last)
|
||||
{
|
||||
auto const avail =
|
||||
out_->size() - out_pos_;
|
||||
if (n < avail)
|
||||
{
|
||||
out_pos_ += n;
|
||||
in_size_ += n;
|
||||
debug_check();
|
||||
return;
|
||||
}
|
||||
++out_;
|
||||
n -= avail;
|
||||
out_pos_ = 0;
|
||||
in_size_ += avail;
|
||||
debug_check();
|
||||
}
|
||||
|
||||
n = std::min (n, out_end_ - out_pos_);
|
||||
out_pos_ += n;
|
||||
in_size_ += n;
|
||||
if (out_pos_ == out_->size())
|
||||
{
|
||||
++out_;
|
||||
out_pos_ = 0;
|
||||
out_end_ = 0;
|
||||
}
|
||||
debug_check();
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
auto
|
||||
basic_streambuf<Allocator>::data() const ->
|
||||
const_buffers_type
|
||||
{
|
||||
return const_buffers_type(*this);
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::consume (size_type n)
|
||||
{
|
||||
if (list_.empty())
|
||||
return;
|
||||
|
||||
auto pos = list_.begin();
|
||||
for(;;)
|
||||
{
|
||||
if (pos != out_)
|
||||
{
|
||||
auto const avail = pos->size() - in_pos_;
|
||||
if (n < avail)
|
||||
{
|
||||
in_size_ -= n;
|
||||
in_pos_ += n;
|
||||
debug_check();
|
||||
break;
|
||||
}
|
||||
n -= avail;
|
||||
in_size_ -= avail;
|
||||
in_pos_ = 0;
|
||||
debug_check();
|
||||
|
||||
element& e = *pos++;
|
||||
list_.erase(list_.iterator_to(e));
|
||||
size_type const len = e.alloc_size();
|
||||
alloc_traits::destroy(this->member(), &e);
|
||||
alloc_traits::deallocate(this->member(),
|
||||
reinterpret_cast<char*>(&e), len);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const avail = out_pos_ - in_pos_;
|
||||
if (n < avail)
|
||||
{
|
||||
in_size_ -= n;
|
||||
in_pos_ += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_size_ -= avail;
|
||||
if (out_pos_ != out_end_||
|
||||
out_ != list_.iterator_to(list_.back()))
|
||||
{
|
||||
in_pos_ = out_pos_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the whole buffer now.
|
||||
// Alternatively we could deallocate it.
|
||||
in_pos_ = 0;
|
||||
out_pos_ = 0;
|
||||
out_end_ = 0;
|
||||
}
|
||||
}
|
||||
debug_check();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Allocator>
|
||||
void
|
||||
basic_streambuf<Allocator>::debug_check() const
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (list_.empty())
|
||||
{
|
||||
assert(in_pos_ == 0);
|
||||
assert(in_size_ == 0);
|
||||
assert(out_pos_ == 0);
|
||||
assert(out_end_ == 0);
|
||||
assert(out_ == list_.end());
|
||||
return;
|
||||
}
|
||||
|
||||
auto const& front = list_.front();
|
||||
|
||||
assert(in_pos_ < front.size());
|
||||
|
||||
if (out_ == list_.end())
|
||||
{
|
||||
assert(out_pos_ == 0);
|
||||
assert(out_end_ == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const& out = *out_;
|
||||
auto const& back = list_.back();
|
||||
|
||||
assert(out_end_ <= back.size());
|
||||
assert(out_pos_ < out.size());
|
||||
assert(&out != &front || out_pos_ >= in_pos_);
|
||||
assert(&out != &front || out_pos_ - in_pos_ == in_size_);
|
||||
assert(&out != &back || out_pos_ <= out_end_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Alloc, class T>
|
||||
basic_streambuf<Alloc>&
|
||||
operator<< (basic_streambuf<Alloc>& buf, T const& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
auto const& s = ss.str();
|
||||
buf.commit(boost::asio::buffer_copy(
|
||||
buf.prepare(s.size()), boost::asio::buffer(s)));
|
||||
return buf;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using streambuf = basic_streambuf<std::allocator<char>>;
|
||||
|
||||
/** Convert the entire basic_streambuf to a string.
|
||||
@note It is more efficient to deal directly in the streambuf instead.
|
||||
*/
|
||||
template <class Allocator>
|
||||
std::string
|
||||
to_string (basic_streambuf<Allocator> const& buf)
|
||||
{
|
||||
std::string s;
|
||||
s.resize(buf.size());
|
||||
boost::asio::buffer_copy(boost::asio::buffer(
|
||||
&s[0], s.size()), buf.data());
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,55 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// LIBS: boost_system
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
#include <beast/asio/bind_handler.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class bind_handler_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
static void foo (int)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
auto f (bind_handler (
|
||||
std::bind (&foo, std::placeholders::_1),
|
||||
42));
|
||||
f();
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(bind_handler,asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/asio/streambuf.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
class streambuf_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
// Convert a buffer sequence to a string
|
||||
template <class Buffers>
|
||||
static
|
||||
std::string
|
||||
to_str (Buffers const& b)
|
||||
{
|
||||
std::string s;
|
||||
auto const n = boost::asio::buffer_size(b);
|
||||
s.resize(n);
|
||||
boost::asio::buffer_copy(
|
||||
boost::asio::buffer(&s[0], n), b);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Fill a buffer sequence with predictable data
|
||||
template <class Buffers>
|
||||
static
|
||||
void
|
||||
fill (Buffers const& b)
|
||||
{
|
||||
char c = 0;
|
||||
auto first = boost::asio::buffers_begin(b);
|
||||
auto last = boost::asio::buffers_end(b);
|
||||
while (first != last)
|
||||
*first++ = c++;
|
||||
}
|
||||
|
||||
// Check that a buffer sequence has predictable data
|
||||
template <class Buffers>
|
||||
void
|
||||
check (Buffers const& b, char c = 0)
|
||||
{
|
||||
auto first = boost::asio::buffers_begin(b);
|
||||
auto last = boost::asio::buffers_end(b);
|
||||
while (first != last)
|
||||
expect (*first++ == c++);
|
||||
}
|
||||
|
||||
void
|
||||
test_prepare()
|
||||
{
|
||||
testcase << "prepare";
|
||||
beast::asio::streambuf b(11);
|
||||
for (std::size_t n = 0; n < 97; ++n)
|
||||
{
|
||||
fill(b.prepare(n));
|
||||
b.commit(n);
|
||||
check(b.data());
|
||||
b.consume(n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_commit()
|
||||
{
|
||||
testcase << "commit";
|
||||
beast::asio::streambuf b(11);
|
||||
for (std::size_t n = 0; n < 97; ++n)
|
||||
{
|
||||
fill(b.prepare(n));
|
||||
char c = 0;
|
||||
for (int i = 1;; ++i)
|
||||
{
|
||||
b.commit(i);
|
||||
check(b.data(), c);
|
||||
b.consume(i);
|
||||
if (b.size() < 1)
|
||||
break;
|
||||
c += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_consume()
|
||||
{
|
||||
testcase << "consume";
|
||||
beast::asio::streambuf b(11);
|
||||
for (std::size_t n = 0; n < 97; ++n)
|
||||
{
|
||||
fill(b.prepare(n));
|
||||
b.commit(n);
|
||||
char c = 0;
|
||||
for (int i = 1; b.size() > 0; ++i)
|
||||
{
|
||||
check(b.data(), c);
|
||||
b.consume(i);
|
||||
c += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
{
|
||||
beast::asio::streambuf b(10);
|
||||
std::string const s = "1234567890";
|
||||
b << s;
|
||||
expect (to_str(b.data()) == s);
|
||||
b.prepare(5);
|
||||
}
|
||||
|
||||
{
|
||||
beast::asio::streambuf b(10);
|
||||
b.prepare(10);
|
||||
b.commit(10);
|
||||
b.consume(10);
|
||||
}
|
||||
|
||||
{
|
||||
beast::asio::streambuf b(5);
|
||||
boost::asio::buffer_copy(b.prepare(14),
|
||||
boost::asio::buffer(std::string("1234567890ABCD")));
|
||||
b.commit(4);
|
||||
expect(to_str(b.data()) == "1234");
|
||||
b.consume(4);
|
||||
b.commit(10);
|
||||
expect(to_str(b.data()) == "567890ABCD");
|
||||
}
|
||||
|
||||
test_prepare();
|
||||
test_commit();
|
||||
test_consume();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(streambuf,asio,beast);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_WAITABLE_EXECUTOR_H_INCLUDED
|
||||
#define BEAST_ASIO_WAITABLE_EXECUTOR_H_INCLUDED
|
||||
|
||||
#include <boost/asio/handler_alloc_hook.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Owner, class Handler>
|
||||
class waitable_executor_wrapped_handler
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
|
||||
"Owner cannot be a const or reference type");
|
||||
|
||||
Handler handler_;
|
||||
std::reference_wrapper <Owner> owner_;
|
||||
bool cont_;
|
||||
|
||||
public:
|
||||
waitable_executor_wrapped_handler (Owner& owner,
|
||||
Handler&& handler, bool continuation = false)
|
||||
: handler_ (std::move(handler))
|
||||
, owner_ (owner)
|
||||
{
|
||||
using boost::asio::asio_handler_is_continuation;
|
||||
cont_ = continuation ? true :
|
||||
asio_handler_is_continuation(
|
||||
std::addressof(handler_));
|
||||
owner_.get().increment();
|
||||
}
|
||||
|
||||
waitable_executor_wrapped_handler (Owner& owner,
|
||||
Handler const& handler, bool continuation = false)
|
||||
: handler_ (handler)
|
||||
, owner_ (owner)
|
||||
{
|
||||
using boost::asio::asio_handler_is_continuation;
|
||||
cont_ = continuation ? true :
|
||||
asio_handler_is_continuation(
|
||||
std::addressof(handler_));
|
||||
owner_.get().increment();
|
||||
}
|
||||
|
||||
~waitable_executor_wrapped_handler()
|
||||
{
|
||||
owner_.get().decrement();
|
||||
}
|
||||
|
||||
waitable_executor_wrapped_handler (
|
||||
waitable_executor_wrapped_handler const& other)
|
||||
: handler_ (other.handler_)
|
||||
, owner_ (other.owner_)
|
||||
, cont_ (other.cont_)
|
||||
{
|
||||
owner_.get().increment();
|
||||
}
|
||||
|
||||
waitable_executor_wrapped_handler (
|
||||
waitable_executor_wrapped_handler&& other)
|
||||
: handler_ (std::move(other.handler_))
|
||||
, owner_ (other.owner_)
|
||||
, cont_ (other.cont_)
|
||||
{
|
||||
owner_.get().increment();
|
||||
}
|
||||
|
||||
waitable_executor_wrapped_handler& operator=(
|
||||
waitable_executor_wrapped_handler const&) = delete;
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator()(Args&&... args)
|
||||
{
|
||||
handler_(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator()(Args&&... args) const
|
||||
{
|
||||
handler_(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f,
|
||||
waitable_executor_wrapped_handler* h)
|
||||
{
|
||||
using boost::asio::asio_handler_invoke;
|
||||
asio_handler_invoke(f,
|
||||
std::addressof(h->handler_));
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f,
|
||||
waitable_executor_wrapped_handler* h)
|
||||
{
|
||||
using boost::asio::asio_handler_invoke;
|
||||
asio_handler_invoke(f,
|
||||
std::addressof(h->handler_));
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size,
|
||||
waitable_executor_wrapped_handler* h)
|
||||
{
|
||||
using boost::asio::asio_handler_allocate;
|
||||
return asio_handler_allocate(
|
||||
size, std::addressof(h->handler_));
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size,
|
||||
waitable_executor_wrapped_handler* h)
|
||||
{
|
||||
using boost::asio::asio_handler_deallocate;
|
||||
asio_handler_deallocate(
|
||||
p, size, std::addressof(h->handler_));
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (
|
||||
waitable_executor_wrapped_handler* h)
|
||||
{
|
||||
return h->cont_;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Executor which provides blocking until all handlers are called. */
|
||||
class waitable_executor
|
||||
{
|
||||
private:
|
||||
template <class, class>
|
||||
friend class detail::waitable_executor_wrapped_handler;
|
||||
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
std::size_t count_ = 0;
|
||||
std::vector<std::function<void(void)>> notify_;
|
||||
|
||||
public:
|
||||
/** Block until all handlers are called. */
|
||||
template <class = void>
|
||||
void
|
||||
wait();
|
||||
|
||||
/** Blocks until all handlers are called or time elapses.
|
||||
@return `true` if all handlers are done or `false` if the time elapses.
|
||||
*/
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
wait_for (std::chrono::duration<
|
||||
Rep, Period> const& elapsed_time);
|
||||
|
||||
/** Blocks until all handlers are called or a time is reached.
|
||||
@return `true` if all handlers are done or `false` on timeout.
|
||||
*/
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
wait_until (std::chrono::time_point<
|
||||
Clock, Duration> const& timeout_time);
|
||||
|
||||
/** Call a function asynchronously after all handlers are called.
|
||||
The function may be called on the callers thread.
|
||||
*/
|
||||
template <class = void>
|
||||
void
|
||||
async_wait(std::function<void(void)> f);
|
||||
|
||||
/** Create a new handler that dispatches the wrapped handler on the Context. */
|
||||
template <class Handler>
|
||||
detail::waitable_executor_wrapped_handler<waitable_executor,
|
||||
std::remove_reference_t<Handler>>
|
||||
wrap (Handler&& handler);
|
||||
|
||||
private:
|
||||
template <class = void>
|
||||
void
|
||||
increment();
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
decrement();
|
||||
};
|
||||
|
||||
template <class>
|
||||
void
|
||||
waitable_executor::wait()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
cond_.wait(lock,
|
||||
[this]() { return count_ == 0; });
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
bool
|
||||
waitable_executor::wait_for (std::chrono::duration<
|
||||
Rep, Period> const& elapsed_time)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return cond_.wait_for(lock, elapsed_time,
|
||||
[this]() { return count_ == 0; }) ==
|
||||
std::cv_status::no_timeout;
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
bool
|
||||
waitable_executor::wait_until (std::chrono::time_point<
|
||||
Clock, Duration> const& timeout_time)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return cond_.wait_until(lock, timeout_time,
|
||||
[this]() { return count_ == 0; }) ==
|
||||
std::cv_status::no_timeout;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
waitable_executor::async_wait(std::function<void(void)> f)
|
||||
{
|
||||
bool busy;
|
||||
{
|
||||
std::lock_guard<std::mutex> _(mutex_);
|
||||
busy = count_ > 0;
|
||||
if (busy)
|
||||
notify_.emplace_back(std::move(f));
|
||||
}
|
||||
if (! busy)
|
||||
f();
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::waitable_executor_wrapped_handler<waitable_executor,
|
||||
std::remove_reference_t<Handler>>
|
||||
waitable_executor::wrap (Handler&& handler)
|
||||
{
|
||||
return detail::waitable_executor_wrapped_handler<
|
||||
waitable_executor, std::remove_reference_t<Handler>>(
|
||||
*this, std::forward<Handler>(handler));
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
waitable_executor::increment()
|
||||
{
|
||||
std::lock_guard<std::mutex> _(mutex_);
|
||||
++count_;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
waitable_executor::decrement()
|
||||
{
|
||||
bool notify;
|
||||
std::vector<std::function<void(void)>> list;
|
||||
{
|
||||
std::lock_guard<std::mutex> _(mutex_);
|
||||
notify = --count_ == 0;
|
||||
if (notify)
|
||||
std::swap(list, notify_);
|
||||
}
|
||||
if (notify)
|
||||
{
|
||||
cond_.notify_all();
|
||||
for(auto& _ : list)
|
||||
_();
|
||||
}
|
||||
}
|
||||
|
||||
} // asio
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/boost/ErrorCode.h>
|
||||
|
||||
namespace detail {
|
||||
|
||||
// to squelch linker warnings
|
||||
int boostUnusedVariable = 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_BOOST_ERRORCODE_H_INCLUDED
|
||||
#define BEAST_BOOST_ERRORCODE_H_INCLUDED
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// Lift this into our namespace. For now we will
|
||||
// use boost, and then switch to std::error_code when
|
||||
// it is available on all our supported platforms.
|
||||
//
|
||||
using ErrorCode = boost::system::error_code;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/chrono/impl/chrono_io.cpp>
|
||||
#include <beast/chrono/impl/RelativeTime.cpp>
|
||||
|
||||
#include <beast/chrono/tests/abstract_clock.test.cpp>
|
||||
#include <beast/chrono/tests/basic_seconds_clock.test.cpp>
|
||||
@@ -1,803 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// chrono_io
|
||||
//
|
||||
// (C) Copyright Howard Hinnant
|
||||
// Use, modification and distribution are subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
#ifndef BEAST_CHRONO_CHRONO_IO_H_INCLUDED
|
||||
#define BEAST_CHRONO_CHRONO_IO_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <locale>
|
||||
|
||||
/*
|
||||
|
||||
chrono_io synopsis
|
||||
|
||||
#include <chrono>
|
||||
#include <ratio_io>
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
enum duration_style {prefix, symbol};
|
||||
enum timezone {utc, local};
|
||||
|
||||
// facets
|
||||
|
||||
class durationpunct
|
||||
: public locale::facet
|
||||
{
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit durationpunct(size_t refs = 0);
|
||||
explicit durationpunct(duration_style fmt, size_t refs = 0);
|
||||
|
||||
bool is_symbol_name() const noexcept;
|
||||
bool is_prefix_name() const noexcept;
|
||||
};
|
||||
|
||||
template <class charT>
|
||||
class timepunct
|
||||
: public locale::facet
|
||||
{
|
||||
public:
|
||||
typedef basic_string<charT> string_type;
|
||||
|
||||
static locale::id id;
|
||||
|
||||
explicit timepunct(size_t refs = 0);
|
||||
timepunct(timezone tz, string_type fmt, size_t refs = 0);
|
||||
|
||||
const string_type& fmt() const noexcept;
|
||||
std::chrono::timezone timezone() const noexcept;
|
||||
};
|
||||
|
||||
// manipulators
|
||||
|
||||
class duration_fmt
|
||||
{
|
||||
public:
|
||||
explicit duration_fmt(duration_style f) noexcept;
|
||||
explicit operator duration_style() const noexcept;
|
||||
};
|
||||
|
||||
unspecified time_fmt(timezone tz);
|
||||
template<class charT>
|
||||
unspecified time_fmt(timezone tz, basic_string<charT> fmt);
|
||||
template<class charT>
|
||||
unspecified time_fmt(timezone tz, const charT* fmt);
|
||||
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, duration_fmt d);
|
||||
|
||||
template<class charT, class traits>
|
||||
std::basic_istream<charT, traits>&
|
||||
operator>>(std::basic_istream<charT, traits>& is, duration_fmt d);
|
||||
|
||||
// duration I/O
|
||||
|
||||
template <class charT, class Traits, class Rep, class Period>
|
||||
basic_ostream<charT, Traits>&
|
||||
operator<<(basic_ostream<charT, Traits>& os, const duration<Rep, Period>& d);
|
||||
|
||||
template <class charT, class Traits, class Rep, class Period>
|
||||
basic_istream<charT, Traits>&
|
||||
operator>>(basic_istream<charT, Traits>& is, duration<Rep, Period>& d);
|
||||
|
||||
// system_clock I/O
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_ostream<charT, Traits>&
|
||||
operator<<(basic_ostream<charT, Traits>& os,
|
||||
const time_point<system_clock, Duration>& tp);
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_istream<charT, Traits>&
|
||||
operator>>(basic_istream<charT, Traits>& is,
|
||||
time_point<system_clock, Duration>& tp);
|
||||
|
||||
// steady_clock I/O
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_ostream<charT, Traits>&
|
||||
operator<<(basic_ostream<charT, Traits>& os,
|
||||
const time_point<steady_clock, Duration>& tp);
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_istream<charT, Traits>&
|
||||
operator>>(basic_istream<charT, Traits>& is,
|
||||
time_point<steady_clock, Duration>& tp);
|
||||
|
||||
// high_resolution_clock I/O
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_ostream<charT, Traits>&
|
||||
operator<<(basic_ostream<charT, Traits>& os,
|
||||
const time_point<high_resolution_clock, Duration>& tp);
|
||||
|
||||
template <class charT, class Traits, class Duration>
|
||||
basic_istream<charT, Traits>&
|
||||
operator>>(basic_istream<charT, Traits>& is,
|
||||
time_point<high_resolution_clock, Duration>& tp);
|
||||
|
||||
} // chrono
|
||||
} // std
|
||||
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <beast/chrono/ratio_io.h>
|
||||
|
||||
//_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
namespace std {
|
||||
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
template <class To, class Rep, class Period>
|
||||
To
|
||||
round(const duration<Rep, Period>& d)
|
||||
{
|
||||
To t0 = duration_cast<To>(d);
|
||||
To t1 = t0;
|
||||
++t1;
|
||||
typedef typename common_type<To, duration<Rep, Period> >::type _D;
|
||||
_D diff0 = d - t0;
|
||||
_D diff1 = t1 - d;
|
||||
if (diff0 == diff1)
|
||||
{
|
||||
if (t0.count() & 1)
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
else if (diff0 < diff1)
|
||||
return t0;
|
||||
return t1;
|
||||
}
|
||||
|
||||
enum duration_style {prefix, symbol};
|
||||
enum timezone {utc, local};
|
||||
|
||||
class durationpunct
|
||||
: public locale::facet
|
||||
{
|
||||
private:
|
||||
duration_style __style_;
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit durationpunct(size_t refs = 0)
|
||||
: locale::facet(refs), __style_(prefix) {}
|
||||
|
||||
explicit durationpunct(duration_style fmt, size_t refs = 0)
|
||||
: locale::facet(refs), __style_(fmt) {}
|
||||
|
||||
bool is_symbol_name() const noexcept {return __style_ == symbol;}
|
||||
bool is_prefix_name() const noexcept {return __style_ == prefix;}
|
||||
};
|
||||
|
||||
class duration_fmt
|
||||
{
|
||||
duration_style form_;
|
||||
public:
|
||||
explicit duration_fmt(duration_style f) noexcept : form_(f) {}
|
||||
// VFALCO NOTE disabled this for MSVC
|
||||
/*explicit*/
|
||||
operator duration_style() const noexcept {return form_;}
|
||||
};
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_ostream<charT, traits>&
|
||||
operator <<(basic_ostream<charT, traits>& os, duration_fmt d)
|
||||
{
|
||||
os.imbue(locale(os.getloc(), new durationpunct(static_cast<duration_style>(d))));
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_istream<charT, traits>&
|
||||
operator >>(basic_istream<charT, traits>& is, duration_fmt d)
|
||||
{
|
||||
is.imbue(locale(is.getloc(), new durationpunct(static_cast<duration_style>(d))));
|
||||
return is;
|
||||
}
|
||||
|
||||
template <class _CharT, class _Rep, class _Period>
|
||||
basic_string<_CharT>
|
||||
__get_unit(bool __is_long, const duration<_Rep, _Period>& d)
|
||||
{
|
||||
if (__is_long)
|
||||
{
|
||||
_CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's', 0};
|
||||
basic_string<_CharT> s = ratio_string<_Period, _CharT>::prefix() + __p;
|
||||
if (d.count() == 1 || d.count() == -1)
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
return ratio_string<_Period, _CharT>::symbol() + 's';
|
||||
}
|
||||
|
||||
template <class _CharT, class _Rep>
|
||||
basic_string<_CharT>
|
||||
__get_unit(bool __is_long, const duration<_Rep, ratio<1> >& d)
|
||||
{
|
||||
if (__is_long)
|
||||
{
|
||||
_CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'};
|
||||
basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
|
||||
if (d.count() == 1 || d.count() == -1)
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
return basic_string<_CharT>(1, 's');
|
||||
}
|
||||
|
||||
template <class _CharT, class _Rep>
|
||||
basic_string<_CharT>
|
||||
__get_unit(bool __is_long, const duration<_Rep, ratio<60> >& d)
|
||||
{
|
||||
if (__is_long)
|
||||
{
|
||||
_CharT __p[] = {'m', 'i', 'n', 'u', 't', 'e', 's'};
|
||||
basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
|
||||
if (d.count() == 1 || d.count() == -1)
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
_CharT __p[] = {'m', 'i', 'n'};
|
||||
return basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
|
||||
}
|
||||
|
||||
template <class _CharT, class _Rep>
|
||||
basic_string<_CharT>
|
||||
__get_unit(bool __is_long, const duration<_Rep, ratio<3600> >& d)
|
||||
{
|
||||
if (__is_long)
|
||||
{
|
||||
_CharT __p[] = {'h', 'o', 'u', 'r', 's'};
|
||||
basic_string<_CharT> s = basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT));
|
||||
if (d.count() == 1 || d.count() == -1)
|
||||
s.pop_back();
|
||||
return s;
|
||||
}
|
||||
return basic_string<_CharT>(1, 'h');
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Rep, class _Period>
|
||||
basic_ostream<_CharT, _Traits>&
|
||||
operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d)
|
||||
{
|
||||
typename basic_ostream<_CharT, _Traits>::sentry ok(__os);
|
||||
if (ok)
|
||||
{
|
||||
typedef durationpunct _F;
|
||||
typedef basic_string<_CharT> string_type;
|
||||
bool failed = false;
|
||||
try
|
||||
{
|
||||
bool __is_long = true;
|
||||
locale __loc = __os.getloc();
|
||||
if (has_facet<_F>(__loc))
|
||||
{
|
||||
const _F& f = use_facet<_F>(__loc);
|
||||
__is_long = f.is_prefix_name();
|
||||
}
|
||||
string_type __unit = __get_unit<_CharT>(__is_long, __d);
|
||||
__os << __d.count() << ' ' << __unit;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
if (failed)
|
||||
__os.setstate(ios_base::failbit | ios_base::badbit);
|
||||
}
|
||||
return __os;
|
||||
}
|
||||
|
||||
template <class _Rep, bool = is_scalar<_Rep>::value>
|
||||
struct __duration_io_intermediate
|
||||
{
|
||||
typedef _Rep type;
|
||||
};
|
||||
|
||||
template <class _Rep>
|
||||
struct __duration_io_intermediate<_Rep, true>
|
||||
{
|
||||
typedef typename conditional
|
||||
<
|
||||
is_floating_point<_Rep>::value,
|
||||
long double,
|
||||
typename conditional
|
||||
<
|
||||
is_signed<_Rep>::value,
|
||||
long long,
|
||||
unsigned long long
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T
|
||||
__gcd(T x, T y)
|
||||
{
|
||||
while (y != 0)
|
||||
{
|
||||
T old_x = x;
|
||||
x = y;
|
||||
y = old_x % y;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <>
|
||||
long double
|
||||
inline
|
||||
__gcd(long double, long double)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Rep, class _Period>
|
||||
basic_istream<_CharT, _Traits>&
|
||||
operator>>(basic_istream<_CharT, _Traits>& __is, duration<_Rep, _Period>& __d)
|
||||
{
|
||||
// These are unused and generate warnings
|
||||
//typedef basic_string<_CharT> string_type;
|
||||
//typedef durationpunct _F;
|
||||
|
||||
typedef typename __duration_io_intermediate<_Rep>::type _IR;
|
||||
_IR __r;
|
||||
// read value into __r
|
||||
__is >> __r;
|
||||
if (__is.good())
|
||||
{
|
||||
// now determine unit
|
||||
typedef istreambuf_iterator<_CharT, _Traits> _I;
|
||||
_I __i(__is);
|
||||
_I __e;
|
||||
if (__i != __e && *__i == ' ') // mandatory ' ' after value
|
||||
{
|
||||
++__i;
|
||||
if (__i != __e)
|
||||
{
|
||||
locale __loc = __is.getloc();
|
||||
// unit is num / den (yet to be determined)
|
||||
unsigned long long num = 0;
|
||||
unsigned long long den = 0;
|
||||
ios_base::iostate __err = ios_base::goodbit;
|
||||
if (*__i == '[')
|
||||
{
|
||||
// parse [N/D]s or [N/D]seconds format
|
||||
++__i;
|
||||
_CharT __x;
|
||||
__is >> num >> __x >> den;
|
||||
if (!__is.good() || __x != '/')
|
||||
{
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
__i = _I(__is);
|
||||
if (*__i != ']')
|
||||
{
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
++__i;
|
||||
const basic_string<_CharT> __units[] =
|
||||
{
|
||||
__get_unit<_CharT>(true, seconds(2)),
|
||||
__get_unit<_CharT>(true, seconds(1)),
|
||||
__get_unit<_CharT>(false, seconds(1))
|
||||
};
|
||||
const basic_string<_CharT>* __k = __scan_keyword(__i, __e,
|
||||
__units, __units + sizeof(__units)/sizeof(__units[0]),
|
||||
use_facet<ctype<_CharT> >(__loc),
|
||||
__err);
|
||||
switch ((__k - __units) / 3)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
__is.setstate(__err);
|
||||
return __is;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// parse SI name, short or long
|
||||
const basic_string<_CharT> __units[] =
|
||||
{
|
||||
__get_unit<_CharT>(true, duration<_Rep, atto>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, atto>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, atto>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, femto>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, femto>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, femto>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, pico>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, pico>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, pico>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, nano>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, nano>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, nano>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, micro>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, micro>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, micro>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, milli>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, milli>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, milli>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, centi>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, centi>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, centi>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, deci>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, deci>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, deci>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, deca>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, deca>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, deca>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, hecto>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, hecto>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, hecto>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, kilo>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, kilo>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, kilo>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, mega>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, mega>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, mega>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, giga>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, giga>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, giga>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, tera>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, tera>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, tera>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, peta>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, peta>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, peta>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, exa>(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, exa>(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, exa>(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<1> >(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<1> >(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, ratio<1> >(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<60> >(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<60> >(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, ratio<60> >(1)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<3600> >(2)),
|
||||
__get_unit<_CharT>(true, duration<_Rep, ratio<3600> >(1)),
|
||||
__get_unit<_CharT>(false, duration<_Rep, ratio<3600> >(1))
|
||||
};
|
||||
const basic_string<_CharT>* __k = __scan_keyword(__i, __e,
|
||||
__units, __units + sizeof(__units)/sizeof(__units[0]),
|
||||
use_facet<ctype<_CharT> >(__loc),
|
||||
__err);
|
||||
switch (__k - __units)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
num = 1ULL;
|
||||
den = 1000000000000000000ULL;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
num = 1ULL;
|
||||
den = 1000000000000000ULL;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
num = 1ULL;
|
||||
den = 1000000000000ULL;
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
num = 1ULL;
|
||||
den = 1000000000ULL;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
num = 1ULL;
|
||||
den = 1000000ULL;
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
num = 1ULL;
|
||||
den = 1000ULL;
|
||||
break;
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
num = 1ULL;
|
||||
den = 100ULL;
|
||||
break;
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
num = 1ULL;
|
||||
den = 10ULL;
|
||||
break;
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
num = 10ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
num = 100ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
num = 1000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
num = 1000000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 36:
|
||||
case 37:
|
||||
case 38:
|
||||
num = 1000000000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
num = 1000000000000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
num = 1000000000000000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
num = 1000000000000000000ULL;
|
||||
den = 1ULL;
|
||||
break;
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
num = 1;
|
||||
den = 1;
|
||||
break;
|
||||
case 51:
|
||||
case 52:
|
||||
case 53:
|
||||
num = 60;
|
||||
den = 1;
|
||||
break;
|
||||
case 54:
|
||||
case 55:
|
||||
case 56:
|
||||
num = 3600;
|
||||
den = 1;
|
||||
break;
|
||||
default:
|
||||
__is.setstate(__err);
|
||||
return __is;
|
||||
}
|
||||
}
|
||||
// unit is num/den
|
||||
// __r should be multiplied by (num/den) / _Period
|
||||
// Reduce (num/den) / _Period to lowest terms
|
||||
unsigned long long __gcd_n1_n2 = __gcd<unsigned long long>(num, _Period::num);
|
||||
unsigned long long __gcd_d1_d2 = __gcd<unsigned long long>(den, _Period::den);
|
||||
num /= __gcd_n1_n2;
|
||||
den /= __gcd_d1_d2;
|
||||
unsigned long long __n2 = _Period::num / __gcd_n1_n2;
|
||||
unsigned long long __d2 = _Period::den / __gcd_d1_d2;
|
||||
if (num > numeric_limits<unsigned long long>::max() / __d2 ||
|
||||
den > numeric_limits<unsigned long long>::max() / __n2)
|
||||
{
|
||||
// (num/den) / _Period overflows
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
num *= __d2;
|
||||
den *= __n2;
|
||||
// num / den is now factor to multiply by __r
|
||||
typedef typename common_type<_IR, unsigned long long>::type _CT;
|
||||
if (is_integral<_IR>::value)
|
||||
{
|
||||
// Reduce __r * num / den
|
||||
_CT __t = __gcd<_CT>(__r, den);
|
||||
__r /= __t;
|
||||
den /= __t;
|
||||
if (den != 1)
|
||||
{
|
||||
// Conversion to _Period is integral and not exact
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
}
|
||||
if (__r > duration_values<_CT>::max() / num)
|
||||
{
|
||||
// Conversion to _Period overflowed
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
_CT __t = __r * num;
|
||||
__t /= den;
|
||||
if (duration_values<_Rep>::max() < __t)
|
||||
{
|
||||
// Conversion to _Period overflowed
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
// Success! Store it.
|
||||
__r = _Rep(__t);
|
||||
__d = duration<_Rep, _Period>(__r);
|
||||
__is.setstate(__err);
|
||||
}
|
||||
else
|
||||
__is.setstate(__is.failbit | __is.eofbit);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__i == __e)
|
||||
__is.setstate(__is.eofbit);
|
||||
__is.setstate(__is.failbit);
|
||||
}
|
||||
}
|
||||
else
|
||||
__is.setstate(__is.failbit);
|
||||
return __is;
|
||||
}
|
||||
|
||||
template <class charT>
|
||||
class timepunct
|
||||
: public locale::facet
|
||||
{
|
||||
public:
|
||||
typedef basic_string<charT> string_type;
|
||||
|
||||
private:
|
||||
string_type fmt_;
|
||||
chrono::timezone tz_;
|
||||
|
||||
public:
|
||||
static locale::id id;
|
||||
|
||||
explicit timepunct(size_t refs = 0)
|
||||
: locale::facet(refs), tz_(utc) {}
|
||||
timepunct(timezone tz, string_type fmt, size_t refs = 0)
|
||||
: locale::facet(refs), fmt_(std::move(fmt)), tz_(tz) {}
|
||||
|
||||
const string_type& fmt() const noexcept {return fmt_;}
|
||||
chrono::timezone get_timezone() const noexcept {return tz_;}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
locale::id
|
||||
timepunct<CharT>::id;
|
||||
|
||||
template <class _CharT, class _Traits, class _Duration>
|
||||
basic_ostream<_CharT, _Traits>&
|
||||
operator<<(basic_ostream<_CharT, _Traits>& __os,
|
||||
const time_point<steady_clock, _Duration>& __tp)
|
||||
{
|
||||
return __os << __tp.time_since_epoch() << " since boot";
|
||||
}
|
||||
|
||||
template<class charT>
|
||||
struct __time_manip
|
||||
{
|
||||
basic_string<charT> fmt_;
|
||||
timezone tz_;
|
||||
|
||||
__time_manip(timezone tz, basic_string<charT> fmt)
|
||||
: fmt_(std::move(fmt)),
|
||||
tz_(tz) {}
|
||||
};
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_ostream<charT, traits>&
|
||||
operator <<(basic_ostream<charT, traits>& os, __time_manip<charT> m)
|
||||
{
|
||||
os.imbue(locale(os.getloc(), new timepunct<charT>(m.tz_, std::move(m.fmt_))));
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_istream<charT, traits>&
|
||||
operator >>(basic_istream<charT, traits>& is, __time_manip<charT> m)
|
||||
{
|
||||
is.imbue(locale(is.getloc(), new timepunct<charT>(m.tz_, std::move(m.fmt_))));
|
||||
return is;
|
||||
}
|
||||
|
||||
template<class charT>
|
||||
inline
|
||||
__time_manip<charT>
|
||||
time_fmt(timezone tz, const charT* fmt)
|
||||
{
|
||||
return __time_manip<charT>(tz, fmt);
|
||||
}
|
||||
|
||||
template<class charT>
|
||||
inline
|
||||
__time_manip<charT>
|
||||
time_fmt(timezone tz, basic_string<charT> fmt)
|
||||
{
|
||||
return __time_manip<charT>(tz, std::move(fmt));
|
||||
}
|
||||
|
||||
class __time_man
|
||||
{
|
||||
timezone form_;
|
||||
public:
|
||||
explicit __time_man(timezone f) : form_(f) {}
|
||||
// explicit
|
||||
operator timezone() const {return form_;}
|
||||
};
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_ostream<charT, traits>&
|
||||
operator <<(basic_ostream<charT, traits>& os, __time_man m)
|
||||
{
|
||||
os.imbue(locale(os.getloc(), new timepunct<charT>(static_cast<timezone>(m), basic_string<charT>())));
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class charT, class traits>
|
||||
basic_istream<charT, traits>&
|
||||
operator >>(basic_istream<charT, traits>& is, __time_man m)
|
||||
{
|
||||
is.imbue(locale(is.getloc(), new timepunct<charT>(static_cast<timezone>(m), basic_string<charT>())));
|
||||
return is;
|
||||
}
|
||||
|
||||
inline
|
||||
__time_man
|
||||
time_fmt(timezone f)
|
||||
{
|
||||
return __time_man(f);
|
||||
}
|
||||
|
||||
} // chrono
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// chrono_io
|
||||
//
|
||||
// (C) Copyright Howard Hinnant
|
||||
// Use, modification and distribution are subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
#include <beast/chrono/chrono_io.h>
|
||||
|
||||
//_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
namespace std {
|
||||
|
||||
namespace chrono
|
||||
{
|
||||
|
||||
locale::id
|
||||
durationpunct::id;
|
||||
|
||||
} // chrono
|
||||
|
||||
//_LIBCPP_END_NAMESPACE_STD
|
||||
}
|
||||
@@ -1,622 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// ratio_io
|
||||
//
|
||||
// (C) Copyright Howard Hinnant
|
||||
// Use, modification and distribution are subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt).
|
||||
|
||||
#ifndef BEAST_CHRONO_RATIO_IO_H_INCLUDED
|
||||
#define BEAST_CHRONO_RATIO_IO_H_INCLUDED
|
||||
|
||||
/*
|
||||
|
||||
ratio_io synopsis
|
||||
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <class Ratio, class charT>
|
||||
struct ratio_string
|
||||
{
|
||||
static basic_string<charT> symbol();
|
||||
static basic_string<charT> prefix();
|
||||
};
|
||||
|
||||
} // std
|
||||
|
||||
*/
|
||||
|
||||
#include <ratio>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
//_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
namespace std {
|
||||
|
||||
template <class _Ratio, class _CharT>
|
||||
struct ratio_string
|
||||
{
|
||||
static basic_string<_CharT> symbol() {return prefix();}
|
||||
static basic_string<_CharT> prefix();
|
||||
};
|
||||
|
||||
template <class _Ratio, class _CharT>
|
||||
basic_string<_CharT>
|
||||
ratio_string<_Ratio, _CharT>::prefix()
|
||||
{
|
||||
basic_ostringstream<_CharT> __os;
|
||||
__os << _CharT('[') << _Ratio::num << _CharT('/')
|
||||
<< _Ratio::den << _CharT(']');
|
||||
return __os.str();
|
||||
}
|
||||
|
||||
// atto
|
||||
|
||||
template <>
|
||||
struct ratio_string<atto, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'a');}
|
||||
static string prefix() {return string("atto");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<atto, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'a');}
|
||||
static u16string prefix() {return u16string(u"atto");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<atto, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'a');}
|
||||
static u32string prefix() {return u32string(U"atto");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<atto, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'a');}
|
||||
static wstring prefix() {return wstring(L"atto");}
|
||||
};
|
||||
|
||||
// femto
|
||||
|
||||
template <>
|
||||
struct ratio_string<femto, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'f');}
|
||||
static string prefix() {return string("femto");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<femto, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'f');}
|
||||
static u16string prefix() {return u16string(u"femto");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<femto, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'f');}
|
||||
static u32string prefix() {return u32string(U"femto");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<femto, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'f');}
|
||||
static wstring prefix() {return wstring(L"femto");}
|
||||
};
|
||||
|
||||
// pico
|
||||
|
||||
template <>
|
||||
struct ratio_string<pico, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'p');}
|
||||
static string prefix() {return string("pico");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<pico, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'p');}
|
||||
static u16string prefix() {return u16string(u"pico");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<pico, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'p');}
|
||||
static u32string prefix() {return u32string(U"pico");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<pico, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'p');}
|
||||
static wstring prefix() {return wstring(L"pico");}
|
||||
};
|
||||
|
||||
// nano
|
||||
|
||||
template <>
|
||||
struct ratio_string<nano, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'n');}
|
||||
static string prefix() {return string("nano");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<nano, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'n');}
|
||||
static u16string prefix() {return u16string(u"nano");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<nano, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'n');}
|
||||
static u32string prefix() {return u32string(U"nano");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<nano, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'n');}
|
||||
static wstring prefix() {return wstring(L"nano");}
|
||||
};
|
||||
|
||||
// micro
|
||||
|
||||
template <>
|
||||
struct ratio_string<micro, char>
|
||||
{
|
||||
static string symbol() {return string("\xC2\xB5");}
|
||||
static string prefix() {return string("micro");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<micro, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'\xB5');}
|
||||
static u16string prefix() {return u16string(u"micro");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<micro, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'\xB5');}
|
||||
static u32string prefix() {return u32string(U"micro");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<micro, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'\xB5');}
|
||||
static wstring prefix() {return wstring(L"micro");}
|
||||
};
|
||||
|
||||
// milli
|
||||
|
||||
template <>
|
||||
struct ratio_string<milli, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'm');}
|
||||
static string prefix() {return string("milli");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<milli, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'm');}
|
||||
static u16string prefix() {return u16string(u"milli");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<milli, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'm');}
|
||||
static u32string prefix() {return u32string(U"milli");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<milli, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'm');}
|
||||
static wstring prefix() {return wstring(L"milli");}
|
||||
};
|
||||
|
||||
// centi
|
||||
|
||||
template <>
|
||||
struct ratio_string<centi, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'c');}
|
||||
static string prefix() {return string("centi");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<centi, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'c');}
|
||||
static u16string prefix() {return u16string(u"centi");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<centi, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'c');}
|
||||
static u32string prefix() {return u32string(U"centi");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<centi, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'c');}
|
||||
static wstring prefix() {return wstring(L"centi");}
|
||||
};
|
||||
|
||||
// deci
|
||||
|
||||
template <>
|
||||
struct ratio_string<deci, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'd');}
|
||||
static string prefix() {return string("deci");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<deci, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'd');}
|
||||
static u16string prefix() {return u16string(u"deci");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<deci, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'd');}
|
||||
static u32string prefix() {return u32string(U"deci");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<deci, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'd');}
|
||||
static wstring prefix() {return wstring(L"deci");}
|
||||
};
|
||||
|
||||
// deca
|
||||
|
||||
template <>
|
||||
struct ratio_string<deca, char>
|
||||
{
|
||||
static string symbol() {return string("da");}
|
||||
static string prefix() {return string("deca");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<deca, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(u"da");}
|
||||
static u16string prefix() {return u16string(u"deca");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<deca, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(U"da");}
|
||||
static u32string prefix() {return u32string(U"deca");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<deca, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(L"da");}
|
||||
static wstring prefix() {return wstring(L"deca");}
|
||||
};
|
||||
|
||||
// hecto
|
||||
|
||||
template <>
|
||||
struct ratio_string<hecto, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'h');}
|
||||
static string prefix() {return string("hecto");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<hecto, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'h');}
|
||||
static u16string prefix() {return u16string(u"hecto");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<hecto, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'h');}
|
||||
static u32string prefix() {return u32string(U"hecto");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<hecto, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'h');}
|
||||
static wstring prefix() {return wstring(L"hecto");}
|
||||
};
|
||||
|
||||
// kilo
|
||||
|
||||
template <>
|
||||
struct ratio_string<kilo, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'k');}
|
||||
static string prefix() {return string("kilo");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<kilo, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'k');}
|
||||
static u16string prefix() {return u16string(u"kilo");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<kilo, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'k');}
|
||||
static u32string prefix() {return u32string(U"kilo");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<kilo, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'k');}
|
||||
static wstring prefix() {return wstring(L"kilo");}
|
||||
};
|
||||
|
||||
// mega
|
||||
|
||||
template <>
|
||||
struct ratio_string<mega, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'M');}
|
||||
static string prefix() {return string("mega");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<mega, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'M');}
|
||||
static u16string prefix() {return u16string(u"mega");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<mega, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'M');}
|
||||
static u32string prefix() {return u32string(U"mega");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<mega, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'M');}
|
||||
static wstring prefix() {return wstring(L"mega");}
|
||||
};
|
||||
|
||||
// giga
|
||||
|
||||
template <>
|
||||
struct ratio_string<giga, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'G');}
|
||||
static string prefix() {return string("giga");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<giga, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'G');}
|
||||
static u16string prefix() {return u16string(u"giga");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<giga, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'G');}
|
||||
static u32string prefix() {return u32string(U"giga");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<giga, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'G');}
|
||||
static wstring prefix() {return wstring(L"giga");}
|
||||
};
|
||||
|
||||
// tera
|
||||
|
||||
template <>
|
||||
struct ratio_string<tera, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'T');}
|
||||
static string prefix() {return string("tera");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<tera, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'T');}
|
||||
static u16string prefix() {return u16string(u"tera");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<tera, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'T');}
|
||||
static u32string prefix() {return u32string(U"tera");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<tera, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'T');}
|
||||
static wstring prefix() {return wstring(L"tera");}
|
||||
};
|
||||
|
||||
// peta
|
||||
|
||||
template <>
|
||||
struct ratio_string<peta, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'P');}
|
||||
static string prefix() {return string("peta");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<peta, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'P');}
|
||||
static u16string prefix() {return u16string(u"peta");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<peta, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'P');}
|
||||
static u32string prefix() {return u32string(U"peta");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<peta, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'P');}
|
||||
static wstring prefix() {return wstring(L"peta");}
|
||||
};
|
||||
|
||||
// exa
|
||||
|
||||
template <>
|
||||
struct ratio_string<exa, char>
|
||||
{
|
||||
static string symbol() {return string(1, 'E');}
|
||||
static string prefix() {return string("exa");}
|
||||
};
|
||||
|
||||
#if HAS_UNICODE_SUPPORT
|
||||
|
||||
template <>
|
||||
struct ratio_string<exa, char16_t>
|
||||
{
|
||||
static u16string symbol() {return u16string(1, u'E');}
|
||||
static u16string prefix() {return u16string(u"exa");}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ratio_string<exa, char32_t>
|
||||
{
|
||||
static u32string symbol() {return u32string(1, U'E');}
|
||||
static u32string prefix() {return u32string(U"exa");}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct ratio_string<exa, wchar_t>
|
||||
{
|
||||
static wstring symbol() {return wstring(1, L'E');}
|
||||
static wstring prefix() {return wstring(L"exa");}
|
||||
};
|
||||
|
||||
//_LIBCPP_END_NAMESPACE_STD
|
||||
}
|
||||
|
||||
#endif // _RATIO_IO
|
||||
@@ -1,86 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONFIG_CONTRACTCHECKS_H_INCLUDED
|
||||
#define BEAST_CONFIG_CONTRACTCHECKS_H_INCLUDED
|
||||
|
||||
// This file has to work when included in a C source file.
|
||||
|
||||
#if defined (fatal_error) || \
|
||||
defined (fatal_condition) || \
|
||||
defined (meets_condition) || \
|
||||
defined (meets_precondition) || \
|
||||
defined (meets_postcondition) || \
|
||||
defined (meets_invariant) || \
|
||||
defined (check_invariant)
|
||||
#error "Programming by contract macros cannot be overriden!"
|
||||
#endif
|
||||
|
||||
/** Report a fatal error message and terminate the application.
|
||||
This macro automatically fills in the file and line number
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_error (char const* message); @endif
|
||||
@see FatalError
|
||||
*/
|
||||
#define fatal_error(message) beast_reportFatalError (message, __FILE__, __LINE__)
|
||||
|
||||
/** Reports a fatal error message type if the condition is false
|
||||
The condition is always evaluated regardless of settings.
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_condition (bool condition, char const* category); @endcode
|
||||
*/
|
||||
#define fatal_condition(condition,category) static_cast <void> \
|
||||
(((!!(condition)) || (beast_reportFatalError ( \
|
||||
category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), 0)))
|
||||
|
||||
/** Reports a fatal error message type if the condition is false
|
||||
The condition is always evaluated regardless of settings.
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_condition (bool condition, char const* category); @endcode
|
||||
*/
|
||||
#define meets_condition(condition,category) static_cast <bool> \
|
||||
(((!!(condition)) || (beast_reportFatalError ( \
|
||||
category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), false)))
|
||||
|
||||
/** Condition tests for programming by contract.
|
||||
The condition is always evaluated regardless of settings, and gets returned.
|
||||
Meets this declaration syntax:
|
||||
@code inline bool meets_condition (bool); @endcode
|
||||
*/
|
||||
/** @{ */
|
||||
#define meets_precondition(condition) meets_condition(condition,"Pre-condition")
|
||||
#define meets_postcondition(condition) meets_condition(condition,"Post-condition")
|
||||
#define meets_invariant(condition) meets_condition(condition,"Invariant")
|
||||
/** @} */
|
||||
|
||||
/** Condition tests for programming by contract.
|
||||
The condition is evaluated only if BEAST_DISABLE_CONTRACT_CHECKS is 0.
|
||||
Meets this declaration syntax:
|
||||
@code inline void check_condition (bool); @endcode
|
||||
@see BEAST_DISABLE_CONTRACT_CHECKS
|
||||
*/
|
||||
/** @{ */
|
||||
#if ! BEAST_DISABLE_CONTRACT_CHECKS
|
||||
# define check_invariant(condition) meets_invariant(condition)
|
||||
#else
|
||||
# define check_invariant(condition) ((void)0)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Ideas from boost
|
||||
|
||||
// Intel
|
||||
#ifndef BEAST_CONFIG_SELECTCOMPILERCONFIG_H_INCLUDED
|
||||
#define BEAST_CONFIG_SELECTCOMPILERCONFIG_H_INCLUDED
|
||||
|
||||
#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
|
||||
#define BEAST_COMPILER_CONFIG "config/compiler/Intel.h"
|
||||
|
||||
// Clang C++ emulates GCC, so it has to appear early.
|
||||
#elif defined __clang__
|
||||
#define BEAST_COMPILER_CONFIG "config/compiler/Clang.h"
|
||||
|
||||
// GNU C++:
|
||||
#elif defined __GNUC__
|
||||
#define BEAST_COMPILER_CONFIG "config/compiler/Gcc.h"
|
||||
|
||||
// Microsoft Visual C++
|
||||
//
|
||||
// Must remain the last #elif since some other vendors (Metrowerks, for
|
||||
// example) also #define _MSC_VER
|
||||
#elif defined _MSC_VER
|
||||
#define BEAST_COMPILER_CONFIG "config/compiler/VisualC.h"
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Ideas from boost
|
||||
|
||||
// Android, which must be manually set by defining BEAST_ANDROID
|
||||
#ifndef BEAST_CONFIG_SELECTPLATFORMCONFIG_H_INCLUDED
|
||||
#define BEAST_CONFIG_SELECTPLATFORMCONFIG_H_INCLUDED
|
||||
|
||||
#if defined(BEAST_ANDROID)
|
||||
#define BEAST_PLATFORM_CONFIG "config/platform/Android.h"
|
||||
|
||||
// linux, also other platforms (Hurd etc) that use GLIBC
|
||||
#elif (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
|
||||
#define BEAST_PLATFORM_CONFIG "config/platform/Linux.h"
|
||||
|
||||
// BSD
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
#define BEAST_PLATFORM_CONFIG "config/platform/Bsd.h"
|
||||
|
||||
// win32
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(_WIN64)
|
||||
#define BEAST_PLATFORM_CONFIG "config/platform/Win32.h"
|
||||
|
||||
// MacOS
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__APPLE_CPP__)
|
||||
#define BEAST_PLATFORM_CONFIG "config/platform/MacOS.h"
|
||||
|
||||
#else
|
||||
#error "Unsupported platform."
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Ideas from boost
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONFIG_SUFFIX_H_INCLUDED
|
||||
#define BEAST_CONFIG_SUFFIX_H_INCLUDED
|
||||
|
||||
// Included at the end of Config.h
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Clang compiler configuration
|
||||
@@ -1,20 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// GNU C++ compiler configuration
|
||||
@@ -1,25 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Microsoft Visual C++ compiler configuration
|
||||
|
||||
#ifndef BEAST_CONFIG_COMPILER_VISUALC_H_INCLUDED
|
||||
#define BEAST_CONFIG_COMPILER_VISUALC_H_INCLUDED
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Android platform configuration
|
||||
|
||||
#ifndef BEAST_CONFIG_PLATFORM_ANDROID_H_INCLUDED
|
||||
#define BEAST_CONFIG_PLATFORM_ANDROID_H_INCLUDED
|
||||
|
||||
#ifdef BEAST_ANDROID
|
||||
#undef BEAST_ANDROID
|
||||
#endif
|
||||
#define BEAST_ANDROID 1
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// BSD, FreeBSD platform configuration
|
||||
@@ -1,21 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Linux-compatible platform configuration
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// MacOS and iOS platform configuration
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Win32 platform configuration
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/container/tests/aged_associative_container.test.cpp>
|
||||
@@ -1,520 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONTAINER_BUFFER_VIEW_H_INCLUDED
|
||||
#define BEAST_CONTAINER_BUFFER_VIEW_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <array>
|
||||
#include <beast/cxx14/algorithm.h> // <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T, class U,
|
||||
bool = std::is_const <std::remove_reference_t <T>>::value>
|
||||
struct apply_const
|
||||
{
|
||||
using type = U;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct apply_const <T, U, true>
|
||||
{
|
||||
using type = const U;
|
||||
};
|
||||
|
||||
// is_contiguous is true if C is a contiguous container
|
||||
template <class C>
|
||||
struct is_contiguous
|
||||
: public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class C>
|
||||
struct is_contiguous <C const>
|
||||
: public is_contiguous <C>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T, class Alloc>
|
||||
struct is_contiguous <std::vector <T, Alloc>>
|
||||
: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class CharT, class Traits, class Alloc>
|
||||
struct is_contiguous <std::basic_string<
|
||||
CharT, Traits, Alloc>>
|
||||
: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct is_contiguous <std::array<T, N>>
|
||||
: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// True if T is const or U is not const
|
||||
template <class T, class U>
|
||||
struct buffer_view_const_compatible : std::integral_constant <bool,
|
||||
std::is_const<T>::value || ! std::is_const<U>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// True if T and U are the same or differ only in const, or
|
||||
// if T and U are equally sized integral types.
|
||||
template <class T, class U>
|
||||
struct buffer_view_ptr_compatible : std::integral_constant <bool,
|
||||
(std::is_same <std::remove_const <T>, std::remove_const <U>>::value) ||
|
||||
(std::is_integral <T>::value && std::is_integral <U>::value &&
|
||||
sizeof (U) == sizeof (T))
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// Determine if buffer_view <T, ..> is constructible from U*
|
||||
template <class T, class U>
|
||||
struct buffer_view_convertible : std::integral_constant <bool,
|
||||
buffer_view_const_compatible <T, U>::value &&
|
||||
buffer_view_ptr_compatible <T, U>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// True if C is a container that can be used to construct a buffer_view<T>
|
||||
template <class T, class C>
|
||||
struct buffer_view_container_compatible : std::integral_constant <bool,
|
||||
is_contiguous <C>::value && buffer_view_convertible <T,
|
||||
typename apply_const <C, typename C::value_type>::type>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
struct buffer_view_default_tag
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A view into a range of contiguous container elements.
|
||||
|
||||
The size of the view is determined at the time of construction.
|
||||
This tries to emulate the interface of std::vector as closely as possible,
|
||||
with the constraint that the size of the container cannot be changed.
|
||||
|
||||
@tparam T The underlying element type. If T is const, member functions
|
||||
which can modify elements are removed from the interface.
|
||||
|
||||
@tparam Tag A type used to prevent two views with the same T from being
|
||||
comparable or assignable.
|
||||
*/
|
||||
template <
|
||||
class T,
|
||||
class Tag = buffer_view_default_tag
|
||||
>
|
||||
class buffer_view
|
||||
{
|
||||
private:
|
||||
T* m_base;
|
||||
std::size_t m_size;
|
||||
|
||||
static_assert (std::is_same <T, std::remove_reference_t <T>>::value,
|
||||
"T may not be a reference type");
|
||||
|
||||
static_assert (! std::is_same <T, void>::value,
|
||||
"T may not be void");
|
||||
|
||||
static_assert (std::is_same <std::add_const_t <T>,
|
||||
std::remove_reference_t <T> const>::value,
|
||||
"Expected std::add_const to produce T const");
|
||||
|
||||
template <class Iter>
|
||||
void
|
||||
assign (Iter first, Iter last) noexcept
|
||||
{
|
||||
using U = typename std::iterator_traits <Iter>::value_type;
|
||||
|
||||
static_assert (detail::buffer_view_const_compatible <T, U>::value,
|
||||
"Cannot convert from 'U const' to 'T', "
|
||||
"conversion loses const qualifiers");
|
||||
|
||||
static_assert (detail::buffer_view_ptr_compatible <T, U>::value,
|
||||
"Cannot convert from 'U*' to 'T*, "
|
||||
"types are incompatible");
|
||||
|
||||
if (first == last)
|
||||
{
|
||||
m_base = nullptr;
|
||||
m_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// fails on gcc
|
||||
m_base = reinterpret_cast <T*> (
|
||||
std::addressof (*first));
|
||||
#else
|
||||
m_base = reinterpret_cast <T*> (&*first);
|
||||
#endif
|
||||
m_size = std::distance (first, last);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = T&;
|
||||
using const_reference = T const&;
|
||||
using pointer = T*;
|
||||
using const_pointer = T const*;
|
||||
using iterator = T*;
|
||||
using const_iterator = T const*;
|
||||
using reverse_iterator = std::reverse_iterator <iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator <const_iterator>;
|
||||
|
||||
// default construct
|
||||
buffer_view () noexcept
|
||||
: m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
// copy construct
|
||||
template <class U,
|
||||
class = std::enable_if_t <
|
||||
detail::buffer_view_convertible <T, U>::value>
|
||||
>
|
||||
buffer_view (buffer_view <U, Tag> v) noexcept
|
||||
{
|
||||
assign (v.begin(), v.end());
|
||||
}
|
||||
|
||||
// construct from container
|
||||
template <class C,
|
||||
class = std::enable_if_t <
|
||||
detail::buffer_view_container_compatible <T, C>::value
|
||||
>
|
||||
>
|
||||
buffer_view (C& c) noexcept
|
||||
{
|
||||
assign (c.begin(), c.end());
|
||||
}
|
||||
|
||||
// construct from pointer range
|
||||
template <class U,
|
||||
class = std::enable_if_t <
|
||||
detail::buffer_view_convertible <T, U>::value>
|
||||
>
|
||||
buffer_view (U* first, U* last) noexcept
|
||||
{
|
||||
assign (first, last);
|
||||
}
|
||||
|
||||
// construct from base and size
|
||||
template <class U,
|
||||
class = std::enable_if_t <
|
||||
detail::buffer_view_convertible <T, U>::value>
|
||||
>
|
||||
buffer_view (U* u, std::size_t n) noexcept
|
||||
: m_base (u)
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
// assign from container
|
||||
template <class C,
|
||||
class = std::enable_if_t <
|
||||
detail::buffer_view_container_compatible <T, C>::value
|
||||
>
|
||||
>
|
||||
buffer_view&
|
||||
operator= (C& c) noexcept
|
||||
{
|
||||
assign (c.begin(), c.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//
|
||||
// Element access
|
||||
//
|
||||
|
||||
reference
|
||||
at (size_type pos)
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
at (size_type pos) const
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
operator[] (size_type pos) noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[] (size_type pos) const noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
back() noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
reference
|
||||
front() noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
pointer
|
||||
data() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_pointer
|
||||
data() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator (end());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rend() noexcept
|
||||
{
|
||||
return reverse_iterator (begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
size_type
|
||||
size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type
|
||||
capacity() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
//
|
||||
// Modifiers
|
||||
//
|
||||
|
||||
template <class U, class K>
|
||||
friend void swap (buffer_view <U, K>& lhs,
|
||||
buffer_view <U, K>& rhs) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator== (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return std::equal (
|
||||
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator!= (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator< (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return std::lexicographical_compare (
|
||||
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator>= (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator> (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
bool
|
||||
operator<= (buffer_view <T, Tag> lhs, buffer_view <T, Tag> rhs)
|
||||
{
|
||||
return ! (rhs < lhs);
|
||||
}
|
||||
|
||||
template <class T, class Tag>
|
||||
inline
|
||||
void
|
||||
swap (buffer_view <T, Tag>& lhs, buffer_view <T, Tag>& rhs) noexcept
|
||||
{
|
||||
std::swap (lhs.m_base, rhs.m_base);
|
||||
std::swap (lhs.m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
class T,
|
||||
class Tag = buffer_view_default_tag
|
||||
>
|
||||
using const_buffer_view = buffer_view <
|
||||
std::add_const_t <T>, Tag>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,513 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Based on work with these copyrights:
|
||||
Copyright Carl Philipp Reh 2009 - 2013.
|
||||
Copyright Philipp Middendorf 2009 - 2013.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Original code taken from
|
||||
https://github.com/freundlich/fcppt
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONTAINER_CYCLIC_ITERATOR_H_INCLUDED
|
||||
#define BEAST_CONTAINER_CYCLIC_ITERATOR_H_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//
|
||||
// cyclic_iterator_fwd.hpp
|
||||
//
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
class cyclic_iterator;
|
||||
|
||||
//
|
||||
// cyclic_iterator_category.hpp
|
||||
//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<
|
||||
typename SourceCategory
|
||||
>
|
||||
struct cyclic_iterator_category;
|
||||
|
||||
template<>
|
||||
struct cyclic_iterator_category<
|
||||
std::forward_iterator_tag
|
||||
>
|
||||
{
|
||||
using type = std::forward_iterator_tag;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cyclic_iterator_category<
|
||||
std::bidirectional_iterator_tag
|
||||
>
|
||||
{
|
||||
using type = std::bidirectional_iterator_tag;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cyclic_iterator_category<
|
||||
std::random_access_iterator_tag
|
||||
>
|
||||
{
|
||||
using type = std::bidirectional_iterator_tag;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// cyclic_iterator_base.hpp
|
||||
//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
struct cyclic_iterator_base
|
||||
{
|
||||
using type = boost::iterator_facade<
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>,
|
||||
typename std::iterator_traits<
|
||||
ContainerIterator
|
||||
>::value_type,
|
||||
typename detail::cyclic_iterator_category<
|
||||
typename std::iterator_traits<
|
||||
ContainerIterator
|
||||
>::iterator_category
|
||||
>::type,
|
||||
typename std::iterator_traits<
|
||||
ContainerIterator
|
||||
>::reference
|
||||
>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// cyclic_iterator_decl.hpp
|
||||
//
|
||||
|
||||
/**
|
||||
\brief An iterator adaptor that cycles through a range
|
||||
|
||||
\ingroup fcpptmain
|
||||
|
||||
\tparam ContainerIterator The underlying iterator which must be at least a
|
||||
forward iterator
|
||||
|
||||
A cyclic iterator can be useful in cases where you want <code>end()</code> to
|
||||
become <code>begin()</code> again. For example, imagine a cycling through a
|
||||
list of items which means if you skip over the last, you will return to the
|
||||
first one.
|
||||
|
||||
This class can only increment or decrement its underlying iterator, random
|
||||
access is not supported. The iterator category will be at most bidirectional.
|
||||
It inherits all capabilities from <code>boost::iterator_facade</code> which
|
||||
means that it will have the usual iterator operations with their semantics.
|
||||
|
||||
Here is a short example demonstrating its use.
|
||||
|
||||
\snippet cyclic_iterator.cpp cyclic_iterator
|
||||
*/
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
class cyclic_iterator
|
||||
:
|
||||
public detail::cyclic_iterator_base<
|
||||
ContainerIterator
|
||||
>::type
|
||||
{
|
||||
public:
|
||||
/**
|
||||
\brief The base type which is a <code>boost::iterator_facade</code>
|
||||
*/
|
||||
using base_type = typename detail::cyclic_iterator_base<
|
||||
ContainerIterator
|
||||
>::type;
|
||||
|
||||
/**
|
||||
\brief The underlying iterator type
|
||||
*/
|
||||
using container_iterator_type = ContainerIterator;
|
||||
|
||||
/**
|
||||
\brief The value type adapted from \a ContainerIterator
|
||||
*/
|
||||
using value_type = typename base_type::value_type;
|
||||
|
||||
/**
|
||||
\brief The reference type adapted from \a ContainerIterator
|
||||
*/
|
||||
using reference = typename base_type::reference;
|
||||
|
||||
/**
|
||||
\brief The pointer type adapted from \a ContainerIterator
|
||||
*/
|
||||
using pointer = typename base_type::pointer;
|
||||
|
||||
/**
|
||||
\brief The difference type adapted from \a ContainerIterator
|
||||
*/
|
||||
using difference_type = typename base_type::difference_type;
|
||||
|
||||
/**
|
||||
\brief The iterator category, either Forward or Bidirectional
|
||||
*/
|
||||
using iterator_category = typename base_type::iterator_category;
|
||||
|
||||
/**
|
||||
\brief Creates a singular iterator
|
||||
*/
|
||||
cyclic_iterator();
|
||||
|
||||
/**
|
||||
\brief Copy constructs from another cyclic iterator
|
||||
|
||||
Copy constructs from another cyclic iterator \a other. This only works
|
||||
if the underlying iterators are convertible.
|
||||
|
||||
\param other The iterator to copy construct from
|
||||
*/
|
||||
template<
|
||||
typename OtherIterator
|
||||
>
|
||||
explicit
|
||||
cyclic_iterator(
|
||||
cyclic_iterator<OtherIterator> const &other
|
||||
);
|
||||
|
||||
/**
|
||||
\brief Constructs a new cyclic iterator
|
||||
|
||||
Constructs a new cyclic iterator, starting at \a it, inside
|
||||
a range from \a begin to \a end.
|
||||
|
||||
\param pos The start of the iterator
|
||||
\param begin The beginning of the range
|
||||
\param end The end of the range
|
||||
|
||||
\warning The behaviour is undefined if \a pos isn't between \a begin
|
||||
and \a end. Also, the behaviour is undefined, if \a begin and \a end
|
||||
don't form a valid range.
|
||||
*/
|
||||
cyclic_iterator(
|
||||
container_iterator_type const &pos,
|
||||
container_iterator_type const &begin,
|
||||
container_iterator_type const &end
|
||||
);
|
||||
|
||||
/**
|
||||
\brief Assigns from another cyclic iterator
|
||||
|
||||
Assigns from another cyclic iterator \a other. This only works if the
|
||||
underlying iterators are convertible.
|
||||
|
||||
\param other The iterator to assign from
|
||||
|
||||
\return <code>*this</code>
|
||||
*/
|
||||
template<
|
||||
typename OtherIterator
|
||||
>
|
||||
cyclic_iterator<ContainerIterator> &
|
||||
operator=(
|
||||
cyclic_iterator<OtherIterator> const &other
|
||||
);
|
||||
|
||||
/**
|
||||
\brief Returns the beginning of the range
|
||||
*/
|
||||
container_iterator_type
|
||||
begin() const;
|
||||
|
||||
/**
|
||||
\brief Returns the end of the range
|
||||
*/
|
||||
container_iterator_type
|
||||
end() const;
|
||||
|
||||
/**
|
||||
\brief Returns the underlying iterator
|
||||
*/
|
||||
container_iterator_type
|
||||
get() const;
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
void
|
||||
increment();
|
||||
|
||||
void
|
||||
decrement();
|
||||
|
||||
bool
|
||||
equal(
|
||||
cyclic_iterator const &
|
||||
) const;
|
||||
|
||||
reference
|
||||
dereference() const;
|
||||
|
||||
difference_type
|
||||
distance_to(
|
||||
cyclic_iterator const &
|
||||
) const;
|
||||
private:
|
||||
container_iterator_type
|
||||
it_,
|
||||
begin_,
|
||||
end_;
|
||||
};
|
||||
|
||||
//
|
||||
// cyclic_iterator_impl.hpp
|
||||
//
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::cyclic_iterator()
|
||||
:
|
||||
it_(),
|
||||
begin_(),
|
||||
end_()
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
template<
|
||||
typename OtherIterator
|
||||
>
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::cyclic_iterator(
|
||||
cyclic_iterator<
|
||||
OtherIterator
|
||||
> const &_other
|
||||
)
|
||||
:
|
||||
it_(
|
||||
_other.it_
|
||||
),
|
||||
begin_(
|
||||
_other.begin_
|
||||
),
|
||||
end_(
|
||||
_other.end_
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::cyclic_iterator(
|
||||
container_iterator_type const &_it,
|
||||
container_iterator_type const &_begin,
|
||||
container_iterator_type const &_end
|
||||
)
|
||||
:
|
||||
it_(
|
||||
_it
|
||||
),
|
||||
begin_(
|
||||
_begin
|
||||
),
|
||||
end_(
|
||||
_end
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
template<
|
||||
typename OtherIterator
|
||||
>
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
> &
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::operator=(
|
||||
cyclic_iterator<
|
||||
OtherIterator
|
||||
> const &_other
|
||||
)
|
||||
{
|
||||
it_ = _other.it_;
|
||||
|
||||
begin_ = _other.begin_;
|
||||
|
||||
end_ = _other.end_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
typename cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::container_iterator_type
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::begin() const
|
||||
{
|
||||
return begin_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
typename cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::container_iterator_type
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::end() const
|
||||
{
|
||||
return end_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
typename cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::container_iterator_type
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::get() const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
void
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::increment()
|
||||
{
|
||||
if(
|
||||
begin_ != end_
|
||||
&& ++it_ == end_
|
||||
)
|
||||
it_ = begin_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
void
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::decrement()
|
||||
{
|
||||
if(
|
||||
begin_ == end_
|
||||
)
|
||||
return;
|
||||
|
||||
if(
|
||||
it_ == begin_
|
||||
)
|
||||
it_ =
|
||||
std::prev(
|
||||
end_
|
||||
);
|
||||
else
|
||||
--it_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
bool
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::equal(
|
||||
cyclic_iterator const &_other
|
||||
) const
|
||||
{
|
||||
return it_ == _other.it;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
typename cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::reference
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::dereference() const
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename ContainerIterator
|
||||
>
|
||||
typename cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::difference_type
|
||||
cyclic_iterator<
|
||||
ContainerIterator
|
||||
>::distance_to(
|
||||
cyclic_iterator const &_other
|
||||
) const
|
||||
{
|
||||
return _other.it_ - it_;
|
||||
}
|
||||
|
||||
// Convenience function for template argument deduction
|
||||
template <typename ContainerIterator>
|
||||
cyclic_iterator <ContainerIterator> make_cyclic (
|
||||
ContainerIterator const& pos,
|
||||
ContainerIterator const& begin,
|
||||
ContainerIterator const& end);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/crypto/tests/base64.test.cpp>
|
||||
@@ -1,51 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/crypto/base64.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class base64_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
check (std::string const& in, std::string const& out)
|
||||
{
|
||||
auto const encoded = base64_encode (in);
|
||||
expect (encoded == out);
|
||||
expect (base64_decode (encoded) == in);
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
check ("", "");
|
||||
check ("f", "Zg==");
|
||||
check ("fo", "Zm8=");
|
||||
check ("foo", "Zm9v");
|
||||
check ("foob", "Zm9vYg==");
|
||||
check ("fooba", "Zm9vYmE=");
|
||||
check ("foobar", "Zm9vYmFy");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(base64,crypto,beast);
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/http/impl/basic_parser.cpp>
|
||||
#include <beast/http/impl/joyent_parser.cpp>
|
||||
#include <beast/http/impl/method.cpp>
|
||||
#include <beast/http/impl/raw_parser.cpp>
|
||||
#include <beast/http/impl/URL.cpp>
|
||||
|
||||
#include <beast/http/tests/chunked_encoder.test.cpp>
|
||||
#include <beast/http/tests/parser.test.cpp>
|
||||
#include <beast/http/tests/rfc2616.test.cpp>
|
||||
#include <beast/http/tests/URL.test.cpp>
|
||||
#include <beast/http/tests/urls_large_data.cpp>
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_URL_H_INCLUDED
|
||||
#define BEAST_HTTP_URL_H_INCLUDED
|
||||
|
||||
#include <ios>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A URL.
|
||||
The accompanying robust parser is hardened against all forms of attack.
|
||||
*/
|
||||
class URL
|
||||
{
|
||||
public:
|
||||
/** Construct a URL from it's components. */
|
||||
URL (
|
||||
std::string schema_,
|
||||
std::string host_,
|
||||
std::uint16_t port_,
|
||||
std::string port_string_,
|
||||
std::string path_,
|
||||
std::string query_ = "",
|
||||
std::string fragment_ = "",
|
||||
std::string userinfo_ = "");
|
||||
|
||||
/** Construct an empty URL. */
|
||||
explicit URL () = default;
|
||||
|
||||
/** Copy construct a URL. */
|
||||
URL (URL const& other) = default;
|
||||
|
||||
/** Copy assign a URL. */
|
||||
URL& operator= (URL const& other) = default;
|
||||
|
||||
/** Move construct a URL. */
|
||||
URL (URL&& other) = default;
|
||||
|
||||
/** Returns `true` if this is an empty URL. */
|
||||
bool
|
||||
empty () const;
|
||||
|
||||
/** Returns the scheme of the URL.
|
||||
If no scheme was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
scheme () const;
|
||||
|
||||
/** Returns the host of the URL.
|
||||
If no host was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
host () const;
|
||||
|
||||
/** Returns the port number as an integer.
|
||||
If no port was specified, the value will be zero.
|
||||
*/
|
||||
std::uint16_t
|
||||
port () const;
|
||||
|
||||
/** Returns the port number as a string.
|
||||
If no port was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
port_string () const;
|
||||
|
||||
/** Returns the path of the URL.
|
||||
If no path was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
path () const;
|
||||
|
||||
/** Returns the query parameters portion of the URL.
|
||||
If no query parameters were present, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
query () const;
|
||||
|
||||
/** Returns the URL fragment, if any. */
|
||||
std::string const&
|
||||
fragment () const;
|
||||
|
||||
/** Returns the user information, if any. */
|
||||
std::string const&
|
||||
userinfo () const;
|
||||
|
||||
private:
|
||||
std::string m_scheme;
|
||||
std::string m_host;
|
||||
std::uint16_t m_port = 0;
|
||||
std::string m_port_string;
|
||||
std::string m_path;
|
||||
std::string m_query;
|
||||
std::string m_fragment;
|
||||
std::string m_userinfo;
|
||||
};
|
||||
|
||||
/** Attempt to parse a string into a URL */
|
||||
std::pair<bool, URL>
|
||||
parse_URL(std::string const&);
|
||||
|
||||
/** Retrieve the full URL as a single string. */
|
||||
std::string
|
||||
to_string(URL const& url);
|
||||
|
||||
/** Output stream conversion. */
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, URL const& url);
|
||||
|
||||
/** URL comparisons. */
|
||||
/** @{ */
|
||||
inline bool
|
||||
operator== (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) == to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) != to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator< (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) < to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool operator> (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (rhs) < to_string (lhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return ! (to_string (rhs) < to_string (lhs));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return ! (to_string (lhs) < to_string (rhs));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** boost::hash support */
|
||||
template <class Hasher>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, URL const& url)
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append (h, to_string (url));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash <beast::URL>
|
||||
{
|
||||
std::size_t operator() (beast::URL const& url) const
|
||||
{
|
||||
return std::hash<std::string>{} (to_string (url));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -1,259 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_BASIC_PARSER_H_INCLUDED
|
||||
#define BEAST_HTTP_BASIC_PARSER_H_INCLUDED
|
||||
|
||||
#include <beast/http/method.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace joyent {
|
||||
struct http_parser;
|
||||
};
|
||||
|
||||
namespace http {
|
||||
|
||||
class basic_parser
|
||||
{
|
||||
private:
|
||||
// These structures must exactly match the
|
||||
// declarations in joyent http_parser.h include
|
||||
//
|
||||
struct state_t
|
||||
{
|
||||
unsigned int type : 2;
|
||||
unsigned int flags : 6;
|
||||
unsigned int state : 8;
|
||||
unsigned int header_state : 8;
|
||||
unsigned int index : 8;
|
||||
std::uint32_t nread;
|
||||
std::uint64_t content_length;
|
||||
unsigned short http_major;
|
||||
unsigned short http_minor;
|
||||
unsigned int status_code : 16;
|
||||
unsigned int method : 8;
|
||||
unsigned int http_errno : 7;
|
||||
unsigned int upgrade : 1;
|
||||
void *data;
|
||||
};
|
||||
|
||||
using data_cb_t = int (*) (
|
||||
state_t*, const char *at, size_t length);
|
||||
using cb_t = int (*) (state_t*);
|
||||
|
||||
struct hooks_t
|
||||
{
|
||||
cb_t on_message_begin;
|
||||
data_cb_t on_url;
|
||||
data_cb_t on_status;
|
||||
data_cb_t on_header_field;
|
||||
data_cb_t on_header_value;
|
||||
cb_t on_headers_complete;
|
||||
data_cb_t on_body;
|
||||
cb_t on_message_complete;
|
||||
};
|
||||
|
||||
char state_ [sizeof(state_t)];
|
||||
char hooks_ [sizeof(hooks_t)];
|
||||
|
||||
bool complete_ = false;
|
||||
std::string url_;
|
||||
std::string status_;
|
||||
std::string field_;
|
||||
std::string value_;
|
||||
|
||||
public:
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
virtual
|
||||
~basic_parser() = default;
|
||||
|
||||
/** Construct the parser.
|
||||
If `request` is `true` this sets up the parser to
|
||||
process an HTTP request.
|
||||
*/
|
||||
explicit
|
||||
basic_parser (bool request) noexcept;
|
||||
|
||||
basic_parser&
|
||||
operator= (basic_parser&& other);
|
||||
|
||||
/** Returns `true` if parsing is complete.
|
||||
This is only defined when no errors have been returned.
|
||||
*/
|
||||
bool
|
||||
complete() const noexcept
|
||||
{
|
||||
return complete_;
|
||||
}
|
||||
|
||||
/** Write data to the parser.
|
||||
@param data A buffer containing the data to write
|
||||
@param bytes The size of the buffer pointed to by data.
|
||||
@return A pair with bool success, and the number of bytes consumed.
|
||||
*/
|
||||
std::pair <error_code, std::size_t>
|
||||
write (void const* data, std::size_t bytes);
|
||||
|
||||
/** Write a set of buffer data to the parser.
|
||||
The return value includes the error code if any,
|
||||
and the number of bytes consumed in the input sequence.
|
||||
@param buffers The buffers to write. These must meet the
|
||||
requirements of ConstBufferSequence.
|
||||
@return A pair with bool success, and the number of bytes consumed.
|
||||
*/
|
||||
template <class ConstBufferSequence>
|
||||
std::pair <error_code, std::size_t>
|
||||
write (ConstBufferSequence const& buffers);
|
||||
|
||||
/** Called to indicate the end of file.
|
||||
HTTP needs to know where the end of the stream is. For example,
|
||||
sometimes servers send responses without Content-Length and
|
||||
expect the client to consume input (for the body) until EOF.
|
||||
Callbacks and errors will still be processed as usual.
|
||||
@note This is typically called when a socket read returns eof.
|
||||
@return `true` if the message is complete.
|
||||
*/
|
||||
error_code
|
||||
write_eof();
|
||||
|
||||
protected:
|
||||
/** Called once when a new message begins. */
|
||||
virtual
|
||||
void
|
||||
on_start() = 0;
|
||||
|
||||
/** Called for each header field. */
|
||||
virtual
|
||||
void
|
||||
on_field (std::string const& field, std::string const& value) = 0;
|
||||
|
||||
/** Called for requests when all the headers have been received.
|
||||
This will precede any content body.
|
||||
When keep_alive is false:
|
||||
* Server roles respond with a "Connection: close" header.
|
||||
* Client roles close the connection.
|
||||
When upgrade is true, no content-body is expected, and the
|
||||
return value is ignored.
|
||||
|
||||
@param method The HTTP method specified in the request line
|
||||
@param major The HTTP major version number
|
||||
@param minor The HTTP minor version number
|
||||
@param url The URL specified in the request line
|
||||
@param keep_alive `false` if this is the last message.
|
||||
@param upgrade `true` if the Upgrade header is specified
|
||||
@return `true` If upgrade is false and a content body is expected.
|
||||
*/
|
||||
virtual
|
||||
bool
|
||||
on_request (method_t method, std::string const& url,
|
||||
int major, int minor, bool keep_alive, bool upgrade) = 0;
|
||||
|
||||
/** Called for responses when all the headers have been received.
|
||||
This will precede any content body.
|
||||
When keep_alive is `false`:
|
||||
* Client roles close the connection.
|
||||
* Server roles respond with a "Connection: close" header.
|
||||
When upgrade is true, no content-body is expected, and the
|
||||
return value is ignored.
|
||||
|
||||
@param status The numerical HTTP status code in the response line
|
||||
@param text The status text in the response line
|
||||
@param major The HTTP major version number
|
||||
@param minor The HTTP minor version number
|
||||
@param keep_alive `false` if this is the last message.
|
||||
@param upgrade `true` if the Upgrade header is specified
|
||||
@return `true` If upgrade is false and a content body is expected.
|
||||
*/
|
||||
virtual
|
||||
bool
|
||||
on_response (int status, std::string const& text,
|
||||
int major, int minor, bool keep_alive, bool upgrade) = 0;
|
||||
|
||||
/** Called zero or more times for the content body.
|
||||
Any transfer encoding is already decoded in the
|
||||
memory pointed to by data.
|
||||
|
||||
@param data A memory block containing the next decoded
|
||||
chunk of the content body.
|
||||
@param bytes The number of bytes pointed to by data.
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
on_body (void const* data, std::size_t bytes) = 0;
|
||||
|
||||
/** Called once when the message is complete. */
|
||||
virtual
|
||||
void
|
||||
on_complete() = 0;
|
||||
|
||||
private:
|
||||
void check_header();
|
||||
|
||||
int do_message_start ();
|
||||
int do_url (char const* in, std::size_t bytes);
|
||||
int do_status (char const* in, std::size_t bytes);
|
||||
int do_header_field (char const* in, std::size_t bytes);
|
||||
int do_header_value (char const* in, std::size_t bytes);
|
||||
int do_headers_complete ();
|
||||
int do_body (char const* in, std::size_t bytes);
|
||||
int do_message_complete ();
|
||||
|
||||
static int cb_message_start (joyent::http_parser*);
|
||||
static int cb_url (joyent::http_parser*, char const*, std::size_t);
|
||||
static int cb_status (joyent::http_parser*, char const*, std::size_t);
|
||||
static int cb_header_field (joyent::http_parser*, char const*, std::size_t);
|
||||
static int cb_header_value (joyent::http_parser*, char const*, std::size_t);
|
||||
static int cb_headers_complete (joyent::http_parser*);
|
||||
static int cb_body (joyent::http_parser*, char const*, std::size_t);
|
||||
static int cb_message_complete (joyent::http_parser*);
|
||||
};
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
auto
|
||||
basic_parser::write (ConstBufferSequence const& buffers) ->
|
||||
std::pair <error_code, std::size_t>
|
||||
{
|
||||
std::pair <error_code, std::size_t> result ({}, 0);
|
||||
for (auto const& buffer : buffers)
|
||||
{
|
||||
std::size_t bytes_consumed;
|
||||
std::tie (result.first, bytes_consumed) =
|
||||
write (boost::asio::buffer_cast <void const*> (buffer),
|
||||
boost::asio::buffer_size (buffer));
|
||||
if (result.first)
|
||||
break;
|
||||
result.second += bytes_consumed;
|
||||
if (complete())
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,150 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_BODY_H_INCLUDED
|
||||
#define BEAST_HTTP_BODY_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Container for the HTTP content-body. */
|
||||
class body
|
||||
{
|
||||
private:
|
||||
using buffer_type = boost::asio::streambuf;
|
||||
|
||||
// Hack: use unique_ptr because streambuf cant be moved
|
||||
std::unique_ptr <buffer_type> buf_;
|
||||
|
||||
public:
|
||||
using const_buffers_type = buffer_type::const_buffers_type;
|
||||
|
||||
body();
|
||||
body (body&& other);
|
||||
body& operator= (body&& other);
|
||||
|
||||
body (body const&) = delete;
|
||||
body& operator= (body const&) = delete;
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
write (void const* data, std::size_t bytes);
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
write (ConstBufferSequence const& buffers);
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
const_buffers_type
|
||||
data() const;
|
||||
};
|
||||
|
||||
template <class = void>
|
||||
std::string
|
||||
to_string (body const& b)
|
||||
{
|
||||
std::string s;
|
||||
auto const& data (b.data());
|
||||
auto const n (boost::asio::buffer_size (data));
|
||||
s.resize (n);
|
||||
boost::asio::buffer_copy (
|
||||
boost::asio::buffer (&s[0], n), data);
|
||||
return s;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
body::body()
|
||||
: buf_ (std::make_unique <buffer_type>())
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
body::body (body&& other)
|
||||
: buf_ (std::move(other.buf_))
|
||||
{
|
||||
other.clear();
|
||||
}
|
||||
|
||||
inline
|
||||
body&
|
||||
body::operator= (body&& other)
|
||||
{
|
||||
buf_ = std::move(other.buf_);
|
||||
other.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
body::clear()
|
||||
{
|
||||
buf_ = std::make_unique <buffer_type>();
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
body::write (void const* data, std::size_t bytes)
|
||||
{
|
||||
buf_->commit (boost::asio::buffer_copy (buf_->prepare (bytes),
|
||||
boost::asio::const_buffers_1 (data, bytes)));
|
||||
}
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
body::write (ConstBufferSequence const& buffers)
|
||||
{
|
||||
for (auto const& buffer : buffers)
|
||||
write (boost::asio::buffer_cast <void const*> (buffer),
|
||||
boost::asio::buffer_size (buffer));
|
||||
}
|
||||
|
||||
inline
|
||||
std::size_t
|
||||
body::size() const
|
||||
{
|
||||
return buf_->size();
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
body::data() const
|
||||
-> const_buffers_type
|
||||
{
|
||||
return buf_->data();
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,285 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_CHUNK_ENCODE_H_INCLUDED
|
||||
#define BEAST_HTTP_CHUNK_ENCODE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Buffers>
|
||||
class chunk_encoded_buffers
|
||||
{
|
||||
private:
|
||||
using const_buffer = boost::asio::const_buffer;
|
||||
|
||||
Buffers buffers_;
|
||||
const_buffer head_;
|
||||
const_buffer tail_;
|
||||
|
||||
// Storage for the longest hex string we might need, plus delimiters.
|
||||
std::array<char, 2 * sizeof(std::size_t) + 2> data_;
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::const_buffer;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
chunk_encoded_buffers() = delete;
|
||||
chunk_encoded_buffers (chunk_encoded_buffers const&) = default;
|
||||
chunk_encoded_buffers& operator= (chunk_encoded_buffers const&) = default;
|
||||
|
||||
chunk_encoded_buffers (Buffers const& buffers, bool final_chunk);
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator(*this, false);
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return const_iterator(*this, true);
|
||||
}
|
||||
|
||||
private:
|
||||
// Unchecked conversion of unsigned to hex string
|
||||
template<class OutIter, class Unsigned>
|
||||
static
|
||||
std::enable_if_t<std::is_unsigned<Unsigned>::value, OutIter>
|
||||
to_hex(OutIter const first, OutIter const last, Unsigned n);
|
||||
};
|
||||
|
||||
template <class Buffers>
|
||||
class chunk_encoded_buffers<Buffers>::const_iterator
|
||||
: public std::iterator<std::bidirectional_iterator_tag, const_buffer>
|
||||
{
|
||||
private:
|
||||
using iterator = typename Buffers::const_iterator;
|
||||
enum class Where { head, input, end };
|
||||
chunk_encoded_buffers const* buffers_;
|
||||
Where where_;
|
||||
iterator iter_;
|
||||
|
||||
public:
|
||||
const_iterator();
|
||||
const_iterator (const_iterator const&) = default;
|
||||
const_iterator& operator= (const_iterator const&) = default;
|
||||
bool operator== (const_iterator const& other) const;
|
||||
bool operator!= (const_iterator const& other) const;
|
||||
const_iterator& operator++();
|
||||
const_iterator& operator--();
|
||||
const_iterator operator++(int) const;
|
||||
const_iterator operator--(int) const;
|
||||
const_buffer operator*() const;
|
||||
|
||||
private:
|
||||
friend class chunk_encoded_buffers;
|
||||
const_iterator(chunk_encoded_buffers const& buffers, bool past_the_end);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::chunk_encoded_buffers (
|
||||
Buffers const& buffers, bool final_chunk)
|
||||
: buffers_(buffers)
|
||||
{
|
||||
auto const size = boost::asio::buffer_size(buffers);
|
||||
data_[data_.size() - 2] = '\r';
|
||||
data_[data_.size() - 1] = '\n';
|
||||
auto pos = to_hex(data_.begin(), data_.end() - 2, size);
|
||||
head_ = const_buffer(&*pos,
|
||||
std::distance(pos, data_.end()));
|
||||
if (size > 0 && final_chunk)
|
||||
tail_ = const_buffer("\r\n0\r\n\r\n", 7);
|
||||
else
|
||||
tail_ = const_buffer("\r\n", 2);
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
template <class OutIter, class Unsigned>
|
||||
std::enable_if_t<std::is_unsigned<Unsigned>::value, OutIter>
|
||||
chunk_encoded_buffers<Buffers>::to_hex(
|
||||
OutIter const first, OutIter const last, Unsigned n)
|
||||
{
|
||||
assert(first != last);
|
||||
OutIter iter = last;
|
||||
if(n == 0)
|
||||
{
|
||||
*--iter = '0';
|
||||
return iter;
|
||||
}
|
||||
while(n)
|
||||
{
|
||||
assert(iter != first);
|
||||
*--iter = "0123456789abcdef"[n&0xf];
|
||||
n>>=4;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator()
|
||||
: where_(Where::end)
|
||||
, buffers_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
bool
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator==(
|
||||
const_iterator const& other) const
|
||||
{
|
||||
return buffers_ == other.buffers_ &&
|
||||
where_ == other.where_ && iter_ == other.iter_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
bool
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator!=(
|
||||
const_iterator const& other) const
|
||||
{
|
||||
return buffers_ != other.buffers_ ||
|
||||
where_ != other.where_ || iter_ != other.iter_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator++() ->
|
||||
const_iterator&
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::end);
|
||||
if (where_ == Where::head)
|
||||
where_ = Where::input;
|
||||
else if (iter_ != buffers_->buffers_.end())
|
||||
++iter_;
|
||||
else
|
||||
where_ = Where::end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator--() ->
|
||||
const_iterator&
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::begin);
|
||||
if (where_ == Where::end)
|
||||
where_ = Where::input;
|
||||
else if (iter_ != buffers_->buffers_.begin())
|
||||
--iter_;
|
||||
else
|
||||
where_ = Where::head;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator++(int) const ->
|
||||
const_iterator
|
||||
{
|
||||
auto iter = *this;
|
||||
++iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator--(int) const ->
|
||||
const_iterator
|
||||
{
|
||||
auto iter = *this;
|
||||
--iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
auto
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::operator*() const ->
|
||||
const_buffer
|
||||
{
|
||||
assert(buffers_);
|
||||
assert(where_ != Where::end);
|
||||
if (where_ == Where::head)
|
||||
return buffers_->head_;
|
||||
if (iter_ != buffers_->buffers_.end())
|
||||
return *iter_;
|
||||
return buffers_->tail_;
|
||||
}
|
||||
|
||||
template <class Buffers>
|
||||
chunk_encoded_buffers<Buffers>::const_iterator::const_iterator(
|
||||
chunk_encoded_buffers const& buffers, bool past_the_end)
|
||||
: buffers_(&buffers)
|
||||
, where_(past_the_end ? Where::end : Where::head)
|
||||
, iter_(past_the_end ? buffers_->buffers_.end() :
|
||||
buffers_->buffers_.begin())
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Returns a chunk-encoded BufferSequence.
|
||||
|
||||
See:
|
||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
|
||||
|
||||
@tparam Buffers A type meeting the requirements of BufferSequence.
|
||||
@param buffers The input buffer sequence.
|
||||
@param final_chunk `true` If this should include a final-chunk.
|
||||
@return A chunk-encoded ConstBufferSeqeunce representing the input.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Buffers>
|
||||
detail::chunk_encoded_buffers<Buffers>
|
||||
chunk_encode (Buffers const& buffers,
|
||||
bool final_chunk = false)
|
||||
{
|
||||
return detail::chunk_encoded_buffers<
|
||||
Buffers>(buffers, final_chunk);
|
||||
}
|
||||
|
||||
// Returns a chunked encoding final chunk.
|
||||
inline
|
||||
boost::asio::const_buffers_1
|
||||
chunk_encode_final()
|
||||
{
|
||||
return boost::asio::const_buffers_1(
|
||||
"0\r\n\r\n", 5);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,63 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_DETAIL_HEADER_TRAITS_H_INCLUDED
|
||||
#define BEAST_HTTP_DETAIL_HEADER_TRAITS_H_INCLUDED
|
||||
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace detail {
|
||||
|
||||
// Utilities for dealing with HTTP headers
|
||||
|
||||
template <class Allocator = std::allocator <char>>
|
||||
using basic_field_string =
|
||||
std::basic_string <char, ci_char_traits, Allocator>;
|
||||
|
||||
using field_string = basic_field_string <>;
|
||||
|
||||
using field_string_ref = boost::basic_string_ref <char, ci_char_traits>;
|
||||
|
||||
/** Returns `true` if two header fields are the same.
|
||||
The comparison is case-insensitive.
|
||||
*/
|
||||
template <class Alloc1, class Alloc2>
|
||||
inline
|
||||
bool field_eq (
|
||||
std::basic_string <char, std::char_traits <char>, Alloc1> const& s1,
|
||||
std::basic_string <char, std::char_traits <char>, Alloc2> const& s2)
|
||||
{
|
||||
return field_string_ref (s1.c_str(), s1.size()) ==
|
||||
field_string_ref (s2.c_str(), s2.size());
|
||||
}
|
||||
|
||||
/** Returns the string with leading and trailing LWS removed. */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,399 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_HEADERS_H_INCLUDED
|
||||
#define BEAST_HTTP_HEADERS_H_INCLUDED
|
||||
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Holds a collection of HTTP headers. */
|
||||
class headers
|
||||
{
|
||||
public:
|
||||
using value_type = std::pair<std::string, std::string>;
|
||||
|
||||
private:
|
||||
struct element
|
||||
: boost::intrusive::set_base_hook <
|
||||
boost::intrusive::link_mode <
|
||||
boost::intrusive::normal_link>>
|
||||
, boost::intrusive::list_base_hook <
|
||||
boost::intrusive::link_mode <
|
||||
boost::intrusive::normal_link>>
|
||||
{
|
||||
template <class = void>
|
||||
element (std::string const& f, std::string const& v);
|
||||
|
||||
value_type data;
|
||||
};
|
||||
|
||||
struct less : private beast::ci_less
|
||||
{
|
||||
template <class String>
|
||||
bool
|
||||
operator() (String const& lhs, element const& rhs) const;
|
||||
|
||||
template <class String>
|
||||
bool
|
||||
operator() (element const& lhs, String const& rhs) const;
|
||||
};
|
||||
|
||||
struct transform
|
||||
: public std::unary_function <element, value_type>
|
||||
{
|
||||
value_type const&
|
||||
operator() (element const& e) const
|
||||
{
|
||||
return e.data;
|
||||
}
|
||||
};
|
||||
|
||||
using list_t = boost::intrusive::make_list <element,
|
||||
boost::intrusive::constant_time_size <false>
|
||||
>::type;
|
||||
|
||||
using set_t = boost::intrusive::make_set <element,
|
||||
boost::intrusive::constant_time_size <true>
|
||||
>::type;
|
||||
|
||||
list_t list_;
|
||||
set_t set_;
|
||||
|
||||
public:
|
||||
using iterator = boost::transform_iterator <transform,
|
||||
list_t::const_iterator>;
|
||||
using const_iterator = iterator;
|
||||
|
||||
~headers()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
headers() = default;
|
||||
|
||||
headers (headers&& other);
|
||||
headers& operator= (headers&& other);
|
||||
|
||||
headers (headers const& other);
|
||||
headers& operator= (headers const& other);
|
||||
|
||||
/** Returns an iterator to headers in order of appearance. */
|
||||
/** @{ */
|
||||
iterator
|
||||
begin() const;
|
||||
|
||||
iterator
|
||||
end() const;
|
||||
|
||||
iterator
|
||||
cbegin() const;
|
||||
|
||||
iterator
|
||||
cend() const;
|
||||
/** @} */
|
||||
|
||||
/** Returns an iterator to the case-insensitive matching header. */
|
||||
template <class = void>
|
||||
iterator
|
||||
find (std::string const& field) const;
|
||||
|
||||
/** Returns the value for a case-insensitive matching header, or "" */
|
||||
template <class = void>
|
||||
std::string const&
|
||||
operator[] (std::string const& field) const;
|
||||
|
||||
/** Clear the contents of the headers. */
|
||||
template <class = void>
|
||||
void
|
||||
clear() noexcept;
|
||||
|
||||
/** Remove a field.
|
||||
@return The number of fields removed.
|
||||
*/
|
||||
template <class = void>
|
||||
std::size_t
|
||||
erase (std::string const& field);
|
||||
|
||||
/** Append a field value.
|
||||
If a field value already exists the new value will be
|
||||
extended as per RFC2616 Section 4.2.
|
||||
*/
|
||||
// VFALCO TODO Consider allowing rvalue references for std::move
|
||||
template <class = void>
|
||||
void
|
||||
append (std::string const& field, std::string const& value);
|
||||
};
|
||||
|
||||
template <class = void>
|
||||
std::string
|
||||
to_string (headers const& h);
|
||||
|
||||
// HACK!
|
||||
template <class = void>
|
||||
std::map <std::string, std::string>
|
||||
build_map (headers const& h);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class>
|
||||
headers::element::element (
|
||||
std::string const& f, std::string const& v)
|
||||
{
|
||||
data.first = f;
|
||||
data.second = v;
|
||||
}
|
||||
|
||||
template <class String>
|
||||
bool
|
||||
headers::less::operator() (
|
||||
String const& lhs, element const& rhs) const
|
||||
{
|
||||
return beast::ci_less::operator() (lhs, rhs.data.first);
|
||||
}
|
||||
|
||||
template <class String>
|
||||
bool
|
||||
headers::less::operator() (
|
||||
element const& lhs, String const& rhs) const
|
||||
{
|
||||
return beast::ci_less::operator() (lhs.data.first, rhs);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
headers::headers (headers&& other)
|
||||
: list_ (std::move (other.list_))
|
||||
, set_ (std::move (other.set_))
|
||||
{
|
||||
other.list_.clear();
|
||||
other.set_.clear();
|
||||
}
|
||||
|
||||
inline
|
||||
headers&
|
||||
headers::operator= (headers&& other)
|
||||
{
|
||||
list_ = std::move(other.list_);
|
||||
set_ = std::move(other.set_);
|
||||
other.list_.clear();
|
||||
other.set_.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
headers::headers (headers const& other)
|
||||
{
|
||||
for (auto const& e : other.list_)
|
||||
append (e.data.first, e.data.second);
|
||||
}
|
||||
|
||||
inline
|
||||
headers&
|
||||
headers::operator= (headers const& other)
|
||||
{
|
||||
clear();
|
||||
for (auto const& e : other.list_)
|
||||
append (e.data.first, e.data.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
headers::iterator
|
||||
headers::begin() const
|
||||
{
|
||||
return {list_.cbegin(), transform{}};
|
||||
}
|
||||
|
||||
inline
|
||||
headers::iterator
|
||||
headers::end() const
|
||||
{
|
||||
return {list_.cend(), transform{}};
|
||||
}
|
||||
|
||||
inline
|
||||
headers::iterator
|
||||
headers::cbegin() const
|
||||
{
|
||||
return {list_.cbegin(), transform{}};
|
||||
}
|
||||
|
||||
inline
|
||||
headers::iterator
|
||||
headers::cend() const
|
||||
{
|
||||
return {list_.cend(), transform{}};
|
||||
}
|
||||
|
||||
template <class>
|
||||
headers::iterator
|
||||
headers::find (std::string const& field) const
|
||||
{
|
||||
auto const iter (set_.find (field, less{}));
|
||||
if (iter == set_.end())
|
||||
return {list_.end(), transform{}};
|
||||
return {list_.iterator_to (*iter), transform{}};
|
||||
}
|
||||
|
||||
template <class>
|
||||
std::string const&
|
||||
headers::operator[] (std::string const& field) const
|
||||
{
|
||||
static std::string none;
|
||||
auto const found (find (field));
|
||||
if (found == end())
|
||||
return none;
|
||||
return found->second;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
headers::clear() noexcept
|
||||
{
|
||||
for (auto iter (list_.begin()); iter != list_.end();)
|
||||
delete &(*iter++);
|
||||
}
|
||||
|
||||
template <class>
|
||||
std::size_t
|
||||
headers::erase (std::string const& field)
|
||||
{
|
||||
auto const iter = set_.find(field, less{});
|
||||
if (iter == set_.end())
|
||||
return 0;
|
||||
element& e = *iter;
|
||||
set_.erase(set_.iterator_to(e));
|
||||
list_.erase(list_.iterator_to(e));
|
||||
delete &e;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
headers::append (std::string const& field,
|
||||
std::string const& value)
|
||||
{
|
||||
set_t::insert_commit_data d;
|
||||
auto const result (set_.insert_check (field, less{}, d));
|
||||
if (result.second)
|
||||
{
|
||||
element* const p = new element (field, value);
|
||||
list_.push_back (*p);
|
||||
set_.insert_commit (*p, d);
|
||||
return;
|
||||
}
|
||||
// If field already exists, append comma
|
||||
// separated value as per RFC2616 section 4.2
|
||||
auto& cur (result.first->data.second);
|
||||
cur.reserve (cur.size() + 1 + value.size());
|
||||
cur.append (1, ',');
|
||||
cur.append (value);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Streambuf>
|
||||
void
|
||||
write (Streambuf& stream, std::string const& s)
|
||||
{
|
||||
stream.commit (boost::asio::buffer_copy (
|
||||
stream.prepare (s.size()), boost::asio::buffer(s)));
|
||||
}
|
||||
|
||||
template <class Streambuf>
|
||||
void
|
||||
write (Streambuf& stream, char const* s)
|
||||
{
|
||||
auto const len (::strlen(s));
|
||||
stream.commit (boost::asio::buffer_copy (
|
||||
stream.prepare (len), boost::asio::buffer (s, len)));
|
||||
}
|
||||
|
||||
template <class Streambuf>
|
||||
void
|
||||
write (Streambuf& stream, headers const& h)
|
||||
{
|
||||
for (auto const& _ : h)
|
||||
{
|
||||
write (stream, _.first);
|
||||
write (stream, ": ");
|
||||
write (stream, _.second);
|
||||
write (stream, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <class>
|
||||
std::string
|
||||
to_string (headers const& h)
|
||||
{
|
||||
std::string s;
|
||||
std::size_t n (0);
|
||||
for (auto const& e : h)
|
||||
n += e.first.size() + 2 + e.second.size() + 2;
|
||||
s.reserve (n);
|
||||
for (auto const& e : h)
|
||||
{
|
||||
s.append (e.first);
|
||||
s.append (": ");
|
||||
s.append (e.second);
|
||||
s.append ("\r\n");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream&
|
||||
operator<< (std::ostream& s, headers const& h)
|
||||
{
|
||||
s << to_string(h);
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class>
|
||||
std::map <std::string, std::string>
|
||||
build_map (headers const& h)
|
||||
{
|
||||
std::map <std::string, std::string> c;
|
||||
for (auto const& e : h)
|
||||
{
|
||||
auto key (e.first);
|
||||
// TODO Replace with safe C++14 version
|
||||
std::transform (key.begin(), key.end(), key.begin(), ::tolower);
|
||||
c [key] = e.second;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
git-subtree: "http-parser"
|
||||
remote: https://github.com/joyent/http-parser.git
|
||||
branch: master
|
||||
@@ -1,230 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/http/URL.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
URL::URL (
|
||||
std::string scheme_,
|
||||
std::string host_,
|
||||
std::uint16_t port_,
|
||||
std::string port_string_,
|
||||
std::string path_,
|
||||
std::string query_,
|
||||
std::string fragment_,
|
||||
std::string userinfo_)
|
||||
: m_scheme (scheme_)
|
||||
, m_host (host_)
|
||||
, m_port (port_)
|
||||
, m_port_string (port_string_)
|
||||
, m_path (path_)
|
||||
, m_query (query_)
|
||||
, m_fragment (fragment_)
|
||||
, m_userinfo (userinfo_)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
URL::empty () const
|
||||
{
|
||||
return m_scheme.empty ();
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::scheme () const
|
||||
{
|
||||
return m_scheme;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::host () const
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::port_string () const
|
||||
{
|
||||
return m_port_string;
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
URL::port () const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::path () const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::query () const
|
||||
{
|
||||
return m_query;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::fragment () const
|
||||
{
|
||||
return m_fragment;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::userinfo () const
|
||||
{
|
||||
return m_userinfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::pair<bool, URL>
|
||||
parse_URL(std::string const& url)
|
||||
{
|
||||
std::size_t const buflen (url.size ());
|
||||
char const* const buf (url.c_str ());
|
||||
|
||||
joyent::http_parser_url parser;
|
||||
|
||||
if (joyent::http_parser_parse_url (buf, buflen, false, &parser) != 0)
|
||||
return std::make_pair (false, URL{});
|
||||
|
||||
std::string scheme;
|
||||
std::string host;
|
||||
std::uint16_t port (0);
|
||||
std::string port_string;
|
||||
std::string path;
|
||||
std::string query;
|
||||
std::string fragment;
|
||||
std::string userinfo;
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_SCHEMA)) != 0)
|
||||
{
|
||||
scheme = std::string (
|
||||
buf + parser.field_data [joyent::UF_SCHEMA].off,
|
||||
parser.field_data [joyent::UF_SCHEMA].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_HOST)) != 0)
|
||||
{
|
||||
host = std::string (
|
||||
buf + parser.field_data [joyent::UF_HOST].off,
|
||||
parser.field_data [joyent::UF_HOST].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_PORT)) != 0)
|
||||
{
|
||||
port = parser.port;
|
||||
port_string = std::string (
|
||||
buf + parser.field_data [joyent::UF_PORT].off,
|
||||
parser.field_data [joyent::UF_PORT].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_PATH)) != 0)
|
||||
{
|
||||
path = std::string (
|
||||
buf + parser.field_data [joyent::UF_PATH].off,
|
||||
parser.field_data [joyent::UF_PATH].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_QUERY)) != 0)
|
||||
{
|
||||
query = std::string (
|
||||
buf + parser.field_data [joyent::UF_QUERY].off,
|
||||
parser.field_data [joyent::UF_QUERY].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_FRAGMENT)) != 0)
|
||||
{
|
||||
fragment = std::string (
|
||||
buf + parser.field_data [joyent::UF_FRAGMENT].off,
|
||||
parser.field_data [joyent::UF_FRAGMENT].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<joyent::UF_USERINFO)) != 0)
|
||||
{
|
||||
userinfo = std::string (
|
||||
buf + parser.field_data [joyent::UF_USERINFO].off,
|
||||
parser.field_data [joyent::UF_USERINFO].len);
|
||||
}
|
||||
|
||||
return std::make_pair (true,
|
||||
URL {scheme, host, port, port_string, path, query, fragment, userinfo});
|
||||
}
|
||||
|
||||
std::string
|
||||
to_string (URL const& url)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (!url.empty ())
|
||||
{
|
||||
// Pre-allocate enough for components and inter-component separators
|
||||
s.reserve (
|
||||
url.scheme ().length () + url.userinfo ().length () +
|
||||
url.host ().length () + url.port_string ().length () +
|
||||
url.query ().length () + url.fragment ().length () + 16);
|
||||
|
||||
s.append (url.scheme ());
|
||||
s.append ("://");
|
||||
|
||||
if (!url.userinfo ().empty ())
|
||||
{
|
||||
s.append (url.userinfo ());
|
||||
s.append ("@");
|
||||
}
|
||||
|
||||
s.append (url.host ());
|
||||
|
||||
if (url.port ())
|
||||
{
|
||||
s.append (":");
|
||||
s.append (url.port_string ());
|
||||
}
|
||||
|
||||
s.append (url.path ());
|
||||
|
||||
if (!url.query ().empty ())
|
||||
{
|
||||
s.append ("?");
|
||||
s.append (url.query ());
|
||||
}
|
||||
|
||||
if (!url.fragment ().empty ())
|
||||
{
|
||||
s.append ("#");
|
||||
s.append (url.fragment ());
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream &os, URL const& url)
|
||||
{
|
||||
os << to_string (url);
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/http/basic_parser.h>
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
#include <beast/http/rfc2616.h>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
boost::system::error_category const&
|
||||
message_category() noexcept
|
||||
{
|
||||
class message_category_t : public boost::system::error_category
|
||||
{
|
||||
public:
|
||||
const char*
|
||||
name() const noexcept override
|
||||
{
|
||||
return "http::message";
|
||||
}
|
||||
|
||||
std::string
|
||||
message (int ev) const override
|
||||
{
|
||||
return joyent::http_errno_description (
|
||||
static_cast<joyent::http_errno>(ev));
|
||||
}
|
||||
|
||||
boost::system::error_condition
|
||||
default_error_condition (int ev) const noexcept override
|
||||
{
|
||||
return boost::system::error_condition (ev, *this);
|
||||
}
|
||||
|
||||
bool
|
||||
equivalent (int ev, boost::system::error_condition const& condition
|
||||
) const noexcept override
|
||||
{
|
||||
return condition.value() == ev &&
|
||||
&condition.category() == this;
|
||||
}
|
||||
|
||||
bool
|
||||
equivalent (boost::system::error_code const& error,
|
||||
int ev) const noexcept override
|
||||
{
|
||||
return error.value() == ev &&
|
||||
&error.category() == this;
|
||||
}
|
||||
};
|
||||
|
||||
static message_category_t cat;
|
||||
return cat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
basic_parser::basic_parser (bool request) noexcept
|
||||
{
|
||||
static_assert (sizeof(joyent::http_parser) == sizeof(state_t),
|
||||
"state_t size must match http_parser size");
|
||||
|
||||
static_assert (sizeof(joyent::http_parser_settings) == sizeof(hooks_t),
|
||||
"hooks_t size must match http_parser_settings size");
|
||||
|
||||
auto s (reinterpret_cast <joyent::http_parser*> (&state_));
|
||||
s->data = this;
|
||||
|
||||
auto h (reinterpret_cast <joyent::http_parser_settings*> (&hooks_));
|
||||
h->on_message_begin = &basic_parser::cb_message_start;
|
||||
h->on_url = &basic_parser::cb_url;
|
||||
h->on_status = &basic_parser::cb_status;
|
||||
h->on_header_field = &basic_parser::cb_header_field;
|
||||
h->on_header_value = &basic_parser::cb_header_value;
|
||||
h->on_headers_complete = &basic_parser::cb_headers_complete;
|
||||
h->on_body = &basic_parser::cb_body;
|
||||
h->on_message_complete = &basic_parser::cb_message_complete;
|
||||
|
||||
joyent::http_parser_init (s, request
|
||||
? joyent::http_parser_type::HTTP_REQUEST
|
||||
: joyent::http_parser_type::HTTP_RESPONSE);
|
||||
}
|
||||
|
||||
basic_parser&
|
||||
basic_parser::operator= (basic_parser&& other)
|
||||
{
|
||||
*reinterpret_cast<joyent::http_parser*>(&state_) =
|
||||
*reinterpret_cast<joyent::http_parser*>(&other.state_);
|
||||
reinterpret_cast<joyent::http_parser*>(&state_)->data = this;
|
||||
complete_ = other.complete_;
|
||||
url_ = std::move (other.url_);
|
||||
status_ = std::move (other.status_);
|
||||
field_ = std::move (other.field_);
|
||||
value_ = std::move (other.value_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto
|
||||
basic_parser::write (void const* data, std::size_t bytes) ->
|
||||
std::pair <error_code, std::size_t>
|
||||
{
|
||||
std::pair <error_code, std::size_t> result ({}, 0);
|
||||
auto s (reinterpret_cast <joyent::http_parser*> (&state_));
|
||||
auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_));
|
||||
result.second = joyent::http_parser_execute (s, h,
|
||||
static_cast <const char*> (data), bytes);
|
||||
result.first = error_code{static_cast<int>(s->http_errno),
|
||||
message_category()};
|
||||
return result;
|
||||
}
|
||||
|
||||
auto
|
||||
basic_parser::write_eof() ->
|
||||
error_code
|
||||
{
|
||||
auto s (reinterpret_cast <joyent::http_parser*> (&state_));
|
||||
auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_));
|
||||
joyent::http_parser_execute (s, h, nullptr, 0);
|
||||
return error_code{static_cast<int>(s->http_errno),
|
||||
message_category()};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
basic_parser::check_header()
|
||||
{
|
||||
if (! value_.empty())
|
||||
{
|
||||
rfc2616::trim_right_in_place (value_);
|
||||
on_field (field_, value_);
|
||||
field_.clear();
|
||||
value_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::do_message_start ()
|
||||
{
|
||||
complete_ = false;
|
||||
url_.clear();
|
||||
status_.clear();
|
||||
field_.clear();
|
||||
value_.clear();
|
||||
on_start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::do_url (char const* in, std::size_t bytes)
|
||||
{
|
||||
url_.append (static_cast <char const*> (in), bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::do_status (char const* in, std::size_t bytes)
|
||||
{
|
||||
status_.append (static_cast <char const*> (in), bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::do_header_field (char const* in, std::size_t bytes)
|
||||
{
|
||||
check_header();
|
||||
field_.append (static_cast <char const*> (in), bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::do_header_value (char const* in, std::size_t bytes)
|
||||
{
|
||||
value_.append (static_cast <char const*> (in), bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when all the headers are complete but before
|
||||
the content body, if present.
|
||||
Returning 1 from here tells the joyent parser
|
||||
that the message has no body (e.g. a HEAD request).
|
||||
*/
|
||||
int
|
||||
basic_parser::do_headers_complete()
|
||||
{
|
||||
check_header();
|
||||
auto const p (reinterpret_cast <joyent::http_parser const*> (&state_));
|
||||
bool const keep_alive (joyent::http_should_keep_alive (p) != 0);
|
||||
if (p->type == joyent::http_parser_type::HTTP_REQUEST)
|
||||
return on_request (joyent::convert_http_method (
|
||||
joyent::http_method(p->method)), url_,
|
||||
p->http_major, p->http_minor, keep_alive, p->upgrade) ? 0 : 1;
|
||||
return on_response (p->status_code, status_,
|
||||
p->http_major, p->http_minor, keep_alive, p->upgrade) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Called repeatedly for the content body. The passed buffer
|
||||
has already had the transfer-encoding removed.
|
||||
*/
|
||||
int
|
||||
basic_parser::do_body (char const* in, std::size_t bytes)
|
||||
{
|
||||
on_body (in, bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when the both the headers and content body (if any) are complete. */
|
||||
int
|
||||
basic_parser::do_message_complete ()
|
||||
{
|
||||
complete_ = true;
|
||||
on_complete();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int
|
||||
basic_parser::cb_message_start (joyent::http_parser* p)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_message_start();
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_url (joyent::http_parser* p,
|
||||
char const* in, std::size_t bytes)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_url (in, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_status (joyent::http_parser* p,
|
||||
char const* in, std::size_t bytes)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_status (in, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_header_field (joyent::http_parser* p,
|
||||
char const* in, std::size_t bytes)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_header_field (in, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_header_value (joyent::http_parser* p,
|
||||
char const* in, std::size_t bytes)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_header_value (in, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_headers_complete (joyent::http_parser* p)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_headers_complete();
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_body (joyent::http_parser* p,
|
||||
char const* in, std::size_t bytes)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_body (
|
||||
in, bytes);
|
||||
}
|
||||
|
||||
int
|
||||
basic_parser::cb_message_complete (joyent::http_parser* p)
|
||||
{
|
||||
return reinterpret_cast <basic_parser*> (
|
||||
p->data)->do_message_complete();
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
@@ -1,128 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/http/basic_url.h>
|
||||
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace detail {
|
||||
|
||||
void
|
||||
basic_url_base::parse_impl (string_ref s, boost::system::error_code& ec)
|
||||
{
|
||||
joyent::http_parser_url p;
|
||||
|
||||
value_type const* const data (s.data());
|
||||
|
||||
int const error (joyent::http_parser_parse_url (
|
||||
data, s.size(), false, &p));
|
||||
|
||||
if (error)
|
||||
{
|
||||
ec = boost::system::error_code (
|
||||
boost::system::errc::invalid_argument,
|
||||
boost::system::generic_category());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_SCHEMA)) != 0)
|
||||
{
|
||||
m_scheme = string_ref (
|
||||
data + p.field_data [joyent::UF_SCHEMA].off,
|
||||
p.field_data [joyent::UF_SCHEMA].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scheme = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_HOST)) != 0)
|
||||
{
|
||||
m_host = string_ref (
|
||||
data + p.field_data [joyent::UF_HOST].off,
|
||||
p.field_data [joyent::UF_HOST].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_PORT)) != 0)
|
||||
{
|
||||
m_port = p.port;
|
||||
m_port_string = string_ref (
|
||||
data + p.field_data [joyent::UF_PORT].off,
|
||||
p.field_data [joyent::UF_PORT].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_port = 0;
|
||||
m_port_string = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_PATH)) != 0)
|
||||
{
|
||||
m_path = string_ref (
|
||||
data + p.field_data [joyent::UF_PATH].off,
|
||||
p.field_data [joyent::UF_PATH].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_path = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_QUERY)) != 0)
|
||||
{
|
||||
m_query = string_ref (
|
||||
data + p.field_data [joyent::UF_QUERY].off,
|
||||
p.field_data [joyent::UF_QUERY].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_query = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_FRAGMENT)) != 0)
|
||||
{
|
||||
m_fragment = string_ref (
|
||||
data + p.field_data [joyent::UF_FRAGMENT].off,
|
||||
p.field_data [joyent::UF_FRAGMENT].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fragment = string_ref {};
|
||||
}
|
||||
|
||||
if ((p.field_set & (1<<joyent::UF_USERINFO)) != 0)
|
||||
{
|
||||
m_userinfo = string_ref (
|
||||
data + p.field_data [joyent::UF_USERINFO].off,
|
||||
p.field_data [joyent::UF_USERINFO].len);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_userinfo = string_ref {};
|
||||
}
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // http
|
||||
} // beast
|
||||
27
src/beast/beast/http/impl/http-parser/.gitignore
vendored
@@ -1,27 +0,0 @@
|
||||
/out/
|
||||
core
|
||||
tags
|
||||
*.o
|
||||
test
|
||||
test_g
|
||||
test_fast
|
||||
url_parser
|
||||
parsertrace
|
||||
parsertrace_g
|
||||
*.mk
|
||||
*.Makefile
|
||||
*.so.*
|
||||
*.a
|
||||
|
||||
|
||||
# Visual Studio uglies
|
||||
*.suo
|
||||
*.sln
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.opensdf
|
||||
*.ncrunchsolution*
|
||||
*.sdf
|
||||
*.vsp
|
||||
*.psess
|
||||
@@ -1,7 +0,0 @@
|
||||
# update AUTHORS with:
|
||||
# git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS
|
||||
Ryan Dahl <ry@tinyclouds.org>
|
||||
Salman Haq <salman.haq@asti-usa.com>
|
||||
Simon Zimmermann <simonz05@gmail.com>
|
||||
Thomas LE ROUX <thomas@november-eleven.fr> LE ROUX Thomas <thomas@procheo.fr>
|
||||
Thomas LE ROUX <thomas@november-eleven.fr> Thomas LE ROUX <thomas@procheo.fr>
|
||||
@@ -1,13 +0,0 @@
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
script:
|
||||
- "make"
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
- "irc.freenode.net#libuv"
|
||||
@@ -1,4 +0,0 @@
|
||||
Contributors must agree to the Contributor License Agreement before patches
|
||||
can be accepted.
|
||||
|
||||
http://spreadsheets2.google.com/viewform?hl=en&formkey=dDJXOGUwbzlYaWM4cHN1MERwQS1CSnc6MQ
|
||||
@@ -1,105 +0,0 @@
|
||||
# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
PLATFORM ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"')
|
||||
SONAME ?= libhttp_parser.so.2.2.1
|
||||
|
||||
CC?=gcc
|
||||
AR?=ar
|
||||
|
||||
CPPFLAGS += -I.
|
||||
CPPFLAGS_DEBUG = $(CPPFLAGS) -DHTTP_PARSER_STRICT=1
|
||||
CPPFLAGS_DEBUG += $(CPPFLAGS_DEBUG_EXTRA)
|
||||
CPPFLAGS_FAST = $(CPPFLAGS) -DHTTP_PARSER_STRICT=0
|
||||
CPPFLAGS_FAST += $(CPPFLAGS_FAST_EXTRA)
|
||||
|
||||
CFLAGS += -Wall -Wextra -Werror
|
||||
CFLAGS_DEBUG = $(CFLAGS) -O0 -g $(CFLAGS_DEBUG_EXTRA)
|
||||
CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA)
|
||||
CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
||||
|
||||
LDFLAGS_LIB = $(LDFLAGS) -shared
|
||||
|
||||
ifneq (darwin,$(PLATFORM))
|
||||
# TODO(bnoordhuis) The native SunOS linker expects -h rather than -soname...
|
||||
LDFLAGS_LIB += -Wl,-soname=$(SONAME)
|
||||
endif
|
||||
|
||||
test: test_g test_fast
|
||||
./test_g
|
||||
./test_fast
|
||||
|
||||
test_g: http_parser_g.o test_g.o
|
||||
$(CC) $(CFLAGS_DEBUG) $(LDFLAGS) http_parser_g.o test_g.o -o $@
|
||||
|
||||
test_g.o: test.c http_parser.h Makefile
|
||||
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c test.c -o $@
|
||||
|
||||
http_parser_g.o: http_parser.c http_parser.h Makefile
|
||||
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c http_parser.c -o $@
|
||||
|
||||
test_fast: http_parser.o test.o http_parser.h
|
||||
$(CC) $(CFLAGS_FAST) $(LDFLAGS) http_parser.o test.o -o $@
|
||||
|
||||
test.o: test.c http_parser.h Makefile
|
||||
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c test.c -o $@
|
||||
|
||||
http_parser.o: http_parser.c http_parser.h Makefile
|
||||
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c http_parser.c
|
||||
|
||||
test-run-timed: test_fast
|
||||
while(true) do time ./test_fast > /dev/null; done
|
||||
|
||||
test-valgrind: test_g
|
||||
valgrind ./test_g
|
||||
|
||||
libhttp_parser.o: http_parser.c http_parser.h Makefile
|
||||
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_LIB) -c http_parser.c -o libhttp_parser.o
|
||||
|
||||
library: libhttp_parser.o
|
||||
$(CC) $(LDFLAGS_LIB) -o $(SONAME) $<
|
||||
|
||||
package: http_parser.o
|
||||
$(AR) rcs libhttp_parser.a http_parser.o
|
||||
|
||||
url_parser: http_parser.o contrib/url_parser.c
|
||||
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o $@
|
||||
|
||||
url_parser_g: http_parser_g.o contrib/url_parser.c
|
||||
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o $@
|
||||
|
||||
parsertrace: http_parser.o contrib/parsertrace.c
|
||||
$(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o parsertrace
|
||||
|
||||
parsertrace_g: http_parser_g.o contrib/parsertrace.c
|
||||
$(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o parsertrace_g
|
||||
|
||||
tags: http_parser.c http_parser.h test.c
|
||||
ctags $^
|
||||
|
||||
clean:
|
||||
rm -f *.o *.a tags test test_fast test_g \
|
||||
http_parser.tar libhttp_parser.so.* \
|
||||
url_parser url_parser_g parsertrace parsertrace_g
|
||||
|
||||
contrib/url_parser.c: http_parser.h
|
||||
contrib/parsertrace.c: http_parser.h
|
||||
|
||||
.PHONY: clean package test-run test-run-timed test-valgrind
|
||||
@@ -1,156 +0,0 @@
|
||||
/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
|
||||
*
|
||||
* Additional changes are licensed under the same terms as NGINX and
|
||||
* copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Dump what the parser finds to stdout as it happen */
|
||||
|
||||
#include "http_parser.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int on_message_begin(http_parser* _) {
|
||||
(void)_;
|
||||
printf("\n***MESSAGE BEGIN***\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_headers_complete(http_parser* _) {
|
||||
(void)_;
|
||||
printf("\n***HEADERS COMPLETE***\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_message_complete(http_parser* _) {
|
||||
(void)_;
|
||||
printf("\n***MESSAGE COMPLETE***\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_url(http_parser* _, const char* at, size_t length) {
|
||||
(void)_;
|
||||
printf("Url: %.*s\n", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_header_field(http_parser* _, const char* at, size_t length) {
|
||||
(void)_;
|
||||
printf("Header field: %.*s\n", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_header_value(http_parser* _, const char* at, size_t length) {
|
||||
(void)_;
|
||||
printf("Header value: %.*s\n", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int on_body(http_parser* _, const char* at, size_t length) {
|
||||
(void)_;
|
||||
printf("Body: %.*s\n", (int)length, at);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(const char* name) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s $type $filename\n"
|
||||
" type: -x, where x is one of {r,b,q}\n"
|
||||
" parses file as a Response, reQuest, or Both\n",
|
||||
name);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
enum http_parser_type file_type;
|
||||
|
||||
if (argc != 3) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
char* type = argv[1];
|
||||
if (type[0] != '-') {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
switch (type[1]) {
|
||||
/* in the case of "-", type[1] will be NUL */
|
||||
case 'r':
|
||||
file_type = HTTP_RESPONSE;
|
||||
break;
|
||||
case 'q':
|
||||
file_type = HTTP_REQUEST;
|
||||
break;
|
||||
case 'b':
|
||||
file_type = HTTP_BOTH;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
char* filename = argv[2];
|
||||
FILE* file = fopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
perror("fopen");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long file_length = ftell(file);
|
||||
if (file_length == -1) {
|
||||
perror("ftell");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
char* data = malloc(file_length);
|
||||
if (fread(data, 1, file_length, file) != (size_t)file_length) {
|
||||
fprintf(stderr, "couldn't read entire file\n");
|
||||
free(data);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
http_parser_settings settings;
|
||||
memset(&settings, 0, sizeof(settings));
|
||||
settings.on_message_begin = on_message_begin;
|
||||
settings.on_url = on_url;
|
||||
settings.on_header_field = on_header_field;
|
||||
settings.on_header_value = on_header_value;
|
||||
settings.on_headers_complete = on_headers_complete;
|
||||
settings.on_body = on_body;
|
||||
settings.on_message_complete = on_message_complete;
|
||||
|
||||
http_parser parser;
|
||||
http_parser_init(&parser, file_type);
|
||||
size_t nparsed = http_parser_execute(&parser, &settings, data, file_length);
|
||||
free(data);
|
||||
|
||||
if (nparsed != (size_t)file_length) {
|
||||
fprintf(stderr,
|
||||
"Error: %s (%s)\n",
|
||||
http_errno_description(HTTP_PARSER_ERRNO(&parser)),
|
||||
http_errno_name(HTTP_PARSER_ERRNO(&parser)));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#include "http_parser.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
dump_url (const char *url, const struct http_parser_url *u)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port);
|
||||
for (i = 0; i < UF_MAX; i++) {
|
||||
if ((u->field_set & (1 << i)) == 0) {
|
||||
printf("\tfield_data[%u]: unset\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n",
|
||||
i,
|
||||
u->field_data[i].off,
|
||||
u->field_data[i].len,
|
||||
u->field_data[i].len,
|
||||
url + u->field_data[i].off);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
if (argc != 3) {
|
||||
printf("Syntax : %s connect|get url\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
struct http_parser_url u;
|
||||
int len = strlen(argv[2]);
|
||||
int connect = strcmp("connect", argv[1]) == 0 ? 1 : 0;
|
||||
printf("Parsing %s, connect %d\n", argv[2], connect);
|
||||
|
||||
int result = http_parser_parse_url(argv[2], len, connect, &u);
|
||||
if (result != 0) {
|
||||
printf("Parse error : %d\n", result);
|
||||
return result;
|
||||
}
|
||||
printf("Parse ok, result : \n");
|
||||
dump_url(argv[2], &u);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
# This file is used with the GYP meta build system.
|
||||
# http://code.google.com/p/gyp/
|
||||
# To build try this:
|
||||
# svn co http://gyp.googlecode.com/svn/trunk gyp
|
||||
# ./gyp/gyp -f make --depth=`pwd` http_parser.gyp
|
||||
# ./out/Debug/test
|
||||
{
|
||||
'target_defaults': {
|
||||
'default_configuration': 'Debug',
|
||||
'configurations': {
|
||||
# TODO: hoist these out and put them somewhere common, because
|
||||
# RuntimeLibrary MUST MATCH across the entire project
|
||||
'Debug': {
|
||||
'defines': [ 'DEBUG', '_DEBUG' ],
|
||||
'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': 1, # static debug
|
||||
},
|
||||
},
|
||||
},
|
||||
'Release': {
|
||||
'defines': [ 'NDEBUG' ],
|
||||
'cflags': [ '-Wall', '-Wextra', '-O3' ],
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': 0, # static release
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
},
|
||||
'VCLibrarianTool': {
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
'GenerateDebugInformation': 'true',
|
||||
},
|
||||
},
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'defines': [
|
||||
'WIN32'
|
||||
],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'http_parser',
|
||||
'type': 'static_library',
|
||||
'include_dirs': [ '.' ],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [ 'HTTP_PARSER_STRICT=0' ],
|
||||
'include_dirs': [ '.' ],
|
||||
},
|
||||
'defines': [ 'HTTP_PARSER_STRICT=0' ],
|
||||
'sources': [ './http_parser.c', ],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
# Compile as C++. http_parser.c is actually C99, but C++ is
|
||||
# close enough in this case.
|
||||
'CompileAs': 2,
|
||||
},
|
||||
},
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'http_parser_strict',
|
||||
'type': 'static_library',
|
||||
'include_dirs': [ '.' ],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [ 'HTTP_PARSER_STRICT=1' ],
|
||||
'include_dirs': [ '.' ],
|
||||
},
|
||||
'defines': [ 'HTTP_PARSER_STRICT=1' ],
|
||||
'sources': [ './http_parser.c', ],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
# Compile as C++. http_parser.c is actually C99, but C++ is
|
||||
# close enough in this case.
|
||||
'CompileAs': 2,
|
||||
},
|
||||
},
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'test-nonstrict',
|
||||
'type': 'executable',
|
||||
'dependencies': [ 'http_parser' ],
|
||||
'sources': [ 'test.c' ]
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'test-strict',
|
||||
'type': 'executable',
|
||||
'dependencies': [ 'http_parser_strict' ],
|
||||
'sources': [ 'test.c' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
#include <beast/http/method.h>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace joyent {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127) // conditional expression is constant
|
||||
# pragma warning (disable: 4244) // integer conversion, possible loss of data
|
||||
#endif
|
||||
#include <beast/http/impl/http-parser/http_parser.c>
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace boost {
|
||||
namespace system {
|
||||
|
||||
template <>
|
||||
struct is_error_code_enum <beast::joyent::http_errno>
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_error_condition_enum <beast::joyent::http_errno>
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace beast {
|
||||
namespace joyent {
|
||||
|
||||
http::method_t
|
||||
convert_http_method (joyent::http_method m)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case HTTP_DELETE: return http::method_t::http_delete;
|
||||
case HTTP_GET: return http::method_t::http_get;
|
||||
case HTTP_HEAD: return http::method_t::http_head;
|
||||
case HTTP_POST: return http::method_t::http_post;
|
||||
case HTTP_PUT: return http::method_t::http_put;
|
||||
|
||||
// pathological
|
||||
case HTTP_CONNECT: return http::method_t::http_connect;
|
||||
case HTTP_OPTIONS: return http::method_t::http_options;
|
||||
case HTTP_TRACE: return http::method_t::http_trace;
|
||||
|
||||
// webdav
|
||||
case HTTP_COPY: return http::method_t::http_copy;
|
||||
case HTTP_LOCK: return http::method_t::http_lock;
|
||||
case HTTP_MKCOL: return http::method_t::http_mkcol;
|
||||
case HTTP_MOVE: return http::method_t::http_move;
|
||||
case HTTP_PROPFIND: return http::method_t::http_propfind;
|
||||
case HTTP_PROPPATCH: return http::method_t::http_proppatch;
|
||||
case HTTP_SEARCH: return http::method_t::http_search;
|
||||
case HTTP_UNLOCK: return http::method_t::http_unlock;
|
||||
|
||||
// subversion
|
||||
case HTTP_REPORT: return http::method_t::http_report;
|
||||
case HTTP_MKACTIVITY: return http::method_t::http_mkactivity;
|
||||
case HTTP_CHECKOUT: return http::method_t::http_checkout;
|
||||
case HTTP_MERGE: return http::method_t::http_merge;
|
||||
|
||||
// upnp
|
||||
case HTTP_MSEARCH: return http::method_t::http_msearch;
|
||||
case HTTP_NOTIFY: return http::method_t::http_notify;
|
||||
case HTTP_SUBSCRIBE: return http::method_t::http_subscribe;
|
||||
case HTTP_UNSUBSCRIBE: return http::method_t::http_unsubscribe;
|
||||
|
||||
// RFC-5789
|
||||
case HTTP_PATCH: return http::method_t::http_patch;
|
||||
case HTTP_PURGE: return http::method_t::http_purge;
|
||||
};
|
||||
|
||||
return http::method_t::http_get;
|
||||
}
|
||||
|
||||
boost::system::error_code
|
||||
convert_http_errno (joyent::http_errno err)
|
||||
{
|
||||
class http_error_category_t
|
||||
: public boost::system::error_category
|
||||
{
|
||||
private:
|
||||
using error_code = boost::system::error_code;
|
||||
using error_condition = boost::system::error_condition;
|
||||
|
||||
public:
|
||||
char const*
|
||||
name() const noexcept override
|
||||
{
|
||||
return "http_errno";
|
||||
}
|
||||
|
||||
std::string
|
||||
message (int ev) const override
|
||||
{
|
||||
return joyent::http_errno_name (
|
||||
joyent::http_errno (ev));
|
||||
}
|
||||
|
||||
error_condition
|
||||
default_error_condition (int ev) const noexcept override
|
||||
{
|
||||
return error_condition (ev, *this);
|
||||
}
|
||||
|
||||
bool
|
||||
equivalent (int code, error_condition const& condition
|
||||
) const noexcept override
|
||||
{
|
||||
return default_error_condition (code) == condition;
|
||||
}
|
||||
|
||||
bool
|
||||
equivalent (error_code const& code, int condition
|
||||
) const noexcept override
|
||||
{
|
||||
return *this == code.category() &&
|
||||
code.value() == condition;
|
||||
}
|
||||
};
|
||||
|
||||
static http_error_category_t http_error_category;
|
||||
|
||||
return boost::system::error_code (
|
||||
err, http_error_category);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||