use alloc::collections::BTreeMap; use alloc::vec::Vec; use binary_serde::{BinarySerde, Endianness, DeserializeError}; //use crate::card::model::NfcPayload; use crate::card::model::NfcPayload; use crate::storage::store::{Store, StoreError}; use crate::storage::{MemoryRegion,CARDSTORE_REGION}; const MAX_CARDS: usize = 20000; const COUNT_REGION: MemoryRegion = MemoryRegion { offset: CARDSTORE_REGION.offset, size: size_of::()}; #[derive(Debug, BinarySerde, Default, PartialEq, Eq)] #[repr(C)] pub struct AllocationTableEntry { uuid: u32, offset: u32, creation_date: u64, last_read_date: u64, // how often a card has been read read_count: u32, deleted: bool, reserved: [u64; 4], } const ALLOCATION_TABLE_SIZE: usize = size_of::(); const ALLOCATION_TABLE_REGION: MemoryRegion = MemoryRegion {offset: COUNT_REGION.end() as u32, size: MAX_CARDS * size_of::()}; const CARDS_REGION: MemoryRegion = MemoryRegion { offset: ALLOCATION_TABLE_REGION.end() as u32, size: CARDSTORE_REGION.size - ALLOCATION_TABLE_REGION.end()}; #[derive(Debug)] pub enum CardStoreError { Store(StoreError), CorruptedEntry(DeserializeError), NoEntry } impl From for CardStoreError { fn from(error: StoreError) -> CardStoreError { CardStoreError::Store(error) } } impl From for CardStoreError { fn from(error: DeserializeError) -> CardStoreError { CardStoreError::CorruptedEntry(error) } } pub struct CardStore { store: Store, count: usize, pub allocation_table: BTreeMap } impl CardStore { pub fn new(mut store: Store) -> Result { let mut count_bytes: [u8; COUNT_REGION.size] = [0; COUNT_REGION.size]; store.read(COUNT_REGION.offset, &mut count_bytes)?; let count: usize = usize::from_ne_bytes(count_bytes); let mut allocation_table_entries: Vec = Vec::with_capacity(ALLOCATION_TABLE_SIZE * count); store .read(ALLOCATION_TABLE_REGION.offset, &mut allocation_table_entries)?; let chunks = allocation_table_entries.into_chunks::(); let mut allocation_table = BTreeMap::::new(); for chunk in chunks { let allocation_table_entry = AllocationTableEntry::binary_deserialize(chunk.as_ref(), Endianness::Little)?; allocation_table.insert(allocation_table_entry.uuid, allocation_table_entry); } Ok(Self { store, count, allocation_table }) } pub fn get_card_by_uuid(&mut self, uuid: u32) -> Result { let entry = self.allocation_table.get(&uuid).ok_or(CardStoreError::NoEntry)?; let mut payload: [u8; size_of::()] = [0; size_of::()]; self.store.read(entry.offset, &mut payload)?; Ok(NfcPayload::binary_deserialize(payload.as_ref(), Endianness::Little)?) } }