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_ERRORF( wxS( "OrCAD structure: prefix type mismatch %d != %d" ), typeId, first );
71 }
72
73 if( i == aCount - 1 )
74 {
75 // Short prefix i16 pair count, then (u32 nameIdx, u32 valueIdx) pairs. Negative count = no pairs.
76 int16_t count = m_stream.ReadI16();
77
78 if( count >= 0 )
79 {
80 for( int k = 0; k < count; k++ )
81 {
82 uint32_t nameIdx = m_stream.ReadU32();
83 uint32_t valueIdx = m_stream.ReadU32();
84 pfx.props.emplace_back( nameIdx, valueIdx );
85 }
86 }
87 }
88 else
89 {
90 // Long prefix u32 body length, then always-zero u32.
91 uint32_t bodyLen = m_stream.ReadU32();
92 uint32_t zeros = m_stream.ReadU32();
93
94 if( zeros != 0 )
95 THROW_IO_ERROR( wxS( "OrCAD structure: long prefix pad not zero" ) );
96
97 pfx.bodyLens.push_back( bodyLen );
98 }
99 }
100
101 // Preamble magic must follow prefix chain (not consumed here).
102 if( !m_stream.AtPreamble() )
103 THROW_IO_ERROR( wxS( "OrCAD structure: no preamble after prefixes" ) );
104
105 pfx.typeId = first;
106 return pfx;
107}
108
109
111{
112 size_t saved = m_stream.GetOffset();
113 wxString lastErr;
114 ORCAD_PREFIXES pfx;
115 bool found = false;
116
117 // Long-prefix count type-dependent; try longest chain first so short chain never wins as prefix of longer.
118 for( int n = 10; n >= 1 && !found; n-- )
119 {
120 m_stream.Seek( saved );
121
122 try
123 {
124 pfx = TryReadPrefixes( n );
125 found = true;
126 }
127 catch( const IO_ERROR& e )
128 {
129 lastErr = e.Problem();
130 }
131 }
132
133 if( !found )
134 {
135 m_stream.Seek( saved );
136 THROW_IO_ERRORF( wxS( "OrCAD structure: no valid prefix chain at 0x%zx: %s" ), saved, lastErr );
137 }
138
139 m_stream.ExpectPreamble( wxS( "structure preamble" ) );
140 uint32_t trail = m_stream.ReadU32();
141 m_stream.Skip( trail );
142 pfx.bodyStart = m_stream.GetOffset();
143
144 if( !pfx.bodyLens.empty() )
145 {
146 // Body length counts bytes after own 9-byte record; outermost bounds whole structure.
147 for( size_t i = 0; i < pfx.bodyLens.size(); i++ )
148 pfx.stops.push_back( pfx.start + 9 * i + 9 + pfx.bodyLens[i] );
149
150 pfx.end = pfx.stops[0];
151 }
152
153 return pfx;
154}
155
156
157std::string ORCAD_STRUCT_READER::Resolve( uint32_t aIndex ) const
158{
159 if( m_strings && aIndex < m_strings->size() )
160 return ( *m_strings )[aIndex];
161
162 return std::string();
163}
164
165
166std::map<std::string, std::string> ORCAD_STRUCT_READER::PropsDict( const ORCAD_PREFIXES& aPrefixes ) const
167{
168 std::map<std::string, std::string> out;
169
170 for( const std::pair<uint32_t, uint32_t>& prop : aPrefixes.props )
171 {
172 std::string name = Resolve( prop.first );
173
174 if( !name.empty() )
175 out[name] = Resolve( prop.second );
176 }
177
178 return out;
179}
180
181
182void ORCAD_STRUCT_READER::SkipStructure( const ORCAD_PREFIXES& aPrefixes, const wxString& aWhat )
183{
184 if( aPrefixes.end != 0 && aPrefixes.end >= m_stream.GetOffset() )
185 {
186 m_stream.Seek( aPrefixes.end );
187 }
188 else
189 {
190 THROW_IO_ERRORF( wxS( "OrCAD structure: cannot skip structure %s" ), aWhat );
191 }
192}
193
194
196{
197 size_t start = m_stream.GetOffset();
199
201 result.typeId = pfx.typeId;
202
203 try
204 {
205 switch( pfx.typeId )
206 {
209 result.record = OrcadReadWire( *this, pfx );
210 break;
211
212 case ORCAD_ST_ALIAS:
213 result.record = OrcadReadAlias( *this, pfx );
214 break;
215
217 result.record = OrcadReadDisplayProp( *this, pfx );
218 break;
219
221 result.record = OrcadReadPlacedInstance( *this, pfx );
222 break;
223
224 case ORCAD_ST_PORT:
225 result.record = OrcadReadPort( *this, pfx );
226 break;
227
228 case ORCAD_ST_GLOBAL:
240 result.record = OrcadReadGraphicInst( *this, pfx );
241 break;
242
244 result.record = OrcadReadTitleBlock( *this, pfx );
245 break;
246
248 result.record = OrcadReadErcObject( *this, pfx );
249 break;
250
252 result.record = OrcadReadBusEntry( *this, pfx );
253 break;
254
255 case ORCAD_ST_T0X10:
256 case ORCAD_ST_T0X11:
257 result.record = OrcadReadPinInst( *this, pfx );
258 break;
259
261 result.record = OrcadReadSthInPages0( *this, pfx );
262 break;
263
265 result.record = OrcadReadDrawnInstance( *this, pfx );
266 break;
267
268 default:
269 SkipStructure( pfx, wxString::Format( wxS( "type %d" ), pfx.typeId ) );
270 break;
271 }
272 }
273 catch( const IO_ERROR& )
274 {
275 // Recover via prefix offsets on body-parse failure; one bad record must not abort page/cache parse.
276 if( pfx.end != 0 && pfx.end > start )
277 {
278 Warn( wxString::Format( wxS( "OrCAD structure type %d at 0x%zx: body parse failed, "
279 "skipped" ),
280 pfx.typeId, start ) );
281 m_stream.Seek( pfx.end );
282 result.record = std::monostate();
283 return result;
284 }
285
286 throw;
287 }
288
289 return result;
290}
291
292
293// -- per-type body readers ----------------------------------------------------------------
294
295
297 const ORCAD_PREFIXES& /* aPrefixes */ )
298{
299 ORCAD_STREAM& ds = aReader.Stream();
301
302 prop.nameIdx = ds.ReadU32();
303 prop.name = aReader.Resolve( prop.nameIdx );
304 prop.x = ds.ReadI16();
305 prop.y = ds.ReadI16();
306
307 // u16 bits 0..13 = 1-based font index, bits 14..15 = quarter turns.
308 uint16_t rotFont = ds.ReadU16();
309 prop.fontIdx = rotFont & 0x3FFF;
310 prop.rotation = ( rotFont >> 14 ) & 0x3;
311
312 prop.color = ds.ReadU8();
313 prop.dispMode = ds.ReadU16();
314 ds.ExpectByte( 0x00, wxS( "display prop tail" ) );
315
316 return prop;
317}
318
319
321{
322 ORCAD_STREAM& ds = aReader.Stream();
323 ORCAD_ALIAS alias;
324
325 alias.x = ds.ReadI32();
326 alias.y = ds.ReadI32();
327 alias.color = static_cast<int>( ds.ReadU32() );
328 alias.rotation = static_cast<int>( ds.ReadU32() );
329 alias.fontIdx = static_cast<int>( ds.ReadU32() );
330 alias.name = ds.ReadLzt();
331
332 return alias;
333}
334
335
337{
338 ORCAD_STREAM& ds = aReader.Stream();
339 ORCAD_WIRE wire;
340
341 ds.Skip( 4 ); // unknown
342 wire.id = ds.ReadU32();
343 wire.color = static_cast<int>( ds.ReadU32() );
344 wire.x1 = ds.ReadI32();
345 wire.y1 = ds.ReadI32();
346 wire.x2 = ds.ReadI32();
347 wire.y2 = ds.ReadI32();
348 ds.Skip( 1 );
349
350 uint16_t aliasCount = ds.ReadU16();
351
352 for( int i = 0; i < aliasCount; i++ )
353 {
354 ORCAD_READ_RESULT r = aReader.ReadStructure();
355
356 if( ORCAD_ALIAS* alias = std::get_if<ORCAD_ALIAS>( &r.record ) )
357 wire.aliases.push_back( std::move( *alias ) );
358 }
359
360 uint16_t propCount = ds.ReadU16();
361
362 for( int i = 0; i < propCount; i++ )
363 aReader.ReadStructure();
364
365 wire.lineWidth = static_cast<int>( ds.ReadU32() );
366 wire.lineStyle = static_cast<int>( ds.ReadU32() );
367
368 wire.isBus = ( aPrefixes.typeId == ORCAD_ST_WIRE_BUS );
369
370 return wire;
371}
372
373
375 const ORCAD_PREFIXES& aPrefixes )
376{
377 ORCAD_STREAM& ds = aReader.Stream();
379
380 ds.Skip( 8 ); // unknown, zeros observed
381 inst.pkgName = ds.ReadLzt();
382 inst.dbId = ds.ReadU32();
383
384 // Placed bbox stored y-first; includes displayed text.
385 int by1 = ds.ReadI16();
386 int bx1 = ds.ReadI16();
387 int by2 = ds.ReadI16();
388 int bx2 = ds.ReadI16();
389 inst.bbox.x1 = bx1;
390 inst.bbox.y1 = by1;
391 inst.bbox.x2 = bx2;
392 inst.bbox.y2 = by2;
393
394 inst.x = ds.ReadI16();
395 inst.y = ds.ReadI16();
396 inst.color = ds.ReadU8();
397
398 // Orientation byte bits 0..1 = quarter turns, bit 2 = mirror.
399 uint8_t orientation = ds.ReadU8();
400 inst.rotation = orientation & 0x3;
401 inst.mirror = ( orientation & 0x4 ) != 0;
402
403 ds.Skip( 2 ); // structId, unknown
404
405 inst.displayProps = OrcadReadDisplayPropList( aReader );
406
407 ds.Skip( 1 );
408 inst.reference = ds.ReadLzt();
409
410 // Part Value = u32 string-table index after reference; next 10 bytes unknown.
411 uint32_t valueIdx = ds.ReadU32();
412 inst.value = aReader.Resolve( valueIdx );
413 ds.Skip( 10 );
414
415 uint16_t pinCount = ds.ReadU16();
416
417 for( int i = 0; i < pinCount; i++ )
418 {
419 ORCAD_READ_RESULT r = aReader.ReadStructure();
420
421 if( ORCAD_PIN_INST* pin = std::get_if<ORCAD_PIN_INST>( &r.record ) )
422 inst.pins.push_back( std::move( *pin ) );
423 }
424
425 inst.sourcePackage = ds.ReadLzt();
426 ds.Skip( 2 );
427
428 inst.props = aReader.PropsDict( aPrefixes );
429
430 return inst;
431}
432
433
435 const ORCAD_PREFIXES& aPrefixes )
436{
437 ORCAD_STREAM& ds = aReader.Stream();
439
440 uint32_t nameIdx = ds.ReadU32(); // logical net/port name string index (ports)
441 ds.ReadU32(); // source library string index
442 inst.name = ds.ReadLzt();
443 inst.dbId = ds.ReadU32();
444
445 // Anchor and bbox stored interleaved: y, x, y2, x2, x1, y1.
446 inst.y = ds.ReadI16();
447 inst.x = ds.ReadI16();
448 int y2 = ds.ReadI16();
449 int x2 = ds.ReadI16();
450 int x1 = ds.ReadI16();
451 int y1 = ds.ReadI16();
452 inst.bbox.x1 = x1;
453 inst.bbox.y1 = y1;
454 inst.bbox.x2 = x2;
455 inst.bbox.y2 = y2;
456
457 inst.color = ds.ReadU8();
458
459 // Orientation byte bits 0..1 = quarter turns, bit 2 = mirror.
460 uint8_t orientation = ds.ReadU8();
461 inst.rotation = orientation & 0x3;
462 inst.mirror = ( orientation & 0x4 ) != 0;
463
464 ds.Skip( 2 ); // structId, unknown
465
466 inst.displayProps = OrcadReadDisplayPropList( aReader );
467
468 // Flag 0x02 = one nested structure, usually SthInPages0 symbol body with drawable primitives.
469 uint8_t flag = ds.ReadU8();
470
471 if( flag == 0x02 )
472 {
473 ORCAD_READ_RESULT nested = aReader.ReadStructure();
474
475 if( ORCAD_SYMBOL_DEF* def = std::get_if<ORCAD_SYMBOL_DEF>( &nested.record ) )
476 inst.nested = std::make_unique<ORCAD_SYMBOL_DEF>( std::move( *def ) );
477 }
478
479 inst.typeId = aPrefixes.typeId;
480 inst.props = aReader.PropsDict( aPrefixes );
481 inst.logicalName = aReader.Resolve( nameIdx );
482
483 return inst;
484}
485
486
488{
489 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
490 aReader.Stream().Skip( 9 );
491
492 return inst;
493}
494
495
497 const ORCAD_PREFIXES& aPrefixes )
498{
499 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
500 aReader.Stream().Skip( 12 );
501
502 return inst;
503}
504
505
507 const ORCAD_PREFIXES& aPrefixes )
508{
509 ORCAD_GRAPHIC_INST inst = OrcadReadGraphicInst( aReader, aPrefixes );
510
511 aReader.Stream().ReadLzt();
512 aReader.Stream().ReadLzt();
513 aReader.Stream().ReadLzt();
514
515 return inst;
516}
517
518
520{
521 ORCAD_STREAM& ds = aReader.Stream();
523
524 ds.ReadU16();
525 pin.x = ds.ReadI16();
526 pin.y = ds.ReadI16();
527 pin.wordA = ds.ReadU32();
528 pin.wordB = ds.ReadU32();
529
530 pin.displayProps = OrcadReadDisplayPropList( aReader );
531
532 // Remaining body bytes padding; record ends at outer stop.
533 if( aPrefixes.end != 0 && aPrefixes.end > ds.GetOffset() )
534 ds.Seek( aPrefixes.end );
535
536 return pin;
537}
538
539
541 const ORCAD_PREFIXES& /* aPrefixes */ )
542{
543 ORCAD_STREAM& ds = aReader.Stream();
544 ORCAD_BUS_ENTRY entry;
545
546 entry.color = static_cast<int>( ds.ReadU32() );
547 entry.x1 = ds.ReadI32();
548 entry.y1 = ds.ReadI32();
549 entry.x2 = ds.ReadI32();
550 entry.y2 = ds.ReadI32();
551 ds.Skip( 8 ); // unknown
552
553 return entry;
554}
555
556
557std::vector<ORCAD_DISPLAY_PROP> OrcadReadDisplayPropList( ORCAD_STRUCT_READER& aReader )
558{
559 std::vector<ORCAD_DISPLAY_PROP> out;
560
561 uint16_t count = aReader.Stream().ReadU16();
562
563 for( int i = 0; i < count; i++ )
564 {
565 ORCAD_READ_RESULT r = aReader.ReadStructure();
566
567 if( ORCAD_DISPLAY_PROP* prop = std::get_if<ORCAD_DISPLAY_PROP>( &r.record ) )
568 out.push_back( std::move( *prop ) );
569 }
570
571 return out;
572}
573
574
576{
577 aStream.Skip( 9 );
578 aStream.ReadU32(); // id
579 aStream.ReadLzt();
580 aStream.ReadU32();
581 aStream.ReadU32(); // color
582 aStream.ReadU32(); // line style
583 aStream.ReadU32(); // line width
584}
585
586
588{
589 OrcadReadT0x34Raw( aStream );
590
591 uint16_t count = aStream.ReadU16();
592 aStream.Skip( 4 * static_cast<size_t>( count ) );
593}
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
#define THROW_IO_ERRORF(msg,...)
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.