|
10 | 10 | //! A very simple serialization framework which is used to serialize/deserialize messages as well
|
11 | 11 | //! as ChannelsManagers and ChannelMonitors.
|
12 | 12 |
|
13 |
| -use std::io::{Read, Write}; |
| 13 | +use std::io::{Read, Write, Cursor}; |
14 | 14 | use std::collections::HashMap;
|
15 | 15 | use std::hash::Hash;
|
16 | 16 | use std::sync::Mutex;
|
@@ -62,6 +62,22 @@ impl Writer {
|
62 | 62 | pub fn len(&self) -> usize {
|
63 | 63 | self.0.len()
|
64 | 64 | }
|
| 65 | + |
| 66 | + /// Insert the length of a data slice before the slice start |
| 67 | + pub fn insert_length(&mut self, slice_start: usize, length_adjust: usize) -> Result<(), ::std::io::Error> { |
| 68 | + let slice_end = self.len(); |
| 69 | + let length = slice_end - slice_start + length_adjust; |
| 70 | + // Write the length after the slice, to check how many bytes |
| 71 | + BigSize(length as u64).write(self)?; |
| 72 | + let len_end = self.len(); |
| 73 | + let len_len = len_end - slice_end; |
| 74 | + // Shift the slice to make space for the length |
| 75 | + self.0.copy_within(slice_start..slice_end, slice_start + len_len); |
| 76 | + let mut cursor = Cursor::new(&mut self.0); |
| 77 | + cursor.set_position(slice_start as u64); |
| 78 | + // Write the length again at the right spot |
| 79 | + BigSize(length as u64).write_write(&mut cursor) |
| 80 | + } |
65 | 81 | }
|
66 | 82 |
|
67 | 83 | impl Write for Writer {
|
@@ -225,28 +241,34 @@ impl Readable for U48 {
|
225 | 241 | /// you're looking for an example of a variable-length integer to use for your own project, move
|
226 | 242 | /// along, this is a rather poor design.
|
227 | 243 | pub(crate) struct BigSize(pub u64);
|
228 |
| -impl Writeable for BigSize { |
229 |
| - #[inline] |
230 |
| - fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> { |
| 244 | +impl BigSize { |
| 245 | + pub fn write_write<W: Write>(&self, write: &mut W) -> Result<(), ::std::io::Error> { |
231 | 246 | match self.0 {
|
232 | 247 | 0...0xFC => {
|
233 |
| - (self.0 as u8).write(writer) |
| 248 | + write.write_all(&[self.0 as u8]) |
234 | 249 | },
|
235 | 250 | 0xFD...0xFFFF => {
|
236 |
| - 0xFDu8.write(writer)?; |
237 |
| - (self.0 as u16).write(writer) |
| 251 | + write.write_all(&[0xFDu8])?; |
| 252 | + write.write_all(&be16_to_array(self.0 as u16)) |
238 | 253 | },
|
239 | 254 | 0x10000...0xFFFFFFFF => {
|
240 |
| - 0xFEu8.write(writer)?; |
241 |
| - (self.0 as u32).write(writer) |
| 255 | + write.write_all(&[0xFEu8])?; |
| 256 | + write.write_all(&be32_to_array(self.0 as u32)) |
242 | 257 | },
|
243 | 258 | _ => {
|
244 |
| - 0xFFu8.write(writer)?; |
245 |
| - (self.0 as u64).write(writer) |
| 259 | + write.write_all(&[0xFFu8])?; |
| 260 | + write.write_all(&be64_to_array(self.0 as u64)) |
246 | 261 | },
|
247 | 262 | }
|
248 | 263 | }
|
249 | 264 | }
|
| 265 | + |
| 266 | +impl Writeable for BigSize { |
| 267 | + #[inline] |
| 268 | + fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> { |
| 269 | + self.write_write(writer) |
| 270 | + } |
| 271 | +} |
250 | 272 | impl Readable for BigSize {
|
251 | 273 | #[inline]
|
252 | 274 | fn read<R: Read>(reader: &mut R) -> Result<BigSize, DecodeError> {
|
@@ -609,10 +631,9 @@ impl<T: Writeable> Writeable for Option<T> {
|
609 | 631 | match *self {
|
610 | 632 | None => 0u8.write(w)?,
|
611 | 633 | Some(ref data) => {
|
612 |
| - let mut len_calc = Writer::new(); |
613 |
| - data.write(&mut len_calc).expect("No in-memory data may fail to serialize"); |
614 |
| - BigSize(len_calc.len() as u64 + 1).write(w)?; |
615 |
| - data.write(w)?; |
| 634 | + let start = w.len(); |
| 635 | + data.write(w).expect("No in-memory data may fail to serialize"); |
| 636 | + w.insert_length(start, 1)?; |
616 | 637 | }
|
617 | 638 | }
|
618 | 639 | Ok(())
|
|
0 commit comments