|
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,25 @@ 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 | + self.0.resize(slice_end, 0); |
| 75 | + // Shift the slice to make space for the length |
| 76 | + for _ in 0 .. len_len { |
| 77 | + self.0.insert(slice_start, 0); |
| 78 | + } |
| 79 | + let mut cursor = Cursor::new(&mut self.0); |
| 80 | + cursor.set_position(slice_start as u64); |
| 81 | + // Write the length again at the right spot |
| 82 | + BigSize(length as u64).write_write(&mut cursor) |
| 83 | + } |
65 | 84 | }
|
66 | 85 |
|
67 | 86 | impl Write for Writer {
|
@@ -225,28 +244,34 @@ impl Readable for U48 {
|
225 | 244 | /// you're looking for an example of a variable-length integer to use for your own project, move
|
226 | 245 | /// along, this is a rather poor design.
|
227 | 246 | pub(crate) struct BigSize(pub u64);
|
228 |
| -impl Writeable for BigSize { |
229 |
| - #[inline] |
230 |
| - fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> { |
| 247 | +impl BigSize { |
| 248 | + pub fn write_write<W: Write>(&self, write: &mut W) -> Result<(), ::std::io::Error> { |
231 | 249 | match self.0 {
|
232 | 250 | 0...0xFC => {
|
233 |
| - (self.0 as u8).write(writer) |
| 251 | + write.write_all(&[self.0 as u8]) |
234 | 252 | },
|
235 | 253 | 0xFD...0xFFFF => {
|
236 |
| - 0xFDu8.write(writer)?; |
237 |
| - (self.0 as u16).write(writer) |
| 254 | + write.write_all(&[0xFDu8])?; |
| 255 | + write.write_all(&be16_to_array(self.0 as u16)) |
238 | 256 | },
|
239 | 257 | 0x10000...0xFFFFFFFF => {
|
240 |
| - 0xFEu8.write(writer)?; |
241 |
| - (self.0 as u32).write(writer) |
| 258 | + write.write_all(&[0xFEu8])?; |
| 259 | + write.write_all(&be32_to_array(self.0 as u32)) |
242 | 260 | },
|
243 | 261 | _ => {
|
244 |
| - 0xFFu8.write(writer)?; |
245 |
| - (self.0 as u64).write(writer) |
| 262 | + write.write_all(&[0xFFu8])?; |
| 263 | + write.write_all(&be64_to_array(self.0 as u64)) |
246 | 264 | },
|
247 | 265 | }
|
248 | 266 | }
|
249 | 267 | }
|
| 268 | + |
| 269 | +impl Writeable for BigSize { |
| 270 | + #[inline] |
| 271 | + fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> { |
| 272 | + self.write_write(writer) |
| 273 | + } |
| 274 | +} |
250 | 275 | impl Readable for BigSize {
|
251 | 276 | #[inline]
|
252 | 277 | fn read<R: Read>(reader: &mut R) -> Result<BigSize, DecodeError> {
|
@@ -609,10 +634,9 @@ impl<T: Writeable> Writeable for Option<T> {
|
609 | 634 | match *self {
|
610 | 635 | None => 0u8.write(w)?,
|
611 | 636 | 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)?; |
| 637 | + let start = w.len(); |
| 638 | + data.write(w).expect("No in-memory data may fail to serialize"); |
| 639 | + w.insert_length(start, 1)?; |
616 | 640 | }
|
617 | 641 | }
|
618 | 642 | Ok(())
|
|
0 commit comments