mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
historypack: add serialization logic for FileSectionHeaders
Summary: In an upcoming diff we'll start writing the actual history pack data file. The file section headers are part of that file, so let's implement the serialization logic and unit test it. Reviewed By: markbt Differential Revision: D9231400 fbshipit-source-id: eb1494e3b8fe3419f77edcaab25f640b48f16e4b
This commit is contained in:
parent
1d19243ea1
commit
6158355747
@ -72,7 +72,7 @@ pub struct NodeLocation {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
struct FileIndexEntry {
|
||||
pub(crate) struct FileIndexEntry {
|
||||
pub node: Node,
|
||||
pub file_section_offset: u64,
|
||||
pub file_section_size: u64,
|
||||
@ -107,7 +107,7 @@ impl FileIndexEntry {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct NodeIndexEntry {
|
||||
pub(crate) struct NodeIndexEntry {
|
||||
pub node: Node,
|
||||
pub offset: u64,
|
||||
}
|
||||
@ -132,7 +132,7 @@ impl NodeIndexEntry {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HistoryIndex {
|
||||
pub(crate) struct HistoryIndex {
|
||||
mmap: Mmap,
|
||||
version: HistoryPackVersion,
|
||||
fanout_size: usize,
|
||||
|
@ -1,3 +1,6 @@
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::io::{Cursor, Read, Write};
|
||||
|
||||
use error::Result;
|
||||
|
||||
#[derive(Debug, Fail)]
|
||||
@ -31,3 +34,58 @@ impl From<HistoryPackVersion> for u8 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct FileSectionHeader<'a> {
|
||||
pub file_name: &'a [u8],
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
fn read_slice<'a, 'b>(cur: &'a mut Cursor<&[u8]>, buf: &'b [u8], size: usize) -> Result<&'b [u8]> {
|
||||
let start = cur.position() as usize;
|
||||
let end = start + size;
|
||||
let file_name = &buf.get(start..end).ok_or_else(|| {
|
||||
HistoryPackError(format!(
|
||||
"buffer (length {:?}) not long enough to read {:?} bytes",
|
||||
buf.len(),
|
||||
size
|
||||
))
|
||||
})?;
|
||||
cur.set_position(end as u64);
|
||||
Ok(file_name)
|
||||
}
|
||||
|
||||
impl<'a> FileSectionHeader<'a> {
|
||||
pub(crate) fn read(buf: &[u8]) -> Result<FileSectionHeader> {
|
||||
let mut cur = Cursor::new(buf);
|
||||
let file_name_len = cur.read_u16::<BigEndian>()? as usize;
|
||||
let file_name = read_slice(&mut cur, &buf, file_name_len)?;
|
||||
|
||||
let count = cur.read_u32::<BigEndian>()?;
|
||||
Ok(FileSectionHeader { file_name, count })
|
||||
}
|
||||
|
||||
pub fn write<T: Write>(&self, writer: &mut T) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(self.file_name.len() as u16)?;
|
||||
writer.write_all(self.file_name)?;
|
||||
writer.write_u32::<BigEndian>(self.count)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
quickcheck! {
|
||||
fn test_file_section_header_serialization(name: Vec<u8>, count: u32) -> bool {
|
||||
let header = FileSectionHeader {
|
||||
file_name: name.as_ref(),
|
||||
count: count,
|
||||
};
|
||||
let mut buf = vec![];
|
||||
header.write(&mut buf).unwrap();
|
||||
header == FileSectionHeader::read(&buf).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user