product bundle

This commit is contained in:
sleptworld 2023-01-22 11:59:31 +08:00
parent 7b790830f4
commit 99e15dc8aa
55 changed files with 702 additions and 148 deletions

17
.vscode/launch.json vendored Normal file
View File

@ -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}"
}
]
}

275
Cargo.lock generated
View File

@ -25,6 +25,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.0"
@ -44,6 +50,64 @@ dependencies = [
"winapi", "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]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.8" version = "0.2.8"
@ -55,6 +119,21 @@ dependencies = [
"wasi 0.11.0+wasi-snapshot-preview1", "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]] [[package]]
name = "ibmfloat" name = "ibmfloat"
version = "0.1.1" version = "0.1.1"
@ -67,6 +146,28 @@ version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2d6f23ffea9d7e76c53eee25dfb67bcd8fde7f1198b0855350698c9f07c780" 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]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -75,9 +176,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.126" version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "lock_api" name = "lock_api"
@ -89,6 +196,15 @@ dependencies = [
"scopeguard", "scopeguard",
] ]
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "matrixmultiply" name = "matrixmultiply"
version = "0.3.2" version = "0.3.2"
@ -191,6 +307,12 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "os_str_bytes"
version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -214,6 +336,72 @@ dependencies = [
"windows-sys", "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]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.49" version = "1.0.49"
@ -292,6 +480,21 @@ dependencies = [
"proc-macro2", "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]] [[package]]
name = "rawpointer" name = "rawpointer"
version = "0.2.1" version = "0.2.1"
@ -313,11 +516,29 @@ version = "0.1.0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chrono", "chrono",
"clap",
"ibmfloat", "ibmfloat",
"lazy_static", "lazy_static",
"log",
"nom", "nom",
"numpy", "numpy",
"phf",
"pyo3", "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]] [[package]]
@ -326,12 +547,24 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "siphasher"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.10.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.107" version = "1.0.107"
@ -349,6 +582,35 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" 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]] [[package]]
name = "time" name = "time"
version = "0.1.44" version = "0.1.44"
@ -406,6 +668,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 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]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"

View File

@ -5,13 +5,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # 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. # "cdylib" is necessary to produce a shared library for Python to import from.
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
phf = { version = "0.11", features = ["macros"] }
nom = "7.1.1" nom = "7.1.1"
chrono = "0.4" chrono = "0.4"
bitflags = "1.3.2" bitflags = "1.3.2"
@ -19,3 +17,6 @@ lazy_static = "1.4.0"
pyo3 = { version = "0.17.3", features = ["extension-module"] } pyo3 = { version = "0.17.3", features = ["extension-module"] }
numpy = "0.17" numpy = "0.17"
ibmfloat = "0.1.1" ibmfloat = "0.1.1"
thiserror = "1.0.38"
clap = {version="4.1.1",features=["derive"]}
log = "0.4"

View File

@ -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",
]

1
src/config.rs Normal file
View File

@ -0,0 +1 @@
pub struct Config {}

21
src/error.rs Normal file
View File

@ -0,0 +1,21 @@
use std::io;
use thiserror::Error;
pub type Result<T> = std::result::Result<std::result::Result<T, AppError>, UnexpectedError>;
#[derive(Error, Debug)]
pub enum UnexpectedError {
#[error("")]
IOError {
#[from]
source: io::Error,
},
#[error("")]
FormatError,
#[error("")]
FileNotExistError,
}
#[derive(Error, Debug)]
pub enum AppError {}

View File

@ -1,7 +1,7 @@
use bitflags::bitflags; use bitflags::bitflags;
use nom::{ use nom::{
bytes::complete::take, bytes::complete::take,
number::complete::{le_f32, le_i16, le_u24, u8}, number::complete::{be_i16, be_u24, be_u32, u8},
sequence::tuple, sequence::tuple,
IResult, IResult,
}; };
@ -16,6 +16,11 @@ bitflags! {
const COMPLEX_PACKING = 0b01000000; const COMPLEX_PACKING = 0b01000000;
const INTEGER_NUMBERIC = 0b00100000; const INTEGER_NUMBERIC = 0b00100000;
const ADDITIONAL_FLAG = 0b00010000; 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>, 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)] #[derive(Debug)]
enum PackedData<'a> { enum PackedData<'a> {
Simple(&'a [u8]), Simple(&'a [u8]),
@ -45,39 +63,36 @@ enum PackedData<'a> {
first_order_packed_values: &'a [u8], first_order_packed_values: &'a [u8],
second_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>> { pub fn bds_parser<'a>(input: &'a [u8]) -> IResult<&'a [u8], BDS<'a>> {
let (next, (length, flag_bit, scale, refrence, number)) = 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(); let flags = BdsFlag::from_bits(flag_bit).unwrap();
if flags.contains(BdsFlag::COMPLEX_PACKING) { if flags.contains(BdsFlag::COMPLEX_PACKING) {
panic!(); panic!();
} else { } else {
let (next, value) = take(length - 11)(next)?; let (next, value) = take((length - 11) as usize)(next)?;
Ok(( Ok((
next, next,
BDS { BDS {
length: length as usize, length: length as usize,
flag: flags, flag: flags,
scale, scale,
refrence_value: refrence, refrence_value: float_transer(refrence),
bit_number: number as usize, bit_number: number as usize,
data: PackedData::Simple(value), 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 {}
// }
// }
} }

View File

@ -1,6 +1,6 @@
use nom::{ use nom::{
bytes::complete::take, bytes::complete::take,
number::complete::{le_u16, le_u24, u8}, number::complete::{be_u16, be_u24, u8},
sequence::tuple, sequence::tuple,
IResult, IResult,
}; };
@ -72,7 +72,7 @@ impl<'a> Iterator for BitMap<'a> {
} }
pub fn bms_parser(input: &[u8]) -> IResult<&[u8], BMS> { 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 { let map_type = if b_type == 0 {
BitmapType::Follows BitmapType::Follows
@ -81,7 +81,7 @@ pub fn bms_parser(input: &[u8]) -> IResult<&[u8], BMS> {
}; };
let map: Option<BitMap> = if let BitmapType::Follows = map_type { let map: Option<BitMap> = 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; next = n;
let len = map_part.len(); let len = map_part.len();
Some(BitMap::new(&map_part, unused as usize)) Some(BitMap::new(&map_part, unused as usize))

View File

@ -2,9 +2,8 @@ use lazy_static::lazy_static;
use nom::{ use nom::{
bytes::complete::take, bytes::complete::take,
character::complete::u8,
multi::count, 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, sequence::tuple,
IResult, IResult,
}; };
@ -21,6 +20,7 @@ lazy_static! {
// Type declare // Type declare
#[derive(Debug)] #[derive(Debug)]
pub struct GDS<'a> { pub struct GDS<'a> {
length: usize,
pub nv: usize, pub nv: usize,
pub representation: DataRepresentation, pub representation: DataRepresentation,
pv: Option<&'a [u8]>, pv: Option<&'a [u8]>,
@ -175,13 +175,13 @@ impl Default for DP {
let (next, nj) = be_u16(next)?; let (next, nj) = be_u16(next)?;
let (next, (lat1, lon1, reso, lat2, lon2, di, dj, scan_mode, _)) = let (next, (lat1, lon1, reso, lat2, lon2, di, dj, scan_mode, _)) =
tuple(( tuple((
le_i24, be_i24,
le_i24, be_i24,
u8, u8,
le_i24, be_i24,
le_i24, be_i24,
le_i16, be_i16,
le_i16, be_i16,
u8, u8,
take(4usize), take(4usize),
))(next)?; ))(next)?;
@ -212,15 +212,15 @@ impl Default for DP {
let (next, nj) = be_u16(next)?; let (next, nj) = be_u16(next)?;
let (next, (lat1, lon1, reso, lat2, lon2, latin, _, scan_mode, dij, _)) = let (next, (lat1, lon1, reso, lat2, lon2, latin, _, scan_mode, dij, _)) =
tuple(( tuple((
le_i24, be_i24,
le_i24, be_i24,
u8, u8,
le_i24, be_i24,
le_i24, be_i24,
le_u24, be_u24,
take(1usize), take(1usize),
u8, u8,
count(le_i24, 2), count(be_i24, 2),
take(8usize), take(8usize),
))(next)?; ))(next)?;
@ -250,13 +250,13 @@ impl Default for DP {
let (next, ny) = be_u16(next)?; let (next, ny) = be_u16(next)?;
let (next, (lat1, lon1, reso, lxy, center, scan, lls, _)) = let (next, (lat1, lon1, reso, lxy, center, scan, lls, _)) =
tuple(( tuple((
le_i24, be_i24,
le_i24, be_i24,
u8, u8,
count(le_i24, 3), count(be_i24, 3),
u8, u8,
u8, u8,
count(le_i24, 4), count(be_i24, 4),
take(2usize), take(2usize),
))(next)?; ))(next)?;
@ -293,7 +293,7 @@ impl Default for DP {
let (next, ny) = be_u16(next)?; let (next, ny) = be_u16(next)?;
let (next, (lat1, lon1, reso, lxy, center, scan, _)) = 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(( return Ok((
next, next,
@ -324,7 +324,7 @@ impl Default for DP {
let (next, nj) = be_u16(next)?; let (next, nj) = be_u16(next)?;
let (next, (lat1, lon1, reso, lij, scan, _)) = 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(( return Ok((
next, next,
@ -364,22 +364,34 @@ impl DP {
fn representation_parser(input: &[u8]) -> IResult<&[u8], DataRepresentation> { fn representation_parser(input: &[u8]) -> IResult<&[u8], DataRepresentation> {
let (next, projection_type_mask) = u8(input)?; let (next, projection_type_mask) = u8(input)?;
return E.run_event(next, projection_type_mask); return E.run_event(next, projection_type_mask);
} }
pub fn gds_parser(input: &[u8]) -> IResult<&[u8], GDS> { pub fn gds_parser(input: &[u8]) -> IResult<&[u8], GDS> {
let (next, gds_length) = le_u24(input)?; let (next, gds_length) = be_u24(input)?;
let nv_p = u8;
let pv_or_pl_p = u8;
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 { if nv == 0 {
assert!(pv_pl != 255);
let (next, pl_list) = take(data_repr.row_length * 2)(next)?; let (next, pl_list) = take(data_repr.row_length * 2)(next)?;
return Ok(( return Ok((
next, next,
GDS { GDS {
length: gds_length as usize,
nv: nv as usize, nv: nv as usize,
representation: data_repr, representation: data_repr,
pv: None, pv: None,
@ -392,6 +404,7 @@ pub fn gds_parser(input: &[u8]) -> IResult<&[u8], GDS> {
return Ok(( return Ok((
next, next,
GDS { GDS {
length: gds_length as usize,
nv: nv as usize, nv: nv as usize,
representation: data_repr, representation: data_repr,
pv: Some(pv_list), pv: Some(pv_list),

View File

@ -1,19 +1,19 @@
use nom::{ use nom::{
bytes::complete::tag, bytes::complete::tag,
number::{complete::le_u24, complete::u8}, number::{complete::be_u24, complete::u8},
sequence::{preceded, tuple}, sequence::{preceded, tuple},
IResult, IResult,
}; };
#[derive(Debug)] #[derive(Debug, Default)]
pub struct IS { pub struct IS {
total_length: usize, total_length: usize,
version_number: u8, version_number: u8,
} }
pub fn is_parser(input: &[u8]) -> IResult<&[u8], IS> { pub fn is_parser(input: &[u8]) -> IResult<&[u8], IS> {
let grib = tag([]); let grib = tag([71, 82, 73, 66]);
let total_length = le_u24; let total_length = be_u24;
let editon = u8; let editon = u8;
let (input, (len, edition_number)) = preceded(grib, tuple((total_length, editon)))(input)?; let (input, (len, edition_number)) = preceded(grib, tuple((total_length, editon)))(input)?;

View File

@ -3,5 +3,6 @@ pub mod bms;
pub mod gds; pub mod gds;
pub mod is; pub mod is;
pub mod pds; pub mod pds;
pub mod product;
mod parm_tables; mod parm_tables;

View File

@ -41,3 +41,9 @@ pub mod dwdtable_204;
pub mod dwdtable_205; pub mod dwdtable_205;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Parm(&'static str, &'static str); pub struct Parm(&'static str, &'static str);
impl Default for Parm {
fn default() -> Self {
Parm("", "")
}
}

View File

@ -1,28 +1,56 @@
use chrono::prelude::*; use chrono::prelude::*;
use nom::bytes::complete::{tag, take}; use nom::bytes::complete::take;
use nom::multi::count; use nom::{
use nom::number::complete::{i16, u16, u24, u8}; multi::count,
use nom::number::Endianness::Little; number::complete::{be_i16, be_u16, be_u24, u8},
use nom::sequence::{preceded, tuple, Tuple}; };
use nom::IResult; use nom::{sequence::tuple, IResult};
use super::parm_tables; use super::parm_tables;
use super::parm_tables::Parm; use super::parm_tables::Parm;
#[derive(Debug)]
enum ProductType {
Anal,
Fcst,
Unknown,
}
#[derive(Debug)] #[derive(Debug)]
pub struct PDS { pub struct PDS {
center_identification: Center, _length: usize,
generating_process_id: u8, _center_identification: Center,
grid_identification: u8, _generating_process_id: u8,
_grid_identification: u8,
pub gds_or_bms: (bool, bool), pub gds_or_bms: (bool, bool),
unit: Parm, _unit: Parm,
level_type_and_value: String, _level_type_and_value: String,
datetime: DateTime<Utc>, _datetime: DateTime<Utc>,
time_range: String, _time_range: String,
average_or_missing_number: i16, _average_or_missing_number: i16,
decimal_scale: i32, _decimal_scale: i16,
sub_center: SubCenter, _sub_center: SubCenter,
missing: u8, _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)] #[derive(Clone, Debug)]
@ -381,9 +409,10 @@ fn time_range_parser(input: &[u8]) -> IResult<&[u8], String> {
let unit = time_unit(value[0]); let unit = time_unit(value[0]);
let time_range = value[1]; let p1 = value[1];
let p1 = value[2]; let p2 = value[2];
let p2 = value[3];
let time_range = value[3];
Ok(( Ok((
next, next,
@ -467,18 +496,17 @@ fn time_range_parser(input: &[u8]) -> IResult<&[u8], String> {
)) ))
} }
fn decimal_scale_parser(input: &[u8]) -> IResult<&[u8], i32> { fn decimal_scale_parser(input: &[u8]) -> IResult<&[u8], i16> {
let (next, value) = take(2usize)(input)?; // let result = 1 - ((value[0] & 0x80) >> 6) as i32 * (((value[0] & 0x7f) << 8) + value[1]) as i32;
//
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)) Ok((next, result))
} }
pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> { pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> {
let date_time_parser = take(5usize); let date_time_parser = take(5usize);
let length = be_u24;
let length = u24(Little);
let ( let (
next, next,
@ -509,10 +537,10 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> {
gds_or_bms_parser, gds_or_bms_parser,
u8, u8,
u8, u8,
u16(Little), be_u16,
date_time_parser, date_time_parser,
time_range_parser, time_range_parser,
i16(Little), be_i16,
u8, u8,
u8, u8,
subcenter_parser, subcenter_parser,
@ -526,6 +554,7 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> {
&subcenter, &subcenter,
process, process,
); );
let levels = levels(level_type, &center_and_preconf.1, raw_level); let levels = levels(level_type, &center_and_preconf.1, raw_level);
let init_time = init_time(date_time, init_century); let init_time = init_time(date_time, init_century);
@ -533,18 +562,19 @@ pub fn pds_parser(input: &[u8]) -> IResult<&[u8], PDS> {
Ok(( Ok((
next, next,
PDS { PDS {
center_identification: center_and_preconf.0, _length: ll as usize,
generating_process_id: process, _center_identification: center_and_preconf.0,
grid_identification: grid_id, _generating_process_id: process,
_grid_identification: grid_id,
gds_or_bms: flag, gds_or_bms: flag,
unit, _unit: unit,
time_range, _time_range: time_range,
level_type_and_value: levels, _level_type_and_value: levels,
datetime: init_time, _datetime: init_time,
average_or_missing_number: average_or_acc, _average_or_missing_number: average_or_acc,
decimal_scale: decimal_factor, _decimal_scale: decimal_factor,
sub_center: subcenter, _sub_center: subcenter,
missing, _missing: missing,
}, },
)) ))
} }

60
src/grib1/product.rs Normal file
View File

@ -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<GDS<'a>>,
bms: Option<BMS<'a>>,
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<GDS> = None;
let mut bms: Option<BMS> = 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,
},
))
}

View File

@ -1,51 +1,159 @@
use grib::{ use grib1::product::Grib1Product;
bds::{self, bds_parser, BDS}, use std::{
bms::{bms_parser, BMS}, borrow::Borrow,
gds::{gds_parser, GDS}, ffi::OsString,
is::{is_parser, IS}, fmt,
pds::{pds_parser, PDS}, 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<T: AsRef<str>> = (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<T>(&self) -> Option<FormattingMessage<T>>
where
T: AsRef<str>;
}
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<dyn ProductRecord>,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Project<'a> { struct Raw<'a> {
is: IS, _raw_data: &'a [u8],
pds: PDS, _length: usize,
gds: Option<GDS<'a>>, _read: usize,
bms: Option<BMS<'a>>,
bds: BDS<'a>,
} }
pub fn test_mth<'a>(input: &'a [u8]) -> IResult<&'a [u8], Project<'a>> { struct Header {
let (mut next, (is, pds)) = tuple((is_parser, pds_parser))(input)?; keys: Vec<String>,
}
let mut gds: Option<GDS> = None;
let mut bms: Option<BMS> = None; trait ProductRecord {
fn header_parse(&mut self);
if pds.gds_or_bms.0 { fn data_parse(&mut self);
let (n, g) = gds_parser(next)?; }
next = n;
gds = Some(g); pub struct DataSet<'a>(Vec<DataPack<'a>>);
}
impl<'a> DataSet<'a> {}
if pds.gds_or_bms.1 {
let (n, b) = bms_parser(next)?; ///
next = n; /// File
bms = Some(b); ///
} pub struct ProductBundle<'a, T: AsRef<Path>> {
_filename: OsString,
let (next, bds) = bds_parser(next)?; _path: T,
_raw_data: RawData,
Ok(( pub dataset: Option<DataSet<'a>>,
next, }
Project {
is, impl<'a, T: AsRef<Path>> ProductBundle<'a, T> {
pds, pub fn new(path: T) -> Result<Self> {
gds, let real_path = path.as_ref();
bms, if !(real_path.exists() && real_path.is_file()) {
bds, 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<u8> = vec![];
self._file.read_to_end(&mut raw)?;
} else if file_size >= mini && file_size < middle {
} else {
}
Ok(Ok(()))
}
fn seek<T: AsRef<[u8]>>(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;
}
};
}
} }

View File

@ -1,3 +1,5 @@
use std::{borrow::Borrow, fs, path::Path};
fn main() { fn main() {
println!("Hello, world!"); println!("Hello, world!");
} }

20
src/tools.rs Normal file
View File

@ -0,0 +1,20 @@
fn prefix_function(pat: impl AsRef<[u8]>) -> Vec<usize> {
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
}