KiCad PCB EDA Suite
Loading...
Searching...
No Matches
orcad_structures.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * Based on the dsn2kicad reference implementation and on OrCAD file format
7 * documentation from the OpenOrCadParser project (MIT licensed).
8 *
9 * This program is free software: you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
24
25#include <memory>
26#include <utility>
27#include <variant>
28
29#include <ki_exception.h>
30
32
33
35 const std::vector<std::string>* aStrings,
36 ORCAD_WARN_FN aWarn ) :
37 m_stream( aStream ),
38 m_strings( aStrings ),
39 m_warn( std::move( aWarn ) )
40{
41}
42
43
44void ORCAD_STRUCT_READER::Warn( const wxString& aMsg ) const
45{
46 if( m_warn )
47 m_warn( aMsg );
48}
49
50
52{
54 pfx.start = m_stream.GetOffset();
55
56 bool haveFirst = false;
57 int first = 0;
58
59 for( int i = 0; i < aCount; i++ )
60 {
61 int typeId = m_stream.ReadU8();
62
63 if( !haveFirst )
64 {
65 first = typeId;
66 haveFirst = true;
67 }
68 else if( typeId != first )
69 {
70 THROW_IO_ERROR( wxString::Format( wxS( "OrCAD structure: prefix type mismatch "
71 "%d != %d" ),
72 typeId, first ) );
73 }
74
75 if( i == aCount - 1 )
76 {
77 // Short prefix i16 pair count, then (u32 nameIdx, u32 valueIdx) pairs. Negative count = no pairs.
78 int16_t count = m_stream.ReadI16();
79
80 if( count >= 0 )
81 {
82 for( int k = 0; k < count; k++ )
83 {
84 uint32_t nameIdx = m_stream.ReadU32();
85 uint32_t valueIdx = m_stream.ReadU32();
86 pfx.props.emplace_back( nameIdx, valueIdx );
87 }
88 }
89 }
90 else
91 {
92 // Long prefix u32 body length, then always-zero u32.
93 uint32_t bodyLen = m_stream.ReadU32();
94 uint32_t zeros = m_stream.ReadU32();
95
96 if( zeros != 0 )
97 THROW_IO_ERROR( wxS( "OrCAD structure: long prefix pad not zero" ) );
98
99 pfx.bodyLens.push_back( bodyLen );
100 }
101 }
102
103 // Preamble magic must follow prefix chain (not consumed here).
104 if( !m_stream.AtPreamble() )
105 THROW_IO_ERROR( wxS( "OrCAD structure: no preamble after prefixes" ) );
106
107 pfx.typeId = first;
108 return pfx;
109}
110
111
113{
114 size_t saved = m_stream.GetOffset();
115 wxString lastErr;
116 ORCAD_PREFIXES pfx;
117 bool found = false;
118
119 // Long-prefix count type-dependent; try longest chain first so short chain never wins as prefix of longer.
120 for( int n = 10; n >= 1 && !found; n-- )
121 {
122 m_stream.Seek( saved );
123
124 try
125 {
126 pfx = TryReadPrefixes( n );
127 found = true;
128 }
129 catch( const IO_ERROR& e )
130 {
131 lastErr = e.Problem();
132 }
133 }
134
135 if( !found )
136 {
137 m_stream.Seek( saved );
138 THROW_IO_ERROR( wxString::Format( wxS( "OrCAD structure: no valid prefix chain at "
139 "0x%zx: %s" ),
140 saved, lastErr ) );
141 }
142
143 m_stream.ExpectPreamble( wxS( "structure preamble" ) );
144 uint32_t trail = m_stream.ReadU32();
145 m_stream.Skip( trail );
146 pfx.bodyStart = m_stream.GetOffset();
147
148 if( !pfx.bodyLens.empty() )
149 {
150 // Body length counts bytes after own 9-byte record; outermost bounds whole structure.
151 for( size_t i = 0; i < pfx.bodyLens.size(); i++ )
152 pfx.stops.push_back( pfx.start + 9 * i + 9 + pfx.bodyLens[i] );
153
154 pfx.end = pfx.stops[0];
155 }
156
157 return pfx;
158}
159
160
161std::string ORCAD_STRUCT_READER::Resolve( uint32_t aIndex ) const
162{
163 if( m_strings && aIndex < m_strings->size() )
164 return ( *m_strings )[aIndex];
165
166 return std::string();
167}
168
169
170std::map<std::string, std::string> ORCAD_STRUCT_READER::PropsDict( const ORCAD_PREFIXES& aPrefixes ) const
171{
172 std::map<std::string, std::string> out;
173
174 for( const std::pair<uint32_t, uint32_t>& prop : aPrefixes.props )
175 {
176 std::string name = Resolve( prop.first );
177
178 if( !name.empty() )
179 out[name] = Resolve( prop.second );
180 }
181
182 return out;
183}
184
185
186void ORCAD_STRUCT_READER::SkipStructure( const ORCAD_PREFIXES& aPrefixes, const wxString& aWhat )
187{
188 if( aPrefixes.end != 0 && aPrefixes.end >= m_stream.GetOffset() )
189 {
190 m_stream.Seek( aPrefixes.end );
191 }
192 else
193 {
194 THROW_IO_ERROR( wxString::Format( wxS( "OrCAD structure: cannot skip structure %s" ),
195 aWhat ) );
196 }
197}
198
199
201{
202 size_t start = m_stream.GetOffset();
204
206 result.typeId = pfx.typeId;
207
208 try
209 {
210 switch( pfx.typeId )
211 {
214 result.record = OrcadReadWire( *this, pfx );
215 break;
216
217 case ORCAD_ST_ALIAS:
218 result.record = OrcadReadAlias( *this, pfx );
219 break;
220
222 result.record = OrcadReadDisplayProp( *this, pfx );
223 break;
224
226 result.record = OrcadReadPlacedInstance( *this, pfx );
227 break;
228
229 case ORCAD_ST_PORT:
230 result.record = OrcadReadPort( *this, pfx );
231 break;
232
233 case ORCAD_ST_GLOBAL:
245 result.record = OrcadReadGraphicInst( *this, pfx );
246 break;
247
249 result.record = OrcadReadTitleBlock( *this, pfx );
250 break;
251
253 result.record = OrcadReadErcObject( *this, pfx );
254 break;
255
257 result.record = OrcadReadBusEntry( *this, pfx );
258 break;
259
260 case ORCAD_ST_T0X10:
261 case ORCAD_ST_T0X11:
262 result.record = OrcadReadPinInst( *this, pfx );
263 break;
264
266 result.record = OrcadReadSthInPages0( *this, pfx );
267 break;
268
270 result.record = OrcadReadDrawnInstance( *this, pfx );
271 break;
272
273 default:
274 SkipStructure( pfx, wxString::Format( wxS( "type %d" ), pfx.typeId ) );
275 break;
276 }
277 }
278 catch( const IO_ERROR& )
279 {
280 // Recover via prefix offsets on body-parse failure; one bad record must not abort page/cache parse.
281 if( pfx.end != 0 && pfx.end > start )
282 {
283 Warn( wxString::Format( wxS( "OrCAD structure type %d at 0x%zx: body parse failed, "
284 "skipped" ),
285 pfx.typeId, start ) );
286 m_stream.Seek( pfx.end );
287 result.record = std::monostate();
288 return result;
289 }
290
291 throw;
292 }
293
294 return result;
295}
296
297
298// -- per-type body readers ----------------------------------------------------------------
299
300
302 const ORCAD_PREFIXES& /* aPrefixes */ )
303{
304 ORCAD_STREAM& ds = aReader.Stream();
306
307 prop.nameIdx = ds.ReadU32();
308 prop.name = aReader.Resolve( prop.nameIdx );
309 prop.x = ds.ReadI16();
310 prop.y = ds.ReadI16();
311
312 // u16 bits 0..13 = 1-based font index, bits 14..15 = quarter turns.
313 uint16_t rotFont = ds.ReadU16();
314 prop.fontIdx = rotFont & 0x3FFF;
315 prop.rotation = ( rotFont >> 14 ) & 0x3;
316
317 prop.color = ds.ReadU8();
318 prop.dispMode = ds.ReadU16();
319 ds.ExpectByte( 0x00, wxS( "display prop tail" ) );
320
321 return prop;
322}
323
324
326{
327 ORCAD_STREAM& ds = aReader.Stream();
328 ORCAD_ALIAS alias;
329
330 alias.x = ds.ReadI32();
331 alias.y = ds.ReadI32();
332 alias.color = static_cast<int>( ds.ReadU32() );
333 alias.rotation = static_cast<int>( ds.ReadU32() );
334 alias.fontIdx = static_cast<int>( ds.ReadU32() );
335 alias.name = ds.ReadLzt();
336
337 return alias;
338}
339
340
342{
343 ORCAD_STREAM& ds = aReader.Stream();
344 ORCAD_WIRE wire;
345
346 ds.Skip( 4 ); // unknown
347 wire.id = ds.ReadU32();
348 wire.color = static_cast<int>( ds.ReadU32() );
349 wire.x1 = ds.ReadI32();
350 wire.y1 = ds.ReadI32();
351 wire.x2 = ds.ReadI32();
352 wire.y2 = ds.ReadI32();
353 ds.Skip( 1 );
354
355 uint16_t aliasCount = ds.ReadU16();
356
357 for( int i = 0; i < aliasCount; i++ )
358 {
359 ORCAD_READ_RESULT r = aReader.ReadStructure();
360
361 if( ORCAD_ALIAS* alias = std::get_if<ORCAD_ALIAS>( &r.record ) )
362 wire.aliases.push_back( std::move( *alias ) );
363 }
364
365 uint16_t propCount = ds.ReadU16();
366
367 for( int i = 0; i < propCount; i++ )
368 aReader.ReadStructure();
369
370 wire.lineWidth = static_cast<int>( ds.ReadU32() );
371 wire.lineStyle = static_cast<int>( ds.ReadU32() );
372
373 wire.isBus = ( aPrefixes.typeId == ORCAD_ST_WIRE_BUS );
374
375 return wire;
376}
377
378
380 const ORCAD_PREFIXES& aPrefixes )
381{
382 ORCAD_STREAM& ds = aReader.Stream();
384
385 ds.Skip( 8 ); // unknown, zeros observed
386 inst.pkgName = ds.ReadLzt();
387 inst.dbId = ds.ReadU32();
388
389 // Placed bbox stored y-first; includes displayed text.
390 int by1 = ds.ReadI16();
391 int bx1 = ds.ReadI16();
392 int by2 = ds.ReadI16();
393 int bx2 = ds.ReadI16();
394 inst.bbox.x1 = bx1;
395 inst.bbox.y1 = by1;
396 inst.bbox.x2 = bx2;
397 inst.bbox.y2 = by2;
398
399 inst.x = ds.ReadI16();
400 inst.y = ds.ReadI16();
401 inst.color = ds.ReadU8();
402
403 // Orientation byte bits 0..1 = quarter turns, bit 2 = mirror.
404 uint8_t orientation = ds.ReadU8();
405 inst.rotation = orientation & 0x3;
406 inst.mirror = ( orientation & 0x4 ) != 0;
407
408 ds.Skip( 2 ); // structId, unknown
409
410 inst.displayProps = OrcadReadDisplayPropList( aReader );
411
412 ds.Skip( 1 );
413 inst.reference = ds.ReadLzt();
414
415 // Part Value = u32 string-table index after reference; next 10 bytes unknown.
416 uint32_t valueIdx = ds.ReadU32();
417 inst.value = aReader.Resolve( valueIdx );
418 ds.Skip( 10 );
419
420 uint16_t pinCount = ds.ReadU16();
421
422 for( int i = 0; i < pinCount; i++ )
423 {
424 ORCAD_READ_RESULT r = aReader.ReadStructure();
425
426 if( ORCAD_PIN_INST* pin = std::get_if<ORCAD_PIN_INST>( &r.record ) )
427 inst.pins.push_back( std::move( *pin ) );
428 }
429
430 inst.sourcePackage = ds.ReadLzt();
431 ds.Skip( 2 );
432
433 inst.props = aReader.PropsDict( aPrefixes );
434
435 return inst;
436}
437
438
440 const ORCAD_PREFIXES& aPrefixes )
441{
442 ORCAD_STREAM& ds = aReader.Stream();
444
445 uint32_t nameIdx = ds.ReadU32(); // logical net/port name string index (ports)
446 ds.ReadU32(); // source library string index
447 inst.name = ds.ReadLzt();
448 inst.dbId = ds.ReadU32();
449
450 // Anchor and bbox stored interleaved: y, x, y2, x2, x1, y1.
451 inst.y = ds.ReadI16();
452 inst.x = ds.ReadI16();
453 int y2 = ds.ReadI16();
454 int x2 = ds.ReadI16();
455 int x1 = ds.ReadI16();
456 int y1 = ds.ReadI16();
457 inst.bbox.x1 = x1;
458 inst.bbox.y1 = y1;
459 inst.bbox.x2 = x2;
460 inst.bbox.y2 = y2;
461
462 inst.color = ds.ReadU8();
463
464 // Orientation byte bits 0..1 = quarter turns, bit 2 = mirror.
465 uint8_t orientation = ds.ReadU8();
466 inst.rotation = orientation & 0x3;
467 inst.mirror = ( orientation & 0x4 ) != 0;
468
469 ds.Skip( 2 ); // structId, unknown
470
471 inst.displayProps = OrcadReadDisplayPropList( aReader );
472
473 // Flag 0x02 = one nested structure, usually SthInPages0 symbol body with drawable primitives.
474 uint8_t flag = ds.ReadU8();
475
476 if( flag == 0x02 )
477 {
478 ORCAD_READ_RESULT nested = aReader.ReadStructure();
479
480 if( ORCAD_SYMBOL_DEF* def = std::get_if<ORCAD_SYMBOL_DEF>( &nested.record ) )
481 inst.nested = std::make_unique<ORCAD_SYMBOL_DEF>( std::move( *def ) );
482 }
483
484 inst.typeId = aPrefixes.typeId;
485 inst.props = aReader.PropsDict( aPrefixes );
486 inst.logicalName = aReader.Resolve( nameIdx );
487
488 return inst;
489}
490
491
493{
494 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
495 aReader.Stream().Skip( 9 );
496
497 return inst;
498}
499
500
502 const ORCAD_PREFIXES& aPrefixes )
503{
504 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
505 aReader.Stream().Skip( 12 );
506
507 return inst;
508}
509
510
512 const ORCAD_PREFIXES& aPrefixes )
513{
514 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
515
516 aReader.Stream().ReadLzt();
517 aReader.Stream().ReadLzt();
518 aReader.Stream().ReadLzt();
519
520 return inst;
521}
522
523
525{
526 ORCAD_STREAM& ds = aReader.Stream();
528
529 ds.ReadU16();
530 pin.x = ds.ReadI16();
531 pin.y = ds.ReadI16();
532 pin.wordA = ds.ReadU32();
533 pin.wordB = ds.ReadU32();
534
535 pin.displayProps = OrcadReadDisplayPropList( aReader );
536
537 // Remaining body bytes padding; record ends at outer stop.
538 if( aPrefixes.end != 0 && aPrefixes.end > ds.GetOffset() )
539 ds.Seek( aPrefixes.end );
540
541 return pin;
542}
543
544
546 const ORCAD_PREFIXES& /* aPrefixes */ )
547{
548 ORCAD_STREAM& ds = aReader.Stream();
549 ORCAD_BUS_ENTRY entry;
550
551 entry.color = static_cast<int>( ds.ReadU32() );
552 entry.x1 = ds.ReadI32();
553 entry.y1 = ds.ReadI32();
554 entry.x2 = ds.ReadI32();
555 entry.y2 = ds.ReadI32();
556 ds.Skip( 8 ); // unknown
557
558 return entry;
559}
560
561
562std::vector<ORCAD_DISPLAY_PROP> OrcadReadDisplayPropList( ORCAD_STRUCT_READER& aReader )
563{
564 std::vector<ORCAD_DISPLAY_PROP> out;
565
566 uint16_t count = aReader.Stream().ReadU16();
567
568 for( int i = 0; i < count; i++ )
569 {
570 ORCAD_READ_RESULT r = aReader.ReadStructure();
571
572 if( ORCAD_DISPLAY_PROP* prop = std::get_if<ORCAD_DISPLAY_PROP>( &r.record ) )
573 out.push_back( std::move( *prop ) );
574 }
575
576 return out;
577}
578
579
581{
582 aStream.Skip( 9 );
583 aStream.ReadU32(); // id
584 aStream.ReadLzt();
585 aStream.ReadU32();
586 aStream.ReadU32(); // color
587 aStream.ReadU32(); // line style
588 aStream.ReadU32(); // line width
589}
590
591
593{
594 OrcadReadT0x34Raw( aStream );
595
596 uint16_t count = aStream.ReadU16();
597 aStream.Skip( 4 * static_cast<size_t>( count ) );
598}
const char * name
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString Problem() const
what was the problem?
Little-endian byte cursor over one OrCAD Capture DSN stream.
uint8_t ReadU8()
size_t GetOffset() const
uint16_t ReadU16()
void Skip(size_t aCount)
Advance the cursor; throws IO_ERROR when aCount exceeds the remaining bytes.
std::string ReadLzt()
Read a length-prefixed zero-terminated string: u16 length, length content bytes, then a mandatory 0x0...
void Seek(size_t aOffset)
Set the absolute cursor position.
int32_t ReadI32()
void ExpectByte(uint8_t aValue, const wxString &aWhat)
Consume one byte and require the given value.
uint32_t ReadU32()
int16_t ReadI16()
Stateful reader shared by all structure parsers.
std::map< std::string, std::string > PropsDict(const ORCAD_PREFIXES &aPrefixes) const
Resolve the short-prefix (nameIdx, valueIdx) pairs; empty names are dropped.
void SkipStructure(const ORCAD_PREFIXES &aPrefixes, const wxString &aWhat)
Seek to the end of a structure using its outermost prefix length.
ORCAD_STREAM & Stream()
void Warn(const wxString &aMsg) const
Report a recoverable problem to the warning sink (no-op when none was given).
std::string Resolve(uint32_t aIndex) const
String-table lookup; returns "" for out-of-range indices.
ORCAD_STRUCT_READER(ORCAD_STREAM &aStream, const std::vector< std::string > *aStrings=nullptr, ORCAD_WARN_FN aWarn=nullptr)
ORCAD_READ_RESULT ReadStructure()
Read one structure of any type: prefixes, then the type-specific body via the reader dispatch below.
const std::vector< std::string > * m_strings
ORCAD_PREFIXES TryReadPrefixes(int aCount)
Attempt to read exactly aCount prefixes (aCount - 1 long + 1 short) at the current position and verif...
ORCAD_PREFIXES ReadPrefixes()
Discover the prefix count by trial from 10 down to 1 (longest chain first), then consume the prefixes...
ORCAD_STREAM & m_stream
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
STL namespace.
ORCAD_DRAWN_INSTANCE OrcadReadDrawnInstance(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Structure type 12 (DrawnInstance): hierarchical block instance.
ORCAD_SYMBOL_DEF OrcadReadSthInPages0(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Structure type 2 (SthInPages0): nested symbol body inside Graphic*Inst structures on pages; carries t...
Parsers for the DSN 'Cache' stream and the 'Packages/<name>' streams: symbol definitions with graphic...
std::function< void(const wxString &aMsg)> ORCAD_WARN_FN
Warning sink shared by all parser entry points (recoverable-issue channel).
@ ORCAD_ST_STH_IN_PAGES0
nested symbol body inside Graphic*Inst
@ ORCAD_ST_T0X10
scalar pin instance (absolute pos)
@ ORCAD_ST_WIRE_SCALAR
@ ORCAD_ST_PLACED_INSTANCE
@ ORCAD_ST_GRAPHIC_ARC_INST
@ ORCAD_ST_DRAWN_INSTANCE
hierarchical block instance
@ ORCAD_ST_TITLEBLOCK
@ ORCAD_ST_GLOBAL
placed power symbol
@ ORCAD_ST_GRAPHIC_BITMAP_INST
@ ORCAD_ST_OFFPAGE_CONNECTOR
@ ORCAD_ST_PORT
@ ORCAD_ST_GRAPHIC_LINE_INST
@ ORCAD_ST_GRAPHIC_COMMENT_TEXT_INST
@ ORCAD_ST_GRAPHIC_ELLIPSE_INST
@ ORCAD_ST_GRAPHIC_BOX_INST
@ ORCAD_ST_ERC_OBJECT
placed ERC marker (no-connect)
@ ORCAD_ST_GRAPHIC_POLYLINE_INST
@ ORCAD_ST_GRAPHIC_BEZIER_INST
@ ORCAD_ST_GRAPHIC_POLYGON_INST
@ ORCAD_ST_ALIAS
net alias attached to a wire
@ ORCAD_ST_WIRE_BUS
@ ORCAD_ST_SYMBOL_DISPLAY_PROP
@ ORCAD_ST_T0X11
bus pin instance (absolute pos)
@ ORCAD_ST_BUS_ENTRY
@ ORCAD_ST_GRAPHIC_OLE_INST
ORCAD_WIRE OrcadReadWire(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Types 20 (wire) and 21 (bus); isBus is set from the prefix type.
ORCAD_PLACED_INSTANCE OrcadReadPlacedInstance(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
void OrcadReadT0x34Raw(ORCAD_STREAM &aStream)
T0x34 records are NOT prefix-framed.
ORCAD_GRAPHIC_INST OrcadReadPort(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by a 9-byte trailer.
std::vector< ORCAD_DISPLAY_PROP > OrcadReadDisplayPropList(ORCAD_STRUCT_READER &aReader)
Read a u16-counted list of framed DisplayProp structures via ReadStructure(), keeping only the succes...
ORCAD_PIN_INST OrcadReadPinInst(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
ORCAD_DISPLAY_PROP OrcadReadDisplayProp(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &)
ORCAD_GRAPHIC_INST OrcadReadErcObject(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by 3 lzt strings.
ORCAD_ALIAS OrcadReadAlias(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &)
ORCAD_GRAPHIC_INST OrcadReadTitleBlock(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by a 12-byte trailer.
ORCAD_BUS_ENTRY OrcadReadBusEntry(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &)
ORCAD_GRAPHIC_INST OrcadReadGraphicInst(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Common body of Port/Global/OffPageConnector/TitleBlock/ERCObject/Graphic*Inst.
void OrcadReadT0x35Raw(ORCAD_STREAM &aStream)
T0x35 = the T0x34 raw layout followed by u16 n and 4 * n bytes.
Prefix framing machinery and readers for the prefix-framed OrCAD structures found in Page/Cache/Schem...
ORCAD_WIRE OrcadReadWire(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Types 20 (wire) and 21 (bus); isBus is set from the prefix type.
ORCAD_PLACED_INSTANCE OrcadReadPlacedInstance(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
ORCAD_GRAPHIC_INST OrcadReadPort(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by a 9-byte trailer.
ORCAD_PIN_INST OrcadReadPinInst(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
ORCAD_DISPLAY_PROP OrcadReadDisplayProp(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
ORCAD_GRAPHIC_INST OrcadReadErcObject(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by 3 lzt strings.
ORCAD_GRAPHIC_INST OrcadReadTitleBlock(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
GraphicInst body followed by a 12-byte trailer.
ORCAD_GRAPHIC_INST OrcadReadGraphicInst(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Common body of Port/Global/OffPageConnector/TitleBlock/ERCObject/Graphic*Inst.
ORCAD_BUS_ENTRY OrcadReadBusEntry(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
ORCAD_ALIAS OrcadReadAlias(ORCAD_STRUCT_READER &aReader, const ORCAD_PREFIXES &aPrefixes)
Net alias attached to a wire (becomes a local label).
std::string name
int rotation
0..3 quarter turns
Bus entry (structure type 29).
int y1
int color
int x2
int y2
int x1
One displayed property of an instance (Part Reference, Value, user fields).
int fontIdx
1-based into ORCAD_LIBRARY_INFO::fonts; 0 = default
int rotation
0..3 quarter turns
std::string name
resolved property name (empty when index invalid)
Shared body of Port / Global / OffPageConnector / TitleBlock / ERCObject and the Graphic*Inst shapes ...
std::unique_ptr< ORCAD_SYMBOL_DEF > nested
SthInPages0 body, else nullptr.
std::map< std::string, std::string > props
int rotation
0..3 quarter turns
std::string name
cache symbol name
std::vector< ORCAD_DISPLAY_PROP > displayProps
std::string logicalName
ports: resolved net/port name
int typeId
ORCAD_ST value.
T0x10: one pin of a placed instance, carrying the pin's absolute page position (the connection point ...
A placed part instance on a page (structure type 13).
std::string sourcePackage
package base name
std::vector< ORCAD_DISPLAY_PROP > displayProps
ORCAD_BBOX bbox
placed box, page DBU
int rotation
0..3 quarter turns
std::map< std::string, std::string > props
short-prefix property pairs
bool mirror
orientation bit 2
std::string value
resolved Part Value
std::vector< ORCAD_PIN_INST > pins
successfully parsed T0x10 records
The decoded prefix chain of one framed structure.
std::vector< size_t > stops
checkpoint offsets, one per long prefix: start + 9 * i + 9 + bodyLens[i]
int typeId
ORCAD_ST value (u8 in the stream)
size_t bodyStart
offset right after the preamble trail
std::vector< std::pair< uint32_t, uint32_t > > props
short prefix (nameIdx, valueIdx) pairs
std::vector< uint32_t > bodyLens
one per long prefix, outermost first
size_t end
offset right after the whole structure (from the outermost long prefix); 0 when unknown
size_t start
stream offset where the chain began
ORCAD_RECORD_VARIANT record
A symbol definition from the design Cache (LibraryPart / GlobalSymbol / PortSymbol / OffPageSymbol / ...
One wire or bus segment.
uint32_t id
bool isBus
true for structure type 21
std::vector< ORCAD_ALIAS > aliases
KIBIS_PIN * pin
wxString result
Test unit parsing edge cases and error handling.