Skip to content

Commit 975c765

Browse files
committed
Add API for reading message slices from a source.
This change will support: - Generic statistics (esrlabs#31) - Reading messages from streams (esrlabs#34) Additionally it provides a cleanup of the crate's feature names and removes the dependecy to the legacy buf_redux create.
1 parent 25706ea commit 975c765

File tree

12 files changed

+404
-242
lines changed

12 files changed

+404
-242
lines changed

CHANGELOG.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.20.0] - 2025-02-25
11+
12+
### Added
13+
14+
- Support generic statistics from reading messages
15+
- Support parsing of DLT messages from streams
16+
17+
### Changed
18+
19+
- Cleanup feature names
20+
1021
## [0.19.2] - 2025-02-06
1122

1223
### Changed
@@ -36,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3647

3748
### Changed
3849

39-
- Add feature "serde-support", which adds to crate's types Serialize/Deserialize
50+
- Add feature "serialization", which adds to crate's types Serialize/Deserialize
4051

4152
## [0.17.0] - 2024-10-04
4253

Cargo.toml

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dlt-core"
3-
version = "0.19.2"
3+
version = "0.20.0"
44
authors = ["esrlabs.com"]
55
edition = "2021"
66
description = """
@@ -10,7 +10,6 @@ license = "Apache-2.0"
1010
repository = "https://github.com/esrlabs/dlt-core"
1111

1212
[dependencies]
13-
buf_redux = { version = "0.8.4", optional = true }
1413
byteorder = "1.4"
1514
bytes = "1.0"
1615
log = "0.4"
@@ -21,25 +20,29 @@ rustc-hash = { version = "2.1", optional = true }
2120
serde = { version = "1.0", features = ["derive"], optional = true }
2221
serde_json = { version = "1.0", optional = true }
2322
thiserror = "1.0"
23+
futures = "0.3"
2424

2525
[features]
2626
default = []
27-
statistics = ["buf_redux", "rustc-hash"]
28-
fibex_parser = ["quick-xml"]
29-
debug_parser = []
30-
serde-support = ["serde", "serde_json"]
27+
statistics = ["rustc-hash"]
28+
fibex = ["quick-xml"]
29+
debug = []
30+
serialization = ["serde", "serde_json"]
31+
stream = []
3132

3233
[lints.rust]
3334
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
3435

3536
[dev-dependencies]
36-
buf_redux = "0.8.4"
3737
criterion = { version = "0.4", features = ["html_reports"] }
3838
dirs = "4.0"
3939
env_logger = "0.10"
4040
pretty_assertions = "1.3"
4141
proptest = "1.6"
4242
proptest-derive = "0.5"
43+
tokio = { version = "1", features = ["full"] }
44+
tokio-stream = "0.1"
45+
tokio-util = "0.7"
4346

4447
[[bench]]
4548
name = "dlt_benchmarks"

README.md

+18-45
Original file line numberDiff line numberDiff line change
@@ -69,61 +69,32 @@ The following example can be run with `cargo run --example file_parser --release
6969

7070
<!-- example start -->
7171
```rust
72-
use buf_redux::{policy::MinBuffered, BufReader};
73-
use dlt_core::parse::{dlt_message, DltParseError};
74-
use std::{env, fs, fs::File, io::BufRead, path::PathBuf, time::Instant};
75-
76-
const BIN_READER_CAPACITY: usize = 10 * 1024 * 1024;
77-
const BIN_MIN_BUFFER_SPACE: usize = 10 * 1024;
72+
use dlt_core::read::{parse_message, DltMessageReader};
73+
use std::{env, fs, fs::File, io::Read, path::PathBuf, time::Instant};
7874

7975
fn main() {
8076
// collect input file details
8177
let dlt_file_path = PathBuf::from(&env::args().nth(1).expect("No filename given"));
82-
let dlt_file = File::open(&dlt_file_path).expect("could not open file");
78+
let mut dlt_file = File::open(&dlt_file_path).expect("could not open file");
8379
let source_file_size = fs::metadata(&dlt_file_path).expect("file size error").len();
84-
// create a reader that maintains a minimum amount of bytes in it's buffer
85-
let mut reader = BufReader::with_capacity(BIN_READER_CAPACITY, dlt_file)
86-
.set_policy(MinBuffered(BIN_MIN_BUFFER_SPACE));
8780
// now parse all file content
81+
let mut contents = Vec::new(); // TODO temp!
82+
dlt_file
83+
.read_to_end(&mut contents)
84+
.expect("read file contents");
85+
let mut reader = DltMessageReader::new(contents.as_slice(), true);
8886
let mut parsed = 0usize;
8987
let start = Instant::now();
9088
loop {
91-
let consumed: usize = match reader.fill_buf() {
92-
Ok(content) => {
93-
if content.is_empty() {
94-
println!("empty content after {} parsed messages", parsed);
95-
break;
96-
}
97-
let available = content.len();
98-
99-
match dlt_message(content, None, true) {
100-
Ok((rest, _maybe_msg)) => {
101-
let consumed = available - rest.len();
102-
parsed += 1;
103-
consumed
104-
}
105-
Err(DltParseError::IncompleteParse { needed }) => {
106-
println!("parse incomplete, needed: {:?}", needed);
107-
return;
108-
}
109-
Err(DltParseError::ParsingHickup(reason)) => {
110-
println!("parse error: {}", reason);
111-
4 //skip 4 bytes
112-
}
113-
Err(DltParseError::Unrecoverable(cause)) => {
114-
println!("unrecoverable parse failure: {}", cause);
115-
return;
116-
}
117-
}
89+
match parse_message(&mut reader, None).expect("parse next dlt message") {
90+
Some(_message) => {
91+
parsed += 1;
11892
}
119-
Err(e) => {
120-
println!("Error reading: {}", e);
121-
return;
93+
None => {
94+
break;
12295
}
12396
};
124-
reader.consume(consumed);
12597
}
126-
12798
// print some stats
12899
let duration_in_s = start.elapsed().as_millis() as f64 / 1000.0;
129100
let file_size_in_mb = source_file_size as f64 / 1024.0 / 1024.0;
@@ -150,11 +121,13 @@ Below is the revised and improved English version of the documentation:
150121

151122
* **`statistics`**: Enables the `statistics` module, which scans the source data and provides a summary of its contents. This gives you an overview of the number of messages and their content.
152123

153-
* **`fibex_parser`**: Enables the `fibex` module, which allows to parse configurations for non-verbose messages from a fibex model.
124+
* **`fibex`**: Enables the `fibex` module, which allows to parse configurations for non-verbose messages from a fibex model.
125+
126+
* **`debug`**: Adds additional log output for debugging purposes.
154127

155-
* **`debug_parser`**: Adds additional log output for debugging purposes.
128+
* **`serialization`**: Adds `Serialize` and `Deserialize` implementations (via `serde`) to all public types. This feature is useful if you need to encode or decode these types for transmission or storage.
156129

157-
* **`serde-support`**: Adds `Serialize` and `Deserialize` implementations (via `serde`) to all public types. This feature is useful if you need to encode or decode these types for transmission or storage.
130+
* **`stream`**: Provides API for parsing DLT messages from streams.
158131

159132
## Example users
160133

examples/file_parser.rs

+13-42
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,29 @@
1-
use buf_redux::{policy::MinBuffered, BufReader};
2-
use dlt_core::parse::{dlt_message, DltParseError};
3-
use std::{env, fs, fs::File, io::BufRead, path::PathBuf, time::Instant};
4-
5-
const BIN_READER_CAPACITY: usize = 10 * 1024 * 1024;
6-
const BIN_MIN_BUFFER_SPACE: usize = 10 * 1024;
1+
use dlt_core::read::{parse_message, DltMessageReader};
2+
use std::{env, fs, fs::File, io::Read, path::PathBuf, time::Instant};
73

84
fn main() {
95
// collect input file details
106
let dlt_file_path = PathBuf::from(&env::args().nth(1).expect("No filename given"));
11-
let dlt_file = File::open(&dlt_file_path).expect("could not open file");
7+
let mut dlt_file = File::open(&dlt_file_path).expect("could not open file");
128
let source_file_size = fs::metadata(&dlt_file_path).expect("file size error").len();
13-
// create a reader that maintains a minimum amount of bytes in it's buffer
14-
let mut reader = BufReader::with_capacity(BIN_READER_CAPACITY, dlt_file)
15-
.set_policy(MinBuffered(BIN_MIN_BUFFER_SPACE));
169
// now parse all file content
10+
let mut contents = Vec::new(); // TODO temp!
11+
dlt_file
12+
.read_to_end(&mut contents)
13+
.expect("read file contents");
14+
let mut reader = DltMessageReader::new(contents.as_slice(), true);
1715
let mut parsed = 0usize;
1816
let start = Instant::now();
1917
loop {
20-
let consumed: usize = match reader.fill_buf() {
21-
Ok(content) => {
22-
if content.is_empty() {
23-
println!("empty content after {} parsed messages", parsed);
24-
break;
25-
}
26-
let available = content.len();
27-
28-
match dlt_message(content, None, true) {
29-
Ok((rest, _maybe_msg)) => {
30-
let consumed = available - rest.len();
31-
parsed += 1;
32-
consumed
33-
}
34-
Err(DltParseError::IncompleteParse { needed }) => {
35-
println!("parse incomplete, needed: {:?}", needed);
36-
return;
37-
}
38-
Err(DltParseError::ParsingHickup(reason)) => {
39-
println!("parse error: {}", reason);
40-
4 //skip 4 bytes
41-
}
42-
Err(DltParseError::Unrecoverable(cause)) => {
43-
println!("unrecoverable parse failure: {}", cause);
44-
return;
45-
}
46-
}
18+
match parse_message(&mut reader, None).expect("parse next dlt message") {
19+
Some(_message) => {
20+
parsed += 1;
4721
}
48-
Err(e) => {
49-
println!("Error reading: {}", e);
50-
return;
22+
None => {
23+
break;
5124
}
5225
};
53-
reader.consume(consumed);
5426
}
55-
5627
// print some stats
5728
let duration_in_s = start.elapsed().as_millis() as f64 / 1000.0;
5829
let file_size_in_mb = source_file_size as f64 / 1024.0 / 1024.0;

0 commit comments

Comments
 (0)