epee_encoding/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2//! Epee Encoding
3//!
4//! This library contains the Epee binary format found in Monero, unlike other
5//! crates this crate does not use serde.
6//!
7//! example without derive:
8//! ```rust
9//! use epee_encoding::{EpeeObject, EpeeObjectBuilder, read_epee_value, write_field, to_bytes, from_bytes};
10//! use epee_encoding::io::{Read, Write};
11//!
12//! pub struct Test {
13//!     val: u64
14//! }
15//!
16//! #[derive(Default)]
17//! pub struct __TestEpeeBuilder {
18//!     val: Option<u64>,
19//! }
20//!
21//! impl EpeeObjectBuilder<Test> for __TestEpeeBuilder {
22//!     fn add_field<R: Read>(&mut self, name: &str, r: &mut R) -> epee_encoding::error::Result<bool> {
23//!         match name {
24//!             "val" => {self.val = Some(read_epee_value(r)?);}
25//!             _ => return Ok(false),
26//!         }
27//!         Ok(true)
28//!     }
29//!
30//!     fn finish(self) -> epee_encoding::error::Result<Test> {
31//!         Ok(
32//!             Test {
33//!                 val: self.val.ok_or_else(|| epee_encoding::error::Error::Format("Required field was not found!"))?
34//!             }
35//!         )
36//!     }
37//! }
38//!
39//! impl EpeeObject for Test {
40//!     type Builder = __TestEpeeBuilder;
41//!
42//!     fn number_of_fields(&self) -> u64 {
43//!         1
44//!     }
45//!
46//!     fn write_fields<W: Write>(&self, w: &mut W) -> epee_encoding::error::Result<()> {
47//!        // write the fields
48//!        write_field(&self.val, "val", w)
49//!    }
50//! }
51//!
52//!
53//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
54//! let val: Test = from_bytes(&data).unwrap();
55//! let data = to_bytes(&val).unwrap();
56//!
57//!
58//! ```
59//!
60//! example with derive:
61//! ```ignore
62//! use epee_encoding::{EpeeObject, from_bytes, to_bytes};
63//!
64//! #[derive(EpeeObject)]
65//! struct Test2 {
66//!     val: u64
67//! }
68//!
69//!
70//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
71//! let val: Test2 = from_bytes(&data).unwrap();
72//! let data = to_bytes(&val).unwrap();
73//!
74//! ```
75
76extern crate alloc;
77
78use alloc::string::String;
79use alloc::vec::Vec;
80
81pub mod error;
82pub mod io;
83pub mod marker;
84mod value;
85mod varint;
86
87#[cfg(feature = "derive")]
88pub use epee_encoding_derive::EpeeObject;
89
90pub use error::*;
91use io::*;
92pub use marker::{InnerMarker, Marker};
93pub use value::EpeeValue;
94use varint::*;
95
96/// Header that needs to be at the beginning of every binary blob that follows
97/// this binary serialization format.
98const HEADER: &[u8] = b"\x01\x11\x01\x01\x01\x01\x02\x01\x01";
99/// The maximum length a byte array (marked as a string) can be.
100const MAX_STRING_LEN_POSSIBLE: u64 = 2000000000;
101/// The maximum depth of skipped objects.
102const MAX_DEPTH_OF_SKIPPED_OBJECTS: u8 = 20;
103/// The maximum number of fields in an object.
104const MAX_NUM_FIELDS: u64 = 1000;
105
106/// A trait for an object that can build a type `T` from the epee format.
107pub trait EpeeObjectBuilder<T>: Default + Sized {
108    /// Called when a field names has been read no other bytes following the field
109    /// name will have been read.
110    ///
111    /// Returns a bool if true then the field has been read otherwise the field is not
112    /// needed and has not been read.
113    fn add_field<R: Read>(&mut self, name: &str, r: &mut R) -> Result<bool>;
114
115    /// Called when the number of fields has been read.
116    fn finish(self) -> Result<T>;
117}
118
119/// A trait for an object that can be turned into epee bytes.
120pub trait EpeeObject: Sized {
121    type Builder: EpeeObjectBuilder<Self>;
122
123    /// Returns the number of fields to be encoded.
124    fn number_of_fields(&self) -> u64;
125
126    /// write the objects fields into the writer.
127    fn write_fields<W: Write>(&self, w: &mut W) -> Result<()>;
128}
129
130/// Read the object `T` from a byte array.
131pub fn from_bytes<T: EpeeObject>(mut buf: &[u8]) -> Result<T> {
132    read_head_object(&mut buf)
133}
134
135/// Turn the object into epee bytes.
136pub fn to_bytes<T: EpeeObject>(val: &T) -> Result<Vec<u8>> {
137    let mut buf = Vec::<u8>::new();
138    write_head_object(val, &mut buf)?;
139    Ok(buf)
140}
141
142fn read_header<R: Read>(r: &mut R) -> Result<()> {
143    let mut buf = [0; 9];
144    r.read_exact(&mut buf)?;
145    if buf != HEADER {
146        return Err(Error::Format("Data does not contain header"));
147    }
148    Ok(())
149}
150
151fn write_header<W: Write>(w: &mut W) -> Result<()> {
152    w.write_all(HEADER)
153}
154
155fn write_head_object<T: EpeeObject, W: Write>(val: &T, w: &mut W) -> Result<()> {
156    write_header(w)?;
157    val.write(w)
158}
159
160fn read_head_object<T: EpeeObject, R: Read>(r: &mut R) -> Result<T> {
161    read_header(r)?;
162    let mut skipped_objects = 0;
163    read_object(r, &mut skipped_objects)
164}
165
166fn read_field_name<R: Read>(r: &mut R) -> Result<String> {
167    let len = read_byte(r)?;
168    read_string(r, len.into())
169}
170
171fn write_field_name<W: Write>(val: &str, w: &mut W) -> Result<()> {
172    w.write(&[val.len().try_into()?])?;
173    w.write_all(val.as_bytes())
174}
175
176/// Write an epee field.
177pub fn write_field<T: EpeeValue, W: Write>(val: &T, field_name: &str, w: &mut W) -> Result<()> {
178    if val.should_write() {
179        write_field_name(field_name, w)?;
180        write_epee_value(val, w)?;
181    }
182    Ok(())
183}
184
185fn read_object<T: EpeeObject, R: Read>(r: &mut R, skipped_objects: &mut u8) -> Result<T> {
186    let mut object_builder = T::Builder::default();
187
188    let number_o_field = read_varint(r)?;
189
190    if number_o_field > MAX_NUM_FIELDS {
191        return Err(Error::Format(
192            "Data has object with more fields than the maximum allowed",
193        ));
194    }
195
196    for _ in 0..number_o_field {
197        let field_name = read_field_name(r)?;
198
199        if !object_builder.add_field(&field_name, r)? {
200            skip_epee_value(r, skipped_objects)?;
201        }
202    }
203    object_builder.finish()
204}
205
206/// Read a marker from the [`Read`], this function should only be used for
207/// custom serialisation based on the marker otherwise just use [`read_epee_value`].
208pub fn read_marker<R: Read>(r: &mut R) -> Result<Marker> {
209    Marker::try_from(read_byte(r)?)
210}
211
212/// Read an epee value from the stream, an epee value is the part after the key
213/// including the marker.
214pub fn read_epee_value<T: EpeeValue, R: Read>(r: &mut R) -> Result<T> {
215    let marker = read_marker(r)?;
216    T::read(r, &marker)
217}
218
219/// Write an epee value to the stream, an epee value is the part after the key
220/// including the marker.
221fn write_epee_value<T: EpeeValue, W: Write>(val: &T, w: &mut W) -> Result<()> {
222    w.write_all(&[T::MARKER.as_u8()])?;
223    val.write(w)
224}
225
226/// A helper object builder that just skips every field.
227#[derive(Default)]
228struct SkipObjectBuilder;
229
230impl EpeeObjectBuilder<SkipObject> for SkipObjectBuilder {
231    fn add_field<R: Read>(&mut self, _name: &str, _r: &mut R) -> Result<bool> {
232        Ok(false)
233    }
234
235    fn finish(self) -> Result<SkipObject> {
236        Ok(SkipObject)
237    }
238}
239
240/// A helper object that just skips every field.
241struct SkipObject;
242
243impl EpeeObject for SkipObject {
244    type Builder = SkipObjectBuilder;
245
246    fn number_of_fields(&self) -> u64 {
247        panic!("This is a helper function to use when de-serialising")
248    }
249
250    fn write_fields<W: Write>(&self, _w: &mut W) -> Result<()> {
251        panic!("This is a helper function to use when de-serialising")
252    }
253}
254
255/// Skip an epee value, should be used when you do not need the value
256/// stored at a key.
257fn skip_epee_value<R: Read>(r: &mut R, skipped_objects: &mut u8) -> Result<()> {
258    let marker = read_marker(r)?;
259    let mut len = 1;
260    if marker.is_seq {
261        len = read_varint(r)?;
262    }
263    for _ in 0..len {
264        match marker.inner_marker {
265            InnerMarker::I64 | InnerMarker::U64 | InnerMarker::F64 => {
266                read_bytes::<_, 8>(r)?;
267            }
268            InnerMarker::I32 | InnerMarker::U32 => {
269                read_bytes::<_, 4>(r)?;
270            }
271            InnerMarker::I16 | InnerMarker::U16 => {
272                read_bytes::<_, 2>(r)?;
273            }
274            InnerMarker::I8 | InnerMarker::U8 | InnerMarker::Bool => {
275                read_bytes::<_, 1>(r)?;
276            }
277            InnerMarker::String => {
278                Vec::<u8>::read(r, &marker)?;
279            }
280            InnerMarker::Object => {
281                *skipped_objects += 1;
282                if *skipped_objects > MAX_DEPTH_OF_SKIPPED_OBJECTS {
283                    return Err(Error::Format("Depth of skipped objects exceeded maximum"));
284                }
285                read_object::<SkipObject, _>(r, skipped_objects)?;
286                *skipped_objects -= 1;
287            }
288        };
289    }
290    Ok(())
291}