diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..5bb6c5e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Launch", + "program": "${workspaceFolder}/target/debug/ripgrib", + "args": [], + "cwd": "${workspaceFolder}" + } + + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index a842f02..640bbef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + [[package]] name = "cfg-if" version = "1.0.0" @@ -44,6 +50,64 @@ dependencies = [ "winapi", ] +[[package]] +name = "clap" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "getrandom" version = "0.2.8" @@ -55,6 +119,21 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "ibmfloat" version = "0.1.1" @@ -67,6 +146,28 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2d6f23ffea9d7e76c53eee25dfb67bcd8fde7f1198b0855350698c9f07c780" +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -75,9 +176,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "lock_api" @@ -89,6 +196,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + [[package]] name = "matrixmultiply" version = "0.3.2" @@ -191,6 +307,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + [[package]] name = "parking_lot" version = "0.12.1" @@ -214,6 +336,72 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.49" @@ -292,6 +480,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "rawpointer" version = "0.2.1" @@ -313,11 +516,29 @@ version = "0.1.0" dependencies = [ "bitflags", "chrono", + "clap", "ibmfloat", "lazy_static", + "log", "nom", "numpy", + "phf", "pyo3", + "thiserror", +] + +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", ] [[package]] @@ -326,12 +547,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + [[package]] name = "smallvec" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.107" @@ -349,6 +582,35 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" @@ -406,6 +668,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index e019f08..d1e2972 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # -[lib] -name = "pyo3_example" - # "cdylib" is necessary to produce a shared library for Python to import from. crate-type = ["cdylib"] [dependencies] +phf = { version = "0.11", features = ["macros"] } nom = "7.1.1" chrono = "0.4" bitflags = "1.3.2" @@ -19,3 +17,6 @@ lazy_static = "1.4.0" pyo3 = { version = "0.17.3", features = ["extension-module"] } numpy = "0.17" ibmfloat = "0.1.1" +thiserror = "1.0.38" +clap = {version="4.1.1",features=["derive"]} +log = "0.4" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index d010ffb..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,12 +0,0 @@ -[build-system] -requires = ["maturin>=0.13,<0.14"] -build-backend = "maturin" - -[project] -name = "pyo3_example" -requires-python = ">=3.7" -classifiers = [ - "Programming Language :: Rust", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", -] diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..50449d5 --- /dev/null +++ b/src/config.rs @@ -0,0 +1 @@ +pub struct Config {} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..c465797 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,21 @@ +use std::io; +use thiserror::Error; + +pub type Result = std::result::Result, UnexpectedError>; + +#[derive(Error, Debug)] +pub enum UnexpectedError { + #[error("")] + IOError { + #[from] + source: io::Error, + }, + #[error("")] + FormatError, + + #[error("")] + FileNotExistError, +} + +#[derive(Error, Debug)] +pub enum AppError {} diff --git a/src/grib/bds.rs b/src/grib1/bds.rs similarity index 64% rename from src/grib/bds.rs rename to src/grib1/bds.rs index 7b01d1a..ce9d7d6 100644 --- a/src/grib/bds.rs +++ b/src/grib1/bds.rs @@ -1,7 +1,7 @@ use bitflags::bitflags; use nom::{ bytes::complete::take, - number::complete::{le_f32, le_i16, le_u24, u8}, + number::complete::{be_i16, be_u24, be_u32, u8}, sequence::tuple, IResult, }; @@ -16,6 +16,11 @@ bitflags! { const COMPLEX_PACKING = 0b01000000; const INTEGER_NUMBERIC = 0b00100000; const ADDITIONAL_FLAG = 0b00010000; + + const RESERVE = 0b00001000; + const MATRIX_VALUE = 0b00000100; + const SECONDARY_BIT_MAP = 0b00000010; + const DIFFERENT_WIDTH = 0b00000001; } } @@ -31,6 +36,19 @@ pub struct BDS<'a> { data: PackedData<'a>, } +impl<'a> Default for BDS<'a> { + fn default() -> Self { + BDS { + length: 0, + flag: BdsFlag::empty(), + scale: 0, + refrence_value: 0.0, + bit_number: 0, + data: PackedData::Other, + } + } +} + #[derive(Debug)] enum PackedData<'a> { Simple(&'a [u8]), @@ -45,39 +63,36 @@ enum PackedData<'a> { first_order_packed_values: &'a [u8], second_order_packed_values: &'a [u8], }, + + Other, +} + +fn float_transer(input: u32) -> f32 { + ibmfloat::F32::from_bits(input).into() } pub fn bds_parser<'a>(input: &'a [u8]) -> IResult<&'a [u8], BDS<'a>> { let (next, (length, flag_bit, scale, refrence, number)) = - tuple((le_u24, u8, le_i16, le_f32, u8))(input)?; + tuple((be_u24, u8, be_i16, be_u32, u8))(input)?; + + println!("length:{},flag:{:#b}", length, flag_bit); let flags = BdsFlag::from_bits(flag_bit).unwrap(); if flags.contains(BdsFlag::COMPLEX_PACKING) { panic!(); } else { - let (next, value) = take(length - 11)(next)?; + let (next, value) = take((length - 11) as usize)(next)?; + Ok(( next, BDS { length: length as usize, flag: flags, scale, - refrence_value: refrence, + refrence_value: float_transer(refrence), bit_number: number as usize, data: PackedData::Simple(value), }, )) } - // // Grid-point data - Simple packing - // let g_s = BdsFlag::DATA_TYPE | BdsFlag::PACKING_TYPE; - // let s_s = !BdsFlag::DATA_TYPE | BdsFlag::PACKING_TYPE; - // let g_c = BdsFlag::DATA_TYPE | !BdsFlag::PACKING_TYPE; - // // total length - // let total_length: usize = gds.representation.get_total(); - - // if flags.contains(g_s) { - // if let Some(b) = bms.as_ref() { - // for v in bms {} - // } - // } } diff --git a/src/grib/bms.rs b/src/grib1/bms.rs similarity index 90% rename from src/grib/bms.rs rename to src/grib1/bms.rs index 20f0f97..0a89aad 100644 --- a/src/grib/bms.rs +++ b/src/grib1/bms.rs @@ -1,6 +1,6 @@ use nom::{ bytes::complete::take, - number::complete::{le_u16, le_u24, u8}, + number::complete::{be_u16, be_u24, u8}, sequence::tuple, IResult, }; @@ -72,7 +72,7 @@ impl<'a> Iterator for BitMap<'a> { } pub fn bms_parser(input: &[u8]) -> IResult<&[u8], BMS> { - let (mut next, (length, unused, b_type)) = tuple((le_u24, u8, le_u16))(input)?; + let (mut next, (length, unused, b_type)) = tuple((be_u24, u8, be_u16))(input)?; let map_type = if b_type == 0 { BitmapType::Follows @@ -81,7 +81,7 @@ pub fn bms_parser(input: &[u8]) -> IResult<&[u8], BMS> { }; let map: Option = if let BitmapType::Follows = map_type { - let (n, map_part) = take((length - 7) as usize)(next)?; + let (n, map_part) = take((length - 6) as usize)(next)?; next = n; let len = map_part.len(); Some(BitMap::new(&map_part, unused as usize)) diff --git a/src/grib/gds.rs b/src/grib1/gds.rs similarity index 89% rename from src/grib/gds.rs rename to src/grib1/gds.rs index e25479a..380ca77 100644 --- a/src/grib/gds.rs +++ b/src/grib1/gds.rs @@ -2,9 +2,8 @@ use lazy_static::lazy_static; use nom::{ bytes::complete::take, - character::complete::u8, multi::count, - number::complete::{be_u16, le_i16, le_i24, le_u24}, + number::complete::{be_i16, be_i24, be_u16, be_u24, u8}, sequence::tuple, IResult, }; @@ -21,6 +20,7 @@ lazy_static! { // Type declare #[derive(Debug)] pub struct GDS<'a> { + length: usize, pub nv: usize, pub representation: DataRepresentation, pv: Option<&'a [u8]>, @@ -175,13 +175,13 @@ impl Default for DP { let (next, nj) = be_u16(next)?; let (next, (lat1, lon1, reso, lat2, lon2, di, dj, scan_mode, _)) = tuple(( - le_i24, - le_i24, + be_i24, + be_i24, u8, - le_i24, - le_i24, - le_i16, - le_i16, + be_i24, + be_i24, + be_i16, + be_i16, u8, take(4usize), ))(next)?; @@ -212,15 +212,15 @@ impl Default for DP { let (next, nj) = be_u16(next)?; let (next, (lat1, lon1, reso, lat2, lon2, latin, _, scan_mode, dij, _)) = tuple(( - le_i24, - le_i24, + be_i24, + be_i24, u8, - le_i24, - le_i24, - le_u24, + be_i24, + be_i24, + be_u24, take(1usize), u8, - count(le_i24, 2), + count(be_i24, 2), take(8usize), ))(next)?; @@ -250,13 +250,13 @@ impl Default for DP { let (next, ny) = be_u16(next)?; let (next, (lat1, lon1, reso, lxy, center, scan, lls, _)) = tuple(( - le_i24, - le_i24, + be_i24, + be_i24, u8, - count(le_i24, 3), + count(be_i24, 3), u8, u8, - count(le_i24, 4), + count(be_i24, 4), take(2usize), ))(next)?; @@ -293,7 +293,7 @@ impl Default for DP { let (next, ny) = be_u16(next)?; let (next, (lat1, lon1, reso, lxy, center, scan, _)) = - tuple((le_i24, le_i24, u8, count(le_i24, 3), u8, u8, take(4usize)))(next)?; + tuple((be_i24, be_i24, u8, count(be_i24, 3), u8, u8, take(4usize)))(next)?; return Ok(( next, @@ -324,7 +324,7 @@ impl Default for DP { let (next, nj) = be_u16(next)?; let (next, (lat1, lon1, reso, lij, scan, _)) = - tuple((le_i24, le_i24, u8, count(le_i24, 4), u8, take(4usize)))(next)?; + tuple((be_i24, be_i24, u8, count(be_i24, 4), u8, take(4usize)))(next)?; return Ok(( next, @@ -364,22 +364,34 @@ impl DP { fn representation_parser(input: &[u8]) -> IResult<&[u8], DataRepresentation> { let (next, projection_type_mask) = u8(input)?; + return E.run_event(next, projection_type_mask); } pub fn gds_parser(input: &[u8]) -> IResult<&[u8], GDS> { - let (next, gds_length) = le_u24(input)?; - let nv_p = u8; - let pv_or_pl_p = u8; + let (next, gds_length) = be_u24(input)?; - let (next, (nv, pv_pl, data_repr)) = tuple((nv_p, pv_or_pl_p, representation_parser))(next)?; + let (next, (nv, pv_pl, data_repr)) = tuple((u8, u8, representation_parser))(next)?; + + if pv_pl == 255 { + return Ok(( + next, + GDS { + length: gds_length as usize, + nv: nv as usize, + representation: data_repr, + pv: None, + pl: None, + }, + )); + } if nv == 0 { - assert!(pv_pl != 255); let (next, pl_list) = take(data_repr.row_length * 2)(next)?; return Ok(( next, GDS { + length: gds_length as usize, nv: nv as usize, representation: data_repr, pv: None, @@ -392,6 +404,7 @@ pub fn gds_parser(input: &[u8]) -> IResult<&[u8], GDS> { return Ok(( next, GDS { + length: gds_length as usize, nv: nv as usize, representation: data_repr, pv: Some(pv_list), diff --git a/src/grib/is.rs b/src/grib1/is.rs similarity index 76% rename from src/grib/is.rs rename to src/grib1/is.rs index 84dd519..c75f455 100644 --- a/src/grib/is.rs +++ b/src/grib1/is.rs @@ -1,19 +1,19 @@ use nom::{ bytes::complete::tag, - number::{complete::le_u24, complete::u8}, + number::{complete::be_u24, complete::u8}, sequence::{preceded, tuple}, IResult, }; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct IS { total_length: usize, version_number: u8, } pub fn is_parser(input: &[u8]) -> IResult<&[u8], IS> { - let grib = tag([]); - let total_length = le_u24; + let grib = tag([71, 82, 73, 66]); + let total_length = be_u24; let editon = u8; let (input, (len, edition_number)) = preceded(grib, tuple((total_length, editon)))(input)?; diff --git a/src/grib/mod.rs b/src/grib1/mod.rs similarity index 82% rename from src/grib/mod.rs rename to src/grib1/mod.rs index 60473c1..0b86171 100644 --- a/src/grib/mod.rs +++ b/src/grib1/mod.rs @@ -3,5 +3,6 @@ pub mod bms; pub mod gds; pub mod is; pub mod pds; +pub mod product; mod parm_tables; diff --git a/src/grib/parm_tables/dwdtable_002.rs b/src/grib1/parm_tables/dwdtable_002.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_002.rs rename to src/grib1/parm_tables/dwdtable_002.rs diff --git a/src/grib/parm_tables/dwdtable_201.rs b/src/grib1/parm_tables/dwdtable_201.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_201.rs rename to src/grib1/parm_tables/dwdtable_201.rs diff --git a/src/grib/parm_tables/dwdtable_202.rs b/src/grib1/parm_tables/dwdtable_202.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_202.rs rename to src/grib1/parm_tables/dwdtable_202.rs diff --git a/src/grib/parm_tables/dwdtable_203.rs b/src/grib1/parm_tables/dwdtable_203.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_203.rs rename to src/grib1/parm_tables/dwdtable_203.rs diff --git a/src/grib/parm_tables/dwdtable_204.rs b/src/grib1/parm_tables/dwdtable_204.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_204.rs rename to src/grib1/parm_tables/dwdtable_204.rs diff --git a/src/grib/parm_tables/dwdtable_205.rs b/src/grib1/parm_tables/dwdtable_205.rs similarity index 100% rename from src/grib/parm_tables/dwdtable_205.rs rename to src/grib1/parm_tables/dwdtable_205.rs diff --git a/src/grib/parm_tables/ectable_128.rs b/src/grib1/parm_tables/ectable_128.rs similarity index 100% rename from src/grib/parm_tables/ectable_128.rs rename to src/grib1/parm_tables/ectable_128.rs diff --git a/src/grib/parm_tables/ectable_129.rs b/src/grib1/parm_tables/ectable_129.rs similarity index 100% rename from src/grib/parm_tables/ectable_129.rs rename to src/grib1/parm_tables/ectable_129.rs diff --git a/src/grib/parm_tables/ectable_130.rs b/src/grib1/parm_tables/ectable_130.rs similarity index 100% rename from src/grib/parm_tables/ectable_130.rs rename to src/grib1/parm_tables/ectable_130.rs diff --git a/src/grib/parm_tables/ectable_131.rs b/src/grib1/parm_tables/ectable_131.rs similarity index 100% rename from src/grib/parm_tables/ectable_131.rs rename to src/grib1/parm_tables/ectable_131.rs diff --git a/src/grib/parm_tables/ectable_132.rs b/src/grib1/parm_tables/ectable_132.rs similarity index 100% rename from src/grib/parm_tables/ectable_132.rs rename to src/grib1/parm_tables/ectable_132.rs diff --git a/src/grib/parm_tables/ectable_133.rs b/src/grib1/parm_tables/ectable_133.rs similarity index 100% rename from src/grib/parm_tables/ectable_133.rs rename to src/grib1/parm_tables/ectable_133.rs diff --git a/src/grib/parm_tables/ectable_140.rs b/src/grib1/parm_tables/ectable_140.rs similarity index 100% rename from src/grib/parm_tables/ectable_140.rs rename to src/grib1/parm_tables/ectable_140.rs diff --git a/src/grib/parm_tables/ectable_150.rs b/src/grib1/parm_tables/ectable_150.rs similarity index 100% rename from src/grib/parm_tables/ectable_150.rs rename to src/grib1/parm_tables/ectable_150.rs diff --git a/src/grib/parm_tables/ectable_151.rs b/src/grib1/parm_tables/ectable_151.rs similarity index 100% rename from src/grib/parm_tables/ectable_151.rs rename to src/grib1/parm_tables/ectable_151.rs diff --git a/src/grib/parm_tables/ectable_160.rs b/src/grib1/parm_tables/ectable_160.rs similarity index 100% rename from src/grib/parm_tables/ectable_160.rs rename to src/grib1/parm_tables/ectable_160.rs diff --git a/src/grib/parm_tables/ectable_162.rs b/src/grib1/parm_tables/ectable_162.rs similarity index 100% rename from src/grib/parm_tables/ectable_162.rs rename to src/grib1/parm_tables/ectable_162.rs diff --git a/src/grib/parm_tables/ectable_170.rs b/src/grib1/parm_tables/ectable_170.rs similarity index 100% rename from src/grib/parm_tables/ectable_170.rs rename to src/grib1/parm_tables/ectable_170.rs diff --git a/src/grib/parm_tables/ectable_171.rs b/src/grib1/parm_tables/ectable_171.rs similarity index 100% rename from src/grib/parm_tables/ectable_171.rs rename to src/grib1/parm_tables/ectable_171.rs diff --git a/src/grib/parm_tables/ectable_172.rs b/src/grib1/parm_tables/ectable_172.rs similarity index 100% rename from src/grib/parm_tables/ectable_172.rs rename to src/grib1/parm_tables/ectable_172.rs diff --git a/src/grib/parm_tables/ectable_173.rs b/src/grib1/parm_tables/ectable_173.rs similarity index 100% rename from src/grib/parm_tables/ectable_173.rs rename to src/grib1/parm_tables/ectable_173.rs diff --git a/src/grib/parm_tables/ectable_174.rs b/src/grib1/parm_tables/ectable_174.rs similarity index 100% rename from src/grib/parm_tables/ectable_174.rs rename to src/grib1/parm_tables/ectable_174.rs diff --git a/src/grib/parm_tables/ectable_180.rs b/src/grib1/parm_tables/ectable_180.rs similarity index 100% rename from src/grib/parm_tables/ectable_180.rs rename to src/grib1/parm_tables/ectable_180.rs diff --git a/src/grib/parm_tables/ectable_190.rs b/src/grib1/parm_tables/ectable_190.rs similarity index 100% rename from src/grib/parm_tables/ectable_190.rs rename to src/grib1/parm_tables/ectable_190.rs diff --git a/src/grib/parm_tables/ectable_200.rs b/src/grib1/parm_tables/ectable_200.rs similarity index 100% rename from src/grib/parm_tables/ectable_200.rs rename to src/grib1/parm_tables/ectable_200.rs diff --git a/src/grib/parm_tables/ectable_210.rs b/src/grib1/parm_tables/ectable_210.rs similarity index 100% rename from src/grib/parm_tables/ectable_210.rs rename to src/grib1/parm_tables/ectable_210.rs diff --git a/src/grib/parm_tables/ectable_211.rs b/src/grib1/parm_tables/ectable_211.rs similarity index 100% rename from src/grib/parm_tables/ectable_211.rs rename to src/grib1/parm_tables/ectable_211.rs diff --git a/src/grib/parm_tables/ectable_228.rs b/src/grib1/parm_tables/ectable_228.rs similarity index 100% rename from src/grib/parm_tables/ectable_228.rs rename to src/grib1/parm_tables/ectable_228.rs diff --git a/src/grib/parm_tables/mod.rs b/src/grib1/parm_tables/mod.rs similarity index 91% rename from src/grib/parm_tables/mod.rs rename to src/grib1/parm_tables/mod.rs index ef438dd..e334812 100644 --- a/src/grib/parm_tables/mod.rs +++ b/src/grib1/parm_tables/mod.rs @@ -41,3 +41,9 @@ pub mod dwdtable_204; pub mod dwdtable_205; #[derive(Clone, Copy, Debug)] pub struct Parm(&'static str, &'static str); + +impl Default for Parm { + fn default() -> Self { + Parm("", "") + } +} diff --git a/src/grib/parm_tables/nceptab_128.rs b/src/grib1/parm_tables/nceptab_128.rs similarity index 100% rename from src/grib/parm_tables/nceptab_128.rs rename to src/grib1/parm_tables/nceptab_128.rs diff --git a/src/grib/parm_tables/nceptab_129.rs b/src/grib1/parm_tables/nceptab_129.rs similarity index 100% rename from src/grib/parm_tables/nceptab_129.rs rename to src/grib1/parm_tables/nceptab_129.rs diff --git a/src/grib/parm_tables/nceptab_130.rs b/src/grib1/parm_tables/nceptab_130.rs similarity index 100% rename from src/grib/parm_tables/nceptab_130.rs rename to src/grib1/parm_tables/nceptab_130.rs diff --git a/src/grib/parm_tables/nceptab_131.rs b/src/grib1/parm_tables/nceptab_131.rs similarity index 100% rename from src/grib/parm_tables/nceptab_131.rs rename to src/grib1/parm_tables/nceptab_131.rs diff --git a/src/grib/parm_tables/nceptab_133.rs b/src/grib1/parm_tables/nceptab_133.rs similarity index 100% rename from src/grib/parm_tables/nceptab_133.rs rename to src/grib1/parm_tables/nceptab_133.rs diff --git a/src/grib/parm_tables/nceptab_140.rs b/src/grib1/parm_tables/nceptab_140.rs similarity index 100% rename from src/grib/parm_tables/nceptab_140.rs rename to src/grib1/parm_tables/nceptab_140.rs diff --git a/src/grib/parm_tables/nceptab_141.rs b/src/grib1/parm_tables/nceptab_141.rs similarity index 100% rename from src/grib/parm_tables/nceptab_141.rs rename to src/grib1/parm_tables/nceptab_141.rs diff --git a/src/grib/parm_tables/nceptable_mdl.rs b/src/grib1/parm_tables/nceptable_mdl.rs similarity index 100% rename from src/grib/parm_tables/nceptable_mdl.rs rename to src/grib1/parm_tables/nceptable_mdl.rs diff --git a/src/grib/parm_tables/nceptable_opn.rs b/src/grib1/parm_tables/nceptable_opn.rs similarity index 100% rename from src/grib/parm_tables/nceptable_opn.rs rename to src/grib1/parm_tables/nceptable_opn.rs diff --git a/src/grib/parm_tables/nceptable_reanal.rs b/src/grib1/parm_tables/nceptable_reanal.rs similarity index 100% rename from src/grib/parm_tables/nceptable_reanal.rs rename to src/grib1/parm_tables/nceptable_reanal.rs diff --git a/src/grib/pds.rs b/src/grib1/pds.rs similarity index 88% rename from src/grib/pds.rs rename to src/grib1/pds.rs index c55f74e..85a609b 100644 --- a/src/grib/pds.rs +++ b/src/grib1/pds.rs @@ -1,28 +1,56 @@ use chrono::prelude::*; -use nom::bytes::complete::{tag, take}; -use nom::multi::count; -use nom::number::complete::{i16, u16, u24, u8}; -use nom::number::Endianness::Little; -use nom::sequence::{preceded, tuple, Tuple}; -use nom::IResult; +use nom::bytes::complete::take; +use nom::{ + multi::count, + number::complete::{be_i16, be_u16, be_u24, u8}, +}; +use nom::{sequence::tuple, IResult}; use super::parm_tables; use super::parm_tables::Parm; +#[derive(Debug)] +enum ProductType { + Anal, + Fcst, + Unknown, +} + #[derive(Debug)] pub struct PDS { - center_identification: Center, - generating_process_id: u8, - grid_identification: u8, + _length: usize, + _center_identification: Center, + _generating_process_id: u8, + _grid_identification: u8, pub gds_or_bms: (bool, bool), - unit: Parm, - level_type_and_value: String, - datetime: DateTime, - time_range: String, - average_or_missing_number: i16, - decimal_scale: i32, - sub_center: SubCenter, - missing: u8, + _unit: Parm, + _level_type_and_value: String, + _datetime: DateTime, + _time_range: String, + _average_or_missing_number: i16, + _decimal_scale: i16, + _sub_center: SubCenter, + _missing: u8, +} + +impl Default for PDS { + fn default() -> Self { + PDS { + _length: 0, + _center_identification: Center::Other(100), + _generating_process_id: 0, + _grid_identification: 0, + gds_or_bms: (false, false), + _unit: Parm::default(), + _level_type_and_value: String::new(), + _datetime: Utc::now(), + _time_range: String::new(), + _average_or_missing_number: 0, + _decimal_scale: 0, + _sub_center: SubCenter::Other, + _missing: 0, + } + } } #[derive(Clone, Debug)] @@ -381,9 +409,10 @@ fn time_range_parser(input: &[u8]) -> IResult<&[u8], String> { let unit = time_unit(value[0]); - let time_range = value[1]; - let p1 = value[2]; - let p2 = value[3]; + let p1 = value[1]; + let p2 = value[2]; + + let time_range = value[3]; Ok(( next, @@ -467,18 +496,17 @@ fn time_range_parser(input: &[u8]) -> IResult<&[u8], String> { )) } -fn decimal_scale_parser(input: &[u8]) -> IResult<&[u8], i32> { - let (next, value) = take(2usize)(input)?; - - let result = 1 - ((value[0] & 0x80) >> 6) as i32 * (((value[0] & 0x7f) << 8) + value[1]) as i32; +fn decimal_scale_parser(input: &[u8]) -> IResult<&[u8], i16> { + // let result = 1 - ((value[0] & 0x80) >> 6) as i32 * (((value[0] & 0x7f) << 8) + value[1]) as i32; + // + let (next, result) = be_i16(input)?; Ok((next, result)) } pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> { let date_time_parser = take(5usize); - - let length = u24(Little); + let length = be_u24; let ( next, @@ -509,10 +537,10 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> { gds_or_bms_parser, u8, u8, - u16(Little), + be_u16, date_time_parser, time_range_parser, - i16(Little), + be_i16, u8, u8, subcenter_parser, @@ -526,6 +554,7 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> { &subcenter, process, ); + let levels = levels(level_type, ¢er_and_preconf.1, raw_level); let init_time = init_time(date_time, init_century); @@ -533,18 +562,19 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> { Ok(( next, PDS { - center_identification: center_and_preconf.0, - generating_process_id: process, - grid_identification: grid_id, + _length: ll as usize, + _center_identification: center_and_preconf.0, + _generating_process_id: process, + _grid_identification: grid_id, gds_or_bms: flag, - unit, - time_range, - level_type_and_value: levels, - datetime: init_time, - average_or_missing_number: average_or_acc, - decimal_scale: decimal_factor, - sub_center: subcenter, - missing, + _unit: unit, + _time_range: time_range, + _level_type_and_value: levels, + _datetime: init_time, + _average_or_missing_number: average_or_acc, + _decimal_scale: decimal_factor, + _sub_center: subcenter, + _missing: missing, }, )) } diff --git a/src/grib1/product.rs b/src/grib1/product.rs new file mode 100644 index 0000000..72f2f2f --- /dev/null +++ b/src/grib1/product.rs @@ -0,0 +1,60 @@ +use nom::{ + bytes::complete::tag, + sequence::{terminated, tuple}, + IResult, +}; + +use crate::{ProductRecord, Raw}; + +use super::{ + bds::{bds_parser, BDS}, + bms::{bms_parser, BMS}, + gds::{gds_parser, GDS}, + is::{is_parser, IS}, + pds::{pds_parser, PDS}, +}; + +#[derive(Debug, Default)] +pub struct Grib1Product<'a> { + is: IS, + pds: PDS, + gds: Option>, + bms: Option>, + bds: BDS<'a>, +} + +impl<'a> ProductRecord for Grib1Product<'a> { + fn header_parse(&mut self) {} + fn data_parse(&mut self) {} +} + +pub fn test_mth<'a>(input: &'a [u8]) -> IResult<&'a [u8], Grib1Product<'a>> { + let (mut next, (is, pds)) = tuple((is_parser, pds_parser))(input)?; + + let mut gds: Option = None; + let mut bms: Option = None; + + if pds.gds_or_bms.0 { + let (n, g) = gds_parser(next)?; + + next = n; + gds = Some(g); + } + + if pds.gds_or_bms.1 { + let (n, b) = bms_parser(next)?; + next = n; + bms = Some(b); + } + let (next, bds): (&[u8], BDS) = terminated(bds_parser, tag([55, 55, 55, 55]))(next)?; + Ok(( + next, + Grib1Product { + is, + pds, + gds, + bms, + bds, + }, + )) +} diff --git a/src/lib.rs b/src/lib.rs index 7be1ccc..af2bd46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,51 +1,159 @@ -use grib::{ - bds::{self, bds_parser, BDS}, - bms::{bms_parser, BMS}, - gds::{gds_parser, GDS}, - is::{is_parser, IS}, - pds::{pds_parser, PDS}, +use grib1::product::Grib1Product; +use std::{ + borrow::Borrow, + ffi::OsString, + fmt, + fs::metadata, + fs::File, + io::{BufReader, Read}, + os::unix::prelude::MetadataExt, + path::Path, }; -use nom::{sequence::tuple, IResult}; -pub mod grib; +use crate::error::*; +mod config; +mod error; +mod grib1; +mod tools; + +// Grib Version Branches +#[derive(Debug)] +pub enum Version { + Grib1, + Grib2, +} + +// Section Trait +type FormattingMessage> = (usize, T); + +trait Section: fmt::Display { + fn parse<'a, T>(input: T) -> Self + where + T: Borrow<&'a [u8]>; + // For printing more pretty + fn formatting_print(&self) -> Option> + where + T: AsRef; +} + +trait PrFactory { + fn make_pd<'a, 'b>(&'b self, version: Version, data: &'a [u8]) -> DataPack<'a> + where + 'a: 'b; +} + +pub struct PD; +impl PrFactory for PD { + fn make_pd<'a, 'b>(&'b self, version: Version, data: &'a [u8]) -> DataPack<'a> + where + 'a: 'b, + { + DataPack { + _data: Raw { + _raw_data: data, + _length: data.len(), + _read: 0, + }, + _product: match version { + Version::Grib1 => Box::new(Grib1Product::default()), + _ => Box::new(Grib1Product::default()), + }, + } + } +} + +pub struct DataPack<'a> { + _data: Raw<'a>, + _product: Box, +} #[derive(Debug)] -pub struct Project<'a> { - is: IS, - pds: PDS, - gds: Option>, - bms: Option>, - bds: BDS<'a>, +struct Raw<'a> { + _raw_data: &'a [u8], + _length: usize, + _read: usize, } -pub fn test_mth<'a>(input: &'a [u8]) -> IResult<&'a [u8], Project<'a>> { - let (mut next, (is, pds)) = tuple((is_parser, pds_parser))(input)?; - - let mut gds: Option = None; - let mut bms: Option = None; - - if pds.gds_or_bms.0 { - let (n, g) = gds_parser(next)?; - next = n; - gds = Some(g); - } - - if pds.gds_or_bms.1 { - let (n, b) = bms_parser(next)?; - next = n; - bms = Some(b); - } - - let (next, bds) = bds_parser(next)?; - - Ok(( - next, - Project { - is, - pds, - gds, - bms, - bds, - }, - )) +struct Header { + keys: Vec, +} + +trait ProductRecord { + fn header_parse(&mut self); + fn data_parse(&mut self); +} + +pub struct DataSet<'a>(Vec>); + +impl<'a> DataSet<'a> {} + +/// +/// File +/// +pub struct ProductBundle<'a, T: AsRef> { + _filename: OsString, + _path: T, + _raw_data: RawData, + pub dataset: Option>, +} + +impl<'a, T: AsRef> ProductBundle<'a, T> { + pub fn new(path: T) -> Result { + let real_path = path.as_ref(); + if !(real_path.exists() && real_path.is_file()) { + Err(UnexpectedError::FileNotExistError) + } else { + let name = real_path.file_name().unwrap(); + let file = File::open(path.as_ref())?; + Ok(Ok(ProductBundle { + _filename: OsString::from(name), + _path: path, + _raw_data: RawData::new(file), + dataset: None, + })) + } + } + + fn seek_grib(&mut self) {} +} + +struct RawData { + _file: File, +} + +impl RawData { + fn new(file: File) -> Self { + RawData { _file: file } + } + + fn read(&mut self) -> Result<()> { + let file_size = self._file.metadata()?.len(); + + let mini = 1024 * 1024 * 200; + let middle = 1024 * 1024 * 2048; + + if file_size < mini { + let mut raw: Vec = vec![]; + self._file.read_to_end(&mut raw)?; + } else if file_size >= mini && file_size < middle { + } else { + } + + Ok(Ok(())) + } + + fn seek>(raw: T, pattern: T) { + let p = pattern.as_ref(); + + let bad_letter = { + let len = p.len(); + let deltas = vec![len; len]; + + let mut j = len - 1; + + while j > 0 { + j -= 1; + } + }; + } } diff --git a/src/main.rs b/src/main.rs index e7a11a9..6938319 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::{borrow::Borrow, fs, path::Path}; + fn main() { println!("Hello, world!"); } diff --git a/src/tools.rs b/src/tools.rs new file mode 100644 index 0000000..0bacee5 --- /dev/null +++ b/src/tools.rs @@ -0,0 +1,20 @@ +fn prefix_function(pat: impl AsRef<[u8]>) -> Vec { + let p = pat.as_ref(); + let len = p.len(); + assert!(len == 0); + let mut pi = vec![0; len]; + + for i in 1..len { + let mut j = pi[i - 1]; + + while j > 0 && p[i] != p[j] { + j = pi[j - 1]; + } + + if p[i] == p[j] { + pi[i] = j + 1; + } + } + + pi +}