Read more of the file
This commit is contained in:
+54
-15
@@ -1,4 +1,5 @@
|
|||||||
use err::Error;
|
use err::Error;
|
||||||
|
use netpod::log::*;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tokio::fs::OpenOptions;
|
use tokio::fs::OpenOptions;
|
||||||
@@ -8,7 +9,7 @@ use tokio::io::AsyncReadExt;
|
|||||||
// Wrap each I/O operation into a stopwatch to detect bad NFS performance!
|
// Wrap each I/O operation into a stopwatch to detect bad NFS performance!
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct IndexFileBasics {
|
pub struct IndexFileBasics {
|
||||||
version: u8,
|
version: u8,
|
||||||
name_hash_anchor_beg: u64,
|
name_hash_anchor_beg: u64,
|
||||||
name_hash_anchor_len: u64,
|
name_hash_anchor_len: u64,
|
||||||
@@ -23,26 +24,63 @@ struct IndexFileBasics {
|
|||||||
fa_header_len: u64,
|
fa_header_len: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IndexFileBasics {
|
||||||
|
pub fn file_offset_size(&self) -> u64 {
|
||||||
|
if self.version == 3 {
|
||||||
|
64
|
||||||
|
} else if self.version == 2 {
|
||||||
|
32
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name_hash(s: &str, ht_len: u32) -> u32 {
|
||||||
|
let mut h = 0;
|
||||||
|
for ch in s.as_bytes() {
|
||||||
|
h = (128 * h + *ch as u32) % ht_len;
|
||||||
|
}
|
||||||
|
h
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn read_file_basics(path: PathBuf) -> Result<IndexFileBasics, Error> {
|
pub async fn read_file_basics(path: PathBuf) -> Result<IndexFileBasics, Error> {
|
||||||
let mut f1 = OpenOptions::new().read(true).open(path).await?;
|
let mut f1 = OpenOptions::new().read(true).open(path).await?;
|
||||||
let mut buf = vec![0; 0x34];
|
let mut buf = vec![0; 0x4000];
|
||||||
f1.read_exact(&mut buf).await?;
|
f1.read_exact(&mut buf).await?;
|
||||||
let version = String::from_utf8(buf[3..4].to_vec())?.parse()?;
|
let version = String::from_utf8(buf[3..4].to_vec())?.parse()?;
|
||||||
|
fn readu64(buf: &[u8], pos: usize) -> u64 {
|
||||||
|
u64::from_be_bytes(buf.as_ref()[pos..pos + 8].try_into().unwrap()) as u64
|
||||||
|
}
|
||||||
|
fn readu32(buf: &[u8], pos: usize) -> u64 {
|
||||||
|
u32::from_be_bytes(buf.as_ref()[pos..pos + 4].try_into().unwrap()) as u64
|
||||||
|
}
|
||||||
|
let b = &buf;
|
||||||
|
//let s: String = b.iter().map(|x| format!(" {:02x}", *x)).collect();
|
||||||
|
//info!("\n\n{}", s);
|
||||||
|
let mut i1 = 0x2800;
|
||||||
|
while i1 < 0x2880 {
|
||||||
|
let s: String = b[i1..i1 + 8].iter().map(|x| format!(" {:02x}", *x)).collect();
|
||||||
|
info!("{}", s);
|
||||||
|
i1 += 8;
|
||||||
|
}
|
||||||
|
info!("{}", String::from_utf8_lossy(&b[0x2800..0x2880]));
|
||||||
let ret = IndexFileBasics {
|
let ret = IndexFileBasics {
|
||||||
version,
|
version,
|
||||||
name_hash_anchor_beg: u32::from_be_bytes(buf[0x04..0x08].try_into().unwrap()) as u64,
|
name_hash_anchor_beg: readu64(b, 0x04),
|
||||||
name_hash_anchor_len: u32::from_be_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
name_hash_anchor_len: readu32(b, 0x0c),
|
||||||
// TODO:
|
fa_used_list_len: readu64(b, 0x10),
|
||||||
fa_used_list_beg: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_used_list_beg: readu64(b, 0x18),
|
||||||
fa_used_list_end: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_used_list_end: readu64(b, 0x20),
|
||||||
fa_used_list_len: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_free_list_len: readu64(b, 0x28),
|
||||||
fa_free_list_beg: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_free_list_beg: readu64(b, 0x30),
|
||||||
fa_free_list_end: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_free_list_end: readu64(b, 0x38),
|
||||||
fa_free_list_len: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_header_len: readu64(b, 0x40),
|
||||||
fa_header_prev: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_header_prev: readu64(b, 0x48),
|
||||||
fa_header_next: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
fa_header_next: readu64(b, 0x50),
|
||||||
fa_header_len: u32::from_le_bytes(buf[0x08..0x0c].try_into().unwrap()) as u64,
|
|
||||||
};
|
};
|
||||||
|
let chn_hash = name_hash("X05DA-FE-WI1:TC1", ret.name_hash_anchor_len as u32);
|
||||||
|
info!("channel hash: {:08x}", chn_hash);
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +113,8 @@ mod test {
|
|||||||
let fut = async {
|
let fut = async {
|
||||||
let res = read_file_basics(CHN_0_MASTER_INDEX.into()).await?;
|
let res = read_file_basics(CHN_0_MASTER_INDEX.into()).await?;
|
||||||
info!("got {:?}", res);
|
info!("got {:?}", res);
|
||||||
assert!(res.version == 2 || res.version == 3);
|
assert_eq!(res.version, 3);
|
||||||
|
assert_eq!(res.file_offset_size(), 64);
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
Ok(taskrun::run(fut).unwrap())
|
Ok(taskrun::run(fut).unwrap())
|
||||||
|
|||||||
Reference in New Issue
Block a user