Skip to content

Commit 18c8367

Browse files
committed
Dropped data iterators since they seemed like an unnecessary abstraction. Switched focus to headers for the bluejay utility. Still needs extended header support and support for additional bluefile type codes.
1 parent 4185ad0 commit 18c8367

File tree

12 files changed

+203
-576
lines changed

12 files changed

+203
-576
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bluefile"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
edition = "2021"
55
license = "Apache-2.0"
66
readme = "README.md"

README.md

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,7 @@ Add the following to your project's `Cargo.toml`:
1111
bluefile = "*"
1212
```
1313

14-
### Reading Type 2000 frames
15-
16-
```rust
17-
use std::path::PathBuf;
18-
19-
use bluefile::bluefile::BluefileReader;
20-
use bluefile::data_type::DataValue;
21-
use bluefile::type2000::Type2000Reader;
22-
23-
fn main() {
24-
let args: Vec<String> = std::env::args().collect();
25-
let path = PathBuf::from(&args[1]);
26-
let reader = Type2000Reader::new(&path).unwrap();
27-
let adj_header = &reader.get_adj_header();
28-
let frame_size: usize = adj_header.subsize.try_into().unwrap();
29-
let data_reader = &mut reader.get_data_iter().unwrap();
30-
31-
loop {
32-
let frame: Vec<DataValue> = data_reader.take(frame_size).collect();
33-
34-
if frame.len() < frame_size {
35-
break;
36-
}
37-
38-
dbg!(frame);
39-
}
40-
}
41-
```
42-
43-
More examples can be found in the `tests` directory.
14+
Examples can be found in the `tests` directory.
4415

4516
## Running Tests
4617

src/bluefile.rs

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::endian::Endianness;
1313
use crate::error::Error;
1414
use crate::header::Header;
1515
use crate::result::Result;
16-
use crate::util::{bytes_to_i16, bytes_to_i32, open_file};
16+
use crate::util::{bytes_to_i16, bytes_to_i32};
1717

1818
pub(crate) const ADJUNCT_HEADER_OFFSET: usize = 256;
1919
pub(crate) const ADJUNCT_HEADER_SIZE: usize = 256;
@@ -54,8 +54,7 @@ pub struct ExtHeaderIter {
5454

5555
/// Additional functions for the extended header iterator.
5656
impl ExtHeaderIter {
57-
fn new(path: PathBuf, offset: usize, size: usize, endianness: Endianness) -> Result<Self> {
58-
let file = open_file(&path)?;
57+
fn new(file: File, offset: usize, size: usize, endianness: Endianness) -> Result<Self> {
5958
let mut reader = BufReader::new(file);
6059

6160
match reader.seek(SeekFrom::Start(offset as u64)) {
@@ -100,40 +99,6 @@ impl Iterator for ExtHeaderIter {
10099
}
101100
}
102101

103-
/// Defines a trait that all bluefile readers should implement.
104-
pub trait BluefileReader {
105-
type AdjHeader;
106-
type DataIter;
107-
108-
fn new<P: AsRef<Path>>(path: P) -> Result<Self> where Self: Sized;
109-
fn get_header(&self) -> Header;
110-
fn get_ext_size(&self) -> usize;
111-
fn get_ext_start(&self) -> usize;
112-
fn get_ext_path(&self) -> PathBuf;
113-
fn get_adj_header(&self) -> Self::AdjHeader;
114-
fn get_data_path(&self) -> PathBuf;
115-
fn get_data_start(&self) -> usize;
116-
fn get_data_size(&self) -> usize;
117-
fn get_header_endianness(&self) -> Endianness;
118-
fn get_data_endianness(&self) -> Endianness;
119-
120-
fn get_ext_iter(&self) -> Result<ExtHeaderIter> {
121-
ExtHeaderIter::new(
122-
self.get_ext_path(),
123-
self.get_ext_start(),
124-
self.get_ext_size(),
125-
self.get_header_endianness(),
126-
)
127-
}
128-
129-
fn get_data_iter(&self) -> Result<Self::DataIter>;
130-
}
131-
132-
//fn new_reader(path: &Path) -> Result<Box<dyn BluefileReader>> {
133-
// let file = open_file(path)?;
134-
// let header = read_header(&file);
135-
//}
136-
137102
/// Raw extended header keyword properties.
138103
pub struct ExtKeyword {
139104
pub length: usize,

src/bluejay.rs

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
use std::env;
2+
use std::fs::File;
23
use std::path::PathBuf;
34
use std::process::exit;
45

5-
use bluefile::header::read_header;
6+
use bluefile::bluefile::TypeCode;
7+
use bluefile::header::{
8+
Header,
9+
read_header,
10+
read_type1000_adjunct_header,
11+
read_type2000_adjunct_header,
12+
};
613
use bluefile::error::Error;
714
use bluefile::result::Result;
8-
use bluefile::util::open_file;
915

1016
struct Config {
17+
file: File,
1118
path: PathBuf,
1219
}
1320

@@ -16,20 +23,78 @@ fn get_config() -> Result<Config> {
1623

1724
if args.len() != 2 {
1825
println!("Configuration error");
19-
return Err(Error::BluestatConfigError);
26+
return Err(Error::BluejayConfigError);
2027
}
2128

2229
let path_str = args[1].trim();
2330

2431
if path_str.len() == 0 {
2532
println!("Bluefile path is empty string");
26-
return Err(Error::BluestatConfigError);
33+
return Err(Error::BluejayConfigError);
2734
}
2835

2936
let mut path_buf = PathBuf::new();
3037
path_buf.push(path_str);
3138

32-
Ok(Config{path: path_buf})
39+
let file = match File::open(&path_buf) {
40+
Ok(x) => x,
41+
Err(_) => return Err(Error::FileOpenError(path_buf.display().to_string())),
42+
};
43+
44+
Ok(Config{
45+
file: file,
46+
path: path_buf,
47+
})
48+
}
49+
50+
fn header_lines(header: &Header, lines: &mut Vec<String>) {
51+
lines.push(format!(" \"type_code\": \"{}\"", header.type_code));
52+
lines.push(format!(" \"header_endianness\": \"{}\"", header.header_endianness));
53+
lines.push(format!(" \"data_endianness\": \"{}\"", header.data_endianness));
54+
lines.push(format!(" \"ext_header_start\": {}", header.ext_start));
55+
lines.push(format!(" \"ext_header_size\": {}", header.ext_size));
56+
lines.push(format!(" \"data_start\": {}", header.data_start));
57+
lines.push(format!(" \"data_size\": {}", header.data_size));
58+
lines.push(format!(" \"data_type\": \"{}\"", header.raw_data_type));
59+
lines.push(format!(" \"data_rank\": \"{}\"", header.data_type.rank));
60+
lines.push(format!(" \"data_format\": \"{}\"", header.data_type.format));
61+
lines.push(format!(" \"timecode\": {}", header.timecode));
62+
}
63+
64+
fn adjunct_lines(file: &File, header: &Header, lines: &mut Vec<String>) {
65+
if header.type_code == TypeCode::Type1000(1000) {
66+
let adj = match read_type1000_adjunct_header(file, header) {
67+
Ok(a) => a,
68+
Err(_) => {
69+
println!("Error reading adjunct header");
70+
return;
71+
}
72+
};
73+
74+
lines.push(format!(" \"xstart\": {}", adj.xstart));
75+
lines.push(format!(" \"xdelta\": {}", adj.xdelta));
76+
lines.push(format!(" \"xunits\": {}", adj.xunits));
77+
return;
78+
}
79+
80+
if header.type_code == TypeCode::Type2000(2000) {
81+
let adj = match read_type2000_adjunct_header(file, header) {
82+
Ok(a) => a,
83+
Err(_) => {
84+
println!("Error reading adjunct header");
85+
return;
86+
}
87+
};
88+
89+
lines.push(format!(" \"xstart\": {}", adj.xstart));
90+
lines.push(format!(" \"xdelta\": {}", adj.xdelta));
91+
lines.push(format!(" \"xunits\": {}", adj.xunits));
92+
lines.push(format!(" \"subsize\": {}", adj.subsize));
93+
lines.push(format!(" \"ystart\": {}", adj.ystart));
94+
lines.push(format!(" \"ydelta\": {}", adj.ydelta));
95+
lines.push(format!(" \"yunits\": {}", adj.yunits));
96+
return;
97+
}
3398
}
3499

35100
fn main() {
@@ -38,34 +103,20 @@ fn main() {
38103
Err(_) => exit(1),
39104
};
40105

41-
42-
let file = match open_file(&config.path) {
43-
Ok(f) => f,
44-
Err(_) => {
45-
println!("Could not open file at {}", config.path.display());
46-
exit(1);
47-
},
48-
};
49-
50-
let header = match read_header(&file) {
106+
let header = match read_header(&config.file) {
51107
Ok(h) => h,
52108
Err(_) => {
53109
println!("Could not read header from {}", config.path.display());
54110
exit(1);
55111
},
56112
};
57113

114+
let mut lines: Vec<String> = vec![];
115+
header_lines(&header, &mut lines);
116+
adjunct_lines(&config.file, &header, &mut lines);
117+
let all_lines = lines.join(",\n");
118+
58119
println!("{{");
59-
println!(" \"type_code\": \"{}\",", header.type_code);
60-
println!(" \"header_endianness\": \"{}\",", header.header_endianness);
61-
println!(" \"data_endianness\": \"{}\",", header.data_endianness);
62-
println!(" \"ext_header_start\": {},", header.ext_start);
63-
println!(" \"ext_header_size\": {},", header.ext_size);
64-
println!(" \"data_start\": {},", header.data_start);
65-
println!(" \"data_size\": {},", header.data_size);
66-
println!(" \"data_type\": \"{}\",", header.raw_data_type);
67-
println!(" \"data_rank\": \"{}\",", header.data_type.rank);
68-
println!(" \"data_format\": \"{}\",", header.data_type.format);
69-
println!(" \"timecode\": {}", header.timecode);
120+
println!("{}", all_lines);
70121
println!("}}");
71122
}

src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ pub enum Error {
2121
ExtHeaderKeywordLengthParseError,
2222
ExtHeaderKeywordReadError,
2323
DataSeekError,
24-
BluestatConfigError,
24+
BluejayConfigError,
2525
}

src/header.rs

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ use std::io::Seek;
44
use std::io::SeekFrom;
55
use std::str::from_utf8;
66

7-
use crate::bluefile::TypeCode;
7+
use crate::bluefile::{
8+
ADJUNCT_HEADER_OFFSET,
9+
ADJUNCT_HEADER_SIZE,
10+
TypeCode,
11+
};
812
use crate::data_type::{DataType, Format, Rank};
913
use crate::endian::Endianness;
1014
use crate::error::Error;
@@ -40,6 +44,24 @@ pub struct Header {
4044
pub keywords: Vec<HeaderKeyword>,
4145
}
4246

47+
#[derive(Clone, Debug)]
48+
pub struct Type1000Adjunct {
49+
pub xstart: f64,
50+
pub xdelta: f64,
51+
pub xunits: i32,
52+
}
53+
54+
#[derive(Clone, Debug)]
55+
pub struct Type2000Adjunct {
56+
pub xstart: f64,
57+
pub xdelta: f64,
58+
pub xunits: i32,
59+
pub subsize: i32,
60+
pub ystart: f64,
61+
pub ydelta: f64,
62+
pub yunits: i32,
63+
}
64+
4365
fn is_blue(v: &[u8]) -> bool {
4466
v[0] == b'B' && v[1] == b'L' && v[2] == b'U' && v[3] == b'E'
4567
}
@@ -164,3 +186,67 @@ fn parse_type_code(v: &[u8], endianness: Endianness) -> Result<TypeCode> {
164186
Err(Error::UnknownFileTypeCode(t))
165187
}
166188
}
189+
190+
pub fn read_type1000_adjunct_header(mut file: &File, header: &Header) -> Result<Type1000Adjunct> {
191+
match file.seek(SeekFrom::Start(ADJUNCT_HEADER_OFFSET as u64)) {
192+
Ok(x) => x,
193+
Err(_) => return Err(Error::AdjunctHeaderSeekError),
194+
};
195+
196+
let mut data = vec![0_u8; ADJUNCT_HEADER_SIZE];
197+
let n = match file.read(&mut data) {
198+
Ok(x) => x,
199+
Err(_) => return Err(Error::FileReadError),
200+
};
201+
202+
if n < ADJUNCT_HEADER_SIZE {
203+
return Err(Error::NotEnoughAdjunctHeaderBytes(n))
204+
}
205+
206+
let endianness = header.header_endianness;
207+
let xstart: f64 = bytes_to_f64(&data[0..8], endianness)?;
208+
let xdelta: f64 = bytes_to_f64(&data[8..16], endianness)?;
209+
let xunits: i32 = bytes_to_i32(&data[16..20], endianness)?;
210+
211+
Ok(Type1000Adjunct{
212+
xstart,
213+
xdelta,
214+
xunits,
215+
})
216+
}
217+
218+
pub fn read_type2000_adjunct_header(mut file: &File, header: &Header) -> Result<Type2000Adjunct> {
219+
match file.seek(SeekFrom::Start(ADJUNCT_HEADER_OFFSET as u64)) {
220+
Ok(x) => x,
221+
Err(_) => return Err(Error::AdjunctHeaderSeekError),
222+
};
223+
224+
let mut data = vec![0_u8; ADJUNCT_HEADER_SIZE];
225+
let n = match file.read(&mut data) {
226+
Ok(x) => x,
227+
Err(_) => return Err(Error::FileReadError),
228+
};
229+
230+
if n < ADJUNCT_HEADER_SIZE {
231+
return Err(Error::NotEnoughAdjunctHeaderBytes(n))
232+
}
233+
234+
let endianness = header.header_endianness;
235+
let xstart: f64 = bytes_to_f64(&data[0..8], endianness)?;
236+
let xdelta: f64 = bytes_to_f64(&data[8..16], endianness)?;
237+
let xunits: i32 = bytes_to_i32(&data[16..20], endianness)?;
238+
let subsize: i32 = bytes_to_i32(&data[20..24], endianness)?;
239+
let ystart: f64 = bytes_to_f64(&data[24..32], endianness)?;
240+
let ydelta: f64 = bytes_to_f64(&data[32..40], endianness)?;
241+
let yunits: i32 = bytes_to_i32(&data[40..44], endianness)?;
242+
243+
Ok(Type2000Adjunct{
244+
xstart,
245+
xdelta,
246+
xunits,
247+
subsize,
248+
ystart,
249+
ydelta,
250+
yunits,
251+
})
252+
}

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ pub mod error;
44
pub mod endian;
55
pub mod header;
66
pub mod result;
7-
pub mod type1000;
8-
pub mod type2000;
97
pub mod util;

0 commit comments

Comments
 (0)