Skip to content

Commit b1c6ac6

Browse files
committed
Merge branch 'develop'
2 parents b3a1d9f + 6841169 commit b1c6ac6

52 files changed

Lines changed: 9933 additions & 1888 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docs.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ on:
88

99
jobs:
1010
build:
11-
12-
runs-on: ubuntu-latest
13-
11+
runs-on: ubuntu-20.04
1412
steps:
1513
- uses: actions/checkout@v2
1614
- name: install dependencies

.github/workflows/sanitizers.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: sanitizers
2+
3+
on:
4+
push:
5+
branches: [ master, develop ]
6+
pull_request:
7+
branches: [ master, develop ]
8+
9+
jobs:
10+
sanitizer:
11+
runs-on: ubuntu-20.04
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
sanitizer: [asan, ubsan, lsan]
16+
compiler : [ g++-10 ]
17+
steps:
18+
- uses: actions/checkout@v2
19+
- name: configure
20+
run: mkdir build && cd build &&
21+
cmake -DCMAKE_CXX_COMPILER=${{ matrix.compiler }}
22+
-DBENCODE_BUILD_TESTS=ON
23+
-DBENCODE_BUILD_DOCS=OFF
24+
-DBENCODE_BUILD_BENCHMARKS=OFF
25+
-DBENCODE_ENABLE_COVERAGE=OFF
26+
-DCMAKE_BUILD_TYPE="${{ matrix.sanitizer }}" ..
27+
- working-directory: build/
28+
run: make
29+
- working-directory: build/tests
30+
run: ./bencode-tests

.github/workflows/tests.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,20 @@ on:
88

99
jobs:
1010
build:
11-
12-
runs-on: ubuntu-latest
13-
11+
runs-on: ubuntu-20.04
1412
steps:
1513
- uses: actions/checkout@v2
16-
- name: install g++10
17-
run: sudo apt install gcc-10 g++-10
18-
- name: configure
14+
- name: Configure
1915
run: mkdir build && cd build &&
2016
cmake -DCMAKE_CXX_COMPILER=g++-10
2117
-DCMAKE_BUILD_TYPE=Debug
2218
-DBENCODE_BUILD_TESTS=ON
2319
-DBENCODE_ENABLE_COVERAGE=ON
2420
-DBENCODE_BUILD_DOCS=OFF
2521
-DBENCODE_BUILD_BENCHMARKS=OFF ..
26-
- name: build
22+
- name: Build tests
2723
run: cmake --build build
28-
- name: test
24+
- name: Run tests
2925
run: cd build && ctest
3026
- name: Generate and upload coverage to Codecov
3127
run: bash <(curl -s https://codecov.io/bash) -t ${{ secrets.CODECOV_TOKEN }} -x gcov-10

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## v0.5.0
4+
5+
* Rename event_consumer methods from (begin|end)\_(list|dict) to (begin|end)\_(list|dict).
6+
This makes naming more consistent.
7+
* Add more benchmarks
8+
* Disable contract checks in release build for improved performance.
9+
* Fix parsing from a pair of InputItererators.
10+
* Add string_parsing_mode options to push_parser to allow parsing strings to string_view.
11+
* Add experimental SSE4.1 and AVX2 integer parsing backends. Enable SWAR integer parsing by default.
12+
313
## v0.4.0
414

515
* Reworked parser internals for increased decoding speed.

CMakeLists.txt

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ project(bencode
33
DESCRIPTION "A C++20 header-only bencode library."
44
HOMEPAGE_URL https://github.com/fbdtemme/bencode
55
LANGUAGES CXX
6-
VERSION 0.4.0)
6+
VERSION 0.5.0)
77

88
set(PROJECT_AUTHOR "fbdtemme")
99
# Make Find modules in cmake dir available
1010
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
1111

12+
if (NOT CMAKE_BUILD_TYPE)
13+
set(CMAKE_BUILD_TYPE Release)
14+
endif()
15+
1216
# includes
1317
include(CTest)
1418
include(CMakeDependentOption)
@@ -37,23 +41,64 @@ include(external/gsl-lite.cmake)
3741
include(external/expected-lite.cmake)
3842

3943
option(BENCODE_BUILD_TESTS "Build tests." ${BENCODE_MASTER_PROJECT})
40-
option(BENCODE_BUILD_BENCHMARKS "Build benchmarks" ${BENCODE_MASTER_PROJECT})
41-
option(BENCODE_BUILD_DOCS "Build documentation" ${BENCODE_MASTER_PROJECT})
44+
option(BENCODE_BUILD_BENCHMARKS "Build benchmarks" OFF)
45+
option(BENCODE_BUILD_DOCS "Build documentation" OFF)
4246
option(BENCODE_ENABLE_COVERAGE "Build tests with coverage flags enabled" OFF)
4347
option(BENCODE_ENABLE_INSTALL "Generate an install target." ON)
4448

45-
set(BENCODE_FROM_CHARS_IMPL "swar" CACHE STRING
46-
"The implementation to use. Options: serial or swar")
49+
# Changing these options from their defaults can lead to reduced performance.
50+
# Benchmark before changing these on your target system!
51+
52+
set(BENCODE_FROM_CHARS_INTEGER_IMPL "swar" CACHE STRING
53+
"The implementation to use. Options: serial, swar or sse41, avx2")
54+
set(BENCODE_FROM_CHARS_STRING_IMPL "serial" CACHE STRING
55+
"The implementation to use. Options: serial, swar, sse41, avx2")
56+
57+
58+
string(TOLOWER ${BENCODE_FROM_CHARS_INTEGER_IMPL} BENCODE_FROM_CHARS_INTEGER_IMPL)
59+
string(TOLOWER ${BENCODE_FROM_CHARS_STRING_IMPL} BENCODE_FROM_CHARS_STRING_IMPL)
4760

61+
if (BENCODE_FROM_CHARS_INTEGER_IMPL STREQUAL swar)
62+
message(STATUS "Enabling SWAR integer parsing.")
63+
elseif(BENCODE_FROM_CHARS_INTEGER_IMPL STREQUAL sse41)
64+
message(STATUS "Enabling SSE4.1 integer parsing.")
65+
target_compile_options(bencode INTERFACE -msse4)
66+
elseif(BENCODE_FROM_CHARS_INTEGER_IMPL STREQUAL avx2)
67+
message(STATUS "Enabling AVX2 integer parsing.")
68+
target_compile_options(bencode INTERFACE -mavx2)
69+
endif()
70+
71+
if (BENCODE_FROM_CHARS_STRING_IMPL STREQUAL swar)
72+
message(STATUS "Enabling SWAR string parsing.")
73+
elseif(BENCODE_FROM_CHARS_STRING_IMPL STREQUAL sse41)
74+
message(STATUS "Enabling SSE4.1 string parsing.")
75+
target_compile_options(bencode INTERFACE -msse4)
76+
elseif(BENCODE_FROM_CHARS_STRING_IMPL STREQUAL avx2)
77+
message(STATUS "Enabling AVX2 string parsing.")
78+
target_compile_options(bencode INTERFACE -mavx2)
79+
endif()
4880

49-
string(TOLOWER ${BENCODE_FROM_CHARS_IMPL} BENCODE_FROM_CHARS_IMPL)
81+
82+
target_compile_definitions(
83+
bencode INTERFACE
84+
BENCODE_FROM_CHARS_INTEGER_IMPL=${BENCODE_FROM_CHARS_INTEGER_IMPL}
85+
BENCODE_FROM_CHARS_STRING_IMPL=${BENCODE_FROM_CHARS_STRING_IMPL}
86+
)
5087

5188
target_link_libraries(bencode
5289
INTERFACE
5390
fmt::fmt-header-only
5491
nonstd::expected-lite
5592
gsl::gsl-lite-v1)
5693

94+
string(TOLOWER ${CMAKE_BUILD_TYPE} BENCODE_BUILD_TYPE)
95+
96+
if (BENCODE_BUILD_TYPE STREQUAL release)
97+
message(STATUS "Disabling all runtime checking of contracts")
98+
target_compile_definitions(bencode INTERFACE gsl_CONFIG_CONTRACT_CHECKING_OFF)
99+
endif()
100+
101+
57102
if (BENCODE_BUILD_TESTS)
58103
enable_testing()
59104
message(STATUS "Building tests enabled")
@@ -71,13 +116,6 @@ if (BENCODE_BUILD_DOCS)
71116
endif()
72117

73118

74-
if (BENCODE_FROM_CHARS_IMPL STREQUAL swar)
75-
message(STATUS "Enabling SWAR integer parsing.")
76-
elseif()
77-
message(STATUS "Disabling SWAR integer parsing.")
78-
endif()
79-
target_compile_definitions(bencode INTERFACE BENCODE_FROM_CHARS_IMPL=${BENCODE_FROM_CHARS_IMPL})
80-
81119

82120
if (BENCODE_ENABLE_INSTALL)
83121
set(bencode_package_name ${PROJECT_NAME})

README.md

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
[![build](https://github.com/fbdtemme/bencode/workflows/build/badge.svg?branch=master)](https://github.com/fbdtemme/bencode/actions?query=workflow%3Abuild)
44
[![docs](https://github.com/fbdtemme/bencode/workflows/documentation/badge.svg?branch=master)](https://fbdtemme.github.io/bencode/)
5+
[![santizers](https://github.com/fbdtemme/bencode/workflows/sanitizers/badge.svg?branch=master)](https://github.com/fbdtemme/bencode/actions?query=workflow%3Asanitizers)
56
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/fbdtemme/bencode)](https://github.com/fbdtemme/bencode/releases)
67
[![C++ standard](https://img.shields.io/badge/C%2B%2B-20-blue)](https://isocpp.org/)
78
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5cc3eec94d8a486dab62afeab5130def)](https://app.codacy.com/manual/floriandetemmerman/bencode?utm_source=github.com&utm_medium=referral&utm_content=fbdtemme/bencode&utm_campaign=Badge_Grade_Dashboard)
@@ -10,7 +11,8 @@
1011

1112
[**Features**](#Features) |
1213
[**Status**](#Status) |
13-
[**Documentation**](#Documentation) |
14+
[**Documentation**](#Documentation) |
15+
[**Performance**](#Performance) |
1416
[**Examples**](#Examples) |
1517
[**Building**](#Building) |
1618
[**Integration**](#Integration) |
@@ -29,19 +31,28 @@ A header-only C++20 bencode serialization/deserialization library. Inspired by t
2931

3032
## Features
3133

32-
* Convenient owning representation of bencoded data with `bvalue`.
33-
* Fast and memory efficient read-only, non-owning representation into stable buffers of bencoded data with `bview`.
34-
* Build-in serialization/deserializaton for most standard containers.
35-
* Support for serializing/deserializing to/from user-defined types.
36-
* Parse directly to custom types by satisfying the `EventConsumer` concept.
37-
* Throwing and non throwing variants of common functions.
38-
* Iterative parsing to protect against stack overflow attacks.
39-
* Bencode pointer similar to json pointer.
40-
34+
* **Feature-rich**. The main goal of this library is to provide a complete bencode library that
35+
provides optimal solutions for all common use cases. `bvalue` is an owning representation of bencoded data
36+
and is usefull for creating and modifying bencoded documents.
37+
`bview` is a fast and memory efficient, read-only, non-owning representation into a stable buffer of bencoded data.
38+
`bpointer` can be used to access both `bvalue` and `bview` types.
39+
* **Extensibility**. This library provides built-in serialization and deserialization from/to most standard containers.
40+
Support for user-defined types can be added by implementing the necessary extension points.
41+
Users can parse directly to their data type of preference by implementing a class satisfying
42+
the EventConsumer concept.
43+
* **Conformance**. This library is 100% conforming to the bencode specification.
44+
All parsers validate the input and provide exact error messages.
45+
* **Security**. Parsing arbitrary user data can be dangerous and you do not want your bittorrent tracker
46+
to crash when a user sends malformed data. All parsers are recursion-free to protect against
47+
stack-based buffer overflow attacks. Integer parsing throws when overflows are encountered.
48+
* **Speed**. While not the primary goal of this project this library provides optimized integer parsing with
49+
SWAR techniques. Benchmarks show this library performs well in comparison with other libraries
50+
4151
## Status
4252

43-
This library is under active development, but should be fairly stable.
44-
The API may change at any release prior to 1.0.0.
53+
This library is under active development. The API may change at any release prior to 1.0.0.
54+
Versioning follows the Semantic Versioning Specification.
55+
4556

4657
## Documentation
4758

@@ -54,6 +65,19 @@ Value types own the data they refer to and thus need to copy data from the buffe
5465
View types try to minimize copies from the buffer with bencoded data and instead point
5566
to data directly inside the buffer.
5667

68+
Decoding speed was compared for these libraries in alphabetical order:
69+
70+
* [Aetf/QBencode](https://github.com/Aetf/QBencode)
71+
* [arvidn/libtorrent](https://github.com/arvidn/libtorrent)
72+
* [iRajul/bencode](https://github.com/iRajul/bencode)
73+
* [jimporter/bencode.hpp](https://github.com/jimporter/bencode.hpp)
74+
* [kriben/bencode](https://github.com/kriben/bencode)
75+
* [outputenable/bencode](https://gitlab.com/outputenable/bencode)
76+
* [rakshasa/libtorrent](https://github.com/rakshasa/libtorrent)
77+
* [s3ponia/BencodeParser](https://github.com/s3ponia/BencodeParser)
78+
* [s3rvac/cpp-bencoding](https://github.com/s3rvac/cpp-bencoding)
79+
* [theanti9/cppbencode](https://github.com/theanti9/cppbencode)
80+
5781
#### Parsing to value types
5882

5983
![benchmark-decoding-value](docs/images/benchmark-decoding-value.svg)
@@ -62,7 +86,15 @@ to data directly inside the buffer.
6286

6387
![benchmark-decoding-view](docs/images/benchmark-decoding-view.svg)
6488

65-
Note: libtorrent does not decode integers until they are actually accessed.
89+
All benchmarks were build with GCC 10.2.1 with -O3 and run on an intel i7-7700hq.
90+
91+
Notes:
92+
* arvidn/libtorrent does not decode integers until they are actually accessed.
93+
This gives a performance benefit when decoding but results in slower
94+
access times when retrieving integral values.
95+
* kriben/bencode support only 32-bit integers and fails on the
96+
camelyon17, integers and pneumomia benchmarks
97+
* iRajul/bencode fails all benchmarks and was excluded from the results.
6698

6799
## Examples
68100

@@ -186,7 +218,7 @@ See the [documentation](https://fbdtemme.github.io/bencode/) for more examples.
186218
This project requires C++20.
187219
Currently only GCC 10 and later is supported.
188220

189-
This library depends on following projects:
221+
This library uses following projects:
190222
* [fmt](https://github.com/fmtlib/fmt)
191223
* [gsl-lite](https://github.com/gsl-lite/gsl-lite)
192224
* [expected-lite](https://github.com/martinmoene/expected-lite)
@@ -196,23 +228,29 @@ When building tests:
196228

197229
When building benchmarks:
198230
* [google/benchmark](https://github.com/google/benchmark)
199-
* [libtorrent](https://github.com/arvidn/libtorrent)
200-
* [jimporter/bencode](https://github.com/jimporter/bencode)
201-
* [s3rvac/cpp-bencoding](https://github.com/s3rvac/cpp-bencoding)
231+
* [Boost](https://www.boost.org/)
232+
* [Qt5](https://www.qt.io/)
233+
202234

203235
When building documentation:
204236
* [doxygen](https://github.com/doxygen/doxygen>)
205237
* [sphinx](https://github.com/sphinx-doc/sphinx>)
206238
* [breathe](https://github.com/michaeljones/breathe>)
239+
* [shphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme)
207240

208-
All dependencies for building tests and benchmarks can be fetched from github using
241+
All dependencies except for boost, Qt5 and documentation dependencies can be fetched from github using
209242
cmake FetchContent during configuration if no local installation is found.
210243

211244
The tests can be built as every other project which makes use of the CMake build system.
212245

213246
```{bash}
214247
mkdir build; cd build;
215-
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBENCODE_BUILD_TESTS=ON -DBENCODE_BUILD_BENCHMARKS=OFF =DBENCODE_BUILD_DOCS=OFF
248+
cmake \
249+
-DCMAKE_BUILD_TYPE=Debug \
250+
-DBENCODE_BUILD_TESTS=ON \
251+
-DBENCODE_BUILD_BENCHMARKS=OFF \
252+
-DBENCODE_BUILD_DOCS=OFF \
253+
--build . --target ..
216254
make bencode-tests
217255
```
218256

0 commit comments

Comments
 (0)