// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
//! The node header.
use codec::{Encode, Decode, Input, Output};
use super::{EMPTY_TRIE, LEAF_NODE_OFFSET, LEAF_NODE_BIG, EXTENSION_NODE_OFFSET,
EXTENSION_NODE_BIG, BRANCH_NODE_NO_VALUE, BRANCH_NODE_WITH_VALUE, LEAF_NODE_THRESHOLD,
EXTENSION_NODE_THRESHOLD, LEAF_NODE_SMALL_MAX, EXTENSION_NODE_SMALL_MAX};
/// A node header.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum NodeHeader {
Null,
Branch(bool),
Extension(usize),
Leaf(usize),
}
impl Encode for NodeHeader {
fn encode_to(&self, output: &mut T) {
match self {
NodeHeader::Null => output.push_byte(EMPTY_TRIE),
NodeHeader::Branch(true) => output.push_byte(BRANCH_NODE_WITH_VALUE),
NodeHeader::Branch(false) => output.push_byte(BRANCH_NODE_NO_VALUE),
NodeHeader::Leaf(nibble_count) if *nibble_count < LEAF_NODE_THRESHOLD as usize =>
output.push_byte(LEAF_NODE_OFFSET + *nibble_count as u8),
NodeHeader::Leaf(nibble_count) => {
output.push_byte(LEAF_NODE_BIG);
output.push_byte((*nibble_count - LEAF_NODE_THRESHOLD as usize) as u8);
}
NodeHeader::Extension(nibble_count) if *nibble_count < EXTENSION_NODE_THRESHOLD as usize =>
output.push_byte(EXTENSION_NODE_OFFSET + *nibble_count as u8),
NodeHeader::Extension(nibble_count) => {
output.push_byte(EXTENSION_NODE_BIG);
output.push_byte((*nibble_count - EXTENSION_NODE_THRESHOLD as usize) as u8);
}
}
}
}
impl Decode for NodeHeader {
fn decode(input: &mut I) -> Option {
Some(match input.read_byte()? {
EMPTY_TRIE => NodeHeader::Null, // 0
i @ LEAF_NODE_OFFSET ... LEAF_NODE_SMALL_MAX => // 1 ... (127 - 1)
NodeHeader::Leaf((i - LEAF_NODE_OFFSET) as usize),
LEAF_NODE_BIG => // 127
NodeHeader::Leaf(input.read_byte()? as usize + LEAF_NODE_THRESHOLD as usize),
i @ EXTENSION_NODE_OFFSET ... EXTENSION_NODE_SMALL_MAX =>// 128 ... (253 - 1)
NodeHeader::Extension((i - EXTENSION_NODE_OFFSET) as usize),
EXTENSION_NODE_BIG => // 253
NodeHeader::Extension(input.read_byte()? as usize + EXTENSION_NODE_THRESHOLD as usize),
BRANCH_NODE_NO_VALUE => NodeHeader::Branch(false), // 254
BRANCH_NODE_WITH_VALUE => NodeHeader::Branch(true), // 255
})
}
}