2017-03-21 10:28:11 +00:00
|
|
|
use ::prelude::*;
|
|
|
|
|
2017-03-10 11:43:32 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::path::Path;
|
2017-03-16 08:42:30 +00:00
|
|
|
use std::io::{self, BufReader, Read, Write, BufWriter};
|
2017-03-10 11:43:32 +00:00
|
|
|
use std::fs::File;
|
|
|
|
|
|
|
|
|
|
|
|
static HEADER_STRING: [u8; 7] = *b"zbunmap";
|
|
|
|
static HEADER_VERSION: u8 = 1;
|
|
|
|
|
|
|
|
|
2017-03-16 08:42:30 +00:00
|
|
|
quick_error!{
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum BundleMapError {
|
|
|
|
Io(err: io::Error) {
|
|
|
|
from()
|
|
|
|
cause(err)
|
|
|
|
description("Failed to read/write bundle map")
|
|
|
|
}
|
|
|
|
Decode(err: msgpack::DecodeError) {
|
|
|
|
from()
|
|
|
|
cause(err)
|
|
|
|
description("Failed to decode bundle map")
|
|
|
|
}
|
|
|
|
Encode(err: msgpack::EncodeError) {
|
|
|
|
from()
|
|
|
|
cause(err)
|
|
|
|
description("Failed to encode bundle map")
|
|
|
|
}
|
|
|
|
WrongHeader {
|
|
|
|
description("Wrong header")
|
|
|
|
}
|
|
|
|
WrongVersion(version: u8) {
|
|
|
|
description("Wrong version")
|
|
|
|
display("Wrong version: {}", version)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-22 11:27:17 +00:00
|
|
|
pub struct BundleMap(HashMap<u32, BundleId>);
|
2017-03-10 11:43:32 +00:00
|
|
|
|
|
|
|
impl BundleMap {
|
|
|
|
pub fn create() -> Self {
|
|
|
|
BundleMap(Default::default())
|
|
|
|
}
|
|
|
|
|
2017-03-16 08:42:30 +00:00
|
|
|
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, BundleMapError> {
|
|
|
|
let mut file = BufReader::new(try!(File::open(path.as_ref())));
|
2017-03-10 11:43:32 +00:00
|
|
|
let mut header = [0u8; 8];
|
2017-03-16 08:42:30 +00:00
|
|
|
try!(file.read_exact(&mut header));
|
2017-03-10 11:43:32 +00:00
|
|
|
if header[..HEADER_STRING.len()] != HEADER_STRING {
|
2017-03-16 08:42:30 +00:00
|
|
|
return Err(BundleMapError::WrongHeader)
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
|
|
|
let version = header[HEADER_STRING.len()];
|
|
|
|
if version != HEADER_VERSION {
|
2017-03-16 08:42:30 +00:00
|
|
|
return Err(BundleMapError::WrongVersion(version))
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
2017-03-16 08:42:30 +00:00
|
|
|
Ok(BundleMap(try!(msgpack::decode_from_stream(&mut file))))
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
|
|
|
|
2017-03-16 08:42:30 +00:00
|
|
|
pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<(), BundleMapError> {
|
|
|
|
let mut file = BufWriter::new(try!(File::create(path)));
|
|
|
|
try!(file.write_all(&HEADER_STRING));
|
|
|
|
try!(file.write_all(&[HEADER_VERSION]));
|
|
|
|
msgpack::encode_to_stream(&self.0, &mut file).map_err(BundleMapError::Encode)
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-03-22 11:27:17 +00:00
|
|
|
pub fn get(&self, id: u32) -> Option<BundleId> {
|
|
|
|
self.0.get(&id).cloned()
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
|
|
|
|
2017-03-20 13:03:29 +00:00
|
|
|
#[inline]
|
2017-03-22 11:27:17 +00:00
|
|
|
pub fn remove(&mut self, id: u32) -> Option<BundleId> {
|
2017-03-20 13:03:29 +00:00
|
|
|
self.0.remove(&id)
|
|
|
|
}
|
|
|
|
|
2017-03-22 11:27:17 +00:00
|
|
|
pub fn find(&self, bundle: &BundleId) -> Option<u32> {
|
|
|
|
for (id, bundle_id) in &self.0 {
|
|
|
|
if bundle == bundle_id {
|
|
|
|
return Some(*id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn set(&mut self, id: u32, bundle: BundleId) {
|
|
|
|
self.0.insert(id, bundle);
|
2017-03-15 07:27:27 +00:00
|
|
|
}
|
|
|
|
|
2017-03-22 11:27:17 +00:00
|
|
|
pub fn bundles(&self) -> Vec<(u32, BundleId)> {
|
|
|
|
self.0.iter().map(|(id, bundle)| (*id, bundle.clone())).collect()
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|
2017-04-10 16:21:26 +00:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.0.len()
|
|
|
|
}
|
2017-03-10 11:43:32 +00:00
|
|
|
}
|