pub struct Decoder<R: Read> {
pub library_registry: HashMap<i32, String>,
pub offset: usize,
/* private fields */
}Expand description
A decoder for MS-NRBF binary streams.
Fields§
§library_registry: HashMap<i32, String>Registry of libraries by ID.
offset: usizeCurrent offset in the stream.
Implementations§
Source§impl<R: Read> Decoder<R>
impl<R: Read> Decoder<R>
Sourcepub fn new(reader: R) -> Self
pub fn new(reader: R) -> Self
Creates a new decoder from a reader.
Examples found in repository?
examples/parse_meta.rs (line 32)
23fn main() -> Result<(), Box<dyn std::error::Error>> {
24 let args: Vec<String> = env::args().collect();
25 if args.len() < 2 {
26 eprintln!("Usage: {} <nrbf_file> [output_json]", args[0]);
27 std::process::exit(1);
28 }
29
30 let file = File::open(&args[1])?;
31 let reader = BufReader::new(file);
32 let mut decoder = Decoder::new(reader);
33
34 let mut records = Vec::new();
35 while let Some(record) = decoder.decode_next()? {
36 records.push(record);
37 if let Record::MessageEnd = records.last().unwrap() {
38 break;
39 }
40 }
41
42 let output_path = args.get(2).map(|s| s.as_str()).unwrap_or("output.json");
43 let json = serde_json::to_string_pretty(&records)?;
44
45 let mut out_file = File::create(output_path)?;
46 out_file.write_all(json.as_bytes())?;
47
48 println!(
49 "Successfully parsed {} records and saved to {}",
50 records.len(),
51 output_path
52 );
53
54 Ok(())
55}More examples
examples/round_trip.rs (line 38)
24fn main() -> Result<(), Box<dyn std::error::Error>> {
25 let args: Vec<String> = env::args().collect();
26 if args.len() < 2 {
27 eprintln!("Usage: {} <nrbf_file>", args[0]);
28 std::process::exit(1);
29 }
30
31 let input_path = &args[1];
32 println!("Reading original file: {}", input_path);
33 let file = File::open(input_path)?;
34 let mut original_data = Vec::new();
35 File::open(input_path)?.read_to_end(&mut original_data)?;
36
37 let reader = BufReader::new(file);
38 let mut decoder = Decoder::new(reader);
39
40 let mut records = Vec::new();
41 while let Some(record) = decoder.decode_next()? {
42 let is_end = matches!(record, Record::MessageEnd);
43 records.push(record);
44 if is_end {
45 break;
46 }
47 }
48 println!("Parsed {} records.", records.len());
49
50 // Serialize to JSON
51 let json = serde_json::to_string_pretty(&records)?;
52 let json_path = "output.json";
53 std::fs::write(json_path, &json)?;
54 println!("Saved records to {}", json_path);
55
56 // Deserialize from JSON
57 let deserialized_records: Vec<Record> = serde_json::from_str(&json)?;
58 println!(
59 "Deserialized {} records from JSON.",
60 deserialized_records.len()
61 );
62
63 // Encode back to binary
64 let output_path = "reconstructed.meta";
65 let out_file = File::create(output_path)?;
66 let mut encoder = Encoder::new(BufWriter::new(out_file));
67
68 for record in &deserialized_records {
69 encoder.encode(record)?;
70 }
71 // Ensure everything is flushed
72 drop(encoder);
73 println!("Reconstructed binary saved to {}", output_path);
74
75 // Compare
76 let mut reconstructed_data = Vec::new();
77 File::open(output_path)?.read_to_end(&mut reconstructed_data)?;
78
79 if original_data == reconstructed_data {
80 println!("SUCCESS: Reconstructed binary is identical to original!");
81 } else {
82 println!("FAILURE: Reconstructed binary differs from original.");
83 println!(
84 "Original size: {}, Reconstructed size: {}",
85 original_data.len(),
86 reconstructed_data.len()
87 );
88
89 // Find first difference
90 let min_len = std::cmp::min(original_data.len(), reconstructed_data.len());
91 for i in 0..min_len {
92 if original_data[i] != reconstructed_data[i] {
93 println!(
94 "First difference at offset 0x{:x}: original 0x{:02x}, reconstructed 0x{:02x}",
95 i, original_data[i], reconstructed_data[i]
96 );
97 break;
98 }
99 }
100 }
101
102 Ok(())
103}Sourcepub fn decode_next(&mut self) -> Result<Option<Record>>
pub fn decode_next(&mut self) -> Result<Option<Record>>
Decodes the next record from the stream.
Returns Ok(Some(record)) if a record was successfully read,
Ok(None) if the end of the stream was reached,
or an Err if parsing failed.
Examples found in repository?
examples/parse_meta.rs (line 35)
23fn main() -> Result<(), Box<dyn std::error::Error>> {
24 let args: Vec<String> = env::args().collect();
25 if args.len() < 2 {
26 eprintln!("Usage: {} <nrbf_file> [output_json]", args[0]);
27 std::process::exit(1);
28 }
29
30 let file = File::open(&args[1])?;
31 let reader = BufReader::new(file);
32 let mut decoder = Decoder::new(reader);
33
34 let mut records = Vec::new();
35 while let Some(record) = decoder.decode_next()? {
36 records.push(record);
37 if let Record::MessageEnd = records.last().unwrap() {
38 break;
39 }
40 }
41
42 let output_path = args.get(2).map(|s| s.as_str()).unwrap_or("output.json");
43 let json = serde_json::to_string_pretty(&records)?;
44
45 let mut out_file = File::create(output_path)?;
46 out_file.write_all(json.as_bytes())?;
47
48 println!(
49 "Successfully parsed {} records and saved to {}",
50 records.len(),
51 output_path
52 );
53
54 Ok(())
55}More examples
examples/round_trip.rs (line 41)
24fn main() -> Result<(), Box<dyn std::error::Error>> {
25 let args: Vec<String> = env::args().collect();
26 if args.len() < 2 {
27 eprintln!("Usage: {} <nrbf_file>", args[0]);
28 std::process::exit(1);
29 }
30
31 let input_path = &args[1];
32 println!("Reading original file: {}", input_path);
33 let file = File::open(input_path)?;
34 let mut original_data = Vec::new();
35 File::open(input_path)?.read_to_end(&mut original_data)?;
36
37 let reader = BufReader::new(file);
38 let mut decoder = Decoder::new(reader);
39
40 let mut records = Vec::new();
41 while let Some(record) = decoder.decode_next()? {
42 let is_end = matches!(record, Record::MessageEnd);
43 records.push(record);
44 if is_end {
45 break;
46 }
47 }
48 println!("Parsed {} records.", records.len());
49
50 // Serialize to JSON
51 let json = serde_json::to_string_pretty(&records)?;
52 let json_path = "output.json";
53 std::fs::write(json_path, &json)?;
54 println!("Saved records to {}", json_path);
55
56 // Deserialize from JSON
57 let deserialized_records: Vec<Record> = serde_json::from_str(&json)?;
58 println!(
59 "Deserialized {} records from JSON.",
60 deserialized_records.len()
61 );
62
63 // Encode back to binary
64 let output_path = "reconstructed.meta";
65 let out_file = File::create(output_path)?;
66 let mut encoder = Encoder::new(BufWriter::new(out_file));
67
68 for record in &deserialized_records {
69 encoder.encode(record)?;
70 }
71 // Ensure everything is flushed
72 drop(encoder);
73 println!("Reconstructed binary saved to {}", output_path);
74
75 // Compare
76 let mut reconstructed_data = Vec::new();
77 File::open(output_path)?.read_to_end(&mut reconstructed_data)?;
78
79 if original_data == reconstructed_data {
80 println!("SUCCESS: Reconstructed binary is identical to original!");
81 } else {
82 println!("FAILURE: Reconstructed binary differs from original.");
83 println!(
84 "Original size: {}, Reconstructed size: {}",
85 original_data.len(),
86 reconstructed_data.len()
87 );
88
89 // Find first difference
90 let min_len = std::cmp::min(original_data.len(), reconstructed_data.len());
91 for i in 0..min_len {
92 if original_data[i] != reconstructed_data[i] {
93 println!(
94 "First difference at offset 0x{:x}: original 0x{:02x}, reconstructed 0x{:02x}",
95 i, original_data[i], reconstructed_data[i]
96 );
97 break;
98 }
99 }
100 }
101
102 Ok(())
103}Auto Trait Implementations§
impl<R> Freeze for Decoder<R>where
R: Freeze,
impl<R> RefUnwindSafe for Decoder<R>where
R: RefUnwindSafe,
impl<R> Send for Decoder<R>where
R: Send,
impl<R> Sync for Decoder<R>where
R: Sync,
impl<R> Unpin for Decoder<R>where
R: Unpin,
impl<R> UnwindSafe for Decoder<R>where
R: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more