Skip to content

Commit

Permalink
dev: copy bencode into local contrib folder
Browse files Browse the repository at this point in the history
  • Loading branch information
da2ce7 committed Aug 21, 2023
1 parent c5dc3dc commit fc10b0a
Show file tree
Hide file tree
Showing 24 changed files with 2,171 additions and 17 deletions.
264 changes: 250 additions & 14 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ uuid = { version = "1", features = ["v4"] }
axum = "0.6.20"
axum-server = { version = "0.5", features = ["tls-rustls"] }
axum-client-ip = "0.4.1"
bip_bencode = "0.4"
bencode = { version = "1.0.0-alpha.1", path = "contrib/bencode" }
torrust-tracker-primitives = { version = "3.0.0-alpha.3", path = "packages/primitives" }
torrust-tracker-configuration = { version = "3.0.0-alpha.3", path = "packages/configuration" }
torrust-tracker-located-error = { version = "3.0.0-alpha.3", path = "packages/located-error" }
Expand All @@ -59,6 +59,7 @@ torrust-tracker-test-helpers = { version = "3.0.0-alpha.3", path = "packages/tes

[workspace]
members = [
"contrib/bencode",
"packages/configuration",
"packages/primitives",
"packages/test-helpers",
Expand Down
34 changes: 34 additions & 0 deletions contrib/bencode/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "bencode"
description = "Efficient decoding and encoding for bencode."
keywords = ["bencode"]
readme = "README.md"


authors = [
"Nautilus Cyberneering <[email protected]>, Andrew <[email protected]>",
]
categories = ["network-programming", "web-programming"]
documentation = "https://github.com/torrust/bittorrent-infrastructure-project"
edition = "2021"
homepage = "https://github.com/torrust/bittorrent-infrastructure-project"
license = "Apache-2.0"
publish = false # until we decide where to publish.
repository = "https://github.com/torrust/bittorrent-infrastructure-project"
rust-version = "1.71"
version = "1.0.0-alpha.1"


[dependencies]
error-chain = "0.12"

[dev-dependencies]
criterion = "0.5"

[[test]]
name = "test"
path = "test/mod.rs"

[[bench]]
name = "bencode_benchmark"
harness = false
4 changes: 4 additions & 0 deletions contrib/bencode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Bencode
This library allows for the creation and parsing of bencode encodings.

Bencode is the binary encoding used throughout bittorrent technologies from metainfo files to DHT messages. Bencode types include integers, byte arrays, lists, and dictionaries, of which the last two can hold any bencode type (they could be recursively constructed).
27 changes: 27 additions & 0 deletions contrib/bencode/benches/bencode_benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use bencode::{BDecodeOpt, BencodeRef};
use criterion::{black_box, criterion_group, criterion_main, Criterion};

const B_NESTED_LISTS: &[u8; 100] =
b"lllllllllllllllllllllllllllllllllllllllllllllllllleeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; // cspell:disable-line
const MULTI_KB_BENCODE: &[u8; 30004] = include_bytes!("multi_kb.bencode");

fn bench_nested_lists(bencode: &[u8]) {
BencodeRef::decode(bencode, BDecodeOpt::new(50, true, true)).unwrap();
}

fn bench_multi_kb_bencode(bencode: &[u8]) {
BencodeRef::decode(bencode, BDecodeOpt::default()).unwrap();
}

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("bencode nested lists", |b| {
b.iter(|| bench_nested_lists(black_box(B_NESTED_LISTS)));
});

c.bench_function("bencode multi kb", |b| {
b.iter(|| bench_multi_kb_bencode(black_box(MULTI_KB_BENCODE)));
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
1 change: 1 addition & 0 deletions contrib/bencode/benches/multi_kb.bencode

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions contrib/bencode/src/access/bencode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use crate::access::dict::BDictAccess;
use crate::access::list::BListAccess;

/// Abstract representation of a `BencodeRef` object.
pub enum RefKind<'a, K, V> {
/// Bencode Integer.
Int(i64),
/// Bencode Bytes.
Bytes(&'a [u8]),
/// Bencode List.
List(&'a dyn BListAccess<V>),
/// Bencode Dictionary.
Dict(&'a dyn BDictAccess<K, V>),
}

/// Trait for read access to some bencode type.
pub trait BRefAccess: Sized {
type BKey;
type BType: BRefAccess<BKey = Self::BKey>;

/// Access the bencode as a `BencodeRefKind`.
fn kind(&self) -> RefKind<'_, Self::BKey, Self::BType>;

/// Attempt to access the bencode as a `str`.
fn str(&self) -> Option<&str>;

/// Attempt to access the bencode as an `i64`.
fn int(&self) -> Option<i64>;

/// Attempt to access the bencode as an `[u8]`.
fn bytes(&self) -> Option<&[u8]>;

/// Attempt to access the bencode as an `BListAccess`.
fn list(&self) -> Option<&dyn BListAccess<Self::BType>>;

/// Attempt to access the bencode as an `BDictAccess`.
fn dict(&self) -> Option<&dyn BDictAccess<Self::BKey, Self::BType>>;
}

/// Trait for extended read access to some bencode type.
///
/// Use this trait when you want to make sure that the lifetime of
/// the underlying buffers is tied to the lifetime of the backing
/// bencode buffer.
pub trait BRefAccessExt<'a>: BRefAccess {
/// Attempt to access the bencode as a `str`.
fn str_ext(&self) -> Option<&'a str>;

/// Attempt to access the bencode as an `[u8]`.
fn bytes_ext(&self) -> Option<&'a [u8]>;
}

impl<'a, T> BRefAccess for &'a T
where
T: BRefAccess,
{
type BKey = T::BKey;
type BType = T::BType;

fn kind(&self) -> RefKind<'_, Self::BKey, Self::BType> {
(*self).kind()
}

fn str(&self) -> Option<&str> {
(*self).str()
}

fn int(&self) -> Option<i64> {
(*self).int()
}

fn bytes(&self) -> Option<&[u8]> {
(*self).bytes()
}

fn list(&self) -> Option<&dyn BListAccess<Self::BType>> {
(*self).list()
}

fn dict(&self) -> Option<&dyn BDictAccess<Self::BKey, Self::BType>> {
(*self).dict()
}
}

impl<'a: 'b, 'b, T> BRefAccessExt<'a> for &'b T
where
T: BRefAccessExt<'a>,
{
fn str_ext(&self) -> Option<&'a str> {
(*self).str_ext()
}

fn bytes_ext(&self) -> Option<&'a [u8]> {
(*self).bytes_ext()
}
}

/// Abstract representation of a `BencodeMut` object.
pub enum MutKind<'a, K, V> {
/// Bencode Integer.
Int(i64),
/// Bencode Bytes.
Bytes(&'a [u8]),
/// Bencode List.
List(&'a mut dyn BListAccess<V>),
/// Bencode Dictionary.
Dict(&'a mut dyn BDictAccess<K, V>),
}

/// Trait for write access to some bencode type.
pub trait BMutAccess: Sized + BRefAccess {
/// Access the bencode as a `BencodeMutKind`.
fn kind_mut(&mut self) -> MutKind<'_, Self::BKey, Self::BType>;

/// Attempt to access the bencode as a mutable `BListAccess`.
fn list_mut(&mut self) -> Option<&mut dyn BListAccess<Self::BType>>;

/// Attempt to access the bencode as a mutable `BDictAccess`.
fn dict_mut(&mut self) -> Option<&mut dyn BDictAccess<Self::BKey, Self::BType>>;
}
Loading

0 comments on commit fc10b0a

Please sign in to comment.