sandstone/protocol/serialization/
mod.rs

1//! This file defines the handlers for serialization and deserialization in the API.
2//! Information can be "serialized" from the original type into its raw bytes. This can then be
3//! sent in a packet over the network.
4//! Conversely, information can also be "deserialized" from raw bytes into the original type. This is useful
5//! for reading packets from the network.
6
7use std::cmp::min;
8
9use crate::protocol::packets::packet_definer::{PacketDirection, PacketState};
10use crate::protocol::serialization::serializer_error::SerializingErr;
11
12mod serializer_types;
13pub mod serializer_error;
14mod serializer_testing;
15
16/// The result of a serialization/deserialization operation.
17/// See [SerializingErr] for more information on the error types
18pub type SerializingResult<'a, T> = Result<T, SerializingErr>;
19
20/// Handles the serialization of any types that `impl McSerialize`. Holds an
21/// internal buffer representing the serialized data.
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct McSerializer {
24	pub output: Vec<u8>
25}
26
27impl McSerializer {
28	pub fn new() -> Self {
29		Self {
30			output: vec![]
31		}
32	}
33	
34	/// Initialize the size of the internal serializer buffer. If you plan on serializing a lot of small
35	/// items, then this should be used to avoid unnecessary reallocations.
36	pub fn init_size(size: usize) -> Self {
37		Self {
38			output: Vec::with_capacity(size)
39		}
40	}
41	
42	/// Set the size of the internal buffer. This will resize the buffer to the size specified.
43	/// The provided size must be greater than the current length of the buffer.
44	pub fn set_size(&mut self, size: usize) -> SerializingResult<()> {
45		if size < self.output.len() {
46			return Err(SerializingErr::UniqueFailure("Cannot set size to less than current length".to_string()));
47		}
48		
49		self.output.reserve(size);
50		
51		Ok(())
52	}
53
54	/// Clear the existing serialized data from the internal buffer
55	pub fn clear(&mut self) {
56		self.output.clear();
57	}
58
59	/// Add a slice of bytes to the internal buffer. Reallocates the buffer
60	/// for the new amount of space required before pushing.
61	pub fn serialize_bytes(&mut self, input: &[u8]) {
62		for b in input {
63			self.output.push(*b);
64		}
65	}
66
67	pub fn serialize_vec(&mut self, vec: Vec<u8>) {
68		self.serialize_bytes(&vec);
69	}
70
71	pub fn serialize_u8(&mut self, b: u8) {
72		self.output.push(b);
73	}
74
75	/// Serialized as is, NO LENGTH PREFIX
76	pub fn serialize_str_no_length_prefix(&mut self, s: &str) {
77		self.serialize_bytes(s.as_bytes());
78	}
79
80	pub fn get_last(&self) -> Option<&u8> {
81		self.output.last()
82	}
83
84	pub fn merge(&mut self, serializer: McSerializer) {
85		self.serialize_bytes(&serializer.output);
86	}
87}
88
89/// Helper for deserializing byte data into types that `impl McDeserialize`
90#[derive(Debug, Clone, PartialEq, Eq, Hash)]
91pub struct McDeserializer<'a> {
92	pub data: &'a [u8],
93	pub index: usize
94}
95
96impl <'a> McDeserializer<'a> {
97	pub fn new(data: &'a [u8]) -> Self {
98		Self {
99			data,
100			index: 0
101		}
102	}
103
104	/// Collect the remaining data into a sub-slice
105	pub fn collect_remaining(&self) -> &[u8] {
106		&self.data[self.index..]
107	}
108
109	/// Slice the internal buffer, starting at the current index and up to the bound provided. Will
110	/// cut off the subslice at max(data.len, bound + index) to prevent overflow
111	pub fn slice(&mut self, bound: usize) -> &[u8] {
112		let actual = min(self.data.len(), bound) + self.index;
113		let actual = min(actual, self.data.len());
114
115		let slice = &self.data[self.index..actual];
116		self.increment(slice.len());
117		slice
118	}
119
120	/// Slice the internal buffer, starting at the current index and up to the
121	/// bound provided, but only if it is within bounds
122	pub fn slice_option(&mut self, bound: usize) -> Option<&[u8]> {
123		if self.index + bound > self.data.len() {
124			return None;
125		}
126
127		let slice = &self.data[self.index..(self.index + bound)];
128		self.increment(bound);
129		Some(slice)
130	}
131
132	pub fn pop(&mut self) -> Option<u8> {
133		if self.index < self.data.len() {
134			let u = self.data[self.index];
135			self.increment(1);
136			Some(u)
137		} else {
138			None
139		}
140	}
141
142	/// Increment the index of this McDeserializer by the amount specified
143	pub fn increment(&mut self, amount: usize) {
144		self.index += amount;
145	}
146
147	/// Increment the index of this McDeserializer by the difference between the current index
148	/// and the provided index.
149	pub fn increment_by_diff(&mut self, other: usize) {
150		if other > self.index {
151			self.increment(other - self.index);
152		}
153	}
154
155	pub fn is_at_end(&self) -> bool {
156		self.index >= self.data.len()
157	}
158
159	pub fn reset(&mut self) {
160		self.index = 0;
161	}
162
163	/// Creates a new McDeserializer only including the remaining unused data.
164	/// Used in conjunction with reset()
165	pub fn create_sub_deserializer(&self) -> McDeserializer {
166		McDeserializer::new(&self.data[self.index..])
167	}
168
169	/// Create a new McDeserializer with a start at `index` and an end at `index + end`.
170	/// Basically reserves the number of bytes you specify for the sub-deserializer.
171	/// Also increments the parent McDeserializer's index by `end`
172	pub fn sub_deserializer_length(&mut self, end: usize) -> SerializingResult<McDeserializer> {
173		if self.index + end > self.data.len() {
174			return Err(SerializingErr::UniqueFailure("Sub-deserializer length exceeds data length".to_string()));
175		}
176
177		let ret = Ok(McDeserializer::new(&self.data[self.index..(self.index + end)]));
178
179		self.index += end;
180
181		ret
182	}
183}
184
185/// The standard deserializer used for most regular deserialization operations. Converts
186/// byte data into rust structs and primitive data types
187pub trait McDeserialize {
188	/// Deserialize the byte buffer into the type that implements this trait.
189	/// Note that if the byte buffer does not match the type you are trying to deserialize, or it does not
190	/// contain enough data then this will return an error.
191	fn mc_deserialize<'a>(deserializer: &'a mut McDeserializer) -> SerializingResult<'a, Self> where Self: Sized;
192}
193
194/// Deserialize data given the current packet state and the packet id. This is needed since
195/// the packet id is not enough to determine the packet type in some cases.
196/// (ie. Both STATUS and HANDSHAKING states have a packet with ID 0)
197pub trait StateBasedDeserializer {
198	/// Deserialize the byte buffer into a 'Packet'. This takes 2 extra arguments, the packet state and the 
199	/// direction of the packet to narrow down the exact packet that should be deserialized.
200	fn deserialize_state<'a>(deserializer: &'a mut McDeserializer, state: PacketState, packet_direction: PacketDirection) -> SerializingResult<'a, Self> where Self: Sized;
201}
202
203/// Implement this on a type to enable serializing it into a byte buffer. All types that will be sent
204/// or received from the network must implement this type.
205pub trait McSerialize {
206	/// Serialize the type that implements this trait into a byte buffer. This enables the struct
207	/// to be sent over the Minecraft network.
208	fn mc_serialize(&self, serializer: &mut McSerializer) -> SerializingResult<()>;
209}