use crate::{Hash, Uint256, VarInt};
use encodings::{FromHex, FromHexError, ToHex};
use std::fmt;
use std::ops;
#[derive(Debug)]
pub enum BufferError {
OutOfBounds,
InvalidString(std::string::FromUtf8Error),
NonMinimalVarInt,
}
impl From<std::string::FromUtf8Error> for BufferError {
fn from(e: std::string::FromUtf8Error) -> Self {
BufferError::InvalidString(e)
}
}
impl fmt::Display for BufferError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
BufferError::OutOfBounds => write!(f, "Read Out of Bounds"),
BufferError::InvalidString(ref e) => write!(f, "Invalid String {}", e),
BufferError::NonMinimalVarInt => write!(f, "Non Minimal VarInt!"),
}
}
}
pub type Result<T> = std::result::Result<T, BufferError>;
#[derive(Default, PartialEq, Clone, Eq)]
pub struct Buffer {
data: Vec<u8>,
offset: usize,
}
impl Buffer {
pub fn new() -> Self {
Buffer::default()
}
pub fn write_u8(&mut self, data: u8) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_u16(&mut self, data: u16) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_u32(&mut self, data: u32) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_u64(&mut self, data: u64) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_u256(&mut self, data: Uint256) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_u8_be(&mut self, data: u8) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_u16_be(&mut self, data: u16) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_u32_be(&mut self, data: u32) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_u64_be(&mut self, data: u64) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_i8(&mut self, data: u8) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_i16(&mut self, data: u16) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_i32(&mut self, data: u32) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_i64(&mut self, data: u64) {
self.data.extend_from_slice(&data.to_le_bytes());
}
pub fn write_i8_be(&mut self, data: u8) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_i16_be(&mut self, data: u16) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_i32_be(&mut self, data: u32) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_i64_be(&mut self, data: u64) {
self.data.extend_from_slice(&data.to_be_bytes());
}
pub fn write_bytes(&mut self, bytes: &[u8]) {
self.data.extend_from_slice(bytes);
}
pub fn write_var_bytes(&mut self, bytes: &[u8]) {
self.write_varint(bytes.len());
if bytes.len() == 0 {
return;
}
self.data.extend_from_slice(bytes);
}
pub fn write_str(&mut self, string: &str) {
self.data.extend_from_slice(string.as_bytes());
}
pub fn write_string(&mut self, string: String) {
self.data.extend_from_slice(string.as_bytes());
}
pub fn write_hash(&mut self, hash: Hash) {
self.data.extend(&hash.to_array());
}
pub fn write_varint(&mut self, data: usize) {
if data < 0xFD {
self.write_u8(data as u8);
return;
}
if data < 0xFFFF {
self.write_u8(0xFD);
self.write_u16(data as u16);
return;
}
if data < 0xFFFFFFFF {
self.write_u8(0xFE);
self.write_u32(data as u32);
return;
}
self.write_u8(0xFF);
self.write_u64(data as u64);
}
pub fn fill(&mut self, value: u8, amount: usize) {
let fill_amount = vec![value; amount];
self.data.extend(fill_amount);
}
pub fn extend(&mut self, buffer: Buffer) {
self.data.extend_from_slice(&buffer);
}
pub fn extend_from_slice(&mut self, slice: &[u8]) {
self.data.extend_from_slice(slice);
}
pub fn into_hex(self) -> String {
self.data.to_hex()
}
pub fn check(&self, size: usize) -> Result<()> {
if self.offset + size > self.data.len() {
return Err(BufferError::OutOfBounds);
}
Ok(())
}
pub fn read_u8(&mut self) -> Result<u8> {
self.check(1)?;
let result = self.data[self.offset];
self.offset += 1;
Ok(result)
}
pub fn read_u16(&mut self) -> Result<u16> {
self.check(2)?;
let range = self.offset..self.offset + 2;
let mut buf = [0; 2];
buf.copy_from_slice(&self.data[range]);
let ret = u16::from_le_bytes(buf);
self.offset += 2;
Ok(ret)
}
pub fn read_u32(&mut self) -> Result<u32> {
self.check(4)?;
let range = self.offset..self.offset + 4;
let mut buf = [0; 4];
buf.copy_from_slice(&self.data[range]);
let ret = u32::from_le_bytes(buf);
self.offset += 4;
Ok(ret)
}
pub fn read_u64(&mut self) -> Result<u64> {
self.check(8)?;
let range = self.offset..self.offset + 8;
let mut buf = [0; 8];
buf.copy_from_slice(&self.data[range]);
let ret = u64::from_le_bytes(buf);
self.offset += 8;
Ok(ret)
}
pub fn read_u256(&mut self) -> Result<Uint256> {
self.check(32)?;
let range = self.offset..self.offset + 32;
let ret = Uint256::from_bytes(&self.data[range]);
self.offset += 32;
Ok(ret)
}
pub fn read_varint(&mut self) -> Result<VarInt> {
let len = self.read_u8()?;
match len {
0xFF => {
let num = self.read_u64()?;
if num < 0x100000000 {
Err(BufferError::NonMinimalVarInt)
} else {
Ok(VarInt::from(num))
}
}
0xFE => {
let num = self.read_u32()?;
if num < 0x10000 {
Err(BufferError::NonMinimalVarInt)
} else {
Ok(VarInt::from(num))
}
}
0xFD => {
let num = self.read_u16()?;
if num < 0xFD {
Err(BufferError::NonMinimalVarInt)
} else {
Ok(VarInt::from(num))
}
}
len => Ok(VarInt::from(len)),
}
}
pub fn read_string(&mut self, size: usize) -> Result<String> {
self.check(size)?;
let range = self.offset..self.offset + size;
let ret = String::from_utf8(self.data[range].to_vec())?;
self.offset += size;
Ok(ret)
}
pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
self.check(size)?;
let range = self.offset..self.offset + size;
let ret = self.data[range].to_vec();
self.offset += size;
Ok(ret)
}
pub fn read_var_bytes(&mut self) -> Result<Vec<u8>> {
let length = self.read_varint()?;
let size = length.as_u64() as usize;
let range = self.offset..self.offset + size;
let ret = self.data[range].to_vec();
self.offset += size;
Ok(ret)
}
pub fn read_hash(&mut self) -> Result<Hash> {
self.check(32)?;
let mut array = [0; 32];
let range = self.offset..self.offset + 32;
array.copy_from_slice(&self.data[range]);
let hash = Hash::from(array);
self.offset += 32;
Ok(hash)
}
pub fn seek(&mut self, off: usize) -> Result<()> {
self.check(off)?;
self.offset += off;
Ok(())
}
}
impl From<Vec<u8>> for Buffer {
fn from(buf: Vec<u8>) -> Self {
Buffer {
data: buf,
offset: 0,
}
}
}
impl From<&[u8]> for Buffer {
fn from(buf: &[u8]) -> Self {
Buffer {
data: buf.to_vec(),
offset: 0,
}
}
}
impl ops::Deref for Buffer {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl ops::DerefMut for Buffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl AsRef<[u8]> for Buffer {
fn as_ref(&self) -> &[u8] {
&self.data
}
}
impl AsMut<[u8]> for Buffer {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.data
}
}
impl FromHex for Buffer {
type Error = FromHexError;
fn from_hex<T: AsRef<[u8]>>(hex: T) -> std::result::Result<Self, Self::Error> {
Ok(Buffer::from(Vec::from_hex(hex)?))
}
}
impl ToHex for Buffer {
fn to_hex(&self) -> String {
self.data.to_hex()
}
}
impl fmt::Display for Buffer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Offset: {}, Buffer: {})",
self.offset,
self.data.to_hex(),
)
}
}
impl fmt::Debug for Buffer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Offset: {}, Buffer: {})",
self.offset,
self.data.to_hex(),
)
}
}
#[cfg(feature = "serialization")]
impl serde::Serialize for Buffer {
fn serialize<S: serde::Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
if s.is_human_readable() {
s.serialize_str(&self.to_hex())
} else {
s.serialize_bytes(&self[..])
}
}
}
#[cfg(feature = "serialization")]
impl<'de> serde::Deserialize<'de> for Buffer {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> std::result::Result<Buffer, D::Error> {
if d.is_human_readable() {
struct HexVisitor;
impl<'de> serde::de::Visitor<'de> for HexVisitor {
type Value = Buffer;
fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
formatter.write_str("an ASCII hex string")
}
fn visit_bytes<E>(self, v: &[u8]) -> std::result::Result<Self::Value, E>
where
E: ::serde::de::Error,
{
if let Ok(hex) = ::std::str::from_utf8(v) {
Buffer::from_hex(hex).map_err(E::custom)
} else {
return Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self));
}
}
fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
where
E: ::serde::de::Error,
{
Buffer::from_hex(v).map_err(E::custom)
}
}
d.deserialize_str(HexVisitor)
} else {
struct BytesVisitor;
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
type Value = Buffer;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a bytestring")
}
fn visit_bytes<E>(self, v: &[u8]) -> std::result::Result<Self::Value, E>
where
E: ::serde::de::Error,
{
Ok(Buffer::from(v))
}
}
d.deserialize_bytes(BytesVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_write_u32() {
let version: u32 = 123456789;
let mut buffer = Buffer::new();
buffer.write_u32(version);
assert_eq!(buffer, Buffer::from([21, 205, 91, 7].to_vec()));
}
#[test]
fn test_to_hex() {
let version: u32 = 123456789;
let mut buffer = Buffer::new();
buffer.write_u32(version);
assert_eq!(buffer, Buffer::from([21, 205, 91, 7].to_vec()));
let hex = buffer.to_hex();
assert_eq!(hex, "15cd5b07")
}
#[test]
fn test_into_hex() {
let version: u32 = 123456789;
let mut buffer = Buffer::new();
buffer.write_u32(version);
assert_eq!(buffer, Buffer::from([21, 205, 91, 7].to_vec()));
let hex = buffer.into_hex();
assert_eq!(hex, "15cd5b07")
}
#[test]
fn test_from_hex() {
let mut buffer = Buffer::from_hex("FF00").unwrap();
dbg!(&buffer);
assert_eq!(buffer, Buffer::from(vec![255, 0]));
}
#[cfg(feature = "serialization")]
#[test]
fn test_serde() {
use serde_test::{assert_tokens, Configure, Token};
let version: u32 = 123456789;
let mut buffer = Buffer::new();
buffer.write_u32(version);
static version_bytes: [u8; 4] = [21, 205, 91, 7];
let buffer_readable = buffer.clone();
assert_tokens(&buffer.compact(), &[Token::BorrowedBytes(&version_bytes)]);
assert_tokens(&buffer_readable.readable(), &[Token::Str("15cd5b07")]);
}
}