1use num_traits::Zero;
19
20use db::layout::prelude::*;
21use libreda_db as db;
22
23use byteorder::{LittleEndian, ReadBytesExt};
24use std::io::{Cursor, Read};
25
26use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet};
27
28use crate::base_types::RegularRepetition;
29use crate::base_types::Repetition;
30use crate::base_types::*;
31use crate::{Modal, NameOrRef, XYMode};
32
33#[derive(Debug, Clone)]
34enum PropertyParent<CellId: Clone, ShapeId: Clone, CellInstId: Clone> {
35 None,
36 Cell(CellId),
37 CellName(String),
38 Geometry(Vec<ShapeId>),
39 Placement(Vec<CellInstId>),
40 XElement,
41 XGeometry,
42}
43
44fn read_offset_table<R: Read>(reader: &mut R) -> Result<(), OASISReadError> {
46 let _cellname_flag = read_unsigned_integer(reader)?;
48 let _cellname_offset = read_unsigned_integer(reader)?;
49 let _textstring_flag = read_unsigned_integer(reader)?;
50 let _textstring_offset = read_unsigned_integer(reader)?;
51 let _propname_flag = read_unsigned_integer(reader)?;
52 let _propname_offset = read_unsigned_integer(reader)?;
53 let _propstring_flag = read_unsigned_integer(reader)?;
54 let _propstring_offset = read_unsigned_integer(reader)?;
55 let _layername_flag = read_unsigned_integer(reader)?;
56 let _layername_offset = read_unsigned_integer(reader)?;
57 let _xname_flag = read_unsigned_integer(reader)?;
58 let _xname_offset = read_unsigned_integer(reader)?;
59
60 Ok(())
61}
62
63fn _read_properties<R: Read>(_reader: &mut R) -> Result<(), OASISReadError> {
65 unimplemented!()
66}
67
68fn read_repetition_conditional<R: Read>(
70 reader: &mut R,
71 is_present: bool,
72 modal_value: &mut Option<Repetition>,
73) -> Result<Repetition, OASISReadError> {
74 if is_present {
76 let repetition = read_repetition(reader)?;
77
78 let repetition = match repetition {
80 Repetition::ReusePrevious => modal_value
81 .as_ref()
82 .cloned()
83 .ok_or(OASISReadError::ModalRepetitionNotDefined)?,
84 _ => repetition,
85 };
86
87 assert_ne!(
88 &repetition,
89 &Repetition::ReusePrevious,
90 "`modal.repetition` should never be set to `ReusePrevious`."
91 );
92
93 *modal_value = Some(repetition.clone()); Ok(repetition)
96 } else {
97 Ok(Repetition::Regular(RegularRepetition::new(
99 Vector::zero(),
100 Vector::zero(),
101 1,
102 1,
103 )))
104 }
105}
106
107fn repetition_to_offsets(rep: &Repetition, first_position: Vector<SInt>) -> Vec<Vector<SInt>> {
109 match &rep {
110 Repetition::ReusePrevious => {
111 unreachable!("`modal.repetition` should never be set to `ReusePrevious`.")
112 }
113 Repetition::Regular(r) => r.iter().map(|offset| first_position + offset).collect(),
114 Repetition::Irregular(r) => r.iter().map(|offset| first_position + *offset).collect(),
115 }
116}
117
118fn read_coordinate_conditional<R: Read>(
123 reader: &mut R,
124 is_present: bool,
125 xy_mode: XYMode,
126 modal_value: &mut SInt,
127) -> Result<SInt, OASISReadError> {
128 let c = if is_present {
129 let c = read_signed_integer(reader)?;
130 match xy_mode {
131 XYMode::Absolute => c,
132 XYMode::Relative => *modal_value + c,
133 }
134 } else {
135 *modal_value
136 };
137 *modal_value = c;
138 Ok(c)
139}
140
141fn read_layernum_datatype<R: Read, C>(
143 reader: &mut R,
144 is_layer_present: bool,
145 is_datatype_present: bool,
146 modal: &mut Modal<C>,
147) -> Result<(UInt, UInt), OASISReadError> {
148 let layer = if is_layer_present {
149 read_unsigned_integer(reader)?
150 } else {
151 modal.layer.ok_or(OASISReadError::NoImplicitLayerDefined)?
152 };
153 modal.layer = Some(layer);
154
155 let datatype = if is_datatype_present {
156 read_unsigned_integer(reader)?
157 } else {
158 modal
159 .datatype
160 .ok_or(OASISReadError::NoImplicitDataTypeDefined)?
161 };
162 modal.datatype = Some(datatype);
163
164 Ok((layer, datatype))
165}
166
167#[derive(Eq, PartialEq, Debug)]
169enum IdMode {
170 Any,
172 Impl,
174 Expl,
176}
177
178impl Default for IdMode {
179 fn default() -> Self {
180 Self::Any
181 }
182}
183
184#[derive(Debug)]
186struct ReaderState<L: LayoutBase> {
187 modal: Modal<L::CellId>,
188 table_offsets_at_start: bool,
189 offset_table: (),
190
191 m_expect_strict_mode: bool,
192 m_table_cell_name: Option<UInt>,
193
194 id_counters: IdCounters,
195
196 m_cell_names: HashMap<UInt, String>,
198 m_cell_names_forward_references: HashMap<UInt, L::CellId>,
202 m_property_name_forward_references: HashMap<
205 UInt,
206 Vec<(
207 PropertyParent<L::CellId, L::ShapeId, L::CellInstId>,
208 Vec<PropertyValue>,
209 )>,
210 >,
211 m_propnames: HashMap<UInt, String>,
213 m_propstrings: HashMap<UInt, Vec<u8>>,
215 m_textstrings: HashMap<UInt, String>,
217
218 current_cell: Option<L::CellId>,
220 cell_name_counter: IdCounter,
222
223 placement_cell_forward_references: HashSet<L::CellId>,
228
229 property_parent: PropertyParent<L::CellId, L::ShapeId, L::CellInstId>,
231
232 is_in_cblock: bool,
235}
236
237impl<L: LayoutBase> Default for ReaderState<L> {
238 fn default() -> Self {
239 Self {
240 modal: Default::default(),
241 table_offsets_at_start: false,
242 offset_table: Default::default(),
243 m_expect_strict_mode: false,
244 m_table_cell_name: Default::default(),
245 id_counters: Default::default(),
246 m_cell_names: Default::default(),
247 m_cell_names_forward_references: Default::default(),
248 m_property_name_forward_references: Default::default(),
249 m_propnames: Default::default(),
250 m_propstrings: Default::default(),
251 m_textstrings: Default::default(),
252 current_cell: Default::default(),
253 cell_name_counter: Default::default(),
254 placement_cell_forward_references: Default::default(),
255 property_parent: PropertyParent::None,
256 is_in_cblock: false,
257 }
258 }
259}
260
261#[derive(Debug, Default)]
263struct IdCounter {
264 id_mode: IdMode,
265 counter: u32,
266}
267
268impl IdCounter {
269 fn next(&mut self) -> u32 {
270 let c = self.counter;
271 self.counter += 1;
272 c
273 }
274}
275
276#[derive(Debug, Default)]
278struct IdCounters {
279 cellname: IdCounter,
280 textstrings: IdCounter,
281 propname: IdCounter,
282 propstrings: IdCounter,
283}
284
285impl<L> ReaderState<L>
286where
287 L: LayoutEdit<Coord = SInt>,
288{
289 fn read_layout<R: Read>(
290 mut self,
291 reader: &mut R,
292 layout: &mut L,
293 ) -> Result<(), OASISReadError> {
294 read_magic(reader)?;
295
296 self.read_start_record(reader, layout)?;
297 self.read_body(reader, layout)?;
298
299 Ok(())
300 }
301
302 fn read_start_record<R: Read>(
303 &mut self,
304 reader: &mut R,
305 layout: &mut L,
306 ) -> Result<(), OASISReadError> {
307 let record_id = read_unsigned_integer(reader)?;
308
309 if record_id != 1 {
310 return Err(OASISReadError::UnexpectedRecord(record_id)); }
312
313 let version_string = read_ascii_string(reader)?;
314
315 if !version_string.eq("1.0") {
316 return Err(OASISReadError::WrongVersionString); }
318 let resolution = read_real(reader)?; {
322 let r = resolution.to_f64();
323 if f64::is_sign_negative(r) || f64::is_infinite(r) || f64::is_nan(r) {
324 return Err(OASISReadError::InvalidResolution(resolution)); }
326 }
327
328 let dbu = match resolution.try_to_int() {
329 Some(r) if r > 0 => r as UInt,
330 _ => unreachable!("Resolution must be a positive non-zero integer."), };
332 assert!(dbu >= 1); layout.set_dbu(dbu as SInt);
334
335 let offset_flag = read_unsigned_integer(reader)?;
338 trace!("offset flag = {}", offset_flag);
339 self.table_offsets_at_start = offset_flag == 0;
340 if self.table_offsets_at_start {
341 self.offset_table = read_offset_table(reader)?;
343 }
344
345 Ok(())
346 }
347
348 fn set_property(
350 layout: &mut L,
351 property_parent: &PropertyParent<L::CellId, L::ShapeId, L::CellInstId>,
352 property_name: &String,
353 property_values: &[PropertyValue],
354 property_strings: &HashMap<UInt, Vec<u8>>,
356 ) {
357 let property_values: Vec<db::property_storage::PropertyValue> = property_values
359 .iter()
360 .map(|v| {
361 use db::property_storage::PropertyValue as PV;
362 match v {
363 PropertyValue::SInt(v) => (*v).into(),
364 PropertyValue::UInt(v) => (*v).into(),
365 PropertyValue::Real(v) => match v {
366 Real::IEEEFloat32(v) => PV::Float(*v as f64),
367 Real::IEEEFloat64(v) => PV::Float(*v),
368 Real::PositiveWholeNumber(v) => (*v).into(),
369 Real::NegativeWholeNumber(v) => (0 - *v as i32).into(),
370 x => {
371 dbg!(&property_name, x);
372 unimplemented!();
373 }
374 },
375 PropertyValue::AString(s) => s.clone().into(),
376 PropertyValue::NString(s) => s.clone().into(),
377 PropertyValue::BString(s) => s.clone().into(),
378 PropertyValue::NStringRef(propstring_id) => {
379 let bstring = property_strings
381 .get(propstring_id)
382 .expect("AString forward references are not supported yet."); let s = bytes_to_name_string(bstring.clone())
385 .expect("Failed to convert bytes to name string.");
386 s.into()
387 }
388 PropertyValue::AStringRef(propstring_id) => {
389 let bstring = property_strings
391 .get(propstring_id)
392 .expect("NString forward references are not supported yet."); let s = bytes_to_ascii_string(bstring.clone())
395 .expect("Failed to convert bytes to ascii string.");
396 s.into()
397 }
398 PropertyValue::BStringRef(propstring_id) => {
399 let bstring = property_strings
401 .get(propstring_id)
402 .expect("BString forward references are not supported yet."); bstring.clone().into()
404 }
405 }
406 })
407 .collect();
408 let property_name: L::NameType = property_name.clone().into();
409 match &property_parent {
410 PropertyParent::None => {
411 for v in &property_values {
413 layout.set_chip_property(property_name.clone(), v.clone());
414 }
415 }
416 PropertyParent::Geometry(shapes) => {
417 for shape in shapes {
418 for v in &property_values {
419 layout.set_shape_property(shape, property_name.clone(), v.clone());
420 }
421 }
422 }
423 PropertyParent::Cell(cell) => {
424 for v in &property_values {
425 layout.set_cell_property(cell, property_name.clone(), v.clone());
426 }
427 }
428 PropertyParent::CellName(cell_name) => {
429 let cell = layout
431 .cell_by_name(cell_name)
432 .expect("Cell name not found.");
433 for v in &property_values {
434 layout.set_cell_property(&cell, property_name.clone(), v.clone());
435 }
436 }
437 PropertyParent::Placement(instances) => {
438 for instance in instances {
439 for v in &property_values {
440 layout.set_cell_instance_property(
441 instance,
442 property_name.clone(),
443 v.clone(),
444 );
445 }
446 }
447 }
448 PropertyParent::XElement => {
449 warn!("Storing properties for XElement is not supported yet.");
450 }
451 PropertyParent::XGeometry => {
452 warn!("Storing properties for XGeometry is not supported yet.");
453 }
454 }
455 }
456
457 fn new_cell_name(&mut self) -> L::NameType {
459 format!("$${}$$", self.cell_name_counter.next()).into()
460 }
461
462 fn read_body<R: Read>(&mut self, reader: &mut R, layout: &mut L) -> Result<(), OASISReadError> {
463 loop {
464 let record_id = match read_unsigned_integer(reader) {
465 Ok(id) => id,
466 Err(e) => match e {
467 OASISReadError::UnexpectedEndOfFile if self.is_in_cblock => {
468 break;
471 }
472 other => return Err(other),
473 },
474 };
475
476 trace!("record_id = {}", record_id);
477
478 match record_id {
479 0 => {
480 }
482 1 => {
483 trace!("START record");
485 return Err(OASISReadError::UnexpectedRecord(record_id)); }
487 2 => {
488 self.read_end_record(reader)?;
489 break;
490 }
491 3 | 4 => self.read_cell_name(reader, layout, record_id)?,
492 5 | 6 => {
493 trace!("TEXTSTRING record");
495 let textstring = read_ascii_string(reader)?;
496
497 let id = if record_id == 5 {
498 if self.id_counters.textstrings.id_mode == IdMode::Expl {
500 return Err(OASISReadError::MixedImplExplTextstringModes);
501 };
503 self.id_counters.textstrings.id_mode = IdMode::Impl; self.id_counters.textstrings.next()
505 } else {
506 if self.id_counters.textstrings.id_mode == IdMode::Impl {
508 return Err(OASISReadError::MixedImplExplTextstringModes);
509 };
511 self.id_counters.textstrings.id_mode = IdMode::Expl; read_unsigned_integer(reader)?
513 };
514
515 if self.m_textstrings.insert(id, textstring).is_some() {
517 return Err(OASISReadError::TextStringAlreadyPresent(id));
518 }
519
520 self.modal.reset();
521 }
522 7 | 8 => {
523 trace!("PROPNAME record");
525
526 let property_name = read_name_string(reader)?;
527 trace!("property_name = {}", &property_name);
528
529 let prop_name_id = if record_id == 7 {
530 if self.id_counters.propname.id_mode == IdMode::Expl {
532 return Err(OASISReadError::MixedImplExplPropnameModes);
533 };
535 self.id_counters.propname.id_mode = IdMode::Impl; self.id_counters.propname.next() } else {
538 if self.id_counters.propname.id_mode == IdMode::Impl {
540 return Err(OASISReadError::MixedImplExplPropnameModes);
541 };
543 self.id_counters.propname.id_mode = IdMode::Expl; read_unsigned_integer(reader)?
545 };
546 trace!("prop_id = {}", prop_name_id);
547
548 if let Some(_existing_name) =
552 self.m_propnames.insert(prop_name_id, property_name)
553 {
554 return Err(OASISReadError::PropnameIdAlreadyPresent(prop_name_id));
555 }
556
557 self.modal.reset();
558 }
559 9 | 10 => {
560 trace!("PROPSTRING record");
564 let propstring = read_byte_string(reader)?;
567 trace!("propstring = {:?}", &propstring);
568
569 let id = if record_id == 9 {
570 if self.id_counters.propstrings.id_mode == IdMode::Expl {
572 return Err(OASISReadError::MixedImplExplPropstringModes);
573 };
575 self.id_counters.propstrings.id_mode = IdMode::Impl; self.id_counters.propstrings.next() } else {
578 if self.id_counters.propstrings.id_mode == IdMode::Impl {
580 return Err(OASISReadError::MixedImplExplPropstringModes);
581 };
583 self.id_counters.propstrings.id_mode = IdMode::Expl; read_unsigned_integer(reader)?
585 };
586
587 if let Some(_existing_name) = self.m_propstrings.insert(id, propstring) {
589 return Err(OASISReadError::PropStringAlreadyPresent(id));
591 }
592
593 self.modal.reset();
594 }
595 11 | 12 => {
596 trace!("LAYERNAME record");
598
599 let layer_name = read_name_string(reader)?;
600 trace!("layer_name = {}", &layer_name);
601
602 let read_interval = |reader: &mut R| {
603 let interval_type = read_unsigned_integer(reader)?;
604 let max = UInt::MAX; match interval_type {
606 0 => Ok((0, max)),
607 1 => Ok((0, read_unsigned_integer(reader)?)),
608 2 => Ok((read_unsigned_integer(reader)?, max)),
609 3 => {
610 let a = read_unsigned_integer(reader)?;
611 Ok((a, a))
612 }
613 4 => Ok((
614 read_unsigned_integer(reader)?,
615 read_unsigned_integer(reader)?,
616 )),
617 t => Err(OASISReadError::IllegalIntervalType(t)), }
619 };
620
621 let (layer_start, layer_end) = read_interval(reader)?;
622 let (dtype_start, dtype_end) = read_interval(reader)?;
623
624 let layer_name: L::NameType = layer_name.clone().into();
626 for l in layer_start..layer_end {
627 for d in dtype_start..dtype_end {
628 let idx = layout.find_or_create_layer(l, d);
629 layout.set_layer_name(&idx, Some(layer_name.clone()));
630 }
631 }
632
633 self.modal.reset();
635
636 warn!("LAYERNAME record is not implemented: '{}'", &layer_name);
637 }
638 13 | 14 => {
639 trace!("CELL record");
642
643 let cell_name = if record_id == 13 {
647 let cell_name_reference = read_unsigned_integer(reader)?;
649 let cell_name = self.m_cell_names.get(&cell_name_reference);
650
651 if let Some(cell_name) = cell_name {
653 NameOrRef::Name(cell_name.clone())
654 } else {
655 NameOrRef::NameRef(cell_name_reference)
656 }
657 } else {
658 NameOrRef::Name(read_name_string(reader)?)
659 };
660 trace!("cell_name = {:?}", &cell_name);
661
662 let cell_idx = match cell_name {
665 NameOrRef::Name(n) => {
666 if let Some(cell_idx) = layout.cell_by_name(&n) {
667 if self.placement_cell_forward_references.remove(&cell_idx) {
671 cell_idx
673 } else {
674 return Err(OASISReadError::CellnameAlreadyPresent(n));
676 }
677 } else {
678 layout.create_cell(n.into())
679 }
680 }
681 NameOrRef::NameRef(r) => {
682 if let Some(cell_idx) = self.m_cell_names_forward_references.get(&r) {
684 if self.placement_cell_forward_references.remove(cell_idx) {
685 cell_idx.clone()
687 } else {
688 return Err(OASISReadError::CellnameIdAlreadyPresent(r));
690 }
691 } else {
692 let cell_idx = layout.create_cell(self.new_cell_name());
694 self.m_cell_names_forward_references
696 .insert(r, cell_idx.clone());
697 cell_idx
698 }
699 }
700 };
701
702 self.current_cell = Some(cell_idx.clone());
704
705 self.property_parent = PropertyParent::Cell(cell_idx);
707
708 self.modal.reset();
710 }
711 15 => {
712 trace!("XYABSOLUTE record");
714 self.modal.xy_mode = XYMode::Absolute;
715 }
716 16 => {
717 trace!("XYRELATIVE record");
719 self.modal.xy_mode = XYMode::Relative;
720 }
721 17 | 18 => {
722 trace!("PLACEMENT record");
725
726 let placement_info_byte = read_byte(reader)?;
727 let b = |index| (placement_info_byte >> index) & 1u8 == 1u8;
728 let is_cell_reference_explicit = b(7); let is_cell_reference_number_present = b(6); let is_x_present = b(5); let is_y_present = b(4); let is_repetition_present = b(3); let is_flip = b(0); let instance_ref = if is_cell_reference_explicit {
738 let cell_name = if is_cell_reference_number_present {
740 let cell_name_ref = read_unsigned_integer(reader)?;
742
743 if let Some(cell_name) = self.m_cell_names.get(&cell_name_ref) {
745 NameOrRef::Name(cell_name.clone())
746 } else {
747 NameOrRef::NameRef(cell_name_ref)
748 }
749 } else {
750 NameOrRef::Name(read_name_string(reader)?)
752 };
753
754 match cell_name {
761 NameOrRef::Name(n) => {
762 if let Some(cell) = layout.cell_by_name(&n) {
763 cell
764 } else {
765 let cell = layout.create_cell(n.into());
766 self.placement_cell_forward_references.insert(cell.clone());
768 cell
769 }
770 }
771 NameOrRef::NameRef(r) => {
772 self.m_cell_names_forward_references
774 .get(&r)
775 .cloned()
776 .unwrap_or_else(|| {
779 let cell = layout.create_cell(self.new_cell_name());
781 self.m_cell_names_forward_references
782 .insert(r, cell.clone());
783 self.placement_cell_forward_references.insert(cell.clone());
785 cell
786 })
787 }
788 }
789 } else {
790 self.modal
793 .placement_cell
794 .clone()
795 .ok_or(OASISReadError::ModalPlacementCellNotDefined)?
796 };
797
798 self.modal.placement_cell = Some(instance_ref.clone());
800
801 let (magnification, angle_degrees) = if record_id == 17 {
803 let aa = (placement_info_byte >> 1) & 3u8; let angle_degrees = 90 * (aa as u16);
805 let magnification = 1;
806 (
807 Real::PositiveWholeNumber(magnification),
808 Real::PositiveWholeNumber(angle_degrees.into()),
809 )
810 } else {
811 let is_magnification_present = b(2); let is_angle_present = b(1); let magnification = if is_magnification_present {
816 read_real(reader)?
817 } else {
818 Real::PositiveWholeNumber(1)
819 };
820
821 let angle_degrees = if is_angle_present {
823 read_real(reader)?
824 } else {
825 Real::PositiveWholeNumber(0)
826 };
827
828 (magnification, angle_degrees)
829 };
830
831 let x = read_coordinate_conditional(
833 reader,
834 is_x_present,
835 self.modal.xy_mode,
836 &mut self.modal.placement_x,
837 )?;
838
839 let y = read_coordinate_conditional(
841 reader,
842 is_y_present,
843 self.modal.xy_mode,
844 &mut self.modal.placement_y,
845 )?;
846
847 let displacement = Vector::new(x, y);
849
850 let repetition = read_repetition_conditional(
852 reader,
853 is_repetition_present,
854 &mut self.modal.repetition,
855 )?;
856
857 let angle90 = match angle_degrees.try_to_int() {
859 Some(0) => Some(Angle::R0),
860 Some(90) => Some(Angle::R90),
861 Some(180) => Some(Angle::R180),
862 Some(270) => Some(Angle::R270),
863 _ => None,
864 }
865 .expect("Rotation angle must be a multiple of 90 degree."); let magnification = magnification
869 .try_to_int()
870 .expect("Magnification mut be an integer.");
871
872 let positions = repetition_to_offsets(&repetition, displacement);
874
875 let parent_cell = self
878 .current_cell
879 .as_ref()
880 .ok_or(OASISReadError::NoCellRecordPresent)?;
881
882 let mut instances = Vec::with_capacity(positions.len());
883 for pos in positions {
884 let trans = SimpleTransform::new(is_flip, angle90, magnification, pos);
885 let inst = layout.create_cell_instance(parent_cell, &instance_ref, None);
886 layout.set_transform(&inst, trans);
887 instances.push(inst);
888 }
889
890 self.property_parent = PropertyParent::Placement(instances);
892 }
893 19 => {
894 trace!("TEXT record");
896
897 let text_info_byte = read_byte(reader)?;
898 let b = |index| (text_info_byte >> index) & 1u8 == 1u8;
899 let is_text_reference_explicit = b(6); let text_string = if is_text_reference_explicit {
902 let reference_number_present = b(5);
903 if reference_number_present {
904 let ref_number = read_unsigned_integer(reader)?;
905 let text_string = self.m_textstrings.get(&ref_number);
906 text_string
907 .cloned()
908 .ok_or(OASISReadError::PropStringIdNotFound(ref_number))?
909 } else {
910 read_ascii_string(reader)?
911 }
912 } else {
913 self.modal
914 .text_string
915 .as_ref()
916 .cloned()
917 .ok_or(OASISReadError::NoImplicitTextStringDefined)?
918 };
919 trace!("text_string = {}", &text_string);
920 self.modal.text_string = Some(text_string.clone());
921
922 let is_explicit_textlayer = b(0);
923 let is_explicit_texttype = b(1);
924 let is_repetition_present = b(2);
925 let is_x_present = b(4);
926 let is_y_present = b(3);
927
928 let textlayer = if is_explicit_textlayer {
929 read_unsigned_integer(reader)?
930 } else {
931 self.modal
932 .textlayer
933 .ok_or(OASISReadError::ModalTextLayerDefined)?
934 };
935 self.modal.textlayer = Some(textlayer);
936
937 let texttype = if is_explicit_texttype {
938 read_unsigned_integer(reader)?
939 } else {
940 self.modal
941 .texttype
942 .ok_or(OASISReadError::ModalTextTypeDefined)?
943 };
944 self.modal.texttype = Some(texttype);
945
946 let x = read_coordinate_conditional(
948 reader,
949 is_x_present,
950 self.modal.xy_mode,
951 &mut self.modal.text_x,
952 )?;
953
954 let y = read_coordinate_conditional(
956 reader,
957 is_y_present,
958 self.modal.xy_mode,
959 &mut self.modal.text_y,
960 )?;
961
962 let pos = Vector::new(x, y);
964
965 let repetition = read_repetition_conditional(
967 reader,
968 is_repetition_present,
969 &mut self.modal.repetition,
970 )?;
971 let positions = repetition_to_offsets(&repetition, pos);
972
973 let parent_cell = self
974 .current_cell
975 .as_ref()
976 .ok_or(OASISReadError::NoCellRecordPresent)?;
977 let layer_id = layout.find_or_create_layer(textlayer, texttype);
978
979 let mut shape_instances = Vec::with_capacity(positions.len());
980
981 itertools::repeat_n(text_string, positions.len()) .zip(positions)
985 .for_each(|(text_string, pos)| {
986 let text = Text::new(text_string, pos.into());
987 let shape_id = layout.insert_shape(parent_cell, &layer_id, text.into());
988 shape_instances.push(shape_id); });
990
991 self.property_parent = PropertyParent::Geometry(shape_instances);
993 }
994 20 => {
995 trace!("RECTANGLE record");
997
998 let rectangle_info_byte = read_byte(reader)?;
999 let b = |index| (rectangle_info_byte >> index) & 1u8 == 1u8;
1000
1001 let is_layer_number_present = b(0);
1002 let is_datatype_number_present = b(1);
1003 let is_width_present = b(6); let is_height_present = b(5); let is_x_present = b(4); let is_y_present = b(3); let is_repetition_present = b(2); let is_square = b(7); let (layer, datatype) = read_layernum_datatype(
1011 reader,
1012 is_layer_number_present,
1013 is_datatype_number_present,
1014 &mut self.modal,
1015 )?;
1016
1017 let width = if is_width_present {
1018 read_unsigned_integer(reader)?
1019 } else {
1020 self.modal
1021 .geometry_w
1022 .ok_or(OASISReadError::ModalGeometryWNotDefined)?
1023 };
1024 self.modal.geometry_w = Some(width);
1025
1026 let height = if is_square {
1027 if is_height_present {
1028 return Err(OASISReadError::HeightIsPresentForSquare);
1030 } else {
1031 width
1032 }
1033 } else if is_height_present {
1034 read_unsigned_integer(reader)?
1035 } else {
1036 self.modal
1037 .geometry_h
1038 .ok_or(OASISReadError::ModalGeometryHNotDefined)?
1039 };
1040 self.modal.geometry_h = Some(height);
1041
1042 let x = read_coordinate_conditional(
1044 reader,
1045 is_x_present,
1046 self.modal.xy_mode,
1047 &mut self.modal.geometry_x,
1048 )?;
1049
1050 let y = read_coordinate_conditional(
1052 reader,
1053 is_y_present,
1054 self.modal.xy_mode,
1055 &mut self.modal.geometry_y,
1056 )?;
1057
1058 let pos = Vector::new(x, y);
1060
1061 let repetition = read_repetition_conditional(
1063 reader,
1064 is_repetition_present,
1065 &mut self.modal.repetition,
1066 )?;
1067
1068 let positions = repetition_to_offsets(&repetition, pos);
1069
1070 let diagonal = Vector::new(width as SInt, height as SInt);
1071
1072 let lower_left = Point::zero();
1073 let rect = Rect::new(lower_left, lower_left + diagonal);
1074
1075 if let Some(parent_cell) = &self.current_cell {
1076 let layer_id = layout.find_or_create_layer(layer, datatype);
1077
1078 let mut shape_instances = Vec::new();
1079 for pos in positions {
1081 let r = Rect::new(rect.lower_left() + pos, rect.upper_right() + pos);
1082 let shape_id = layout.insert_shape(parent_cell, &layer_id, r.into());
1083 shape_instances.push(shape_id); }
1085
1086 self.property_parent = PropertyParent::Geometry(shape_instances);
1088 } else {
1089 return Err(OASISReadError::NoCellRecordPresent);
1090 }
1091 }
1092 21 => {
1093 trace!("POLYGON record");
1095
1096 let polygon_info_byte = read_byte(reader)?;
1097 let b = |index| (polygon_info_byte >> index) & 1u8 == 1u8;
1098
1099 let is_layer_number_present = b(0); let is_datatype_number_present = b(1); let is_repetition_present = b(2); let is_y_present = b(3); let is_x_present = b(4); let is_pointlist_present = b(5); let (layer, datatype) = read_layernum_datatype(
1107 reader,
1108 is_layer_number_present,
1109 is_datatype_number_present,
1110 &mut self.modal,
1111 )?;
1112
1113 if is_pointlist_present {
1114 let p = read_point_list(reader)?;
1115 self.modal.polygon_point_list = Some(p);
1116 }
1117
1118 let x = read_coordinate_conditional(
1120 reader,
1121 is_x_present,
1122 self.modal.xy_mode,
1123 &mut self.modal.geometry_x,
1124 )?;
1125
1126 let y = read_coordinate_conditional(
1128 reader,
1129 is_y_present,
1130 self.modal.xy_mode,
1131 &mut self.modal.geometry_y,
1132 )?;
1133
1134 let point0 = Vector::new(x, y);
1135
1136 let points: Vec<_> = self
1138 .modal
1139 .polygon_point_list
1140 .as_ref()
1141 .ok_or(OASISReadError::ModalPolygonPointListNotDefined)
1142 .map(|pointlist| pointlist.points(Vector::zero(), true))?;
1143
1144 let repetition = read_repetition_conditional(
1146 reader,
1147 is_repetition_present,
1148 &mut self.modal.repetition,
1149 )?;
1150 let positions = repetition_to_offsets(&repetition, point0);
1151
1152 let polygon = SimplePolygon::new(points).normalized_orientation::<i64>();
1153
1154 if let Some(parent_cell) = &self.current_cell {
1155 let layer_id = layout.find_or_create_layer(layer, datatype);
1156
1157 let mut shape_instances = Vec::with_capacity(positions.len());
1159
1160 itertools::repeat_n(polygon, positions.len()) .zip(positions)
1163 .for_each(|(mut polygon, pos)| {
1164 polygon.with_points_mut(|points| {
1167 points.iter_mut().for_each(|point| *point += pos)
1168 });
1169
1170 let shape_id =
1171 layout.insert_shape(parent_cell, &layer_id, polygon.into());
1172 shape_instances.push(shape_id); });
1174
1175 self.property_parent = PropertyParent::Geometry(shape_instances);
1177 } else {
1178 return Err(OASISReadError::NoCellRecordPresent);
1179 }
1180 }
1181 22 => {
1182 trace!("PATH record");
1184
1185 let path_info_byte = read_byte(reader)?;
1186 let b = |index| (path_info_byte >> index) & 1u8 == 1u8;
1187
1188 let is_layer_number_present = b(0); let is_datatype_number_present = b(1); let is_repetition_present = b(2); let is_y_present = b(3); let is_x_present = b(4); let is_pointlist_present = b(5); let is_half_width_present = b(6); let is_extension_scheme_present = b(7); let (layer, datatype) = read_layernum_datatype(
1198 reader,
1199 is_layer_number_present,
1200 is_datatype_number_present,
1201 &mut self.modal,
1202 )?;
1203
1204 let half_width = if is_half_width_present {
1205 let hw = read_unsigned_integer(reader)?;
1206 self.modal.path_halfwidth = Some(hw);
1207 hw
1208 } else {
1209 self.modal
1210 .path_halfwidth
1211 .ok_or(OASISReadError::ModalPathHalfWidthNotDefined)?
1212 };
1213
1214 let (start_ext, end_ext) = if is_extension_scheme_present {
1215 let ext_scheme = read_unsigned_integer(reader)?;
1216 let ss = (ext_scheme >> 2) & 0b11; let ee = ext_scheme & 0b11; let start_ext = match ss {
1220 0 => self
1221 .modal
1222 .path_start_extension
1223 .ok_or(OASISReadError::ModalPathStartExtensionNotDefined)?,
1224 1 => 0, 2 => half_width as SInt,
1226 3 => read_signed_integer(reader)?,
1227 _ => unreachable!(), };
1229 let end_ext = match ee {
1230 0 => self
1231 .modal
1232 .path_end_extension
1233 .ok_or(OASISReadError::ModalPathEndExtensionNotDefined)?,
1234 1 => 0, 2 => half_width as SInt,
1236 3 => read_signed_integer(reader)?,
1237 _ => unreachable!(), };
1239
1240 (start_ext, end_ext)
1241 } else {
1242 let s = self
1243 .modal
1244 .path_start_extension
1245 .ok_or(OASISReadError::ModalPathStartExtensionNotDefined)?;
1246 let e = self
1247 .modal
1248 .path_end_extension
1249 .ok_or(OASISReadError::ModalPathEndExtensionNotDefined)?;
1250 (s, e)
1251 };
1252 self.modal.path_start_extension = Some(start_ext);
1253 self.modal.path_end_extension = Some(end_ext);
1254
1255 if is_pointlist_present {
1256 let p = read_point_list(reader)?;
1257 self.modal.path_point_list = Some(p);
1258 }
1259
1260 let x = read_coordinate_conditional(
1262 reader,
1263 is_x_present,
1264 self.modal.xy_mode,
1265 &mut self.modal.geometry_x,
1266 )?;
1267
1268 let y = read_coordinate_conditional(
1270 reader,
1271 is_y_present,
1272 self.modal.xy_mode,
1273 &mut self.modal.geometry_y,
1274 )?;
1275
1276 let point0 = Vector::new(x, y);
1277
1278 let repetition = read_repetition_conditional(
1280 reader,
1281 is_repetition_present,
1282 &mut self.modal.repetition,
1283 )?;
1284 let positions = repetition_to_offsets(&repetition, point0);
1285
1286 let points: Vec<_> = self
1288 .modal
1289 .path_point_list
1290 .as_ref()
1291 .ok_or(OASISReadError::ModalPathPointListNotDefined)
1292 .map(|pointlist| pointlist.points(Vector::zero(), false))?;
1293
1294 let path =
1296 Path::new_extended(points, half_width as SInt * 2, start_ext, end_ext);
1297
1298 if let Some(parent_cell) = &self.current_cell {
1299 let layer_id = layout.find_or_create_layer(layer, datatype);
1300
1301 let mut shape_instances = Vec::with_capacity(positions.len());
1303 itertools::repeat_n(path, positions.len()) .zip(positions)
1306 .for_each(|(mut path, pos)| {
1307 path.points.points.iter_mut().for_each(|p| *p += pos);
1309
1310 let shape_id =
1311 layout.insert_shape(parent_cell, &layer_id, path.into());
1312 shape_instances.push(shape_id); });
1314
1315 self.property_parent = PropertyParent::Geometry(shape_instances);
1317 } else {
1318 return Err(OASISReadError::NoCellRecordPresent);
1319 }
1320 }
1321 28 | 29 => self.read_property_record(reader, layout, record_id)?,
1322 30 | 31 => {
1323 trace!("XNAME record");
1325
1326 let _xname_attribute = read_unsigned_integer(reader)?;
1327 let _xname_string = read_byte_string(reader)?;
1328
1329 if record_id == 31 {
1330 let _reference_number = read_unsigned_integer(reader)?;
1331 }
1332
1333 self.modal.reset();
1334
1335 unimplemented!("XNAME record is not supported yet.")
1338 }
1339 32 => {
1340 trace!("XELEMENT record");
1342
1343 let _xelement_attribute = read_unsigned_integer(reader)?;
1344 let _xelement_string = read_byte_string(reader)?; self.property_parent = PropertyParent::XElement;
1347 }
1348 33 => {
1349 trace!("XGEOMETRY record");
1351
1352 self.property_parent = PropertyParent::XGeometry;
1355
1356 unimplemented!("XGEOMETRY record is not supported yet.")
1357 }
1358 34 => {
1359 trace!("CBLOCK");
1361
1362 if self.is_in_cblock {
1363 log::error!("nested CBLOCK");
1364 return Err(OASISReadError::NestedCblock);
1365 }
1366
1367 let compression_type = read_unsigned_integer(reader)?;
1368
1369 if compression_type != 0 {
1370 return Err(OASISReadError::UnsupportedCompressionType(compression_type));
1371 }
1372
1373 let uncompressed_byte_count = read_unsigned_integer(reader)? as usize;
1374 let compressed_byte_count = read_unsigned_integer(reader)?;
1375
1376 trace!("read compressed bytes: {} bytes", compressed_byte_count);
1377 let mut compressed_bytes = vec![0; compressed_byte_count as usize];
1378 reader.read_exact(&mut compressed_bytes)?;
1379
1380 trace!("deflate CBLOCK");
1383 let mut decompressor = flate2::Decompress::new(false);
1384 let mut uncompressed_bytes =
1385 Vec::with_capacity(uncompressed_byte_count.min(1 << 20));
1386 decompressor
1387 .decompress_vec(
1388 &compressed_bytes,
1389 &mut uncompressed_bytes,
1390 flate2::FlushDecompress::Finish,
1391 )
1392 .map_err(|_e| OASISReadError::DecompressError)?;
1393
1394 if uncompressed_bytes.len() != uncompressed_byte_count {
1396 return Err(OASISReadError::UncompressedByteCountMismatch(
1397 uncompressed_byte_count,
1398 uncompressed_bytes.len(),
1399 ));
1400 }
1401
1402 self.is_in_cblock = true;
1403 let result = self.read_body(&mut Cursor::new(uncompressed_bytes), layout);
1404 self.is_in_cblock = false;
1405 result?;
1406 }
1407 _ => {
1408 return Err(OASISReadError::UnsupportedRecordType(record_id));
1409 }
1410 }
1411 }
1412
1413 for (prop_name_id, forward_references) in self.m_property_name_forward_references.drain() {
1416 let property_name = self.m_propnames.get(&prop_name_id).unwrap();
1417 trace!(
1418 "Resolve {} forward references '{}=>{}'.",
1419 forward_references.len(),
1420 prop_name_id,
1421 &property_name
1422 );
1423
1424 for (property_parent, property_values) in forward_references {
1425 Self::set_property(
1426 layout,
1427 &property_parent,
1428 property_name,
1429 &property_values,
1430 &self.m_propstrings,
1431 );
1432 }
1433 }
1434
1435 if !self.m_cell_names_forward_references.is_empty() {
1437 error!("Some cell name forward references where not resolved.");
1438 return Err(OASISReadError::UnresolvedForwardReferences(
1439 self.m_cell_names_forward_references
1440 .keys()
1441 .copied()
1442 .collect(),
1443 ));
1444 }
1445
1446 debug_assert!(
1447 self.placement_cell_forward_references.is_empty(),
1448 "Some forward references have never been resolved."
1449 );
1450
1451 if !self.m_property_name_forward_references.is_empty() {
1453 error!("Some property name forward references where not resolved.");
1454 return Err(OASISReadError::UnresolvedForwardReferences(
1455 self.m_property_name_forward_references
1456 .keys()
1457 .copied()
1458 .collect(),
1459 ));
1460 }
1461
1462 Ok(())
1463 }
1464
1465 fn read_end_record<R: Read>(&mut self, reader: &mut R) -> Result<(), OASISReadError> {
1466 trace!("END record");
1468 if !self.table_offsets_at_start {
1471 read_offset_table(reader)?;
1473 }
1474
1475 let _padding_string = read_byte_string(reader)?;
1477
1478 let validation_scheme = read_unsigned_integer(reader)?;
1480
1481 match validation_scheme {
1482 0 => {
1483 trace!("No integrity validation.");
1485 }
1486 1 => {
1487 let crc32_expected = reader.read_u32::<LittleEndian>()?;
1489 trace!("CRC32 (from file): {:x}", crc32_expected);
1490 }
1492 2 => {
1493 let checksum32_expected = reader.read_u32::<LittleEndian>()?;
1497 trace!("CHECKSUM32 (from file): {:x}", checksum32_expected);
1498 }
1500 v => {
1501 return Err(OASISReadError::UnknownValidationScheme(v)); }
1503 }
1504
1505 Ok(())
1506 }
1507
1508 fn read_cell_name<R: Read>(
1513 &mut self,
1514 reader: &mut R,
1515 layout: &mut L,
1516 record_id: u32,
1517 ) -> Result<(), OASISReadError> {
1518 trace!("CELLNAME record");
1520
1521 let cell_name = read_name_string(reader)?;
1522 trace!("cell name = {}", &cell_name);
1523
1524 let id = if record_id == 3 {
1525 if self.id_counters.cellname.id_mode == IdMode::Expl {
1527 return Err(OASISReadError::MixedImplExplCellnameModes); };
1529 self.id_counters.cellname.id_mode = IdMode::Impl; self.id_counters.cellname.next() } else {
1532 if self.id_counters.cellname.id_mode == IdMode::Impl {
1534 return Err(OASISReadError::MixedImplExplCellnameModes); };
1536 self.id_counters.cellname.id_mode = IdMode::Expl; read_unsigned_integer(reader)?
1538 };
1539
1540 if self.m_cell_names.insert(id, cell_name.clone()).is_some() {
1543 return Err(OASISReadError::CellnameIdAlreadyPresent(id));
1544 }
1545 self.modal.reset();
1546
1547 if let Some(idx) = self.m_cell_names_forward_references.remove(&id) {
1549 if let Some(_existing_cell) = layout.cell_by_name(&cell_name) {
1551 warn!("Cell already exists: {}", cell_name);
1552 }
1558 layout.rename_cell(&idx, cell_name.clone().into());
1559 }
1560
1561 self.property_parent = PropertyParent::CellName(cell_name);
1563
1564 Ok(())
1565 }
1566
1567 fn read_property_record<R: Read>(
1568 &mut self,
1569 reader: &mut R,
1570 layout: &mut L,
1571 record_id: u32,
1572 ) -> Result<(), OASISReadError> {
1573 trace!("PROPERTY record");
1580
1581 let (property_name_or_ref, property_values) = if record_id == 28 {
1582 let prop_info_byte = read_byte(reader)?;
1583 let b = |index| (prop_info_byte >> index) & 1u8 == 1u8;
1584 let is_name_reference_explicit = b(2); let use_last_value_list = b(3); let _is_standard_property = b(0); let uuuu = ((prop_info_byte >> 4) & 0xF).into(); let property_name_or_ref = if is_name_reference_explicit {
1590 let is_ref_number_present = b(1);
1591 if is_ref_number_present {
1592 let ref_number = read_unsigned_integer(reader)?; let property_name = self.m_propnames.get(&ref_number);
1596 trace!("ref_number = {}", ref_number);
1597 match property_name {
1599 Some(name) => NameOrRef::Name(name.clone()),
1600 None => NameOrRef::NameRef(ref_number), }
1602 } else {
1603 NameOrRef::Name(read_name_string(reader)?)
1604 }
1605 } else {
1606 self.modal
1608 .last_property_name
1609 .take()
1610 .ok_or(OASISReadError::ModalLastPropertyNameNotDefined)?
1611 };
1612
1613 let values = if !use_last_value_list {
1614 let num_values = if uuuu == 15 {
1615 read_unsigned_integer(reader)?
1616 } else {
1617 uuuu
1618 };
1619
1620 let mut prop_value_list = Vec::with_capacity(num_values.min(1 << 20) as usize);
1622 for _i in 0..num_values {
1623 let prop = read_property_value(reader)?;
1624 prop_value_list.push(prop)
1625 }
1626 prop_value_list
1627 } else {
1628 if uuuu != 0 {
1630 log::error!("The bits 'uuuu' must be 0 but is {}", uuuu);
1631 return Err(OASISReadError::FormatError); }
1633
1634 self.modal
1635 .last_value_list
1636 .take()
1637 .ok_or(OASISReadError::ModalLastValueListNotDefined)?
1638 };
1639
1640 self.modal.last_property_name = Some(property_name_or_ref.clone());
1642 self.modal.last_value_list = Some(values.clone());
1643
1644 (property_name_or_ref, values)
1645 } else {
1646 (
1648 self.modal
1649 .last_property_name
1650 .clone()
1651 .ok_or(OASISReadError::ModalLastPropertyNameNotDefined)?,
1652 self.modal
1653 .last_value_list
1654 .clone()
1655 .ok_or(OASISReadError::ModalLastValueListNotDefined)?,
1656 )
1657 };
1658
1659 trace!("property name or reference = {:?}", &property_name_or_ref);
1660 trace!("property values = {:?}", &property_values);
1661
1662 match property_name_or_ref {
1663 NameOrRef::Name(property_name) => {
1664 trace!("property name = {}", &property_name);
1666
1667 Self::set_property(
1669 layout,
1670 &self.property_parent,
1671 &property_name,
1672 &property_values,
1673 &self.m_propstrings,
1674 );
1675 }
1676 NameOrRef::NameRef(property_name_ref) => {
1677 trace!(
1679 "Property name is a forward reference = {}",
1680 &property_name_ref
1681 );
1682
1683 self.m_property_name_forward_references
1685 .entry(property_name_ref)
1686 .or_default()
1687 .push((self.property_parent.clone(), property_values))
1688 }
1689 }
1690
1691 Ok(())
1692 }
1693}
1694
1695pub fn read_layout<R: Read, L: LayoutEdit<Coord = SInt>>(
1697 reader: &mut R,
1698 layout: &mut L,
1699) -> Result<(), OASISReadError> {
1700 let reader_state: ReaderState<L> = Default::default();
1701 reader_state.read_layout(reader, layout)
1702}