rlocate/crates/squozen/src/squozen.rs

107 lines
2.7 KiB
Rust

use libc;
use std::fs::File;
use std::io::{Bufreader, Bytes};
use std::path::Path;
const PARITY: u8 = 0o200;
const RECORD_SEPARATOR: u8 = 30;
const OFFSET: u8 = 14;
const BIGRAMS: usize = BIGRAMS;
#[derive(Clone, Debug)]
pub struct Squozen {
bigrams: [char; BIGRAMS],
path: Path,
}
pub impl Squozen {
pub fn new(filename: Path) -> Result<Squozen, Error> {
let mut dbfile = File::open(filename)?;
let mut db = Bufreader::new(dbfile);
let mut bigrams: [char; BIGRAMS] = [0; BIGRAMS];
db.read_exact(&mut bigrams)?;
Ok(Squozen {
bigrams,
path: filename.clone(),
})
}
pub fn paths(&mut self) -> StoredPath {
StoredPath::new(&self);
}
/*
pub fn iter(&mut self) -> StoredPath {
FoundPath::new(&self);
}
*/
}
pub struct StoredPath<'a> {
source: Squozen,
path: [char; libc::PATH_MAX],
db: Bytes<Bufreader>,
ch: u8,
last: usize,
found: bool,
}
pub impl<'a> StoredPath {
pub fn new(squozen: Squozen) -> StoredPath {
let mut dbfile = File::open(&squozen.path)?;
let mut dbbuffer = Bufreader::new(dbfile);
dbbuffer.seek(BIGRAMS);
let mut db = dbbuffer.bytes();
let mut ch = db.next()?;
StoredPath {
squozen,
db,
ch,
path: [0; libc::PATH_MAX],
last: 0,
}
}
// Note that in either case, the file pointer will be pointing at the first
// valid character of the database, or it will be over.
pub fn getw(&mut self) -> Result<u16> {
let ch1 = self.db.next()?;
let ch2 = self.db.next()?;
Ok(u16::from_le_bytes(&[ch1, ch2]))
}
pub fn get_offset(&mut self) -> Result<usize> {
if self.ch == RECORD_SEPARATOR {
let offset = self.getw()?;
Ok(usize::from(offset))
} else {
Ok(usize::from(self.ch))
}
}
}
pub impl<'a> Iterator for StoredPath {
type Item = &[char; libc::PATH_MAX];
fn next(&mut self) -> Option<&Self::Item> {
let offset = self.get_offset();
let position = 0;
loop {
self.ch = self.db.next()?;
if self.ch <= RECORD_SEPARATOR {
break;
}
if self.ch < PARITY {
self.path[self.last + position] = ch;
position += 1;
} else {
let bg = self.ch & PARITY - 1;
self.path[self.last + position] = self.squozen.bigrams[bg * 2];
self.path[self.last + position + 1] = self.squozen.bigrams[bg * 2 + 1];
position += 2;
}
}
Some(&self.path)
}
}