stack frame

This commit is contained in:
Tsuki 2026-01-05 00:46:59 +08:00
parent ccfe71f852
commit 8c2ac4b300
11 changed files with 936 additions and 328 deletions

7
Cargo.lock generated
View File

@ -1265,6 +1265,7 @@ dependencies = [
"flate2",
"gentools",
"nom",
"rustc-hash",
"serde",
"thiserror 2.0.17",
]
@ -1352,6 +1353,12 @@ dependencies = [
"syn 2.0.111",
]
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "1.1.2"

View File

@ -15,6 +15,7 @@ use rkyv::bytecheck::CheckBytes;
use rkyv::rancor::Error;
use rkyv::{Archive, Deserialize, Serialize};
use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
use std::borrow::Borrow;
use std::fmt::Debug;
use std::io::{Cursor, Write};
use std::path::Path;
@ -116,9 +117,8 @@ where
}
/// 获取拥有的版本
fn get(&self, fxy: FXY) -> Option<&<T as Archive>::Archived> {
fn get<K: BUFRKey>(&self, fxy: &K) -> Option<&<T as Archive>::Archived> {
let hash = self.mphf.get(&fxy)? as usize;
self.archived().ok()?.entries.get(hash)
}
@ -148,13 +148,15 @@ where
rkyv::Serialize,
rkyv::Deserialize,
Debug,
PartialEq,
Eq,
Clone,
Copy,
std::hash::Hash,
)]
#[rkyv(compare(PartialEq), derive(Debug, Clone, Copy))]
#[rkyv(
// compare(PartialEq),
derive(Debug, Clone, Copy, std::hash::Hash, Eq)
)]
pub struct FXY {
pub f: i32,
pub x: i32,
@ -191,14 +193,6 @@ impl FXY {
pub fn to_u32(&self) -> u32 {
((self.f as u32) << 14) | ((self.x as u32) << 8) | (self.y as u32)
}
// pub fn from_u32(value: u32) -> Self {
// FXY {
// f: ((value >> 14) & 0x3) as u16,
// x: ((value >> 8) & 0x3F) as u16,
// y: (value & 0xFF) as u16,
// }
// }
}
pub struct BUFRTableMPH<T: TableTypeTrait> {
@ -234,11 +228,61 @@ where
Ok(BUFRTableMPH { inner: bhm })
}
pub fn lookup(&self, fxy: FXY) -> Option<&<T::EntryType as Archive>::Archived> {
pub fn lookup<K: BUFRKey>(&self, fxy: &K) -> Option<&<T::EntryType as Archive>::Archived> {
self.inner.get(fxy)
}
}
pub trait BUFRKey: Debug + Eq + std::hash::Hash + PartialEq<FXY> + PartialEq<ArchivedFXY> {
fn f(&self) -> i32;
fn x(&self) -> i32;
fn y(&self) -> i32;
}
impl BUFRKey for FXY {
fn f(&self) -> i32 {
self.f
}
fn x(&self) -> i32 {
self.x
}
fn y(&self) -> i32 {
self.y
}
}
impl BUFRKey for ArchivedFXY {
fn f(&self) -> i32 {
self.f.to_native()
}
fn x(&self) -> i32 {
self.x.to_native()
}
fn y(&self) -> i32 {
self.y.to_native()
}
}
impl<K: BUFRKey> PartialEq<K> for FXY {
fn eq(&self, other: &K) -> bool {
self.f == other.f() && self.x == other.x() && self.y == other.y()
}
}
impl<K: BUFRKey> PartialEq<K> for ArchivedFXY {
fn eq(&self, other: &K) -> bool {
self.f.to_native() == other.f()
&& self.x.to_native() == other.x()
&& self.y.to_native() == other.y()
}
}
// impl Borrow<FXY> for ArchivedFXY {
// fn borrow(&self) -> &FXY {
// // SAFETY: ArchivedFXY has the same memory layout as FXY
// unsafe { &*(self as *const ArchivedFXY as *const FXY) }
// }
// }
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TableType {
@ -277,7 +321,7 @@ mod test {
)
.unwrap();
let x = table.lookup(FXY::new(3, 21, 11)).unwrap();
let x = table.lookup(&FXY::new(3, 21, 11)).unwrap();
println!("{:#?}", x);
}

BIN
gen/test.bufrtbl Normal file

Binary file not shown.

View File

@ -16,6 +16,7 @@ serde = { version = "1.0.228", features = ["derive"] }
thiserror = "2.0.17"
gentools = { path = "../gen" }
anyhow = "1.0.100"
rustc-hash = "2.1.1"
[features]
default = ["opera"]

View File

@ -60,7 +60,7 @@ impl MessageBlock {
let opera_bitmap_table = self
.load_opera_bitmap_table(
table_info.center_id,
GENCENTER,
table_info.subcenter_id,
table_info.local_table_version,
master_table_version,
)
@ -76,7 +76,7 @@ impl MessageBlock {
opera_bitmap_table,
);
parser.parse(&self.message)?;
let record = parser.parse(&self.message)?;
Ok(())
}

View File

@ -16,7 +16,7 @@ mod test {
)
.unwrap();
let entry = bufr.lookup(FXY::new(0, 0, 1)).unwrap();
let entry = bufr.lookup(&FXY::new(0, 0, 1)).unwrap();
println!("{:#?}", entry);
}
@ -27,7 +27,7 @@ mod test {
let mut parser = Parser::new();
let parsed_file = parser
.parse("/Users/xiang.li1/Downloads/36_2025-12-22T11_00_00.bufr")
.parse("/Users/tsuki/Downloads/36_2025-12-17T09_00_00.bufr.nc")
.unwrap();
for msg in parsed_file.messages() {

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,17 @@ use crate::errors::{Error, Result};
use crate::structs::bit::{BitInput, parse_arbitrary_bits};
use nom::IResult;
pub(super) fn parse_descriptors(input: &[u8]) -> Result<VecDeque<genlib::FXY>> {
pub(super) fn parse_descriptors(input: &[u8]) -> Result<Vec<genlib::FXY>> {
parse_descriptors_inner(input)
.map(|(_, v)| v)
.map_err(|_| Error::ParseError(format!("Can't parse descriptors from section3")))
}
fn parse_descriptors_inner(mut input: &[u8]) -> IResult<BitInput, VecDeque<genlib::FXY>> {
let mut results = VecDeque::new();
fn parse_descriptors_inner(mut input: &[u8]) -> IResult<BitInput, Vec<genlib::FXY>> {
let mut results = Vec::new();
while input.len() > 1 {
let ((finput, _), fxy) = take_fxy((input, 0))?;
results.push_back(fxy);
results.push(fxy);
input = finput;
}

View File

@ -97,7 +97,7 @@ macro_rules! message {
}
}
fn descriptors(&self) -> Result<VecDeque<FXY>> {
fn descriptors(&self) -> Result<Vec<FXY>> {
match self {
$(
BUFRMessage::$version(msg) => msg.descriptors(),
@ -163,7 +163,7 @@ pub trait MessageVersion: Sized {
fn ndescs(&self) -> usize;
fn descriptors(&self) -> Result<VecDeque<FXY>>;
fn descriptors(&self) -> Result<Vec<FXY>>;
fn data_block(&self) -> Result<&[u8]>;
}

View File

@ -65,7 +65,7 @@ impl MessageVersion for BUFRMessageV2 {
self.section3.data.len() / 2
}
fn descriptors(&self) -> Result<VecDeque<FXY>> {
fn descriptors(&self) -> Result<Vec<FXY>> {
parse_descriptors(&self.section3.data)
}

View File

@ -66,7 +66,7 @@ impl MessageVersion for BUFRMessageV4 {
self.section3.data.len() / 2
}
fn descriptors(&self) -> Result<VecDeque<genlib::FXY>> {
fn descriptors(&self) -> Result<Vec<genlib::FXY>> {
parse_descriptors(&self.section3.data)
}