Compare commits
2 commits
572b39aca0
...
d3bf15f47a
| Author | SHA1 | Date | |
|---|---|---|---|
| d3bf15f47a | |||
| 22040d9432 |
6 changed files with 645 additions and 150 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
name = "klamath_rs_ext"
|
name = "klamath_rs_ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
authors = ["jan <jan@mpxd.net>"]
|
authors = ["jan <jan@mpxd.net>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
|
||||||
20
src/basic.rs
20
src/basic.rs
|
|
@ -15,15 +15,15 @@ pub enum ErrType {
|
||||||
Failed(String),
|
Failed(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fail<O>(input: &[u8], msg: String) -> IResult<O> {
|
pub fn fail<O>(input: &[u8], msg: String) -> IResult<'_, O> {
|
||||||
Err((input, ErrType::Failed(msg)))
|
Err((input, ErrType::Failed(msg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incomplete<O>(input: &[u8], size: Option<usize>) -> IResult<O> {
|
pub fn incomplete<O>(input: &[u8], size: Option<usize>) -> IResult<'_, O> {
|
||||||
Err((input, ErrType::Incomplete(size)))
|
Err((input, ErrType::Incomplete(size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_bytes<CC: Into<usize>>(input: &[u8], count: CC) -> IResult<&[u8]> {
|
pub fn take_bytes<CC: Into<usize>>(input: &[u8], count: CC) -> IResult<'_, &[u8]> {
|
||||||
let cc = count.into();
|
let cc = count.into();
|
||||||
if input.len() < cc {
|
if input.len() < cc {
|
||||||
incomplete(input, Some(cc))
|
incomplete(input, Some(cc))
|
||||||
|
|
@ -37,19 +37,19 @@ pub fn take_bytes<CC: Into<usize>>(input: &[u8], count: CC) -> IResult<&[u8]> {
|
||||||
/*
|
/*
|
||||||
* Parse functions
|
* Parse functions
|
||||||
*/
|
*/
|
||||||
pub fn parse_u16(input: &[u8]) -> IResult<u16> {
|
pub fn parse_u16(input: &[u8]) -> IResult<'_, u16> {
|
||||||
let (input, buf) = take_bytes(input, 2_usize)?;
|
let (input, buf) = take_bytes(input, 2_usize)?;
|
||||||
let val = BigEndian::read_u16(buf);
|
let val = BigEndian::read_u16(buf);
|
||||||
Ok((input, val))
|
Ok((input, val))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_int2(input: &[u8]) -> IResult<i16> {
|
pub fn parse_int2(input: &[u8]) -> IResult<'_, i16> {
|
||||||
let (input, buf) = take_bytes(input, 2_usize)?;
|
let (input, buf) = take_bytes(input, 2_usize)?;
|
||||||
let val = BigEndian::read_i16(buf);
|
let val = BigEndian::read_i16(buf);
|
||||||
Ok((input, val))
|
Ok((input, val))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_int4(input: &[u8]) -> IResult<i32> {
|
pub fn parse_int4(input: &[u8]) -> IResult<'_, i32> {
|
||||||
let (input, buf) = take_bytes(input, 4_usize)?;
|
let (input, buf) = take_bytes(input, 4_usize)?;
|
||||||
let val = BigEndian::read_i32(buf);
|
let val = BigEndian::read_i32(buf);
|
||||||
Ok((input, val))
|
Ok((input, val))
|
||||||
|
|
@ -67,14 +67,14 @@ pub fn decode_real8(int: u64) -> f64 {
|
||||||
mant * 2_f64.powi(exp2)
|
mant * 2_f64.powi(exp2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_real8(input: &[u8]) -> IResult<f64> {
|
pub fn parse_real8(input: &[u8]) -> IResult<'_, f64> {
|
||||||
let (input, buf) = take_bytes(input, 8_usize)?;
|
let (input, buf) = take_bytes(input, 8_usize)?;
|
||||||
let data = BigEndian::read_u64(buf);
|
let data = BigEndian::read_u64(buf);
|
||||||
Ok((input, decode_real8(data)))
|
Ok((input, decode_real8(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_datetime(input: &[u8]) -> IResult<[i16; 6]> {
|
pub fn parse_datetime(input: &[u8]) -> IResult<'_, [i16; 6]> {
|
||||||
let mut buf = [0_i16; 6];
|
let mut buf = [0_i16; 6];
|
||||||
let mut input = input;
|
let mut input = input;
|
||||||
for bb in &mut buf {
|
for bb in &mut buf {
|
||||||
|
|
@ -85,7 +85,7 @@ pub fn parse_datetime(input: &[u8]) -> IResult<[i16; 6]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_bitarray(input: &[u8]) -> IResult<[bool; 16]> {
|
pub fn parse_bitarray(input: &[u8]) -> IResult<'_, [bool; 16]> {
|
||||||
let mut bits = [false; 16];
|
let mut bits = [false; 16];
|
||||||
let (input, val) = parse_int2(input)?;
|
let (input, val) = parse_int2(input)?;
|
||||||
for (ii, bit) in bits.iter_mut().enumerate() {
|
for (ii, bit) in bits.iter_mut().enumerate() {
|
||||||
|
|
@ -95,7 +95,7 @@ pub fn parse_bitarray(input: &[u8]) -> IResult<[bool; 16]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_ascii(input: &[u8], length: u16) -> IResult<Vec<u8>> {
|
pub fn parse_ascii(input: &[u8], length: u16) -> IResult<'_, Vec<u8>> {
|
||||||
let length = length as usize;
|
let length = length as usize;
|
||||||
let (input, data) = take_bytes(input, length)?;
|
let (input, data) = take_bytes(input, length)?;
|
||||||
let last = data[length - 1];
|
let last = data[length - 1];
|
||||||
|
|
|
||||||
610
src/elements.rs
610
src/elements.rs
|
|
@ -28,6 +28,68 @@ use arrow::array::{
|
||||||
pub type DListBuilder = ListBuilder<Box<dyn ArrayBuilder>>;
|
pub type DListBuilder = ListBuilder<Box<dyn ArrayBuilder>>;
|
||||||
pub type FListBuilder = FixedSizeListBuilder<Box<dyn ArrayBuilder>>;
|
pub type FListBuilder = FixedSizeListBuilder<Box<dyn ArrayBuilder>>;
|
||||||
|
|
||||||
|
struct PropertyRecord {
|
||||||
|
key: i16,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BoundaryRecord {
|
||||||
|
layer_id: u32,
|
||||||
|
vertices: Vec<i32>,
|
||||||
|
properties: Vec<PropertyRecord>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BoundaryBatchRecord {
|
||||||
|
layer_id: u32,
|
||||||
|
vertices: Vec<i32>,
|
||||||
|
vertex_offsets: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RectBatchRecord {
|
||||||
|
layer_id: u32,
|
||||||
|
rects: Vec<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SRefRecord {
|
||||||
|
target_id: u32,
|
||||||
|
invert_y: bool,
|
||||||
|
scale: f64,
|
||||||
|
angle_rad: f64,
|
||||||
|
xy: u64,
|
||||||
|
properties: Vec<PropertyRecord>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ARefRecord {
|
||||||
|
target_id: u32,
|
||||||
|
invert_y: bool,
|
||||||
|
scale: f64,
|
||||||
|
angle_rad: f64,
|
||||||
|
xy: u64,
|
||||||
|
xy0: u64,
|
||||||
|
xy1: u64,
|
||||||
|
counts: u32,
|
||||||
|
properties: Vec<PropertyRecord>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RefRecord {
|
||||||
|
SRef(SRefRecord),
|
||||||
|
ARef(ARefRecord),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const UNIT_COUNTS: u32 = (1_u32 << 16) | 1_u32;
|
||||||
|
|
||||||
|
|
||||||
|
fn layer_id_for(
|
||||||
|
layer: i16,
|
||||||
|
dtype: i16,
|
||||||
|
layers: &mut HashMap<u32, u32>,
|
||||||
|
) -> u32 {
|
||||||
|
let layer32 = ((layer as u16 as u32) << 16) | (dtype as u16 as u32);
|
||||||
|
let next_id = layers.len();
|
||||||
|
*layers.entry(layer32).or_insert(next_id.try_into().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn insert_layer(
|
fn insert_layer(
|
||||||
layer: i16,
|
layer: i16,
|
||||||
|
|
@ -36,11 +98,9 @@ fn insert_layer(
|
||||||
struct_builder: &mut StructBuilder,
|
struct_builder: &mut StructBuilder,
|
||||||
field_index: usize,
|
field_index: usize,
|
||||||
) {
|
) {
|
||||||
let layer32 = ((layer as u16 as u32) << 16) | (dtype as u16 as u32);
|
let id = layer_id_for(layer, dtype, layers);
|
||||||
let next_id = layers.len();
|
|
||||||
let id = layers.entry(layer32).or_insert(next_id.try_into().unwrap());
|
|
||||||
let layer_builder = struct_builder.field_builder::<UInt32Builder>(field_index).unwrap();
|
let layer_builder = struct_builder.field_builder::<UInt32Builder>(field_index).unwrap();
|
||||||
layer_builder.append_value(*id);
|
layer_builder.append_value(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -51,12 +111,25 @@ pub fn read_elements<'a>(
|
||||||
layers: &mut HashMap<u32, u32>,
|
layers: &mut HashMap<u32, u32>,
|
||||||
) -> IResult<'a, ()> {
|
) -> IResult<'a, ()> {
|
||||||
let mut input = input;
|
let mut input = input;
|
||||||
|
let mut boundaries = Vec::<BoundaryRecord>::new();
|
||||||
|
let mut srefs = Vec::<SRefRecord>::new();
|
||||||
|
let mut arefs = Vec::<ARefRecord>::new();
|
||||||
let (_, mut header) = RecordHeader::read(input)?; // don't consume tag
|
let (_, mut header) = RecordHeader::read(input)?; // don't consume tag
|
||||||
while header.tag != records::RTAG_ENDSTR {
|
while header.tag != records::RTAG_ENDSTR {
|
||||||
(input, _) = match header.tag {
|
(input, _) = match header.tag {
|
||||||
records::RTAG_SREF => read_ref(input, cell_builder, header.tag, names)?,
|
records::RTAG_SREF | records::RTAG_AREF => {
|
||||||
records::RTAG_AREF => read_ref(input, cell_builder, header.tag, names)?,
|
let (next_input, ref_record) = read_ref(input, header.tag, names)?;
|
||||||
records::RTAG_BOUNDARY => read_boundary(input, cell_builder, layers)?,
|
match ref_record {
|
||||||
|
RefRecord::SRef(sref) => srefs.push(sref),
|
||||||
|
RefRecord::ARef(aref) => arefs.push(aref),
|
||||||
|
}
|
||||||
|
(next_input, ())
|
||||||
|
},
|
||||||
|
records::RTAG_BOUNDARY => {
|
||||||
|
let (next_input, boundary) = read_boundary(input, layers)?;
|
||||||
|
boundaries.push(boundary);
|
||||||
|
(next_input, ())
|
||||||
|
},
|
||||||
records::RTAG_PATH => read_path(input, cell_builder, layers)?,
|
records::RTAG_PATH => read_path(input, cell_builder, layers)?,
|
||||||
records::RTAG_NODE => read_boxnode(input, cell_builder, header.tag, layers)?,
|
records::RTAG_NODE => read_boxnode(input, cell_builder, header.tag, layers)?,
|
||||||
records::RTAG_BOX => read_boxnode(input, cell_builder, header.tag, layers)?,
|
records::RTAG_BOX => read_boxnode(input, cell_builder, header.tag, layers)?,
|
||||||
|
|
@ -71,50 +144,363 @@ pub fn read_elements<'a>(
|
||||||
}
|
}
|
||||||
(input, _) = take_bytes(input, 4_usize)?; // consume endstr tag
|
(input, _) = take_bytes(input, 4_usize)?; // consume endstr tag
|
||||||
|
|
||||||
let refs_builder = cell_builder.field_builder::<DListBuilder>(2).unwrap();
|
let mut sref_plain = Vec::<SRefRecord>::with_capacity(srefs.len() + arefs.len() / 4);
|
||||||
refs_builder.append(true);
|
let mut sref_props = Vec::<SRefRecord>::with_capacity(srefs.len() / 16 + arefs.len() / 64);
|
||||||
let boundaries_builder = cell_builder.field_builder::<DListBuilder>(3).unwrap();
|
for sref in srefs {
|
||||||
boundaries_builder.append(true);
|
if sref.properties.is_empty() {
|
||||||
let paths_builder = cell_builder.field_builder::<DListBuilder>(4).unwrap();
|
sref_plain.push(sref);
|
||||||
|
} else {
|
||||||
|
sref_props.push(sref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut aref_plain = Vec::<ARefRecord>::with_capacity(arefs.len());
|
||||||
|
let mut aref_props = Vec::<ARefRecord>::with_capacity(arefs.len() / 16);
|
||||||
|
for aref in arefs {
|
||||||
|
if aref.counts == UNIT_COUNTS {
|
||||||
|
let sref = aref_to_sref(aref);
|
||||||
|
if sref.properties.is_empty() {
|
||||||
|
sref_plain.push(sref);
|
||||||
|
} else {
|
||||||
|
sref_props.push(sref);
|
||||||
|
}
|
||||||
|
} else if aref.properties.is_empty() {
|
||||||
|
aref_plain.push(aref);
|
||||||
|
} else {
|
||||||
|
aref_props.push(aref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sref_plain.sort_by_key(|sref| sref.target_id);
|
||||||
|
aref_plain.sort_by_key(|aref| aref.target_id);
|
||||||
|
|
||||||
|
let mut boundary_plain = Vec::<BoundaryRecord>::with_capacity(boundaries.len());
|
||||||
|
let mut boundary_props = Vec::<BoundaryRecord>::with_capacity(boundaries.len() / 16);
|
||||||
|
for boundary in boundaries {
|
||||||
|
if boundary.properties.is_empty() {
|
||||||
|
boundary_plain.push(boundary);
|
||||||
|
} else {
|
||||||
|
boundary_props.push(boundary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boundary_plain.sort_by_key(|boundary| boundary.layer_id);
|
||||||
|
|
||||||
|
let mut rect_batches = Vec::<RectBatchRecord>::new();
|
||||||
|
let mut boundary_batches = Vec::<BoundaryBatchRecord>::new();
|
||||||
|
let mut ii = 0;
|
||||||
|
while ii < boundary_plain.len() {
|
||||||
|
let start = ii;
|
||||||
|
let layer_id = boundary_plain[ii].layer_id;
|
||||||
|
while ii < boundary_plain.len() && boundary_plain[ii].layer_id == layer_id {
|
||||||
|
ii += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let group = &boundary_plain[start..ii];
|
||||||
|
let rect_capacity = group.len() * 4;
|
||||||
|
let vertex_capacity = group.iter().map(|boundary| boundary.vertices.len()).sum();
|
||||||
|
let mut rect_batch = RectBatchRecord {
|
||||||
|
layer_id,
|
||||||
|
rects: Vec::with_capacity(rect_capacity),
|
||||||
|
};
|
||||||
|
let mut boundary_batch = BoundaryBatchRecord {
|
||||||
|
layer_id,
|
||||||
|
vertices: Vec::with_capacity(vertex_capacity),
|
||||||
|
vertex_offsets: Vec::with_capacity(group.len()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut next_offset: u32 = 0;
|
||||||
|
for boundary in group {
|
||||||
|
if let Some(rect) = boundary_to_rect(&boundary.vertices) {
|
||||||
|
rect_batch.rects.extend_from_slice(&rect);
|
||||||
|
} else {
|
||||||
|
boundary_batch.vertex_offsets.push(next_offset);
|
||||||
|
boundary_batch.vertices.extend_from_slice(&boundary.vertices);
|
||||||
|
next_offset += (boundary.vertices.len() / 2) as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rect_batch.rects.is_empty() {
|
||||||
|
rect_batches.push(rect_batch);
|
||||||
|
}
|
||||||
|
if !boundary_batch.vertex_offsets.is_empty() {
|
||||||
|
boundary_batches.push(boundary_batch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sref_builder = cell_builder.field_builder::<DListBuilder>(2).unwrap();
|
||||||
|
for sref in sref_plain {
|
||||||
|
append_sref(sref_builder, sref);
|
||||||
|
}
|
||||||
|
sref_builder.append(true);
|
||||||
|
|
||||||
|
let aref_builder = cell_builder.field_builder::<DListBuilder>(3).unwrap();
|
||||||
|
for aref in aref_plain {
|
||||||
|
append_aref(aref_builder, aref);
|
||||||
|
}
|
||||||
|
aref_builder.append(true);
|
||||||
|
|
||||||
|
let sref_props_builder = cell_builder.field_builder::<DListBuilder>(4).unwrap();
|
||||||
|
for sref in sref_props {
|
||||||
|
append_sref_prop(sref_props_builder, sref);
|
||||||
|
}
|
||||||
|
sref_props_builder.append(true);
|
||||||
|
|
||||||
|
let aref_props_builder = cell_builder.field_builder::<DListBuilder>(5).unwrap();
|
||||||
|
for aref in aref_props {
|
||||||
|
append_aref_prop(aref_props_builder, aref);
|
||||||
|
}
|
||||||
|
aref_props_builder.append(true);
|
||||||
|
|
||||||
|
let rect_batches_builder = cell_builder.field_builder::<DListBuilder>(6).unwrap();
|
||||||
|
for rect_batch in rect_batches {
|
||||||
|
append_rect_batch(rect_batches_builder, rect_batch);
|
||||||
|
}
|
||||||
|
rect_batches_builder.append(true);
|
||||||
|
|
||||||
|
let boundary_batches_builder = cell_builder.field_builder::<DListBuilder>(7).unwrap();
|
||||||
|
for boundary_batch in boundary_batches {
|
||||||
|
append_boundary_batch(boundary_batches_builder, boundary_batch);
|
||||||
|
}
|
||||||
|
boundary_batches_builder.append(true);
|
||||||
|
|
||||||
|
let boundary_props_builder = cell_builder.field_builder::<DListBuilder>(8).unwrap();
|
||||||
|
for boundary in boundary_props {
|
||||||
|
append_boundary_prop(boundary_props_builder, boundary);
|
||||||
|
}
|
||||||
|
boundary_props_builder.append(true);
|
||||||
|
|
||||||
|
let paths_builder = cell_builder.field_builder::<DListBuilder>(9).unwrap();
|
||||||
paths_builder.append(true);
|
paths_builder.append(true);
|
||||||
let nodes_builder = cell_builder.field_builder::<DListBuilder>(5).unwrap();
|
let nodes_builder = cell_builder.field_builder::<DListBuilder>(10).unwrap();
|
||||||
nodes_builder.append(true);
|
nodes_builder.append(true);
|
||||||
let boxes_builder = cell_builder.field_builder::<DListBuilder>(6).unwrap();
|
let boxes_builder = cell_builder.field_builder::<DListBuilder>(11).unwrap();
|
||||||
boxes_builder.append(true);
|
boxes_builder.append(true);
|
||||||
let texts_builder = cell_builder.field_builder::<DListBuilder>(7).unwrap();
|
let texts_builder = cell_builder.field_builder::<DListBuilder>(12).unwrap();
|
||||||
texts_builder.append(true);
|
texts_builder.append(true);
|
||||||
|
|
||||||
Ok((input, ()))
|
Ok((input, ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn read_boundary<'a>(
|
fn append_sref(
|
||||||
input: &'a [u8],
|
sref_builder: &mut DListBuilder,
|
||||||
cell_builder: &mut StructBuilder,
|
sref: SRefRecord,
|
||||||
layers: &mut HashMap<u32, u32>,
|
) {
|
||||||
) -> IResult<'a, ()> {
|
let sref_struct_builder = sref_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
let boundaries_builder = cell_builder.field_builder::<DListBuilder>(3).unwrap();
|
|
||||||
let boundary_builder = boundaries_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
|
||||||
|
|
||||||
|
let target_builder = sref_struct_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
target_builder.append_value(sref.target_id);
|
||||||
|
let invert_builder = sref_struct_builder.field_builder::<BooleanBuilder>(1).unwrap();
|
||||||
|
invert_builder.append_value(sref.invert_y);
|
||||||
|
let scale_builder = sref_struct_builder.field_builder::<Float64Builder>(2).unwrap();
|
||||||
|
scale_builder.append_value(sref.scale);
|
||||||
|
let angle_builder = sref_struct_builder.field_builder::<Float64Builder>(3).unwrap();
|
||||||
|
angle_builder.append_value(sref.angle_rad);
|
||||||
|
let xy_builder = sref_struct_builder.field_builder::<UInt64Builder>(4).unwrap();
|
||||||
|
xy_builder.append_value(sref.xy);
|
||||||
|
|
||||||
|
sref_struct_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_aref(
|
||||||
|
aref_builder: &mut DListBuilder,
|
||||||
|
aref: ARefRecord,
|
||||||
|
) {
|
||||||
|
let aref_struct_builder = aref_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let target_builder = aref_struct_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
target_builder.append_value(aref.target_id);
|
||||||
|
let invert_builder = aref_struct_builder.field_builder::<BooleanBuilder>(1).unwrap();
|
||||||
|
invert_builder.append_value(aref.invert_y);
|
||||||
|
let scale_builder = aref_struct_builder.field_builder::<Float64Builder>(2).unwrap();
|
||||||
|
scale_builder.append_value(aref.scale);
|
||||||
|
let angle_builder = aref_struct_builder.field_builder::<Float64Builder>(3).unwrap();
|
||||||
|
angle_builder.append_value(aref.angle_rad);
|
||||||
|
let xy_builder = aref_struct_builder.field_builder::<UInt64Builder>(4).unwrap();
|
||||||
|
xy_builder.append_value(aref.xy);
|
||||||
|
let xy0_builder = aref_struct_builder.field_builder::<UInt64Builder>(5).unwrap();
|
||||||
|
xy0_builder.append_value(aref.xy0);
|
||||||
|
let xy1_builder = aref_struct_builder.field_builder::<UInt64Builder>(6).unwrap();
|
||||||
|
xy1_builder.append_value(aref.xy1);
|
||||||
|
let counts_builder = aref_struct_builder.field_builder::<UInt32Builder>(7).unwrap();
|
||||||
|
counts_builder.append_value(aref.counts);
|
||||||
|
|
||||||
|
aref_struct_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_properties(
|
||||||
|
props_builder: &mut DListBuilder,
|
||||||
|
properties: Vec<PropertyRecord>,
|
||||||
|
) {
|
||||||
|
for prop in properties {
|
||||||
|
let prop_builder = props_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
let key_builder = prop_builder.field_builder::<Int16Builder>(0).unwrap();
|
||||||
|
key_builder.append_value(prop.key);
|
||||||
|
|
||||||
|
let val_builder = prop_builder.field_builder::<StringBuilder>(1).unwrap();
|
||||||
|
val_builder.append_value(prop.value);
|
||||||
|
|
||||||
|
prop_builder.append(true);
|
||||||
|
}
|
||||||
|
props_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_sref_prop(
|
||||||
|
sref_props_builder: &mut DListBuilder,
|
||||||
|
sref: SRefRecord,
|
||||||
|
) {
|
||||||
|
let sref_prop_builder = sref_props_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let target_builder = sref_prop_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
target_builder.append_value(sref.target_id);
|
||||||
|
let invert_builder = sref_prop_builder.field_builder::<BooleanBuilder>(1).unwrap();
|
||||||
|
invert_builder.append_value(sref.invert_y);
|
||||||
|
let scale_builder = sref_prop_builder.field_builder::<Float64Builder>(2).unwrap();
|
||||||
|
scale_builder.append_value(sref.scale);
|
||||||
|
let angle_builder = sref_prop_builder.field_builder::<Float64Builder>(3).unwrap();
|
||||||
|
angle_builder.append_value(sref.angle_rad);
|
||||||
|
let xy_builder = sref_prop_builder.field_builder::<UInt64Builder>(4).unwrap();
|
||||||
|
xy_builder.append_value(sref.xy);
|
||||||
|
|
||||||
|
let props_builder = sref_prop_builder.field_builder::<DListBuilder>(5).unwrap();
|
||||||
|
append_properties(props_builder, sref.properties);
|
||||||
|
|
||||||
|
sref_prop_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_aref_prop(
|
||||||
|
aref_props_builder: &mut DListBuilder,
|
||||||
|
aref: ARefRecord,
|
||||||
|
) {
|
||||||
|
let aref_prop_builder = aref_props_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let target_builder = aref_prop_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
target_builder.append_value(aref.target_id);
|
||||||
|
let invert_builder = aref_prop_builder.field_builder::<BooleanBuilder>(1).unwrap();
|
||||||
|
invert_builder.append_value(aref.invert_y);
|
||||||
|
let scale_builder = aref_prop_builder.field_builder::<Float64Builder>(2).unwrap();
|
||||||
|
scale_builder.append_value(aref.scale);
|
||||||
|
let angle_builder = aref_prop_builder.field_builder::<Float64Builder>(3).unwrap();
|
||||||
|
angle_builder.append_value(aref.angle_rad);
|
||||||
|
let xy_builder = aref_prop_builder.field_builder::<UInt64Builder>(4).unwrap();
|
||||||
|
xy_builder.append_value(aref.xy);
|
||||||
|
let xy0_builder = aref_prop_builder.field_builder::<UInt64Builder>(5).unwrap();
|
||||||
|
xy0_builder.append_value(aref.xy0);
|
||||||
|
let xy1_builder = aref_prop_builder.field_builder::<UInt64Builder>(6).unwrap();
|
||||||
|
xy1_builder.append_value(aref.xy1);
|
||||||
|
let counts_builder = aref_prop_builder.field_builder::<UInt32Builder>(7).unwrap();
|
||||||
|
counts_builder.append_value(aref.counts);
|
||||||
|
|
||||||
|
let props_builder = aref_prop_builder.field_builder::<DListBuilder>(8).unwrap();
|
||||||
|
append_properties(props_builder, aref.properties);
|
||||||
|
|
||||||
|
aref_prop_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn aref_to_sref(aref: ARefRecord) -> SRefRecord {
|
||||||
|
SRefRecord {
|
||||||
|
target_id: aref.target_id,
|
||||||
|
invert_y: aref.invert_y,
|
||||||
|
scale: aref.scale,
|
||||||
|
angle_rad: aref.angle_rad,
|
||||||
|
xy: aref.xy,
|
||||||
|
properties: aref.properties,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn read_boundary<'a>(
|
||||||
|
input: &'a [u8],
|
||||||
|
layers: &mut HashMap<u32, u32>,
|
||||||
|
) -> IResult<'a, BoundaryRecord> {
|
||||||
let (input, _) = records::BOUNDARY::read(input)?;
|
let (input, _) = records::BOUNDARY::read(input)?;
|
||||||
|
|
||||||
let (input, layer) = LAYER::skip_and_read(input)?;
|
let (input, layer) = LAYER::skip_and_read(input)?;
|
||||||
let (input, dtype) = DATATYPE::read(input)?;
|
let (input, dtype) = DATATYPE::read(input)?;
|
||||||
insert_layer(layer, dtype, layers, boundary_builder, 0);
|
let layer_id = layer_id_for(layer, dtype, layers);
|
||||||
|
|
||||||
let xys_builder = boundary_builder.field_builder::<DListBuilder>(1).unwrap();
|
|
||||||
let xy_builder = xys_builder.values().as_any_mut().downcast_mut::<Int32Builder>().unwrap();
|
|
||||||
let (input, xy_iter) = XY::read(input)?;
|
let (input, xy_iter) = XY::read(input)?;
|
||||||
for xy in xy_iter {
|
let mut vertices: Vec<i32> = xy_iter.collect();
|
||||||
xy_builder.append_value(xy);
|
vertices.truncate(vertices.len().saturating_sub(2));
|
||||||
|
|
||||||
|
let (input, properties) = read_properties_vec(input)?;
|
||||||
|
|
||||||
|
Ok((input, BoundaryRecord { layer_id, vertices, properties }))
|
||||||
}
|
}
|
||||||
xys_builder.append(true);
|
|
||||||
|
|
||||||
let props_builder = boundary_builder.field_builder::<DListBuilder>(2).unwrap();
|
|
||||||
let (input, ()) = read_properties(input, props_builder)?;
|
|
||||||
|
|
||||||
boundary_builder.append(true);
|
fn append_boundary_batch(
|
||||||
Ok((input, ()))
|
boundary_batches_builder: &mut DListBuilder,
|
||||||
|
boundary_batch: BoundaryBatchRecord,
|
||||||
|
) {
|
||||||
|
let boundary_batch_builder = boundary_batches_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let layer_builder = boundary_batch_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
layer_builder.append_value(boundary_batch.layer_id);
|
||||||
|
|
||||||
|
let vertices_builder = boundary_batch_builder.field_builder::<DListBuilder>(1).unwrap();
|
||||||
|
let vertex_builder = vertices_builder.values().as_any_mut().downcast_mut::<Int32Builder>().unwrap();
|
||||||
|
vertex_builder.append_slice(&boundary_batch.vertices);
|
||||||
|
vertices_builder.append(true);
|
||||||
|
|
||||||
|
let offsets_builder = boundary_batch_builder.field_builder::<DListBuilder>(2).unwrap();
|
||||||
|
let offset_builder = offsets_builder.values().as_any_mut().downcast_mut::<UInt32Builder>().unwrap();
|
||||||
|
offset_builder.append_slice(&boundary_batch.vertex_offsets);
|
||||||
|
offsets_builder.append(true);
|
||||||
|
|
||||||
|
boundary_batch_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_rect_batch(
|
||||||
|
rect_batches_builder: &mut DListBuilder,
|
||||||
|
rect_batch: RectBatchRecord,
|
||||||
|
) {
|
||||||
|
let rect_batch_builder = rect_batches_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let layer_builder = rect_batch_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
layer_builder.append_value(rect_batch.layer_id);
|
||||||
|
|
||||||
|
let rects_builder = rect_batch_builder.field_builder::<DListBuilder>(1).unwrap();
|
||||||
|
let rect_builder = rects_builder.values().as_any_mut().downcast_mut::<Int32Builder>().unwrap();
|
||||||
|
rect_builder.append_slice(&rect_batch.rects);
|
||||||
|
rects_builder.append(true);
|
||||||
|
|
||||||
|
rect_batch_builder.append(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn append_boundary_prop(
|
||||||
|
boundary_props_builder: &mut DListBuilder,
|
||||||
|
boundary: BoundaryRecord,
|
||||||
|
) {
|
||||||
|
let boundary_prop_builder = boundary_props_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
|
let layer_builder = boundary_prop_builder.field_builder::<UInt32Builder>(0).unwrap();
|
||||||
|
layer_builder.append_value(boundary.layer_id);
|
||||||
|
|
||||||
|
let vertices_builder = boundary_prop_builder.field_builder::<DListBuilder>(1).unwrap();
|
||||||
|
let vertex_builder = vertices_builder.values().as_any_mut().downcast_mut::<Int32Builder>().unwrap();
|
||||||
|
vertex_builder.append_slice(&boundary.vertices);
|
||||||
|
vertices_builder.append(true);
|
||||||
|
|
||||||
|
let props_builder = boundary_prop_builder.field_builder::<DListBuilder>(2).unwrap();
|
||||||
|
for prop in boundary.properties {
|
||||||
|
let prop_builder = props_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
let key_builder = prop_builder.field_builder::<Int16Builder>(0).unwrap();
|
||||||
|
key_builder.append_value(prop.key);
|
||||||
|
|
||||||
|
let val_builder = prop_builder.field_builder::<StringBuilder>(1).unwrap();
|
||||||
|
val_builder.append_value(prop.value);
|
||||||
|
|
||||||
|
prop_builder.append(true);
|
||||||
|
}
|
||||||
|
props_builder.append(true);
|
||||||
|
|
||||||
|
boundary_prop_builder.append(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -123,7 +509,7 @@ pub fn read_path<'a>(
|
||||||
cell_builder: &mut StructBuilder,
|
cell_builder: &mut StructBuilder,
|
||||||
layers: &mut HashMap<u32, u32>,
|
layers: &mut HashMap<u32, u32>,
|
||||||
) -> IResult<'a, ()> {
|
) -> IResult<'a, ()> {
|
||||||
let paths_builder = cell_builder.field_builder::<DListBuilder>(4).unwrap();
|
let paths_builder = cell_builder.field_builder::<DListBuilder>(9).unwrap();
|
||||||
let path_builder = paths_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
let path_builder = paths_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
let (input, _) = records::PATH::read(input)?;
|
let (input, _) = records::PATH::read(input)?;
|
||||||
|
|
@ -196,8 +582,8 @@ pub fn read_boxnode<'a>(
|
||||||
layers: &mut HashMap<u32, u32>,
|
layers: &mut HashMap<u32, u32>,
|
||||||
) -> IResult<'a, ()> {
|
) -> IResult<'a, ()> {
|
||||||
let field_num = match tag {
|
let field_num = match tag {
|
||||||
records::RTAG_NODE => 5,
|
records::RTAG_NODE => 10,
|
||||||
records::RTAG_BOX => 6,
|
records::RTAG_BOX => 11,
|
||||||
_ => return fail(input, format!("Unexpected tag {:04x}", tag)),
|
_ => return fail(input, format!("Unexpected tag {:04x}", tag)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -238,7 +624,7 @@ pub fn read_text<'a>(
|
||||||
cell_builder: &mut StructBuilder,
|
cell_builder: &mut StructBuilder,
|
||||||
layers: &mut HashMap<u32, u32>,
|
layers: &mut HashMap<u32, u32>,
|
||||||
) -> IResult<'a, ()> {
|
) -> IResult<'a, ()> {
|
||||||
let texts_builder = cell_builder.field_builder::<DListBuilder>(7).unwrap();
|
let texts_builder = cell_builder.field_builder::<DListBuilder>(12).unwrap();
|
||||||
let text_builder = texts_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
let text_builder = texts_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
||||||
|
|
||||||
let mut path_type = None;
|
let mut path_type = None;
|
||||||
|
|
@ -333,13 +719,53 @@ pub fn read_text<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn boundary_to_rect(vertices: &[i32]) -> Option<[i32; 4]> {
|
||||||
|
if vertices.len() != 8 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_ref<'a>(
|
let xs = [vertices[0], vertices[2], vertices[4], vertices[6]];
|
||||||
|
let ys = [vertices[1], vertices[3], vertices[5], vertices[7]];
|
||||||
|
|
||||||
|
let min_x = *xs.iter().min().unwrap();
|
||||||
|
let max_x = *xs.iter().max().unwrap();
|
||||||
|
let min_y = *ys.iter().min().unwrap();
|
||||||
|
let max_y = *ys.iter().max().unwrap();
|
||||||
|
if min_x >= max_x || min_y >= max_y {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut seen_corners: u8 = 0;
|
||||||
|
for ii in 0..4 {
|
||||||
|
let jj = (ii + 1) % 4;
|
||||||
|
let dx = xs[jj] - xs[ii];
|
||||||
|
let dy = ys[jj] - ys[ii];
|
||||||
|
if (dx == 0) == (dy == 0) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = xs[ii];
|
||||||
|
let y = ys[ii];
|
||||||
|
if (x != min_x && x != max_x) || (y != min_y && y != max_y) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let code = ((x == max_x) as u8) << 1 | ((y == max_y) as u8);
|
||||||
|
seen_corners |= 1 << code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if seen_corners != 0b1111 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some([min_x, min_y, max_x, max_y])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn read_ref<'a>(
|
||||||
input: &'a [u8],
|
input: &'a [u8],
|
||||||
cell_builder: &mut StructBuilder,
|
|
||||||
tag: u16,
|
tag: u16,
|
||||||
names: &mut HashMap<String, u32>,
|
names: &mut HashMap<String, u32>,
|
||||||
) -> IResult<'a, ()> {
|
) -> IResult<'a, RefRecord> {
|
||||||
let (input, _) = match tag {
|
let (input, _) = match tag {
|
||||||
records::RTAG_SREF => records::SREF::read(input)?,
|
records::RTAG_SREF => records::SREF::read(input)?,
|
||||||
records::RTAG_AREF => records::AREF::read(input)?,
|
records::RTAG_AREF => records::AREF::read(input)?,
|
||||||
|
|
@ -347,20 +773,15 @@ pub fn read_ref<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_aref = tag == records::RTAG_AREF;
|
let is_aref = tag == records::RTAG_AREF;
|
||||||
let refs_builder = cell_builder.field_builder::<DListBuilder>(2).unwrap();
|
let mut invert_y = false;
|
||||||
let ref_builder = refs_builder.values().as_any_mut().downcast_mut::<StructBuilder>().unwrap();
|
let mut scale = 1.0;
|
||||||
|
let mut angle_rad = 0.0;
|
||||||
let mut invert_y = None;
|
|
||||||
let mut mag = None;
|
|
||||||
let mut angle_deg = None;
|
|
||||||
let mut colrow = None;
|
let mut colrow = None;
|
||||||
|
|
||||||
let (input, struct_name_bytes) = SNAME::skip_and_read(input)?;
|
let (input, struct_name_bytes) = SNAME::skip_and_read(input)?;
|
||||||
let struct_name = String::from_utf8(struct_name_bytes).unwrap();
|
let struct_name = String::from_utf8(struct_name_bytes).unwrap();
|
||||||
let next_id = names.len();
|
let next_id = names.len();
|
||||||
let id = names.entry(struct_name).or_insert(next_id.try_into().unwrap());
|
let id = names.entry(struct_name).or_insert(next_id.try_into().unwrap());
|
||||||
let target_builder = ref_builder.field_builder::<UInt32Builder>(0).unwrap();
|
|
||||||
target_builder.append_value(*id);
|
|
||||||
|
|
||||||
let (mut input, mut header) = RecordHeader::read(input)?;
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
||||||
while header.tag != records::RTAG_XY {
|
while header.tag != records::RTAG_XY {
|
||||||
|
|
@ -368,17 +789,17 @@ pub fn read_ref<'a>(
|
||||||
records::RTAG_STRANS => {
|
records::RTAG_STRANS => {
|
||||||
let strans;
|
let strans;
|
||||||
(input, strans) = STRANS::read_data(input, header.data_size)?;
|
(input, strans) = STRANS::read_data(input, header.data_size)?;
|
||||||
invert_y = Some(strans[0]);
|
invert_y = strans[0];
|
||||||
},
|
},
|
||||||
records::RTAG_MAG => {
|
records::RTAG_MAG => {
|
||||||
let _mag;
|
let _mag;
|
||||||
(input, _mag) = MAG::read_data(input, header.data_size)?;
|
(input, _mag) = MAG::read_data(input, header.data_size)?;
|
||||||
mag = Some(_mag);
|
scale = _mag;
|
||||||
},
|
},
|
||||||
records::RTAG_ANGLE => {
|
records::RTAG_ANGLE => {
|
||||||
let _angle_deg;
|
let _angle_deg;
|
||||||
(input, _angle_deg) = ANGLE::read_data(input, header.data_size)?;
|
(input, _angle_deg) = ANGLE::read_data(input, header.data_size)?;
|
||||||
angle_deg = Some(_angle_deg);
|
angle_rad = _angle_deg.to_radians();
|
||||||
},
|
},
|
||||||
records::RTAG_COLROW => {
|
records::RTAG_COLROW => {
|
||||||
let mut _colrow;
|
let mut _colrow;
|
||||||
|
|
@ -393,23 +814,13 @@ pub fn read_ref<'a>(
|
||||||
};
|
};
|
||||||
(input, header) = RecordHeader::read(input)?;
|
(input, header) = RecordHeader::read(input)?;
|
||||||
}
|
}
|
||||||
let inv_builder = ref_builder.field_builder::<BooleanBuilder>(1).unwrap();
|
|
||||||
inv_builder.append_option(invert_y);
|
|
||||||
let mag_builder = ref_builder.field_builder::<Float64Builder>(2).unwrap();
|
|
||||||
mag_builder.append_option(mag);
|
|
||||||
let angle_builder = ref_builder.field_builder::<Float64Builder>(3).unwrap();
|
|
||||||
angle_builder.append_option(angle_deg);
|
|
||||||
|
|
||||||
|
|
||||||
let (input, mut xy_iter) = XY::read_data(input, header.data_size)?;
|
let (input, mut xy_iter) = XY::read_data(input, header.data_size)?;
|
||||||
let xx = xy_iter.next().unwrap();
|
let xx = xy_iter.next().unwrap();
|
||||||
let yy = xy_iter.next().unwrap();
|
let yy = xy_iter.next().unwrap();
|
||||||
let xy = ((xx as u32 as u64) << 32) | (yy as u32 as u64);
|
let xy = ((xx as u32 as u64) << 32) | (yy as u32 as u64);
|
||||||
let xy_builder = ref_builder.field_builder::<UInt64Builder>(4).unwrap();
|
let (input, properties) = read_properties_vec(input)?;
|
||||||
xy_builder.append_value(xy);
|
|
||||||
|
|
||||||
let rep_builder = ref_builder.field_builder::<StructBuilder>(5).unwrap();
|
|
||||||
// println!("ref, {is_aref:?}");
|
|
||||||
if is_aref {
|
if is_aref {
|
||||||
if colrow.is_none() {
|
if colrow.is_none() {
|
||||||
return fail(input, "AREF without COLROW before XY".to_string())
|
return fail(input, "AREF without COLROW before XY".to_string())
|
||||||
|
|
@ -423,30 +834,28 @@ pub fn read_ref<'a>(
|
||||||
|
|
||||||
let xy0a = ((x0a as u32 as u64) << 32) | (y0a as u32 as u64);
|
let xy0a = ((x0a as u32 as u64) << 32) | (y0a as u32 as u64);
|
||||||
let xy1a = ((x1a as u32 as u64) << 32) | (y1a as u32 as u64);
|
let xy1a = ((x1a as u32 as u64) << 32) | (y1a as u32 as u64);
|
||||||
let xy0_builder = rep_builder.field_builder::<UInt64Builder>(0).unwrap();
|
|
||||||
xy0_builder.append_value(xy0a);
|
|
||||||
let xy1_builder = rep_builder.field_builder::<UInt64Builder>(1).unwrap();
|
|
||||||
xy1_builder.append_value(xy1a);
|
|
||||||
|
|
||||||
let counts = ((count0 as u16 as u32) << 16) | (count1 as u16 as u32);
|
let counts = ((count0 as u16 as u32) << 16) | (count1 as u16 as u32);
|
||||||
let counts_builder = rep_builder.field_builder::<UInt32Builder>(2).unwrap();
|
Ok((input, RefRecord::ARef(ARefRecord {
|
||||||
counts_builder.append_value(counts);
|
target_id: *id,
|
||||||
|
invert_y,
|
||||||
|
scale,
|
||||||
|
angle_rad,
|
||||||
|
xy,
|
||||||
|
xy0: xy0a,
|
||||||
|
xy1: xy1a,
|
||||||
|
counts,
|
||||||
|
properties,
|
||||||
|
})))
|
||||||
} else {
|
} else {
|
||||||
let xy0_builder = rep_builder.field_builder::<UInt64Builder>(0).unwrap();
|
Ok((input, RefRecord::SRef(SRefRecord {
|
||||||
xy0_builder.append_null();
|
target_id: *id,
|
||||||
let xy1_builder = rep_builder.field_builder::<UInt64Builder>(1).unwrap();
|
invert_y,
|
||||||
xy1_builder.append_null();
|
scale,
|
||||||
let counts_builder = rep_builder.field_builder::<UInt32Builder>(2).unwrap();
|
angle_rad,
|
||||||
counts_builder.append_null();
|
xy,
|
||||||
|
properties,
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
rep_builder.append(is_aref);
|
|
||||||
|
|
||||||
let props_builder = ref_builder.field_builder::<DListBuilder>(6).unwrap();
|
|
||||||
let (input, ()) = read_properties(input, props_builder)?;
|
|
||||||
|
|
||||||
ref_builder.append(true);
|
|
||||||
Ok((input, ()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -490,6 +899,29 @@ pub fn read_properties<'a>(input: &'a [u8], props_builder: &mut DListBuilder) ->
|
||||||
Ok((input, ()))
|
Ok((input, ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn read_properties_vec<'a>(input: &'a [u8]) -> IResult<'a, Vec<PropertyRecord>> {
|
||||||
|
let mut properties = Vec::<PropertyRecord>::new();
|
||||||
|
|
||||||
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
||||||
|
while header.tag != ENDEL::tag() {
|
||||||
|
if header.tag == PROPATTR::tag() {
|
||||||
|
let key;
|
||||||
|
let value_bytes;
|
||||||
|
(input, key) = PROPATTR::read_data(input, header.data_size)?;
|
||||||
|
(input, value_bytes) = PROPVALUE::read(input)?;
|
||||||
|
|
||||||
|
properties.push(PropertyRecord {
|
||||||
|
key,
|
||||||
|
value: String::from_utf8(value_bytes).unwrap(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
(input, header) = RecordHeader::read(input)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((input, properties))
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -514,7 +946,7 @@ pub trait Element {
|
||||||
/// Read from a stream to construct this object.
|
/// Read from a stream to construct this object.
|
||||||
/// Consumes up to (and including) the ENDEL record.
|
/// Consumes up to (and including) the ENDEL record.
|
||||||
///
|
///
|
||||||
fn read(input: &[u8]) -> IResult<Self> where Self: Sized;
|
fn read(input: &[u8]) -> IResult<'_, Self> where Self: Sized;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Write this element to a stream.
|
/// Write this element to a stream.
|
||||||
|
|
@ -561,7 +993,7 @@ pub struct Reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Reference {
|
impl Element for Reference {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let mut invert_y = false;
|
let mut invert_y = false;
|
||||||
let mut mag = 1.0;
|
let mut mag = 1.0;
|
||||||
let mut angle_deg = 0.0;
|
let mut angle_deg = 0.0;
|
||||||
|
|
@ -662,7 +1094,7 @@ pub struct Boundary {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Boundary {
|
impl Element for Boundary {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let (input, layer) = LAYER::skip_and_read(input)?;
|
let (input, layer) = LAYER::skip_and_read(input)?;
|
||||||
let (input, dtype) = DATATYPE::read(input)?;
|
let (input, dtype) = DATATYPE::read(input)?;
|
||||||
let (input, xy) = XY::read(input)?;
|
let (input, xy) = XY::read(input)?;
|
||||||
|
|
@ -710,7 +1142,7 @@ pub struct Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Path {
|
impl Element for Path {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let mut path_type = 0;
|
let mut path_type = 0;
|
||||||
let mut width = 0;
|
let mut width = 0;
|
||||||
let mut bgn_ext = 0;
|
let mut bgn_ext = 0;
|
||||||
|
|
@ -789,7 +1221,7 @@ pub struct GDSBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for GDSBox {
|
impl Element for GDSBox {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let (input, layer) = LAYER::skip_and_read(input)?;
|
let (input, layer) = LAYER::skip_and_read(input)?;
|
||||||
let (input, dtype) = BOXTYPE::read(input)?;
|
let (input, dtype) = BOXTYPE::read(input)?;
|
||||||
let (input, xy) = XY::read(input)?;
|
let (input, xy) = XY::read(input)?;
|
||||||
|
|
@ -828,7 +1260,7 @@ pub struct Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Node {
|
impl Element for Node {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let (input, layer) = LAYER::skip_and_read(input)?;
|
let (input, layer) = LAYER::skip_and_read(input)?;
|
||||||
let (input, dtype) = NODETYPE::read(input)?;
|
let (input, dtype) = NODETYPE::read(input)?;
|
||||||
let (input, xy) = XY::read(input)?;
|
let (input, xy) = XY::read(input)?;
|
||||||
|
|
@ -885,7 +1317,7 @@ pub struct Text {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for Text {
|
impl Element for Text {
|
||||||
fn read(input: &[u8]) -> IResult<Self> {
|
fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let mut path_type = 0;
|
let mut path_type = 0;
|
||||||
let mut presentation = [false; 16];
|
let mut presentation = [false; 16];
|
||||||
let mut invert_y = false;
|
let mut invert_y = false;
|
||||||
|
|
|
||||||
32
src/lib.rs
32
src/lib.rs
|
|
@ -20,7 +20,7 @@ use arrow::ffi::{to_ffi, FFI_ArrowArray, FFI_ArrowSchema};
|
||||||
use arrow::array::Array;
|
use arrow::array::Array;
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn read_path(
|
pub unsafe extern "C" fn read_path(
|
||||||
cpath: *const c_char,
|
cpath: *const c_char,
|
||||||
arr: *mut FFI_ArrowArray,
|
arr: *mut FFI_ArrowArray,
|
||||||
|
|
@ -40,7 +40,7 @@ pub unsafe extern "C" fn read_path(
|
||||||
|
|
||||||
let input = fs::read(path).expect("File read failed");
|
let input = fs::read(path).expect("File read failed");
|
||||||
let (_input, struct_arr) = read_library(&input).expect("Read failed");
|
let (_input, struct_arr) = read_library(&input).expect("Read failed");
|
||||||
(*arr, *schema) = to_ffi(&struct_arr.to_data()).unwrap();
|
unsafe { (*arr, *schema) = to_ffi(&struct_arr.to_data()).unwrap(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,40 +80,40 @@ macro_rules! impl_i32be {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn f64_to_i16(arr: *mut f64, size: usize) -> f64 { impl_i16be!(f64, arr, size) }
|
pub unsafe extern "C" fn f64_to_i16(arr: *mut f64, size: usize) -> f64 { impl_i16be!(f64, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn f64_to_i32(arr: *mut f64, size: usize) -> f64 { impl_i32be!(f64, arr, size) }
|
pub unsafe extern "C" fn f64_to_i32(arr: *mut f64, size: usize) -> f64 { impl_i32be!(f64, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn f32_to_i16(arr: *mut f32, size: usize) -> f32 { impl_i16be!(f32, arr, size) }
|
pub unsafe extern "C" fn f32_to_i16(arr: *mut f32, size: usize) -> f32 { impl_i16be!(f32, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn f32_to_i32(arr: *mut f32, size: usize) -> f32 { impl_i32be!(f32, arr, size) }
|
pub unsafe extern "C" fn f32_to_i32(arr: *mut f32, size: usize) -> f32 { impl_i32be!(f32, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn u64_to_i16(arr: *mut u64, size: usize) -> u64 { impl_i16be!(u64, arr, size) }
|
pub unsafe extern "C" fn u64_to_i16(arr: *mut u64, size: usize) -> u64 { impl_i16be!(u64, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn u64_to_i32(arr: *mut u64, size: usize) -> u64 { impl_i32be!(u64, arr, size) }
|
pub unsafe extern "C" fn u64_to_i32(arr: *mut u64, size: usize) -> u64 { impl_i32be!(u64, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn i64_to_i16(arr: *mut i64, size: usize) -> i64 { impl_i16be!(i64, arr, size) }
|
pub unsafe extern "C" fn i64_to_i16(arr: *mut i64, size: usize) -> i64 { impl_i16be!(i64, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn i64_to_i32(arr: *mut i64, size: usize) -> i64 { impl_i32be!(i64, arr, size) }
|
pub unsafe extern "C" fn i64_to_i32(arr: *mut i64, size: usize) -> i64 { impl_i32be!(i64, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn u32_to_i16(arr: *mut u32, size: usize) -> u32 { impl_i16be!(u32, arr, size) }
|
pub unsafe extern "C" fn u32_to_i16(arr: *mut u32, size: usize) -> u32 { impl_i16be!(u32, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn u32_to_i32(arr: *mut u32, size: usize) -> u32 { impl_i32be!(u32, arr, size) }
|
pub unsafe extern "C" fn u32_to_i32(arr: *mut u32, size: usize) -> u32 { impl_i32be!(u32, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn i32_to_i16(arr: *mut i32, size: usize) -> i32 { impl_i16be!(i32, arr, size) }
|
pub unsafe extern "C" fn i32_to_i16(arr: *mut i32, size: usize) -> i32 { impl_i16be!(i32, arr, size) }
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn i32_to_i32(arr: *mut i32, size: usize) -> i32 { impl_i32be!(i32, arr, size) }
|
pub unsafe extern "C" fn i32_to_i32(arr: *mut i32, size: usize) -> i32 { impl_i32be!(i32, arr, size) }
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn u16_to_i16(arr: *mut u16, size: usize) -> u16 { impl_i16be!(u16, arr, size) }
|
pub unsafe extern "C" fn u16_to_i16(arr: *mut u16, size: usize) -> u16 { impl_i16be!(u16, arr, size) }
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn i16_to_i16(arr: *mut i16, size: usize) -> i16 { impl_i16be!(i16, arr, size) }
|
pub unsafe extern "C" fn i16_to_i16(arr: *mut i16, size: usize) -> i16 { impl_i16be!(i16, arr, size) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ impl FileHeader {
|
||||||
/// Returns:
|
/// Returns:
|
||||||
/// FileHeader object
|
/// FileHeader object
|
||||||
///
|
///
|
||||||
pub fn read(input: &[u8]) -> IResult<Self> {
|
pub fn read(input: &[u8]) -> IResult<'_, Self> {
|
||||||
let (input, _version) = records::HEADER::read(input)?;
|
let (input, _version) = records::HEADER::read(input)?;
|
||||||
let (input, [mod_time, acc_time]) = records::BGNLIB::read(input)?;
|
let (input, [mod_time, acc_time]) = records::BGNLIB::read(input)?;
|
||||||
let (input, name) = records::LIBNAME::skip_and_read(input)?;
|
let (input, name) = records::LIBNAME::skip_and_read(input)?;
|
||||||
|
|
@ -98,7 +98,7 @@ impl FileHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn read_library(input: &[u8]) -> IResult<StructArray> {
|
pub fn read_library(input: &[u8]) -> IResult<'_, StructArray> {
|
||||||
let input_size = input.len();
|
let input_size = input.len();
|
||||||
|
|
||||||
let property_t = DataType::Struct(Fields::from(vec![
|
let property_t = DataType::Struct(Fields::from(vec![
|
||||||
|
|
@ -111,19 +111,43 @@ pub fn read_library(input: &[u8]) -> IResult<StructArray> {
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
let repetition_struct_t = DataType::Struct(Fields::from(vec![
|
let sref_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
|
Field::new("target", DataType::UInt32, false),
|
||||||
|
Field::new("invert_y", DataType::Boolean, false),
|
||||||
|
Field::new("scale", DataType::Float64, false),
|
||||||
|
Field::new("angle_rad", DataType::Float64, false),
|
||||||
|
Field::new("xy", DataType::UInt64, false),
|
||||||
|
]));
|
||||||
|
|
||||||
|
let aref_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
|
Field::new("target", DataType::UInt32, false),
|
||||||
|
Field::new("invert_y", DataType::Boolean, false),
|
||||||
|
Field::new("scale", DataType::Float64, false),
|
||||||
|
Field::new("angle_rad", DataType::Float64, false),
|
||||||
|
Field::new("xy", DataType::UInt64, false),
|
||||||
Field::new("xy0", DataType::UInt64, false),
|
Field::new("xy0", DataType::UInt64, false),
|
||||||
Field::new("xy1", DataType::UInt64, false),
|
Field::new("xy1", DataType::UInt64, false),
|
||||||
Field::new("counts", DataType::UInt32, false),
|
Field::new("counts", DataType::UInt32, false),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let ref_struct_t = DataType::Struct(Fields::from(vec![
|
let sref_prop_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
Field::new("target", DataType::UInt32, false),
|
Field::new("target", DataType::UInt32, false),
|
||||||
Field::new("invert_y", DataType::Boolean, true),
|
Field::new("invert_y", DataType::Boolean, false),
|
||||||
Field::new("mag", DataType::Float64, true),
|
Field::new("scale", DataType::Float64, false),
|
||||||
Field::new("angle_deg", DataType::Float64, true),
|
Field::new("angle_rad", DataType::Float64, false),
|
||||||
Field::new("xy", DataType::UInt64, false),
|
Field::new("xy", DataType::UInt64, false),
|
||||||
Field::new("repetition", repetition_struct_t, true),
|
Field::new("properties", property_list_t.clone(), true),
|
||||||
|
]));
|
||||||
|
|
||||||
|
let aref_prop_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
|
Field::new("target", DataType::UInt32, false),
|
||||||
|
Field::new("invert_y", DataType::Boolean, false),
|
||||||
|
Field::new("scale", DataType::Float64, false),
|
||||||
|
Field::new("angle_rad", DataType::Float64, false),
|
||||||
|
Field::new("xy", DataType::UInt64, false),
|
||||||
|
Field::new("xy0", DataType::UInt64, false),
|
||||||
|
Field::new("xy1", DataType::UInt64, false),
|
||||||
|
Field::new("counts", DataType::UInt32, false),
|
||||||
Field::new("properties", property_list_t.clone(), true),
|
Field::new("properties", property_list_t.clone(), true),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
|
@ -147,9 +171,24 @@ pub fn read_library(input: &[u8]) -> IResult<StructArray> {
|
||||||
Field::new_list_field(DataType::Int32, false)
|
Field::new_list_field(DataType::Int32, false)
|
||||||
));
|
));
|
||||||
|
|
||||||
let boundary_struct_t = DataType::Struct(Fields::from(vec![
|
let boundary_batch_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
Field::new("layer", DataType::UInt32, false),
|
Field::new("layer", DataType::UInt32, false),
|
||||||
Field::new("xy", coords_t.clone(), false),
|
Field::new("vertices", coords_t.clone(), false),
|
||||||
|
Field::new(
|
||||||
|
"vertex_offsets",
|
||||||
|
DataType::List(Arc::new(Field::new_list_field(DataType::UInt32, false))),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
|
||||||
|
let rect_batch_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
|
Field::new("layer", DataType::UInt32, false),
|
||||||
|
Field::new("rects", coords_t.clone(), false),
|
||||||
|
]));
|
||||||
|
|
||||||
|
let boundary_prop_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
|
Field::new("layer", DataType::UInt32, false),
|
||||||
|
Field::new("vertices", coords_t.clone(), false),
|
||||||
Field::new("properties", property_list_t.clone(), true),
|
Field::new("properties", property_list_t.clone(), true),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
|
@ -169,17 +208,36 @@ pub fn read_library(input: &[u8]) -> IResult<StructArray> {
|
||||||
Field::new("properties", property_list_t.clone(), true),
|
Field::new("properties", property_list_t.clone(), true),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
let sref_list_t = DataType::List(Arc::new(
|
||||||
|
Field::new_list_field(sref_struct_t, false)
|
||||||
|
));
|
||||||
|
|
||||||
let ref_list_t = DataType::List(Arc::new(
|
let aref_list_t = DataType::List(Arc::new(
|
||||||
Field::new_list_field(ref_struct_t, false)
|
Field::new_list_field(aref_struct_t, false)
|
||||||
|
));
|
||||||
|
|
||||||
|
let sref_prop_list_t = DataType::List(Arc::new(
|
||||||
|
Field::new_list_field(sref_prop_struct_t, false)
|
||||||
|
));
|
||||||
|
|
||||||
|
let aref_prop_list_t = DataType::List(Arc::new(
|
||||||
|
Field::new_list_field(aref_prop_struct_t, false)
|
||||||
));
|
));
|
||||||
|
|
||||||
let text_list_t = DataType::List(Arc::new(
|
let text_list_t = DataType::List(Arc::new(
|
||||||
Field::new_list_field(text_struct_t, false)
|
Field::new_list_field(text_struct_t, false)
|
||||||
));
|
));
|
||||||
|
|
||||||
let boundary_list_t = DataType::List(Arc::new(
|
let boundary_batch_list_t = DataType::List(Arc::new(
|
||||||
Field::new_list_field(boundary_struct_t, false)
|
Field::new_list_field(boundary_batch_struct_t, false)
|
||||||
|
));
|
||||||
|
|
||||||
|
let rect_batch_list_t = DataType::List(Arc::new(
|
||||||
|
Field::new_list_field(rect_batch_struct_t, false)
|
||||||
|
));
|
||||||
|
|
||||||
|
let boundary_prop_list_t = DataType::List(Arc::new(
|
||||||
|
Field::new_list_field(boundary_prop_struct_t, false)
|
||||||
));
|
));
|
||||||
|
|
||||||
let path_list_t = DataType::List(Arc::new(
|
let path_list_t = DataType::List(Arc::new(
|
||||||
|
|
@ -207,8 +265,13 @@ pub fn read_library(input: &[u8]) -> IResult<StructArray> {
|
||||||
let cell_struct_t = DataType::Struct(Fields::from(vec![
|
let cell_struct_t = DataType::Struct(Fields::from(vec![
|
||||||
Field::new("id", DataType::UInt32, false),
|
Field::new("id", DataType::UInt32, false),
|
||||||
Field::new("file_offset", DataType::UInt64, false),
|
Field::new("file_offset", DataType::UInt64, false),
|
||||||
Field::new("refs", ref_list_t, false),
|
Field::new("srefs", sref_list_t, false),
|
||||||
Field::new("boundaries", boundary_list_t, false),
|
Field::new("arefs", aref_list_t, false),
|
||||||
|
Field::new("sref_props", sref_prop_list_t, false),
|
||||||
|
Field::new("aref_props", aref_prop_list_t, false),
|
||||||
|
Field::new("rect_batches", rect_batch_list_t, false),
|
||||||
|
Field::new("boundary_batches", boundary_batch_list_t, false),
|
||||||
|
Field::new("boundary_props", boundary_prop_list_t, false),
|
||||||
Field::new("paths", path_list_t, false),
|
Field::new("paths", path_list_t, false),
|
||||||
Field::new("nodes", boxnode_list_t.clone(), true),
|
Field::new("nodes", boxnode_list_t.clone(), true),
|
||||||
Field::new("boxes", boxnode_list_t.clone(), true),
|
Field::new("boxes", boxnode_list_t.clone(), true),
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ pub struct RecordHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecordHeader {
|
impl RecordHeader {
|
||||||
pub fn read(input: &[u8]) -> IResult<RecordHeader> {
|
pub fn read(input: &[u8]) -> IResult<'_, RecordHeader> {
|
||||||
let (input, size) = parse_u16(input)?;
|
let (input, size) = parse_u16(input)?;
|
||||||
let (input, tag) = parse_u16(input)?;
|
let (input, tag) = parse_u16(input)?;
|
||||||
Ok((input, RecordHeader{tag, data_size:size - 4}))
|
Ok((input, RecordHeader{tag, data_size:size - 4}))
|
||||||
|
|
@ -50,7 +50,7 @@ pub trait RecordData {
|
||||||
type InData : ?Sized;
|
type InData : ?Sized;
|
||||||
type ByteData : AsRef<[u8]>;
|
type ByteData : AsRef<[u8]>;
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>>;
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>>;
|
||||||
fn pack_into(buf: &mut [u8], data: &Self::InData);
|
fn pack_into(buf: &mut [u8], data: &Self::InData);
|
||||||
//fn size(data: &Self::BareData<'_>) -> u16;
|
//fn size(data: &Self::BareData<'_>) -> u16;
|
||||||
fn pack(data: &Self::InData) -> Self::ByteData;
|
fn pack(data: &Self::InData) -> Self::ByteData;
|
||||||
|
|
@ -72,7 +72,7 @@ pub trait Record<RData: RecordData> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_header(input: &[u8]) -> IResult<RecordHeader> {
|
fn read_header(input: &[u8]) -> IResult<'_, RecordHeader> {
|
||||||
RecordHeader::read(input)
|
RecordHeader::read(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ pub trait Record<RData: RecordData> {
|
||||||
RecordHeader{tag: Self::tag(), data_size}.write(ww)
|
RecordHeader{tag: Self::tag(), data_size}.write(ww)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_data(input: &[u8], size: u16) -> IResult<RData::BareData<'_>> {
|
fn read_data(input: &[u8], size: u16) -> IResult<'_, RData::BareData<'_>> {
|
||||||
RData::read(input, size)
|
RData::read(input, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ pub trait Record<RData: RecordData> {
|
||||||
/// True if the record was encountered and skipped.
|
/// True if the record was encountered and skipped.
|
||||||
/// False if the end of the library was reached.
|
/// False if the end of the library was reached.
|
||||||
///
|
///
|
||||||
fn skip_past(input: &[u8]) -> IResult<bool> {
|
fn skip_past(input: &[u8]) -> IResult<'_, bool> {
|
||||||
let original_input = input;
|
let original_input = input;
|
||||||
let (mut input, mut header) = RecordHeader::read(input)?;
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
||||||
while header.tag != Self::tag() {
|
while header.tag != Self::tag() {
|
||||||
|
|
@ -109,7 +109,7 @@ pub trait Record<RData: RecordData> {
|
||||||
Ok((input, true))
|
Ok((input, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_and_read(input: &[u8]) -> IResult<RData::BareData<'_>> {
|
fn skip_and_read(input: &[u8]) -> IResult<'_, RData::BareData<'_>> {
|
||||||
let (mut input, mut header) = RecordHeader::read(input)?;
|
let (mut input, mut header) = RecordHeader::read(input)?;
|
||||||
while header.tag != Self::tag() {
|
while header.tag != Self::tag() {
|
||||||
(input, _) = take_bytes(input, header.data_size)?;
|
(input, _) = take_bytes(input, header.data_size)?;
|
||||||
|
|
@ -119,7 +119,7 @@ pub trait Record<RData: RecordData> {
|
||||||
Ok((input, data))
|
Ok((input, data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expect_header(input: &[u8]) -> IResult<u16> {
|
fn expect_header(input: &[u8]) -> IResult<'_, u16> {
|
||||||
let (input, header) = RecordHeader::read(input)?;
|
let (input, header) = RecordHeader::read(input)?;
|
||||||
if header.tag != Self::tag() {
|
if header.tag != Self::tag() {
|
||||||
fail(input, format!("Unexpected record! Got tag 0x{:04x}, expected 0x{:04x}", header.tag, Self::tag()))
|
fail(input, format!("Unexpected record! Got tag 0x{:04x}, expected 0x{:04x}", header.tag, Self::tag()))
|
||||||
|
|
@ -128,7 +128,7 @@ pub trait Record<RData: RecordData> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(input: &[u8]) -> IResult<RData::BareData<'_>> {
|
fn read(input: &[u8]) -> IResult<'_, RData::BareData<'_>> {
|
||||||
let (input, size) = Self::expect_header(input)?;
|
let (input, size) = Self::expect_header(input)?;
|
||||||
Self::check_size(size).unwrap();
|
Self::check_size(size).unwrap();
|
||||||
let (input, data) = Self::read_data(input, size)?;
|
let (input, data) = Self::read_data(input, size)?;
|
||||||
|
|
@ -152,7 +152,7 @@ impl RecordData for BitArray {
|
||||||
type InData = [bool; 16];
|
type InData = [bool; 16];
|
||||||
type ByteData = [u8; 2];
|
type ByteData = [u8; 2];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 2);
|
assert!(size == 2);
|
||||||
parse_bitarray(input)
|
parse_bitarray(input)
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +175,7 @@ impl RecordData for Int2 {
|
||||||
type InData = i16;
|
type InData = i16;
|
||||||
type ByteData = [u8; 2];
|
type ByteData = [u8; 2];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 2);
|
assert!(size == 2);
|
||||||
parse_int2(input)
|
parse_int2(input)
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +197,7 @@ impl RecordData for Int4 {
|
||||||
type InData = i32;
|
type InData = i32;
|
||||||
type ByteData = [u8; 4];
|
type ByteData = [u8; 4];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 4);
|
assert!(size == 4);
|
||||||
parse_int4(input)
|
parse_int4(input)
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +220,7 @@ impl RecordData for Int2Array {
|
||||||
type InData = [i16];
|
type InData = [i16];
|
||||||
type ByteData = Vec<u8>;
|
type ByteData = Vec<u8>;
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size % 2 == 0, "Record must contain an integer quantity of integers");
|
assert!(size % 2 == 0, "Record must contain an integer quantity of integers");
|
||||||
//let mut input = input;
|
//let mut input = input;
|
||||||
let (input, bytes) = take_bytes(input, size)?;
|
let (input, bytes) = take_bytes(input, size)?;
|
||||||
|
|
@ -261,7 +261,7 @@ impl RecordData for Int4Array {
|
||||||
type InData = [i32];
|
type InData = [i32];
|
||||||
type ByteData = Vec<u8>;
|
type ByteData = Vec<u8>;
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size % 4 == 0, "Record must contain an integer quantity of integers");
|
assert!(size % 4 == 0, "Record must contain an integer quantity of integers");
|
||||||
//let mut input = input;
|
//let mut input = input;
|
||||||
let (input, bytes) = take_bytes(input, size)?;
|
let (input, bytes) = take_bytes(input, size)?;
|
||||||
|
|
@ -302,7 +302,7 @@ impl RecordData for Real8 {
|
||||||
type InData = f64;
|
type InData = f64;
|
||||||
type ByteData = [u8; 8];
|
type ByteData = [u8; 8];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 8);
|
assert!(size == 8);
|
||||||
parse_real8(input)
|
parse_real8(input)
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +324,7 @@ impl RecordData for Real8Pair {
|
||||||
type InData = (f64, f64);
|
type InData = (f64, f64);
|
||||||
type ByteData = [u8; 2 * 8];
|
type ByteData = [u8; 2 * 8];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 2 * 8);
|
assert!(size == 2 * 8);
|
||||||
let (input, data0) = parse_real8(input)?;
|
let (input, data0) = parse_real8(input)?;
|
||||||
let (input, data1) = parse_real8(input)?;
|
let (input, data1) = parse_real8(input)?;
|
||||||
|
|
@ -354,7 +354,7 @@ impl RecordData for ASCII {
|
||||||
type InData = [u8];
|
type InData = [u8];
|
||||||
type ByteData = Vec<u8>;
|
type ByteData = Vec<u8>;
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
parse_ascii(input, size)
|
parse_ascii(input, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,7 +376,7 @@ impl RecordData for DateTimePair {
|
||||||
type InData = [[i16; 6]; 2];
|
type InData = [[i16; 6]; 2];
|
||||||
type ByteData = [u8; 2 * 6 * 2];
|
type ByteData = [u8; 2 * 6 * 2];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 2 * 6 * 2);
|
assert!(size == 2 * 6 * 2);
|
||||||
let (input, data0) = parse_datetime(input)?;
|
let (input, data0) = parse_datetime(input)?;
|
||||||
let (input, data1) = parse_datetime(input)?;
|
let (input, data1) = parse_datetime(input)?;
|
||||||
|
|
@ -406,7 +406,7 @@ impl RecordData for Empty {
|
||||||
type InData = ();
|
type InData = ();
|
||||||
type ByteData = [u8; 0];
|
type ByteData = [u8; 0];
|
||||||
|
|
||||||
fn read(input: &[u8], size: u16) -> IResult<Self::BareData<'_>> {
|
fn read(input: &[u8], size: u16) -> IResult<'_, Self::BareData<'_>> {
|
||||||
assert!(size == 0);
|
assert!(size == 0);
|
||||||
Ok((input, ()))
|
Ok((input, ()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue