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", "flate2",
"gentools", "gentools",
"nom", "nom",
"rustc-hash",
"serde", "serde",
"thiserror 2.0.17", "thiserror 2.0.17",
] ]
@ -1352,6 +1353,12 @@ dependencies = [
"syn 2.0.111", "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]] [[package]]
name = "rustix" name = "rustix"
version = "1.1.2" version = "1.1.2"

View File

@ -15,6 +15,7 @@ use rkyv::bytecheck::CheckBytes;
use rkyv::rancor::Error; use rkyv::rancor::Error;
use rkyv::{Archive, Deserialize, Serialize}; use rkyv::{Archive, Deserialize, Serialize};
use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize}; use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
use std::borrow::Borrow;
use std::fmt::Debug; use std::fmt::Debug;
use std::io::{Cursor, Write}; use std::io::{Cursor, Write};
use std::path::Path; 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; let hash = self.mphf.get(&fxy)? as usize;
self.archived().ok()?.entries.get(hash) self.archived().ok()?.entries.get(hash)
} }
@ -148,13 +148,15 @@ where
rkyv::Serialize, rkyv::Serialize,
rkyv::Deserialize, rkyv::Deserialize,
Debug, Debug,
PartialEq,
Eq, Eq,
Clone, Clone,
Copy, Copy,
std::hash::Hash, 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 struct FXY {
pub f: i32, pub f: i32,
pub x: i32, pub x: i32,
@ -191,14 +193,6 @@ impl FXY {
pub fn to_u32(&self) -> u32 { pub fn to_u32(&self) -> u32 {
((self.f as u32) << 14) | ((self.x as u32) << 8) | (self.y as 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> { pub struct BUFRTableMPH<T: TableTypeTrait> {
@ -234,11 +228,61 @@ where
Ok(BUFRTableMPH { inner: bhm }) 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) 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)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TableType { pub enum TableType {
@ -277,7 +321,7 @@ mod test {
) )
.unwrap(); .unwrap();
let x = table.lookup(FXY::new(3, 21, 11)).unwrap(); let x = table.lookup(&FXY::new(3, 21, 11)).unwrap();
println!("{:#?}", x); 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" thiserror = "2.0.17"
gentools = { path = "../gen" } gentools = { path = "../gen" }
anyhow = "1.0.100" anyhow = "1.0.100"
rustc-hash = "2.1.1"
[features] [features]
default = ["opera"] default = ["opera"]

View File

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

View File

@ -16,7 +16,7 @@ mod test {
) )
.unwrap(); .unwrap();
let entry = bufr.lookup(FXY::new(0, 0, 1)).unwrap(); let entry = bufr.lookup(&FXY::new(0, 0, 1)).unwrap();
println!("{:#?}", entry); println!("{:#?}", entry);
} }
@ -27,7 +27,7 @@ mod test {
let mut parser = Parser::new(); let mut parser = Parser::new();
let parsed_file = parser 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(); .unwrap();
for msg in parsed_file.messages() { 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 crate::structs::bit::{BitInput, parse_arbitrary_bits};
use nom::IResult; 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) parse_descriptors_inner(input)
.map(|(_, v)| v) .map(|(_, v)| v)
.map_err(|_| Error::ParseError(format!("Can't parse descriptors from section3"))) .map_err(|_| Error::ParseError(format!("Can't parse descriptors from section3")))
} }
fn parse_descriptors_inner(mut input: &[u8]) -> IResult<BitInput, VecDeque<genlib::FXY>> { fn parse_descriptors_inner(mut input: &[u8]) -> IResult<BitInput, Vec<genlib::FXY>> {
let mut results = VecDeque::new(); let mut results = Vec::new();
while input.len() > 1 { while input.len() > 1 {
let ((finput, _), fxy) = take_fxy((input, 0))?; let ((finput, _), fxy) = take_fxy((input, 0))?;
results.push_back(fxy); results.push(fxy);
input = finput; 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 { match self {
$( $(
BUFRMessage::$version(msg) => msg.descriptors(), BUFRMessage::$version(msg) => msg.descriptors(),
@ -163,7 +163,7 @@ pub trait MessageVersion: Sized {
fn ndescs(&self) -> usize; fn ndescs(&self) -> usize;
fn descriptors(&self) -> Result<VecDeque<FXY>>; fn descriptors(&self) -> Result<Vec<FXY>>;
fn data_block(&self) -> Result<&[u8]>; fn data_block(&self) -> Result<&[u8]>;
} }

View File

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

View File

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