Skip to content

Commit

Permalink
Merge ba28ad1 into 6457a0d
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminwinger committed Aug 25, 2019
2 parents 6457a0d + ba28ad1 commit 5464f99
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
68 changes: 65 additions & 3 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl Default for RecordIds {
struct PluginData {
header_record: Record,
record_ids: RecordIds,
records: Vec<Record>,
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
Expand Down Expand Up @@ -325,6 +326,10 @@ impl Plugin {
fn is_light_master_flag_set(&self) -> bool {
self.data.header_record.header().flags() & 0x200 != 0
}

pub fn get_records(&self) -> &Vec<Record> {
&self.data.records
}
}

fn sorted_slices_intersect<T: PartialOrd>(left: &[T], right: &[T]) -> bool {
Expand Down Expand Up @@ -420,6 +425,19 @@ fn parse_morrowind_record_ids<'a>(input: &'a [u8]) -> IResult<&'a [u8], RecordId
Ok((remaining_input, record_ids.into()))
}

fn parse_morrowind_records<'a>(input: &'a [u8]) -> IResult<&'a [u8], Vec<Record>> {
let mut records = Vec::new();
let mut remaining_input = input;

while !remaining_input.is_empty() {
let (input, record) = Record::parse(remaining_input, GameId::Morrowind, false)?;
remaining_input = input;
records.push(record);
}

Ok((remaining_input, records.into()))
}

fn read_morrowind_record_ids<R: BufRead + Seek>(reader: &mut R) -> Result<RecordIds, Error> {
let mut record_ids = Vec::new();
let mut header_buf = [0; 16]; // Morrowind record headers are 16 bytes long.
Expand All @@ -436,6 +454,18 @@ fn read_morrowind_record_ids<R: BufRead + Seek>(reader: &mut R) -> Result<Record
Ok(record_ids.into())
}

fn read_morrowind_records<R: BufRead + Seek>(reader: &mut R) -> Result<Vec<Record>, Error> {
let mut records = Vec::new();

while !reader.fill_buf()?.is_empty() {
let record = Record::read(reader, GameId::Morrowind, false)?;

records.push(record);
}

Ok(records)
}

fn parse_record_ids<'a>(
input: &'a [u8],
game_id: GameId,
Expand All @@ -457,6 +487,19 @@ fn parse_record_ids<'a>(
}
}

fn parse_records<'a>(
input: &'a [u8],
game_id: GameId,
header_record: &Record,
filename: &str,
) -> IResult<&'a [u8], Vec<Record>> {
if game_id == GameId::Morrowind {
parse_morrowind_records(input)
} else {
panic!("Parsing records is not supported for {:?}", game_id);
}
}

fn read_record_ids<R: BufRead + Seek>(
reader: &mut R,
game_id: GameId,
Expand All @@ -475,6 +518,19 @@ fn read_record_ids<R: BufRead + Seek>(
}
}

fn read_records<R: BufRead + Seek>(
reader: &mut R,
game_id: GameId,
header_record: &Record,
filename: &str,
) -> Result<Vec<Record>, Error> {
if game_id == GameId::Morrowind {
read_morrowind_records(reader)
} else {
panic!("Reading records for is not supported for {:?}", game_id);
}
}

fn parse_plugin<'a>(
input: &'a [u8],
game_id: GameId,
Expand All @@ -489,17 +545,20 @@ fn parse_plugin<'a>(
PluginData {
header_record,
record_ids: RecordIds::None,
records: vec![],
},
));
}

let (input2, record_ids) = parse_record_ids(input1, game_id, &header_record, filename)?;
let (input2, records) = parse_records(input1, game_id, &header_record, filename)?;
let (_, record_ids) = parse_record_ids(input1, game_id, &header_record, filename)?;

Ok((
input2,
PluginData {
header_record,
record_ids,
records,
},
))
}
Expand All @@ -524,14 +583,17 @@ fn read_plugin<R: BufRead + Seek>(
return Ok(PluginData {
header_record,
record_ids: RecordIds::None,
records: vec![],
});
}

let record_ids = read_record_ids(reader, game_id, &header_record, filename)?;
let records = read_records(reader, game_id, &header_record, filename)?;

Ok(PluginData {
header_record,
record_ids,
// TODO: Parse record ids from records
record_ids: RecordIds::None,
records,
})
}

Expand Down
5 changes: 5 additions & 0 deletions src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use std::convert::TryInto;
use std::io;
use std::num::NonZeroU32;
use std::string::FromUtf8Error;

use nom::bytes::complete::take;
use nom::combinator::{cond, map};
Expand Down Expand Up @@ -50,6 +51,10 @@ impl RecordHeader {
pub fn flags(&self) -> u32 {
self.flags
}

pub fn typ(&self) -> Result<String, FromUtf8Error> {
String::from_utf8(self.record_type.to_vec())
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash, Default)]
Expand Down
5 changes: 5 additions & 0 deletions src/subrecord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::convert::TryInto;
use std::io;
#[cfg(feature = "compressed-fields")]
use std::io::Read;
use std::string::FromUtf8Error;

#[cfg(feature = "compressed-fields")]
use flate2::read::DeflateDecoder;
Expand Down Expand Up @@ -93,6 +94,10 @@ impl Subrecord {
pub fn data(&self) -> &[u8] {
&self.data
}

pub fn typ(&self) -> Result<String, FromUtf8Error> {
String::from_utf8(self.subrecord_type.to_vec())
}
}

pub struct SubrecordRef<'a> {
Expand Down

0 comments on commit 5464f99

Please sign in to comment.