1mod error;
2
3pub use error::*;
4use std::collections::HashMap;
5use std::fs::File;
6use std::io::{BufRead, BufReader, Read, Seek, SeekFrom};
7use std::path::Path;
8use std::sync::{Arc, RwLock};
9
10use crate::{
11 GdsAref, GdsArefBuilder, GdsArefBuilderError, GdsBoundary, GdsBoundaryBuilder, GdsBoundaryBuilderError, GdsBox, GdsBoxBuilder, GdsBoxBuilderError, GdsDateTime, GdsCoord, GdsFormat, GdsLibrary, GdsLibraryBuilder, GdsNode, GdsNodeBuilder, GdsNodeBuilderError, GdsPath, GdsPathBuilder, GdsPathBuilderError, GdsPathType, GdsPresentation, GdsSref, GdsSrefBuilder, GdsSrefBuilderError, GdsStructure, GdsText, GdsTextBuilder, GdsTextBuilderError, GdsTransform
12};
13use super::record::GdsRecordType;
14use super::utils;
15
16pub struct GdsReader<R> {
17 reader: BufReader<R>,
18}
19
20impl GdsReader<File> {
21 pub fn open<P: AsRef<Path>>(path: P) -> GdsReadResult<Self> {
22 let reader = BufReader::new(File::open(path)?);
23 Ok(Self { reader })
24 }
25}
26
27impl<R: Read + Seek> GdsReader<R> {
28 pub fn new(reader: R) -> GdsReadResult<Self> {
29 Ok(Self { reader: BufReader::new(reader) })
30 }
31}
32
33impl<R: Read + Seek> GdsReader<R> {
34 pub fn read(&mut self) -> GdsReadResult<GdsLibrary> {
35 match self.read_impl() {
36 Ok(gds) => Ok(gds),
37 Err(e) => {
38 let context = match self.reader.stream_position() {
39 Ok(pos) => format!("read until {pos} bytes"),
40 Err(e) => format!("error to get bytes bias for '{e}'"),
41 };
42 Err(e.wrap(context))
43 }
44 }
45 }
46
47 fn read_impl(&mut self) -> GdsReadResult<GdsLibrary> {
48 let mut builder = GdsLibraryBuilder::default();
49 self.read_header(&mut builder).map_err(|e| e.wrap("read header"))?;
50 self.read_library(&mut builder).map_err(|e| e.wrap("read Library"))?;
51 Ok(builder.build().unwrap())
52 }
53}
54
55impl<R: Read + Seek> GdsReader<R> {
56 fn read_header(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
57 self.ensure_record(6, GdsRecordType::Header)?;
58 builder.version(self.take_i16_record()?);
59 Ok(())
60 }
61}
62
63impl<R: Read + Seek> GdsReader<R> {
64 fn read_library(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
65 self.read_library_begin(builder).map_err(|e| e.wrap("read library begin"))?;
66
67 self.read_library_name(builder).map_err(|e| e.wrap("read library name"))?;
68 self.read_library_options(builder).map_err(|e| e.wrap(""))?;
69 self.read_units(builder).map_err(|e| e.wrap("read units"))?;
70
71 let structures = self.read_structures().map_err(|e| e.wrap("read structures"))?;
72 builder.structures(structures);
73
74 self.read_library_end(builder).map_err(|e| e.wrap("read library end"))?;
75 Ok(())
76 }
77
78 fn read_library_begin(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
79 self.ensure_record(28, GdsRecordType::BgnLib)?;
80 self.jump_bytes(4)?;
81
82 builder.create_date(self.take_datetime()?);
83 builder.modify_date(self.take_datetime()?);
84
85 Ok(())
86 }
87
88 fn read_library_name(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
89 self.ensure_record_type(GdsRecordType::LibName)?;
90 builder.name(self.take_string_record()?);
91 Ok(())
92 }
93
94 fn read_units(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
95 self.ensure_record(20, GdsRecordType::Uints)?;
96 self.jump_bytes(4)?;
97
98 builder.usrunits_per_dbunit(self.take_f64()?);
99 builder.meters_per_dbunit(self.take_f64()?);
100
101 Ok(())
102 }
103
104 fn read_library_end(&mut self, _builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
105 self.ensure_record(4, GdsRecordType::EndLib)?;
106 self.jump_bytes(4)?;
107 Ok(())
108 }
109}
110
111impl<R: Read + Seek> GdsReader<R> {
112 fn read_library_options(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
113 loop {
114 let tp = self.peek_record_type()?;
115 match tp {
116 GdsRecordType::RefLibs => self.read_reflibs(builder).map_err(|e| e.wrap("read reflibs"))?,
117 GdsRecordType::Fonts => self.read_fonts(builder).map_err(|e| e.wrap("read reflibs"))?,
118 GdsRecordType::AttrTable => self.read_attrtable(builder).map_err(|e| e.wrap("read attrtable"))?,
119 GdsRecordType::Generations => self.read_generations(builder).map_err(|e| e.wrap("read generations"))?,
120 GdsRecordType::Format => self.read_format(builder).map_err(|e| e.wrap("read format"))?,
121 _ => return Ok(())
122 }
123 }
124 }
125
126 pub fn read_reflibs(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
127 self.ensure_record(94, GdsRecordType::RefLibs)?;
128 self.jump_bytes(4)?;
129 builder.reflibs([
130 self.take_string(45)?,
131 self.take_string(45)?,
132 ]);
133 Ok(())
134 }
135
136 pub fn read_fonts(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
137 self.ensure_record_size(4 * 44 + 4)?;
138 self.jump_bytes(4)?;
139 builder.fonts([
140 self.take_string(44)?,
141 self.take_string(44)?,
142 self.take_string(44)?,
143 self.take_string(44)?,
144 ]);
145 Ok(())
146 }
147
148 pub fn read_attrtable(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
149 self.ensure_record_size(48)?;
150 self.jump_bytes(4)?;
151 builder.attrtable(self.take_string(44)?);
152 Ok(())
153 }
154
155 pub fn read_generations(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
156 builder.generations(self.take_i16_record()?);
157 Ok(())
158 }
159
160 pub fn read_format(&mut self, builder: &mut GdsLibraryBuilder) -> GdsReadResult<()> {
161 let value = self.take_u16_record()?;
162 let fmt = GdsFormat::from_u16(value)
163 .ok_or_else(|| GdsReadError::InvalidFormat(value))?;
164 builder.format(fmt);
165 Ok(())
166 }
167}
168
169macro_rules! read_optional_field {
170 ($builder:ident.$field:ident <- $this:ident.$method:ident if $record_type:ident) => {
171 if $this.peek_record_type()? == GdsRecordType::$record_type {
172 $builder.$field($this.$method()?);
173 }
174 };
175}
176
177
178macro_rules! read_required_field {
179 (
180 $builder:ident.$field:ident <- $this:ident.$method:ident if $variant:ident =>
181 $read_error_variant:ident ( $builder_error_ty:ty )
182 ) => {
183 if $this.peek_record_type()? == GdsRecordType::$variant {
184 $builder.$field($this.$method()?);
185 } else {
186 return Err(GdsReadError::$read_error_variant(
187 <$builder_error_ty>::UninitializedField(stringify!($field))
188 ));
189 }
190 };
191}
192
193impl<R: Read + Seek> GdsReader<R> {
194 fn read_structures(&mut self) -> GdsReadResult<HashMap<String, Arc<RwLock<GdsStructure>>>> {
195 let mut structures = HashMap::new();
196 let mut size = 0;
197 while self.check_record_type(GdsRecordType::BgnStr)? {
198 let structure = self.read_structure().map_err(|e| e.wrap(format!("read {size} structure")))?;
199 let name = structure.name.clone();
200 structures.insert(name, Arc::new(RwLock::new(structure)));
201 size += 1;
202 }
203 Ok(structures)
204 }
205
206 fn read_structure(&mut self) -> GdsReadResult<GdsStructure> {
207 let mut s = GdsStructure::default();
208
209 self.read_structure_begin(&mut s).map_err(|e| e.wrap("read structure begin"))?;
210 self.read_structure_name(&mut s).map_err(|e| e.wrap("read structure name"))?;
211
212 self.read_structure_elements(&mut s).map_err(|e| e.wrap("read structure elements"))?;
213 self.read_structure_end().map_err(|e| e.wrap("read structure end"))?;
214
215 Ok(s)
216 }
217
218 fn read_structure_begin(&mut self, structure: &mut GdsStructure) -> GdsReadResult<()> {
219 self.ensure_record(28, GdsRecordType::BgnStr)?;
220 self.jump_bytes(4)?;
221 structure.modify_date = self.take_datetime()?;
222 structure.create_date = self.take_datetime()?;
223 Ok(())
224 }
225
226 fn read_structure_name(&mut self, structure: &mut GdsStructure) -> GdsReadResult<()> {
227 self.ensure_record_type(GdsRecordType::StrName)?;
228 structure.name = self.take_string_record()?;
229 Ok(())
230 }
231
232 fn read_structure_end(&mut self) -> GdsReadResult<()> {
233 self.ensure_record(4, GdsRecordType::EndStr)?;
234 self.jump_bytes(4)?;
235 Ok(())
236 }
237
238 fn read_structure_elements(&mut self, s: &mut GdsStructure) -> GdsReadResult<()> {
239 loop {
240 match self.peek_record_type()? {
241 GdsRecordType::Boundary =>
242 s.boundarys.push(self.read_element_boundary().map_err(|e| e.wrap("read boundary"))?),
243 GdsRecordType::Path =>
244 s.paths.push(self.read_element_path().map_err(|e| e.wrap("read path"))?),
245 GdsRecordType::Text =>
246 s.texts.push(self.read_element_text().map_err(|e| e.wrap("read text"))?),
247 GdsRecordType::ARef =>
248 s.arefs.push(self.read_element_aref().map_err(|e| e.wrap("read aref"))?),
249 GdsRecordType::SRef =>
250 s.srefs.push(self.read_element_sref().map_err(|e| e.wrap("read sref"))?),
251 GdsRecordType::Node =>
252 s.nodes.push(self.read_element_node().map_err(|e| e.wrap("read node"))?),
253 GdsRecordType::Box =>
254 s.boxes.push(self.read_element_box().map_err(|e| e.wrap("read box"))?),
255 _ => break
256 }
257 }
258 Ok(())
259 }
260
261 fn read_element_boundary(&mut self) -> GdsReadResult<GdsBoundary> {
262 self.read_element_header()?;
263 let mut builder = GdsBoundaryBuilder::default();
264
265 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
266 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
267 read_required_field!(builder.layer <- self.take_i16_record if Layer => BuildBoundary(GdsBoundaryBuilderError));
268 read_required_field!(builder.data_type <- self.take_i16_record if DataType => BuildBoundary(GdsBoundaryBuilderError));
269 read_required_field!(builder.xy <- self.read_xy if Xy => BuildBoundary(GdsBoundaryBuilderError));
270
271 self.read_element_end()?;
272 Ok(builder.build()?)
273 }
274
275 pub fn read_element_path(&mut self) -> GdsReadResult<GdsPath> {
276 self.read_element_header()?;
277 let mut builder = GdsPathBuilder::default();
278
279 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
280 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
281 read_required_field!(builder.layer <- self.take_i16_record if Layer => BuildPath(GdsPathBuilderError));
282 read_required_field!(builder.data_type <- self.take_i16_record if DataType => BuildPath(GdsPathBuilderError));
283 read_optional_field!(builder.path_type <- self.read_path_type if PathType);
284 read_optional_field!(builder.width <- self.take_i32_record if Width);
285 read_required_field!(builder.xy <- self.read_xy if Xy => BuildPath(GdsPathBuilderError));
286 read_optional_field!(builder.purpose_layer <- self.take_i16_record if TextType);
287
288 if self.peek_record_type()? == GdsRecordType::BgnExtn {
289 self.take_i32_record()?;
290 }
291 if self.peek_record_type()? == GdsRecordType::EndExtn {
292 self.take_i32_record()?;
293 }
294
295 self.read_element_end()?;
296 Ok(builder.build()?)
297 }
298
299 pub fn read_element_sref(&mut self) -> GdsReadResult<GdsSref> {
300 self.read_element_header()?;
301 let mut builder = GdsSrefBuilder::default();
302
303 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
304 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
305 read_required_field!(builder.s_name <- self.take_string_record if SName => BuildSref(GdsSrefBuilderError));
306 read_optional_field!(builder.transform <- self.read_transform if STrans);
307 read_required_field!(builder.position <- self.read_position if Xy => BuildSref(GdsSrefBuilderError));
308
309 self.read_element_end()?;
310 Ok(builder.build()?)
311 }
312
313 pub fn read_element_aref(&mut self) -> GdsReadResult<GdsAref> {
314 self.read_element_header()?;
315 let mut builder = GdsArefBuilder::default();
316
317 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
318 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
319 read_required_field!(builder.s_name <- self.take_string_record if SName => BuildAref(GdsArefBuilderError));
320 read_optional_field!(builder.transform <- self.read_transform if STrans);
321
322 if self.peek_record_type()? == GdsRecordType::ColRow {
323 let (col, row) = self.read_col_row()?;
324 builder.col(col);
325 builder.row(row);
326 }
327 read_required_field!(builder.position <- self.read_position if Xy => BuildSref(GdsSrefBuilderError));
328
329 self.read_element_end()?;
330 Ok(builder.build()?)
331 }
332
333 pub fn read_element_text(&mut self) -> GdsReadResult<GdsText> {
334 self.read_element_header()?;
335 let mut builder = GdsTextBuilder::default();
336
337 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
338 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
339 read_required_field!(builder.layer <- self.take_i16_record if Layer => BuildText(GdsTextBuilderError));
340 read_required_field!(builder.text_type <- self.take_i16_record if TextType => BuildText(GdsTextBuilderError));
341 read_optional_field!(builder.presentation <- self.read_presentation if Presentation);
342 read_optional_field!(builder.path_type <- self.read_path_type if PathType);
343 read_optional_field!(builder.width <- self.take_i32_record if Width);
344 read_optional_field!(builder.transform <- self.read_transform if STrans);
345 read_required_field!(builder.position <- self.read_position if Xy => BuildSref(GdsSrefBuilderError));
346 read_required_field!(builder.string <- self.take_string_record if String => BuildText(GdsTextBuilderError));
347
348 self.read_element_end()?;
349 Ok(builder.build()?)
350 }
351
352 pub fn read_element_node(&mut self) -> GdsReadResult<GdsNode> {
353 self.read_element_header()?;
354 let mut builder = GdsNodeBuilder::default();
355
356 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
357 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
358 read_required_field!(builder.layer <- self.take_i16_record if Layer => BuildNode(GdsNodeBuilderError));
359 read_required_field!(builder.node_type <- self.take_i16_record if Layer => BuildNode(GdsNodeBuilderError));
360 read_required_field!(builder.xy <- self.read_xy if Layer => BuildNode(GdsNodeBuilderError));
361
362 self.read_element_end()?;
363 Ok(builder.build()?)
364 }
365
366 pub fn read_element_box(&mut self) -> GdsReadResult<GdsBox> {
367 self.read_element_header()?;
368 let mut builder = GdsBoxBuilder::default();
369
370 read_optional_field!(builder.elf_flags <- self.take_i16_record if ElFlags);
371 read_optional_field!(builder.plex <- self.take_i32_record if Plex);
372 read_required_field!(builder.layer <- self.take_i16_record if Layer => BuildBox(GdsBoxBuilderError));
373 read_required_field!(builder.box_type <- self.take_i16_record if Layer => BuildBox(GdsBoxBuilderError));
374 read_required_field!(builder.xy <- self.read_xy if Layer => BuildBox(GdsBoxBuilderError));
375
376 self.read_element_end()?;
377 Ok(builder.build()?)
378 }
379
380 fn read_element_header(&mut self) -> GdsReadResult<()> {
381 self.ensure_record_size(4)?;
382 self.jump_bytes(4)?;
383 Ok(())
384 }
385
386 fn read_element_end(&mut self) -> GdsReadResult<()> {
387 self.ensure_record(4, GdsRecordType::EndEle)?;
388 self.jump_bytes(4)?;
389 Ok(())
390 }
391
392 pub fn read_col_row(&mut self) -> GdsReadResult<(i16, i16)> {
393 self.ensure_record_size(8)?;
394 self.jump_bytes(4)?;
395 let col = self.take_i16()?;
396 let row = self.take_i16()?;
397 Ok((col, row))
398 }
399
400 pub fn read_xy(&mut self) -> GdsReadResult<Vec<GdsCoord>> {
401 let mut header = [0u8; 4];
402 self.reader.read_exact(&mut header)?;
403 let record_size = u16::from_be_bytes([header[0], header[1]]) as usize;
404 let record_type = u16::from_be_bytes([header[2], header[3]]);
405 let rec_type = GdsRecordType::from_u16(record_type)
406 .ok_or(GdsReadError::UnsupportRecordType(record_type))?;
407
408 if rec_type != GdsRecordType::Xy {
409 return Err(GdsReadError::UnexpectRecordType(GdsRecordType::Xy, rec_type));
410 }
411
412 if record_size < 4 || (record_size - 4) % 8 != 0 {
413 return Err(GdsReadError::InvalidRecordSize(record_size));
414 }
415
416 let position_count = (record_size - 4) / 8;
417 let mut coords = Vec::with_capacity(position_count);
418 for _ in 0..position_count {
419 let x = self.take_i32()?;
420 let y = self.take_i32()?;
421 coords.push(GdsCoord::new( x, y ));
422 }
423 Ok(coords)
424 }
425
426 pub fn read_position(&mut self) -> GdsReadResult<GdsCoord> {
427 let mut header = [0u8; 4];
428 self.reader.read_exact(&mut header)?;
429 let record_size = u16::from_be_bytes([header[0], header[1]]) as usize;
430 let record_type = u16::from_be_bytes([header[2], header[3]]);
431 let rec_type = GdsRecordType::from_u16(record_type)
432 .ok_or(GdsReadError::UnsupportRecordType(record_type))?;
433
434 if rec_type != GdsRecordType::Xy {
435 return Err(GdsReadError::UnexpectRecordType(GdsRecordType::Xy, rec_type));
436 }
437
438 if record_size < 4 || (record_size - 4) % 8 != 0 {
439 return Err(GdsReadError::InvalidRecordSize(record_size));
440 }
441
442 let position_count = (record_size - 4) / 8;
443 if position_count != 1 {
444 return Err(GdsReadError::ExecptPosition(position_count));
445 }
446
447 let x = self.take_i32()?;
448 let y = self.take_i32()?;
449
450 Ok((x, y).into())
451 }
452
453 pub fn read_transform(&mut self) -> GdsReadResult<GdsTransform> {
454 let value = self.take_u16_record()? as u16;
456 let mut transform = GdsTransform::with_flag(value);
457
458 if self.peek_record_type()? == GdsRecordType::Mag {
460 transform.magnification = Some(self.take_f64_record()?);
461 }
462
463 if self.peek_record_type()? == GdsRecordType::Angle {
465 transform.angle = Some(self.take_f64_record()?);
466 }
467
468 Ok(transform)
469 }
470
471 pub fn read_path_type(&mut self) -> GdsReadResult<GdsPathType> {
472 let value = self.take_u16_record()?;
473 GdsPathType::from_u16(value)
474 .ok_or_else(|| GdsReadError::BuildText(GdsTextBuilderError::ValidationError(format!("'{value}' is not an valid path type"))))
475 }
476
477 pub fn read_presentation(&mut self) -> GdsReadResult<GdsPresentation> {
478 let value = self.take_u16_record()?;
479 GdsPresentation::from_u16(value)
480 .map_err(|e| GdsReadError::BuildText(GdsTextBuilderError::ValidationError(e)))
481 }
482}
483
484impl<R: Read + Seek> GdsReader<R> {
487 fn take_u16_record(&mut self) -> GdsReadResult<u16> {
488 self.ensure_record_size(6)?;
489 self.jump_bytes(4)?; self.take_u16()
491 }
492
493 fn take_i16_record(&mut self) -> GdsReadResult<i16> {
494 self.ensure_record_size(6)?;
495 self.jump_bytes(4)?; self.take_i16()
497 }
498
499 fn take_i32_record(&mut self) -> GdsReadResult<i32> {
500 self.ensure_record_size(6)?;
501 self.jump_bytes(4)?;
502 self.take_i32()
503 }
504
505 fn take_string_record(&mut self) -> GdsReadResult<String> {
506 let size = self.take_record_size()?;
507 self.jump_bytes(2)?;
508 self.take_string(size - 4)
509 }
510
511 fn take_f64_record(&mut self) -> GdsReadResult<f64> {
512 self.ensure_record_size(12)?;
513 self.jump_bytes(4)?;
514 self.take_f64()
515 }
516}
517
518impl<R: Read + Seek> GdsReader<R> {
520 fn take_record_size(&mut self) -> GdsReadResult<usize> {
521 let mut buf = [0u8; 2];
522 self.reader.read_exact(&mut buf)?;
523 let size = u16::from_be_bytes(buf) as usize;
524 if size < 4 {
525 return Err(GdsReadError::InvalidRecordSize(size));
526 }
527 Ok(size)
528 }
529
530 fn take_u16(&mut self) -> GdsReadResult<u16> {
531 let mut buf = [0u8; 2];
532 self.reader.read_exact(&mut buf)?;
533 Ok(u16::from_be_bytes(buf))
534 }
535
536 fn take_i16(&mut self) -> GdsReadResult<i16> {
537 let mut buf = [0u8; 2];
538 self.reader.read_exact(&mut buf)?;
539 Ok(i16::from_be_bytes(buf))
540 }
541
542 fn take_i32(&mut self) -> GdsReadResult<i32> {
543 let mut buf = [0u8; 4];
544 self.reader.read_exact(&mut buf)?;
545 Ok(i32::from_be_bytes(buf))
546 }
547
548 fn take_string(&mut self, len: usize) -> GdsReadResult<String> {
549 let mut buf = vec![0u8; len];
550 self.reader.read_exact(&mut buf)?;
551 while buf.last() == Some(&0) {
552 buf.pop();
553 }
554 let s = String::from_utf8(buf)?;
555 Ok(s)
556 }
557
558 fn take_f64(&mut self) -> GdsReadResult<f64> {
559 let mut buf = [0u8; 8];
560 self.reader.read_exact(&mut buf)?;
561 Ok(utils::bytes_to_f64(buf))
562 }
563
564 fn take_datetime(&mut self) -> GdsReadResult<GdsDateTime> {
565 let year = self.take_i16()?;
566 let month = self.take_i16()?;
567 let day = self.take_i16()?;
568 let hour = self.take_i16()?;
569 let minute = self.take_i16()?;
570 let second = self.take_i16()?;
571
572 Ok(GdsDateTime {
573 year,
574 month,
575 day,
576 hour,
577 minute,
578 second
579 })
580 }
581}
582
583impl<R: Read + Seek> GdsReader<R> {
584 fn check_record_type(&mut self, tp: GdsRecordType) -> GdsReadResult<bool> {
585 let real_tp = self.peek_record_type()?;
586 Ok(real_tp == tp)
587 }
588
589 fn ensure_record(&mut self, size: usize, tp: GdsRecordType) -> GdsReadResult<()> {
590 self.ensure_record_size(size)?;
591 self.ensure_record_type(tp)?;
592 Ok(())
593 }
594
595 fn ensure_record_type(&mut self, tp: GdsRecordType) -> GdsReadResult<()> {
596 let real_tp = self.peek_record_type()?;
597 if real_tp == tp {
598 Ok(())
599 } else {
600 Err(GdsReadError::UnexpectRecordType(tp, real_tp))
601 }
602 }
603
604 fn ensure_record_size(&mut self, size: usize) -> GdsReadResult<()> {
605 let real_size = self.peek_record_size()?;
606 if real_size == size {
607 Ok(())
608 } else {
609 Err(GdsReadError::UnexpectRecordSize(size, real_size))
610 }
611 }
612
613 fn peek_record_size(&mut self) -> GdsReadResult<usize> {
614 let bytes = self.peek_bytes::<2>()?;
615 Ok(u16::from_be_bytes(bytes) as usize)
616 }
617
618 fn peek_record_type(&mut self) -> GdsReadResult<GdsRecordType> {
619 let bytes = self.peek_bytes::<4>()?;
620 let bytes = [bytes[2], bytes[3]];
621 let value = u16::from_be_bytes(bytes);
622 match GdsRecordType::from_u16(value) {
623 Some(t) => Ok(t),
624 None => Err(GdsReadError::UnsupportRecordType(value))
625 }
626 }
627
628 fn peek_bytes<const L: usize>(&mut self) -> GdsReadResult<[u8; L]> {
629 let mut bytes = [0u8; L];
630 let buf = self.reader.fill_buf()?;
631 if buf.len() < L {
632 return Err(GdsReadError::Io(std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "Not enough bytes to peek")));
633 }
634
635 for i in 0..L {
636 bytes[i] = buf[i];
637 }
638
639 Ok(bytes)
640 }
641
642 fn jump_bytes(&mut self, size: i64) -> GdsReadResult<()> {
643 self.reader.seek(SeekFrom::Current(size))?;
644 Ok(())
645 }
646}