diff --git a/client-network/src/data.rs b/client-network/src/data.rs index edf9400..b6c8f9b 100644 --- a/client-network/src/data.rs +++ b/client-network/src/data.rs @@ -208,7 +208,7 @@ impl ChunkNode { // Helper struct #[derive(Debug, Clone)] pub struct DirectoryEntry { - pub filename: [u8; FILENAME_HASH_SIZE], + pub filename: Vec, pub content_hash: NodeHash, } @@ -240,7 +240,7 @@ pub struct BigNode { } impl BigNode { - pub fn new(children_hashes: Vec) -> Result { + /*pub fn new(children_hashes: Vec) -> Result { let n = children_hashes.len(); if n < MIN_BIG_CHILDREN || n > MAX_BIG_CHILDREN { return Err(format!( @@ -249,16 +249,17 @@ impl BigNode { )); } Ok(BigNode { children_hashes }) - } + }*/ } #[derive(Debug, Clone)] pub struct BigDirectoryNode { - pub children_hashes: Vec, + //pub children_hashes: Vec, + pub children_hashes: Vec, } impl BigDirectoryNode { - pub fn new(children_hashes: Vec) -> Result { + /*pub fn new(children_hashes: Vec) -> Result { let n = children_hashes.len(); if n < MIN_BIG_CHILDREN || n > MAX_BIG_CHILDREN { return Err(format!( @@ -267,6 +268,14 @@ impl BigDirectoryNode { )); } Ok(BigDirectoryNode { children_hashes }) + }*/ + pub fn new(entries: Vec) -> Result { + if entries.len() > MAX_DIRECTORY_ENTRIES { + return Err(format!("Directory exceeds {} bytes", entries.len())); + } + Ok(BigDirectoryNode { + children_hashes: entries, + }) } } diff --git a/client-network/src/datum_parsing.rs b/client-network/src/datum_parsing.rs index 0ed934a..aff0dde 100644 --- a/client-network/src/datum_parsing.rs +++ b/client-network/src/datum_parsing.rs @@ -1 +1,96 @@ -fn parse_received_datum(recevied_datum: Vec) {} +use crate::{BigDirectoryNode, DirectoryEntry, DirectoryNode, MerkleNode, MerkleTree, NodeHash}; +use sha2::{Digest, Sha256}; + +const CHUNK: u8 = 0; +const DIRECTORY: u8 = 1; +const BIG: u8 = 2; +const BIGDIRECTORY: u8 = 3; + +fn parse_received_datum(recevied_datum: Vec, datum_length: usize, mut tree: MerkleTree) { + if datum_length > recevied_datum.len() { + return; + } + if datum_length < 32 + 64 { + return; + } + let hash_name: [u8; 32] = recevied_datum[..32].try_into().expect("error"); + let sigstart = datum_length - 64; + let value = &recevied_datum[32..sigstart]; + let value_slice = value.to_vec(); + let signature: [u8; 32] = recevied_datum[sigstart..datum_length] + .try_into() + .expect("Taille incorrecte"); + let datum_type = value_slice[0]; + match datum_type { + CHUNK => { + tree.data.insert( + hash_name, + MerkleNode::Chunk(crate::ChunkNode { data: value_slice }), + ); + } + DIRECTORY => { + let nb_entries = value_slice[1]; + let mut dir_entries = Vec::new(); + let mut offset = 1 as usize; + for i in 0..nb_entries { + offset = (offset as u8 + 64 * i) as usize; + let name = &recevied_datum[offset..offset + 32]; + let mut hash = [0u8; 32]; + hash.copy_from_slice(&recevied_datum[offset + 32..offset + 64]); + // envoyer un datum request + dir_entries.push(DirectoryEntry { + filename: name.to_vec(), + content_hash: hash, + }); + } + + let current = DirectoryNode::new(dir_entries); + match current { + Ok(current_node) => { + tree.data + .insert(hash_name, MerkleNode::Directory(current_node)); + } + Err(e) => { + println!("{}", e); + } + } + } + BIG => { + let chlidren: Vec = Vec::new(); + tree.data.insert( + hash_name, + MerkleNode::Big(crate::BigNode { + children_hashes: chlidren, + }), + ); + } + BIGDIRECTORY => { + let nb_entries = value_slice[1]; + let mut dir_entries = Vec::new(); + let mut offset = 1 as usize; + for i in 0..nb_entries { + offset = (offset as u8 + 64 * i) as usize; + let name = &recevied_datum[offset..offset + 32]; + let mut hash = [0u8; 32]; + hash.copy_from_slice(&recevied_datum[offset + 32..offset + 64]); + // envoyer un datum request + dir_entries.push(DirectoryEntry { + filename: name.to_vec(), + content_hash: hash, + }); + } + + let current = BigDirectoryNode::new(dir_entries); + match current { + Ok(current_node) => { + tree.data + .insert(hash_name, MerkleNode::BigDirectory(current_node)); + } + Err(e) => { + println!("{}", e); + } + } + } + _ => {} + } +}