add rayon
This commit is contained in:
parent
f4d308fd53
commit
ffedf08dfd
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -56,6 +56,12 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -386,6 +392,7 @@ dependencies = [
|
|||||||
name = "rsParser-r"
|
name = "rsParser-r"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"flate2",
|
"flate2",
|
||||||
"indoc",
|
"indoc",
|
||||||
@ -396,6 +403,7 @@ dependencies = [
|
|||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -475,6 +483,26 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.33",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
|||||||
@ -17,3 +17,5 @@ serde_json = "1.0.107"
|
|||||||
flate2 = "1.0.27"
|
flate2 = "1.0.27"
|
||||||
indoc = "2.0.3"
|
indoc = "2.0.3"
|
||||||
num-traits = "0.2.16"
|
num-traits = "0.2.16"
|
||||||
|
thiserror = "1.0.48"
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
|||||||
54
src/app.rs
54
src/app.rs
@ -1,11 +1,57 @@
|
|||||||
use num_traits::Num;
|
use crate::parse::{Parsed, parse};
|
||||||
|
use crate::error::{AResult, BrokenError};
|
||||||
|
use crate::utils::is_gz;
|
||||||
|
use rayon::prelude::{*, IndexedParallelIterator};
|
||||||
|
use flate2::read::GzDecoder;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
|
|
||||||
use crate::parse::Parsed;
|
type AAResult<O> = AResult<O,()>;
|
||||||
|
|
||||||
pub struct App{
|
pub struct App {
|
||||||
datas: Vec<Parsed>
|
paths: Vec<PathBuf>,
|
||||||
|
config: AppConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||||
|
pub struct AppConfig {
|
||||||
|
pub only_header: bool,
|
||||||
|
pub multi_threading: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
pub fn new(paths: Vec<PathBuf>, config: AppConfig) -> Result<Self, BrokenError> {
|
||||||
|
Ok(Self { paths, config })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(&self) ->AAResult<Vec<Parsed>> {
|
||||||
|
let paths = &self.paths;
|
||||||
|
let config = &self.config;
|
||||||
|
let datas = paths.par_iter().map(|p| {
|
||||||
|
let d = Self::data_prepare(p);
|
||||||
|
match d {
|
||||||
|
Ok(_d) => parse(&_d, config.only_header).map(|(_,b)| b).map_err(|e| e.into()),
|
||||||
|
Err(e) => Err(e.into())
|
||||||
|
}
|
||||||
|
}).collect::<Result<Vec<_>, BrokenError>>()?;
|
||||||
|
Ok((datas,()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_prepare(path: &PathBuf) -> Result<Vec<u8>, std::io::Error> {
|
||||||
|
let mut f = File::open(path)?;
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
{
|
||||||
|
let mut magic = [0; 2];
|
||||||
|
f.read_exact(&mut magic)?;
|
||||||
|
f.seek(SeekFrom::Start(0))?;
|
||||||
|
if is_gz(&magic) {
|
||||||
|
let mut d = GzDecoder::new(f);
|
||||||
|
d.read_to_end(&mut buf)?;
|
||||||
|
} else {
|
||||||
|
f.read_to_end(&mut buf)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
18
src/error.rs
Normal file
18
src/error.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
use nom::Err;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum BrokenError {
|
||||||
|
#[error("Can't Open file or file not exist.")]
|
||||||
|
IO(#[from] std::io::Error),
|
||||||
|
#[error("This file is not standard format.")]
|
||||||
|
ParseError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Err<T>> for BrokenError {
|
||||||
|
fn from(value: Err<T>) -> Self {
|
||||||
|
Self::ParseError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type AResult<O, E> = Result<(O, E), BrokenError>;
|
||||||
15
src/main.rs
15
src/main.rs
@ -2,6 +2,8 @@ mod parse;
|
|||||||
mod app;
|
mod app;
|
||||||
mod printer;
|
mod printer;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod error;
|
||||||
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@ -11,6 +13,8 @@ use std::path::PathBuf;
|
|||||||
use clap::{Args, command, Parser, Subcommand, ValueEnum};
|
use clap::{Args, command, Parser, Subcommand, ValueEnum};
|
||||||
use parse::parse;
|
use parse::parse;
|
||||||
|
|
||||||
|
use crate::app::{App, AppConfig};
|
||||||
|
|
||||||
/// A fictional versioning CLI
|
/// A fictional versioning CLI
|
||||||
#[derive(Debug, Parser)] // requires `derive` feature
|
#[derive(Debug, Parser)] // requires `derive` feature
|
||||||
#[command(name = "rsParser")]
|
#[command(name = "rsParser")]
|
||||||
@ -76,12 +80,11 @@ fn main() {
|
|||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
match args.command {
|
match args.command {
|
||||||
Commands::Parse { path, header } => {
|
Commands::Parse { path, header } => {
|
||||||
let f = File::open(path).unwrap();
|
let config = AppConfig{
|
||||||
let mut d = GzDecoder::new(f);
|
only_header:header,
|
||||||
let mut buf = Vec::new();
|
multi_threading:true
|
||||||
d.read_to_end(&mut buf).unwrap();
|
};
|
||||||
let (_, parsed) = parse(&buf, header).unwrap();
|
let app = App::new(vec![path], config).unwrap();
|
||||||
println!("{}", parsed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
63
src/parse.rs
63
src/parse.rs
@ -1,17 +1,12 @@
|
|||||||
use ndarray::ArrayD;
|
|
||||||
use nom::bytes::complete::*;
|
use nom::bytes::complete::*;
|
||||||
use nom::error::ParseError;
|
use nom::error::{ParseError, ErrorKind};
|
||||||
use nom::multi::count;
|
use nom::multi::count;
|
||||||
use nom::number::complete::{
|
use nom::number::complete::{be_f32, be_i32, be_i8, be_u32, be_u8, le_f32, le_i32, le_i8, le_u8, le_u32};
|
||||||
be_f32, be_f64, be_i16, be_i32, be_i8, be_u8, le_f32, le_f64, le_i16, le_i32, le_i8, le_u8,
|
|
||||||
};
|
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
use nom_derive;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use std::string;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct HeaderJson {
|
pub struct HeaderJson {
|
||||||
@ -51,7 +46,7 @@ pub struct CommonHeader {
|
|||||||
|
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub block_info: BlockInfo,
|
pub block_info: BlockInfo,
|
||||||
pub data: Option<Box<dyn Any>>,
|
pub data: Option<Box<dyn Any + Sync + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Parsed {
|
pub struct Parsed {
|
||||||
@ -93,7 +88,8 @@ fn common_parse(input: &[u8]) -> IResult<&[u8], CommonHeader> {
|
|||||||
fn block_parse<'a, Error: ParseError<&'a [u8]>>(
|
fn block_parse<'a, Error: ParseError<&'a [u8]>>(
|
||||||
only_header: bool,
|
only_header: bool,
|
||||||
endian: Endian,
|
endian: Endian,
|
||||||
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Block, Error> {
|
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Block, Error>
|
||||||
|
{
|
||||||
let l_p = match endian {
|
let l_p = match endian {
|
||||||
Endian::Big => be_i32,
|
Endian::Big => be_i32,
|
||||||
Endian::Little => le_i32,
|
Endian::Little => le_i32,
|
||||||
@ -112,28 +108,57 @@ fn block_parse<'a, Error: ParseError<&'a [u8]>>(
|
|||||||
let (next, l2) = l_p(next)?;
|
let (next, l2) = l_p(next)?;
|
||||||
let (next, _data) = take(l2 as usize)(next)?;
|
let (next, _data) = take(l2 as usize)(next)?;
|
||||||
|
|
||||||
|
let mut d: Option<Box<dyn Any + Send + Sync>> = None;
|
||||||
|
|
||||||
if !only_header {
|
if !only_header {
|
||||||
let c = j.dimension_size.iter().fold(1, |i, j| i * (*j)) as usize;
|
let c = j.dimension_size.iter().fold(1, |i, j| i * (*j)) as usize;
|
||||||
match j.value_type.as_str() {
|
d = match j.value_type.as_str() {
|
||||||
"b" => {
|
"b" => {
|
||||||
let (next,v) = count(match endian {
|
let (_, v) = count(match endian {
|
||||||
Endian::Big => be_i8,
|
Endian::Big => be_i8,
|
||||||
_ => le_i8
|
_ => le_i8
|
||||||
},c)(_data)?;
|
}, c)(_data)?;
|
||||||
|
Some(Box::new(v))
|
||||||
}
|
}
|
||||||
"B" => {}
|
"B" => {
|
||||||
"h" => {}
|
let (_, v) = count(match endian {
|
||||||
"f" => {}
|
Endian::Big => be_u8,
|
||||||
_ => {}
|
_ => le_u8
|
||||||
|
}, c)(_data)?;
|
||||||
|
Some(Box::new(v))
|
||||||
}
|
}
|
||||||
|
"i" => {
|
||||||
|
let (_, v) = count(match endian {
|
||||||
|
Endian::Big => be_i32,
|
||||||
|
_ => le_i32
|
||||||
|
}, c)(_data)?;
|
||||||
|
Some(Box::new(v))
|
||||||
|
}
|
||||||
|
"u" => {
|
||||||
|
let (_, v) = count(match endian {
|
||||||
|
Endian::Big => be_u32,
|
||||||
|
_ => le_u32
|
||||||
|
}, c)(_data)?;
|
||||||
|
Some(Box::new(v))
|
||||||
|
}
|
||||||
|
"f" => {
|
||||||
|
let (_, v) = count(match endian {
|
||||||
|
Endian::Big => be_f32,
|
||||||
|
_ => le_f32
|
||||||
|
}, c)(_data)?;
|
||||||
|
Some(Box::new(v))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(nom::Err::Failure(Error::from_error_kind(next, ErrorKind::Alpha)));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let (next, _) = take(8usize)(next)?;
|
let (next, _) = take(8usize)(next)?;
|
||||||
Ok((
|
Ok((
|
||||||
next,
|
next,
|
||||||
Block {
|
Block {
|
||||||
block_info: j,
|
block_info: j,
|
||||||
data: None,
|
data: d,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -151,7 +176,7 @@ fn blocks_parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<'a>(input: &'a [u8], only_header: bool) -> IResult<&'a [u8], Parsed> {
|
pub fn parse<'a>(input: &'a [u8], only_header: bool) -> IResult<&'a [u8], Parsed> {
|
||||||
let (next, magic) = tag(b"UNI_DATA")(input)?;
|
let (next, _) = tag(b"UNI_DATA")(input)?;
|
||||||
let (next, common_header) = common_parse(next)?;
|
let (next, common_header) = common_parse(next)?;
|
||||||
let (next, blocks) = blocks_parse(
|
let (next, blocks) = blocks_parse(
|
||||||
next,
|
next,
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
fn is_gz(data:&[u8;2]) -> bool{
|
pub fn is_gz(data:&[u8;2]) -> bool{
|
||||||
*data == [0x1f, 0x8b]
|
*data == [0x1f, 0x8b]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user