codec.rs 44.4 KB
Newer Older
1
// Copyright 2017-2018 Parity Technologies
Gav's avatar
Stuff.    
Gav committed
2
3
4
5
6
7
8
9
10
11
12
13
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Gav Wood's avatar
Gav Wood committed
14
15
16

//! Serialisation.

17
use core::fmt;
pscott's avatar
pscott committed
18
use core::{mem, ops::Deref, marker::PhantomData, iter::FromIterator, convert::TryFrom, time::Duration};
19
20
21
22
23
24
25
26
27
28
29
30
use core::num::{
	NonZeroI8,
	NonZeroI16,
	NonZeroI32,
	NonZeroI64,
	NonZeroI128,
	NonZeroU8,
	NonZeroU16,
	NonZeroU32,
	NonZeroU64,
	NonZeroU128,
};
Qinxuan Chen's avatar
Qinxuan Chen committed
31
use arrayvec::ArrayVec;
32

33
use byte_slice_cast::{AsByteSlice, AsMutByteSlice, ToMutByteSlice};
34

Hero Bird's avatar
Hero Bird committed
35
#[cfg(any(feature = "std", feature = "full"))]
36
use crate::alloc::{
Hero Bird's avatar
Hero Bird committed
37
	string::String,
38
39
	sync::Arc,
	rc::Rc,
Hero Bird's avatar
Hero Bird committed
40
};
Qinxuan Chen's avatar
Qinxuan Chen committed
41
42
43
use crate::alloc::{
	vec::Vec,
	boxed::Box,
44
	borrow::{Cow, ToOwned},
Qinxuan Chen's avatar
Qinxuan Chen committed
45
46
47
48
49
50
	collections::{
		BTreeMap, BTreeSet, VecDeque, LinkedList, BinaryHeap
	}
};
use crate::compact::Compact;
use crate::encode_like::EncodeLike;
51

52
pub(crate) const MAX_PREALLOCATION: usize = 4 * 1024;
pscott's avatar
pscott committed
53
const A_BILLION: u32 = 1_000_000_000;
54

55
/// Descriptive error type
56
#[cfg(feature = "std")]
57
#[derive(PartialEq, Eq, Clone, Debug)]
58
59
pub struct Error(&'static str);

60
/// Undescriptive error type when compiled for no std
61
#[cfg(not(feature = "std"))]
62
#[derive(PartialEq, Eq, Clone, Debug)]
63
64
65
66
pub struct Error;

impl Error {
	#[cfg(feature = "std")]
67
68
69
70
	/// Error description
	///
	/// This function returns an actual error str when running in `std`
	/// environment, but `""` on `no_std`.
71
72
73
74
75
	pub fn what(&self) -> &'static str {
		self.0
	}

	#[cfg(not(feature = "std"))]
76
77
78
79
	/// Error description
	///
	/// This function returns an actual error str when running in `std`
	/// environment, but `""` on `no_std`.
80
81
82
83
84
85
	pub fn what(&self) -> &'static str {
		""
	}
}

#[cfg(feature = "std")]
86
impl fmt::Display for Error {
87
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88
89
		write!(f, "{}", self.0)
	}
90
91
}

92
93
94
95
96
97
98
#[cfg(not(feature = "std"))]
impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.write_str("Error")
	}
}

99
100
101
102
103
104
105
106
107
108
#[cfg(feature = "std")]
impl std::error::Error for Error {
	fn description(&self) -> &str {
		self.0
	}
}

impl From<&'static str> for Error {
	#[cfg(feature = "std")]
	fn from(s: &'static str) -> Error {
109
		Error(s)
110
111
112
113
	}

	#[cfg(not(feature = "std"))]
	fn from(_s: &'static str) -> Error {
114
		Error
115
116
117
	}
}

Gav Wood's avatar
Gav Wood committed
118
119
/// Trait that allows reading of data into a slice.
pub trait Input {
thiolliere's avatar
thiolliere committed
120
121
122
123
124
125
126
	/// Should return the remaining length of the input data. If no information about the input
	/// length is available, `None` should be returned.
	///
	/// The length is used to constrain the preallocation while decoding. Returning a garbage
	/// length can open the doors for a denial of service attack to your application.
	/// Otherwise, returning `None` can decrease the performance of your application.
	fn remaining_len(&mut self) -> Result<Option<usize>, Error>;
127

thiolliere's avatar
thiolliere committed
128
	/// Read the exact number of bytes required to fill the given buffer.
129
	///
thiolliere's avatar
thiolliere committed
130
131
132
	/// Note that this function is similar to `std::io::Read::read_exact` and not
	/// `std::io::Read::read`.
	fn read(&mut self, into: &mut [u8]) -> Result<(), Error>;
Gav Wood's avatar
Gav Wood committed
133
134

	/// Read a single byte from the input.
135
	fn read_byte(&mut self) -> Result<u8, Error> {
Gav Wood's avatar
Gav Wood committed
136
		let mut buf = [0u8];
137
138
		self.read(&mut buf[..])?;
		Ok(buf[0])
Gav Wood's avatar
Gav Wood committed
139
	}
140
141
142
143
144
145
146
147
148
149
150
151

	/// Descend into nested reference when decoding.
	/// This is called when decoding a new refence-based instance,
	/// such as `Vec` or `Box`. Currently all such types are
	/// allocated on the heap.
	fn descend_ref(&mut self) -> Result<(), Error> {
		Ok(())
	}

	/// Ascend to previous structure level when decoding.
	/// This is called when decoding reference-based type is finished.
	fn ascend_ref(&mut self) {}
Gav Wood's avatar
Gav Wood committed
152
153
154
}

impl<'a> Input for &'a [u8] {
thiolliere's avatar
thiolliere committed
155
156
	fn remaining_len(&mut self) -> Result<Option<usize>, Error> {
		Ok(Some(self.len()))
157
158
	}

thiolliere's avatar
thiolliere committed
159
	fn read(&mut self, into: &mut [u8]) -> Result<(), Error> {
160
		if into.len() > self.len() {
thiolliere's avatar
thiolliere committed
161
			return Err("Not enough data to fill buffer".into());
162
		}
thiolliere's avatar
thiolliere committed
163
164
		let len = into.len();
		into.copy_from_slice(&self[..len]);
Gav Wood's avatar
Gav Wood committed
165
		*self = &self[len..];
thiolliere's avatar
thiolliere committed
166
		Ok(())
167
168
169
170
171
	}
}

#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	fn from(err: std::io::Error) -> Self {
		use std::io::ErrorKind::*;
		match err.kind() {
			NotFound => "io error: NotFound".into(),
			PermissionDenied => "io error: PermissionDenied".into(),
			ConnectionRefused => "io error: ConnectionRefused".into(),
			ConnectionReset => "io error: ConnectionReset".into(),
			ConnectionAborted => "io error: ConnectionAborted".into(),
			NotConnected => "io error: NotConnected".into(),
			AddrInUse => "io error: AddrInUse".into(),
			AddrNotAvailable => "io error: AddrNotAvailable".into(),
			BrokenPipe => "io error: BrokenPipe".into(),
			AlreadyExists => "io error: AlreadyExists".into(),
			WouldBlock => "io error: WouldBlock".into(),
			InvalidInput => "io error: InvalidInput".into(),
			InvalidData => "io error: InvalidData".into(),
			TimedOut => "io error: TimedOut".into(),
			WriteZero => "io error: WriteZero".into(),
			Interrupted => "io error: Interrupted".into(),
			Other => "io error: Other".into(),
			UnexpectedEof => "io error: UnexpectedEof".into(),
193
			_ => "io error: Unknown".into(),
194
		}
Gav Wood's avatar
Gav Wood committed
195
196
197
	}
}

198
/// Wrapper that implements Input for any `Read` type.
199
#[cfg(feature = "std")]
200
pub struct IoReader<R: std::io::Read>(pub R);
201

Gav Wood's avatar
Gav Wood committed
202
#[cfg(feature = "std")]
203
impl<R: std::io::Read> Input for IoReader<R> {
thiolliere's avatar
thiolliere committed
204
	fn remaining_len(&mut self) -> Result<Option<usize>, Error> {
205
		Ok(None)
206
207
	}

thiolliere's avatar
thiolliere committed
208
	fn read(&mut self, into: &mut [u8]) -> Result<(), Error> {
209
		self.0.read_exact(into).map_err(Into::into)
Gav Wood's avatar
Gav Wood committed
210
211
212
213
214
215
216
217
	}
}

/// Trait that allows writing of data.
pub trait Output: Sized {
	/// Write to the output.
	fn write(&mut self, bytes: &[u8]);

218
	/// Write a single byte to the output.
Gav Wood's avatar
Gav Wood committed
219
220
221
222
	fn push_byte(&mut self, byte: u8) {
		self.write(&[byte]);
	}

223
	/// Write encoding of given value to the output.
Gav Wood's avatar
Gav Wood committed
224
225
226
227
228
229
230
231
	fn push<V: Encode + ?Sized>(&mut self, value: &V) {
		value.encode_to(self);
	}
}

#[cfg(not(feature = "std"))]
impl Output for Vec<u8> {
	fn write(&mut self, bytes: &[u8]) {
232
		self.extend_from_slice(bytes)
Gav Wood's avatar
Gav Wood committed
233
234
235
236
	}
}

#[cfg(feature = "std")]
237
impl<W: std::io::Write> Output for W {
Gav Wood's avatar
Gav Wood committed
238
	fn write(&mut self, bytes: &[u8]) {
239
		(self as &mut dyn std::io::Write).write_all(bytes).expect("Codec outputs are infallible");
Gav Wood's avatar
Gav Wood committed
240
241
242
	}
}

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

/// !INTERNAL USE ONLY!
///
/// This enum provides type information to optimize encoding/decoding by doing fake specialization.
#[doc(hidden)]
#[non_exhaustive]
pub enum TypeInfo {
	/// Default value of [`Encode::TYPE_INFO`] to not require implementors to set this value in the trait.
	Unknown,
	U8,
	I8,
	U16,
	I16,
	U32,
	I32,
	U64,
	I64,
	U128,
	I128,
262
263
}

Gav Wood's avatar
Gav Wood committed
264
/// Trait that allows zero-copy write of value-references to slices in LE format.
265
266
267
///
/// Implementations should override `using_encoded` for value types and `encode_to` and `size_hint` for allocating types.
/// Wrapper types should override all methods.
Gav Wood's avatar
Gav Wood committed
268
pub trait Encode {
269
270
	// !INTERNAL USE ONLY!
	// This const helps SCALE to optimize the encoding/decoding by doing fake specialization.
271
	#[doc(hidden)]
272
	const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
273

274
275
276
277
278
279
280
281
	/// If possible give a hint of expected size of the encoding.
	///
	/// This method is used inside default implementation of `encode`
	/// to avoid re-allocations.
	fn size_hint(&self) -> usize {
		0
	}

Gav Wood's avatar
Gav Wood committed
282
283
284
285
286
287
288
	/// Convert self to a slice and append it to the destination.
	fn encode_to<T: Output>(&self, dest: &mut T) {
		self.using_encoded(|buf| dest.write(buf));
	}

	/// Convert self to an owned vector.
	fn encode(&self) -> Vec<u8> {
289
		let mut r = Vec::with_capacity(self.size_hint());
Gav Wood's avatar
Gav Wood committed
290
291
292
293
294
295
296
297
298
299
		self.encode_to(&mut r);
		r
	}

	/// Convert self to a slice and then invoke the given closure with it.
	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
		f(&self.encode())
	}
}

300
301
302
303
/// Trait that allows the length of a collection to be read, without having
/// to read and decode the entire elements.
pub trait DecodeLength {
	/// Return the number of elements in `self_encoded`.
304
	fn len(self_encoded: &[u8]) -> Result<usize, Error>;
305
306
}

Gav Wood's avatar
Gav Wood committed
307
308
/// Trait that allows zero-copy read of value-references from slices in LE format.
pub trait Decode: Sized {
309
310
	// !INTERNAL USE ONLY!
	// This const helps SCALE to optimize the encoding/decoding by doing fake specialization.
311
	#[doc(hidden)]
312
	const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
313

Gav Wood's avatar
Gav Wood committed
314
	/// Attempt to deserialise the value from input.
315
	fn decode<I: Input>(value: &mut I) -> Result<Self, Error>;
Gav Wood's avatar
Gav Wood committed
316
317
318
319
}

/// Trait that allows zero-copy read/write of value-references to/from slices in LE format.
pub trait Codec: Decode + Encode {}
320
321
impl<S: Decode + Encode> Codec for S {}

322
323
324
325
326
327
328
329
330
331
/// Trait that bound `EncodeLike` along with `Encode`. Usefull for generic being used in function
/// with `EncodeLike` parameters.
pub trait FullEncode: Encode + EncodeLike {}
impl<S: Encode + EncodeLike> FullEncode for S {}

/// Trait that bound `EncodeLike` along with `Codec`. Usefull for generic being used in function
/// with `EncodeLike` parameters.
pub trait FullCodec: Decode + FullEncode {}
impl<S: Decode + FullEncode> FullCodec for S {}

332
333
334
335
336
/// A marker trait for types that wrap other encodable type.
///
/// Such types should not carry any additional information
/// that would require to be encoded, because the encoding
/// is assumed to be the same as the wrapped type.
337
338
///
/// The wrapped type that is referred to is the [`Deref::Target`].
339
340
341
pub trait WrapperTypeEncode: Deref {}

impl<T: ?Sized> WrapperTypeEncode for Box<T> {}
Bastian Köcher's avatar
Bastian Köcher committed
342
343
impl<T: ?Sized + Encode> EncodeLike for Box<T> {}
impl<T: Encode> EncodeLike<T> for Box<T> {}
344
impl<T: Encode> EncodeLike<Box<T>> for T {}
Bastian Köcher's avatar
Bastian Köcher committed
345

346
347
348
349
impl<T: ?Sized> WrapperTypeEncode for &T {}
impl<T: ?Sized + Encode> EncodeLike for &T {}
impl<T: Encode> EncodeLike<T> for &T {}
impl<T: Encode> EncodeLike<&T> for T {}
350
351
impl<T: Encode> EncodeLike<T> for &&T {}
impl<T: Encode> EncodeLike<&&T> for T {}
Bastian Köcher's avatar
Bastian Köcher committed
352

353
354
355
356
impl<T: ?Sized> WrapperTypeEncode for &mut T {}
impl<T: ?Sized + Encode> EncodeLike for &mut T {}
impl<T: Encode> EncodeLike<T> for &mut T {}
impl<T: Encode> EncodeLike<&mut T> for T {}
357

358
359
360
361
362
impl<'a, T: ToOwned + ?Sized> WrapperTypeEncode for Cow<'a, T> {}
impl<'a, T: ToOwned + Encode + ?Sized> EncodeLike for Cow<'a, T> {}
impl<'a, T: ToOwned + Encode> EncodeLike<T> for Cow<'a, T> {}
impl<'a, T: ToOwned + Encode> EncodeLike<Cow<'a, T>> for T {}

363
#[cfg(any(feature = "std", feature = "full"))]
Bastian Köcher's avatar
Bastian Köcher committed
364
365
366
367
mod feature_full_wrapper_type_encode {
	use super::*;

	impl<T: ?Sized> WrapperTypeEncode for Arc<T> {}
368
	impl<T: ?Sized + Encode> EncodeLike for Arc<T> {}
Bastian Köcher's avatar
Bastian Köcher committed
369
	impl<T: Encode> EncodeLike<T> for Arc<T> {}
370
	impl<T: Encode> EncodeLike<Arc<T>> for T {}
Bastian Köcher's avatar
Bastian Köcher committed
371
372

	impl<T: ?Sized> WrapperTypeEncode for Rc<T> {}
373
	impl<T: ?Sized + Encode> EncodeLike for Rc<T> {}
Bastian Köcher's avatar
Bastian Köcher committed
374
	impl<T: Encode> EncodeLike<T> for Rc<T> {}
375
	impl<T: Encode> EncodeLike<Rc<T>> for T {}
Bastian Köcher's avatar
Bastian Köcher committed
376
377
378
379
380
381

	impl WrapperTypeEncode for String {}
	impl EncodeLike for String {}
	impl EncodeLike<&str> for String {}
	impl EncodeLike<String> for &str {}
}
382
383
384

impl<T, X> Encode for X where
	T: Encode + ?Sized,
Bastian Köcher's avatar
Bastian Köcher committed
385
	X: WrapperTypeEncode<Target = T>,
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
{
	fn size_hint(&self) -> usize {
		(&**self).size_hint()
	}

	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
		(&**self).using_encoded(f)
	}

	fn encode(&self) -> Vec<u8> {
		(&**self).encode()
	}

	fn encode_to<W: Output>(&self, dest: &mut W) {
		(&**self).encode_to(dest)
	}
}

/// A marker trait for types that can be created solely from other decodable types.
///
/// The decoding of such type is assumed to be the same as the wrapped type.
pub trait WrapperTypeDecode: Sized {
	/// A wrapped type.
	type Wrapped: Into<Self>;
}
impl<T> WrapperTypeDecode for Box<T> {
	type Wrapped = T;
}
#[cfg(any(feature = "std", feature = "full"))]
415
impl<T> WrapperTypeDecode for Arc<T> {
416
417
418
	type Wrapped = T;
}
#[cfg(any(feature = "std", feature = "full"))]
419
impl<T> WrapperTypeDecode for Rc<T> {
420
421
422
423
424
425
426
427
	type Wrapped = T;
}

impl<T, X> Decode for X where
	T: Decode + Into<X>,
	X: WrapperTypeDecode<Wrapped=T>,
{
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
428
429
430
431
		input.descend_ref()?;
		let result = Ok(T::decode(input)?.into());
		input.ascend_ref();
		result
432
	}
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

}

/// A macro that matches on a [`TypeInfo`] and expands a given macro per variant.
///
/// The first parameter to the given macro will be the type of variant (e.g. `u8`, `u32`, etc.) and other parameters
/// given to this macro.
///
/// The last parameter is the code that should be executed for the `Unknown` type info.
macro_rules! with_type_info {
	( $type_info:expr, $macro:ident $( ( $( $params:ident ),* ) )?, { $( $unknown_variant:tt )* }, ) => {
		match $type_info {
			TypeInfo::U8 => { $macro!(u8 $( $( , $params )* )? ) },
			TypeInfo::I8 => { $macro!(i8 $( $( , $params )* )? ) },
			TypeInfo::U16 => { $macro!(u16 $( $( , $params )* )? ) },
			TypeInfo::I16 => { $macro!(i16 $( $( , $params )* )? ) },
			TypeInfo::U32 => { $macro!(u32 $( $( , $params )* )? ) },
			TypeInfo::I32 => { $macro!(i32 $( $( , $params )* )? ) },
			TypeInfo::U64 => { $macro!(u64 $( $( , $params )* )? ) },
			TypeInfo::I64 => { $macro!(i64 $( $( , $params )* )? ) },
			TypeInfo::U128 => { $macro!(u128 $( $( , $params )* )? ) },
			TypeInfo::I128 => { $macro!(i128 $( $( , $params )* )? ) },
			TypeInfo::Unknown => { $( $unknown_variant )* },
		}
	};
458
}
Gav Wood's avatar
Gav Wood committed
459

460
461
462
463
464
465
/// Something that can be encoded as a reference.
pub trait EncodeAsRef<'a, T: 'a> {
	/// The reference type that is used for encoding.
	type RefType: Encode + From<&'a T>;
}

Gav Wood's avatar
Gav Wood committed
466
impl<T: Encode, E: Encode> Encode for Result<T, E> {
467
468
469
470
471
472
473
	fn size_hint(&self) -> usize {
		1 + match *self {
			Ok(ref t) => t.size_hint(),
			Err(ref t) => t.size_hint(),
		}
	}

Gav Wood's avatar
Gav Wood committed
474
475
476
477
478
479
480
481
482
483
484
485
486
487
	fn encode_to<W: Output>(&self, dest: &mut W) {
		match *self {
			Ok(ref t) => {
				dest.push_byte(0);
				t.encode_to(dest);
			}
			Err(ref e) => {
				dest.push_byte(1);
				e.encode_to(dest);
			}
		}
	}
}

488
489
490
491
492
493
494
impl<T, LikeT, E, LikeE> EncodeLike<Result<LikeT, LikeE>> for Result<T, E>
where
	T: EncodeLike<LikeT>,
	LikeT: Encode,
	E: EncodeLike<LikeE>,
	LikeE: Encode,
{}
Bastian Köcher's avatar
Bastian Köcher committed
495

Gav Wood's avatar
Gav Wood committed
496
impl<T: Decode, E: Decode> Decode for Result<T, E> {
497
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Gav Wood's avatar
Gav Wood committed
498
		match input.read_byte()? {
499
500
501
			0 => Ok(Ok(T::decode(input)?)),
			1 => Ok(Err(E::decode(input)?)),
			_ => Err("unexpected first byte decoding Result".into()),
Gav Wood's avatar
Gav Wood committed
502
503
504
505
506
		}
	}
}

/// Shim type because we can't do a specialised implementation for `Option<bool>` directly.
507
#[derive(Eq, PartialEq, Clone, Copy)]
Gav Wood's avatar
Gav Wood committed
508
509
pub struct OptionBool(pub Option<bool>);

510
511
impl fmt::Debug for OptionBool {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
512
513
514
515
		self.0.fmt(f)
	}
}

Gav Wood's avatar
Gav Wood committed
516
impl Encode for OptionBool {
thiolliere's avatar
thiolliere committed
517
518
519
520
	fn size_hint(&self) -> usize {
		1
	}

Gav Wood's avatar
Gav Wood committed
521
522
523
524
525
526
527
528
529
	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
		f(&[match *self {
			OptionBool(None) => 0u8,
			OptionBool(Some(true)) => 1u8,
			OptionBool(Some(false)) => 2u8,
		}])
	}
}

Bastian Köcher's avatar
Bastian Köcher committed
530
531
impl EncodeLike for OptionBool {}

Gav Wood's avatar
Gav Wood committed
532
impl Decode for OptionBool {
533
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Gav Wood's avatar
Gav Wood committed
534
		match input.read_byte()? {
535
536
537
538
			0 => Ok(OptionBool(None)),
			1 => Ok(OptionBool(Some(true))),
			2 => Ok(OptionBool(Some(false))),
			_ => Err("unexpected first byte decoding OptionBool".into()),
Gav Wood's avatar
Gav Wood committed
539
540
541
542
		}
	}
}

543
impl<T: EncodeLike<U>, U: Encode> EncodeLike<Option<U>> for Option<T> {}
Bastian Köcher's avatar
Bastian Köcher committed
544

Gav Wood's avatar
Gav Wood committed
545
impl<T: Encode> Encode for Option<T> {
546
547
548
549
550
551
552
	fn size_hint(&self) -> usize {
		1 + match *self {
			Some(ref t) => t.size_hint(),
			None => 0,
		}
	}

Gav Wood's avatar
Gav Wood committed
553
554
555
556
557
558
559
560
561
562
563
564
	fn encode_to<W: Output>(&self, dest: &mut W) {
		match *self {
			Some(ref t) => {
				dest.push_byte(1);
				t.encode_to(dest);
			}
			None => dest.push_byte(0),
		}
	}
}

impl<T: Decode> Decode for Option<T> {
565
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Gav Wood's avatar
Gav Wood committed
566
		match input.read_byte()? {
567
568
			0 => Ok(None),
			1 => Ok(Some(T::decode(input)?)),
569
			_ => Err("unexpected first byte decoding Option".into()),
Gav Wood's avatar
Gav Wood committed
570
571
572
573
		}
	}
}

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
macro_rules! impl_for_non_zero {
	( $( $name:ty ),* $(,)? ) => {
		$(
			impl Encode for $name {
				fn size_hint(&self) -> usize {
					self.get().size_hint()
				}

				fn encode_to<W: Output>(&self, dest: &mut W) {
					self.get().encode_to(dest)
				}

				fn encode(&self) -> Vec<u8> {
					self.get().encode()
				}

				fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
					self.get().using_encoded(f)
				}
			}

			impl Decode for $name {
				fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
					Self::new(Decode::decode(input)?)
						.ok_or_else(|| Error::from("cannot create non-zero number from 0"))
				}
			}
		)*
	}
}
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

/// Encode the slice without prepending the len.
///
/// This is equivalent to encoding all the element one by one, but it is optimized for some types.
pub(crate) fn encode_slice_no_len<T: Encode, W: Output>(slice: &[T], dest: &mut W) {
	macro_rules! encode_to {
		( u8, $slice:ident, $dest:ident ) => {{
			let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) };
			$dest.write(&typed)
		}};
		( i8, $slice:ident, $dest:ident ) => {{
			// `i8` has the same size as `u8`. We can just convert it here and write to the
			// dest buffer directly.
			let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) };
			$dest.write(&typed)
		}};
		( $ty:ty, $slice:ident, $dest:ident ) => {{
			if cfg!(target_endian = "little") {
				let typed = unsafe { mem::transmute::<&[T], &[$ty]>(&$slice[..]) };
				$dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed))
			} else {
				for item in $slice.iter() {
					item.encode_to(dest);
				}
			}
		}};
	}

	with_type_info! {
		<T as Encode>::TYPE_INFO,
		encode_to(slice, dest),
		{
			for item in slice.iter() {
				item.encode_to(dest);
			}
		},
	}
}

/// Decode the slice (without prepended the len).
///
/// This is equivalent to decode all elements one by one, but it is optimized in some
/// situation.
pub(crate) fn decode_vec_with_len<T: Decode, I: Input>(
	input: &mut I,
	len: usize,
) -> Result<Vec<T>, Error> {
	fn decode_unoptimized<I: Input, T: Decode>(
		input: &mut I,
		items_len: usize,
	) -> Result<Vec<T>, Error> {
		let input_capacity = input.remaining_len()?
			.unwrap_or(MAX_PREALLOCATION)
			.checked_div(mem::size_of::<T>())
			.unwrap_or(0);
		let mut r = Vec::with_capacity(input_capacity.min(items_len));
		input.descend_ref()?;
		for _ in 0..items_len {
			r.push(T::decode(input)?);
		}
		input.ascend_ref();
		Ok(r)
	}

	macro_rules! decode {
		( $ty:ty, $input:ident, $len:ident ) => {{
			if cfg!(target_endian = "little") || mem::size_of::<T>() == 1 {
				let vec = read_vec_from_u8s::<_, $ty>($input, $len)?;
				Ok(unsafe { mem::transmute::<Vec<$ty>, Vec<T>>(vec) })
			} else {
				decode_unoptimized($input, $len)
			}
		}};
	}

	with_type_info! {
		<T as Decode>::TYPE_INFO,
		decode(input, len),
		{
			decode_unoptimized(input, len)
		},
	}
}

688
689
690
691
692
693
694
695
696
697
698
699
700
impl_for_non_zero! {
	NonZeroI8,
	NonZeroI16,
	NonZeroI32,
	NonZeroI64,
	NonZeroI128,
	NonZeroU8,
	NonZeroU16,
	NonZeroU32,
	NonZeroU64,
	NonZeroU128,
}

Gav Wood's avatar
Gav Wood committed
701
macro_rules! impl_array {
Bastian Köcher's avatar
Bastian Köcher committed
702
703
704
	( $( $n:expr, )* ) => {
		$(
			impl<T: Encode> Encode for [T; $n] {
705
706
707
708
				fn size_hint(&self) -> usize {
					mem::size_of::<T>() * $n
				}

Bastian Köcher's avatar
Bastian Köcher committed
709
				fn encode_to<W: Output>(&self, dest: &mut W) {
710
					encode_slice_no_len(&self[..], dest)
Gav Wood's avatar
Gav Wood committed
711
712
				}
			}
713

Bastian Köcher's avatar
Bastian Köcher committed
714
715
716
717
718
719
720
721
722
723
724
725
			impl<T: Decode> Decode for [T; $n] {
				fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
					let mut r = ArrayVec::new();
					for _ in 0..$n {
						r.push(T::decode(input)?);
					}
					let i = r.into_inner();

					match i {
						Ok(a) => Ok(a),
						Err(_) => Err("failed to get inner array from ArrayVec".into()),
					}
726
				}
Gav Wood's avatar
Gav Wood committed
727
			}
Bastian Köcher's avatar
Bastian Köcher committed
728

729
			impl<T: EncodeLike<U>, U: Encode> EncodeLike<[U; $n]> for [T; $n] {}
Bastian Köcher's avatar
Bastian Köcher committed
730
731
		)*
	}
Gav Wood's avatar
Gav Wood committed
732
733
}

734
impl_array!(
735
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
736
737
738
739
740
741
	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
	72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
	109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
742
	125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
743
744
745
746
747
748
749
750
751
	141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
	157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
	173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
	189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
	205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
	221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
	237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
	253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,
);
Gav Wood's avatar
Gav Wood committed
752

753
754
755
756
757
impl Encode for str {
	fn size_hint(&self) -> usize {
		self.as_bytes().size_hint()
	}

Gav Wood's avatar
Gav Wood committed
758
759
760
761
	fn encode_to<W: Output>(&self, dest: &mut W) {
		self.as_bytes().encode_to(dest)
	}

762
763
764
765
766
767
	fn encode(&self) -> Vec<u8> {
		self.as_bytes().encode()
	}

	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
		self.as_bytes().using_encoded(f)
Gav Wood's avatar
Gav Wood committed
768
769
770
	}
}

771
impl<'a, T: ToOwned + ?Sized> Decode for Cow<'a, T>
772
	where <T as ToOwned>::Owned: Decode,
Gav's avatar
Gav committed
773
{
774
775
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
		Ok(Cow::Owned(Decode::decode(input)?))
Gav Wood's avatar
Gav Wood committed
776
777
778
	}
}

Bastian Köcher's avatar
Bastian Köcher committed
779
780
impl<T> EncodeLike for PhantomData<T> {}

781
impl<T> Encode for PhantomData<T> {
782
	fn encode_to<W: Output>(&self, _dest: &mut W) {}
783
784
}

785
impl<T> Decode for PhantomData<T> {
786
787
	fn decode<I: Input>(_input: &mut I) -> Result<Self, Error> {
		Ok(PhantomData)
Gav's avatar
Gav committed
788
	}
789
790
}

Hero Bird's avatar
Hero Bird committed
791
#[cfg(any(feature = "std", feature = "full"))]
Gav Wood's avatar
Gav Wood committed
792
impl Decode for String {
793
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
pscott's avatar
pscott committed
794
		Self::from_utf8(Vec::decode(input)?).map_err(|_| "Invalid utf8 sequence".into())
Gav Wood's avatar
Gav Wood committed
795
796
797
	}
}

798
/// Writes the compact encoding of `len` do `dest`.
799
800
801
802
803
804
805
806
807
pub(crate) fn compact_encode_len_to<W: Output>(dest: &mut W, len: usize) -> Result<(), Error> {
	if len > u32::max_value() as usize {
		return Err("Attempted to serialize a collection with too many elements.".into());
	}

	Compact(len as u32).encode_to(dest);
	Ok(())
}

Gav Wood's avatar
Gav Wood committed
808
impl<T: Encode> Encode for [T] {
809
	fn size_hint(&self) -> usize {
810
		mem::size_of::<u32>() + mem::size_of::<T>() * self.len()
811
812
	}

Gav Wood's avatar
Gav Wood committed
813
	fn encode_to<W: Output>(&self, dest: &mut W) {
814
815
		compact_encode_len_to(dest, self.len()).expect("Compact encodes length");

816
		encode_slice_no_len(self, dest)
Gav Wood's avatar
Gav Wood committed
817
818
819
	}
}

820
821
822
823
824
825
826
827
828
829
830
831
832
833
/// Create a `Vec<T>` by casting directly from a buffer of read `u8`s
///
/// The encoding of `T` must be equal to its binary representation, and size of `T` must be less or
/// equal to [`MAX_PREALLOCATION`].
pub(crate) fn read_vec_from_u8s<I, T>(input: &mut I, items_len: usize) -> Result<Vec<T>, Error>
where
	I: Input,
	T: ToMutByteSlice + Default + Clone,
{
	debug_assert!(MAX_PREALLOCATION >= mem::size_of::<T>(), "Invalid precondition");

	let byte_len = items_len.checked_mul(mem::size_of::<T>())
		.ok_or_else(|| "Item is too big and cannot be allocated")?;

834
835
836
	let input_len = input.remaining_len()?;

	// If there is input len and it cannot be pre-allocated then return directly.
837
	if input_len.map(|l| l < byte_len).unwrap_or(false) {
838
839
840
		return Err("Not enough data to decode vector".into())
	}

841
842
843
	// In both these branches we're going to be creating and resizing a Vec<T>,
	// but casting it to a &mut [u8] for reading.

844
	// Note: we checked that if input_len is some then it can preallocated.
845
	let r = if input_len.is_some() || byte_len < MAX_PREALLOCATION {
846
		// Here we pre-allocate the whole buffer.
847
848
849
		let mut items: Vec<T> = vec![Default::default(); items_len];
		let mut bytes_slice = items.as_mut_byte_slice();
		input.read(&mut bytes_slice)?;
850

851
		items
852
	} else {
853
854
855
856
		// An allowed number of preallocated item.
		// Note: `MAX_PREALLOCATION` is expected to be more or equal to size of `T`, precondition.
		let max_preallocated_items = MAX_PREALLOCATION / mem::size_of::<T>();

857
		// Here we pre-allocate only the maximum pre-allocation
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
		let mut items: Vec<T> = vec![];

		let mut items_remains = items_len;

		while items_remains > 0 {
			let items_len_read = max_preallocated_items.min(items_remains);

			let items_len_filled = items.len();
			let items_new_size = items_len_filled + items_len_read;

			items.reserve_exact(items_len_read);
			unsafe {
				items.set_len(items_new_size);
			}

			let bytes_slice = items.as_mut_byte_slice();
			let bytes_len_filled = items_len_filled * mem::size_of::<T>();
			input.read(&mut bytes_slice[bytes_len_filled..])?;

			items_remains = items_remains.saturating_sub(items_len_read);
878
879
		}

880
		items
881
882
883
884
885
	};

	Ok(r)
}

Bastian Köcher's avatar
Bastian Köcher committed
886
impl<T> WrapperTypeEncode for Vec<T> {}
887
888
889
impl<T: EncodeLike<U>, U: Encode> EncodeLike<Vec<U>> for Vec<T> {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<&[U]> for Vec<T> {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<Vec<U>> for &[T] {}
Bastian Köcher's avatar
Bastian Köcher committed
890

Gav Wood's avatar
Gav Wood committed
891
impl<T: Decode> Decode for Vec<T> {
892
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
Gav's avatar
Gav committed
893
		<Compact<u32>>::decode(input).and_then(move |Compact(len)| {
894
			decode_vec_with_len(input, len as usize)
Gav Wood's avatar
Gav Wood committed
895
896
897
898
		})
	}
}

thiolliere's avatar
thiolliere committed
899
900
macro_rules! impl_codec_through_iterator {
	($(
901
902
903
904
		$type:ident
		{ $( $generics:ident $( : $decode_additional:ident )? ),* }
		{ $( $type_like_generics:ident ),* }
		{ $( $impl_like_generics:tt )* }
thiolliere's avatar
thiolliere committed
905
	)*) => {$(
906
907
908
909
910
		impl<$( $generics: Encode ),*> Encode for $type<$( $generics, )*> {
			fn size_hint(&self) -> usize {
				mem::size_of::<u32>() $( + mem::size_of::<$generics>() * self.len() )*
			}

thiolliere's avatar
thiolliere committed
911
			fn encode_to<W: Output>(&self, dest: &mut W) {
912
913
				compact_encode_len_to(dest, self.len()).expect("Compact encodes length");

thiolliere's avatar
thiolliere committed
914
915
916
917
				for i in self.iter() {
					i.encode_to(dest);
				}
			}
Aton's avatar
Aton committed
918
919
		}

920
		impl<$( $generics: Decode $( + $decode_additional )? ),*> Decode
921
			for $type<$( $generics, )*>
922
		{
thiolliere's avatar
thiolliere committed
923
924
			fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
				<Compact<u32>>::decode(input).and_then(move |Compact(len)| {
925
926
927
928
					input.descend_ref()?;
					let result = Result::from_iter((0..len).map(|_| Decode::decode(input)));
					input.ascend_ref();
					result
thiolliere's avatar
thiolliere committed
929
				})
Aton's avatar
Aton committed
930
			}
thiolliere's avatar
thiolliere committed
931
		}
Bastian Köcher's avatar
Bastian Köcher committed
932

933
934
		impl<$( $impl_like_generics )*> EncodeLike<$type<$( $type_like_generics ),*>>
			for $type<$( $generics ),*> {}
935
		impl<$( $impl_like_generics )*> EncodeLike<&[( $( $type_like_generics, )* )]>
936
937
			for $type<$( $generics ),*> {}
		impl<$( $impl_like_generics )*> EncodeLike<$type<$( $type_like_generics ),*>>
938
			for &[( $( $generics, )* )] {}
thiolliere's avatar
thiolliere committed
939
940
941
942
	)*}
}

impl_codec_through_iterator! {
943
944
945
946
947
948
949
950
	BTreeMap { K: Ord, V } { LikeK, LikeV}
		{ K: EncodeLike<LikeK>, LikeK: Encode, V: EncodeLike<LikeV>, LikeV: Encode }
	BTreeSet { T: Ord } { LikeT }
		{ T: EncodeLike<LikeT>, LikeT: Encode }
	LinkedList { T } { LikeT }
		{ T: EncodeLike<LikeT>, LikeT: Encode }
	BinaryHeap { T: Ord } { LikeT }
		{ T: EncodeLike<LikeT>, LikeT: Encode }
Aton's avatar
Aton committed
951
952
}

953
954
955
956
957
impl<T: Encode> EncodeLike for VecDeque<T> {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<&[U]> for VecDeque<T> {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<VecDeque<U>> for &[T] {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<Vec<U>> for VecDeque<T> {}
impl<T: EncodeLike<U>, U: Encode> EncodeLike<VecDeque<U>> for Vec<T> {}
Bastian Köcher's avatar
Bastian Köcher committed
958

959
impl<T: Encode> Encode for VecDeque<T> {
960
961
962
963
	fn size_hint(&self) -> usize {
		mem::size_of::<u32>() + mem::size_of::<T>() * self.len()
	}

964
	fn encode_to<W: Output>(&self, dest: &mut W) {
965
		compact_encode_len_to(dest, self.len()).expect("Compact encodes length");
thiolliere's avatar
thiolliere committed
966

967
968
		macro_rules! encode_to {
			( $ty:ty, $self:ident, $dest:ident ) => {{
969
970
971
972
973
974
975
976
977
978
979
980
981
				if cfg!(target_endian = "little") || mem::size_of::<T>() == 1 {
					let slices = $self.as_slices();
					let typed = unsafe {
						core::mem::transmute::<(&[T], &[T]), (&[$ty], &[$ty])>(slices)
					};

					$dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.0));
					$dest.write(<[$ty] as AsByteSlice<$ty>>::as_byte_slice(typed.1));
				} else {
					for item in $self {
						item.encode_to($dest);
					}
				}
982
983
984
985
986
987
988
989
990
991
992
			}};
		}

		with_type_info! {
			<T as Encode>::TYPE_INFO,
			encode_to(self, dest),
			{
				for item in self {
					item.encode_to(dest);
				}
			},
993
994
995
996
		}
	}
}

thiolliere's avatar
thiolliere committed
997
impl<T: Decode> Decode for VecDeque<T> {
998
	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
thiolliere's avatar
thiolliere committed
999
		Ok(<Vec<T>>::decode(input)?.into())
1000
	}
For faster browsing, not all history is shown. View entire blame