30#include <wx/translation.h>
44 if(
T* record = std::get_if<T>( &aResult.
record ) )
46 aTarget.push_back( std::move( *record ) );
59 for( uint16_t i = 0; i < count; i++ )
62 takeRecord(
result, aTarget );
102 uint16_t count = stream.
ReadU16();
104 for( uint16_t i = 0; i < count; i++ )
109 for( uint16_t i = 0; i < count; i++ )
115 for( uint16_t i = 0; i < count; i++ )
117 std::string netName = stream.
ReadLzt();
118 uint32_t netId = stream.
ReadU32();
120 page.
netmap[netId] = std::move( netName );
123 readStructureList( reader, page.
wires );
128 for( uint16_t i = 0; i < count; i++ )
136 readStructureList( reader, page.
ports );
141 for( uint16_t i = 0; i < count; i++ )
150 for( uint16_t i = 0; i < count; i++ )
159 readStructureList( reader, page.
graphics );
162 THROW_IO_ERROR( wxS(
"OrCAD page stream: page body exceeds its outer stop" ) );
173 uint16_t count = aStream.
ReadU16();
175 std::vector<std::string> names;
176 names.reserve( count );
178 for( uint16_t i = 0; i < count; i++ )
179 names.push_back( aStream.
ReadLzt() );
181 std::reverse( names.begin(), names.end() );
203 uint16_t count = stream.
ReadU16();
204 std::vector<std::string> names;
205 names.reserve( count );
207 for( uint16_t i = 0; i < count; ++i )
209 names.push_back( stream.
ReadLzt() );
212 THROW_IO_ERROR( wxS(
"OrCAD Views Directory: invalid folder record" ) );
217 if( !stream.
AtEnd() )
226 std::map<std::string, std::string>* aProps =
nullptr )
234 return static_cast<uint8_t
>( prefixes.
typeId );
243 std::map<std::string, std::string> props;
247 uint32_t blockObjectId = aStream.
ReadU32();
249 aStream.
ExpectByte( 0x42, wxS(
"occurrence inner marker" ) );
254 std::string child = aStream.
ReadLzt();
255 std::string ref = aStream.
ReadLzt();
257 uint32_t unitRefIdx = aStream.
ReadU32();
259 uint16_t pinCount = aStream.
ReadU16();
261 for( uint16_t i = 0; i < pinCount; i++ )
275 block.
scope = std::move( nested );
276 aScope.
blocks.push_back( std::move( block ) );
281 aScope.
partRefs[blockObjectId] = ref;
284 aScope.
partProps[blockObjectId] = std::move( props );
286 if( unitRefIdx < aStrings.size() && !aStrings[unitRefIdx].empty() )
288 aScope.
partUnitRefs[blockObjectId] = aStrings[unitRefIdx];
302 uint16_t netCount = aStream.
ReadU16();
304 for( uint16_t i = 0; i < netCount; i++ )
307 uint32_t occurrenceId = aStream.
ReadU32();
312 uint16_t titleBlockCount = aStream.
ReadU16();
314 for( uint16_t i = 0; i < titleBlockCount; i++ )
321 uint32_t globalCount = aStream.
ReadU32();
323 for( uint32_t i = 0; i < globalCount; i++ )
336 uint16_t occCount = aStream.
ReadU16();
338 for( uint16_t i = 0; i < occCount; i++ )
347static std::string
v2Resolve(
const std::vector<std::string>& aStrings, uint16_t aIdx )
349 return ( aIdx != 0xFFFF && aIdx < aStrings.size() ) ? aStrings[aIdx] : std::string();
377 if( aCount > 30000 || aCount > aStream.
Remaining() )
379 THROW_IO_ERRORF( wxS(
"v2 repeat count %u exceeds the sane bound (%zu bytes remain)" ), aCount,
387 std::map<std::string, std::string>* aProps =
nullptr )
389 uint8_t type = aStream.
ReadU8();
390 int16_t count = aStream.
ReadI16();
393 THROW_IO_ERRORF( wxS(
"v2 prefix: absurd property count %d" ), count );
395 for(
int i = 0; i < count; i++ )
397 uint16_t nameIdx = aStream.
ReadU16();
398 uint16_t valueIdx = aStream.
ReadU16();
418 uint16_t rotFont = aStream.
ReadU16();
419 prop.
fontIdx = rotFont & 0x3FFF;
420 prop.
rotation = ( rotFont >> 14 ) & 0x3;
432 aStream.
ExpectByte( 0x00, wxS(
"v2 display prop terminator" ) );
440 const std::vector<std::string>& aStrings )
442 std::vector<ORCAD_DISPLAY_PROP> props;
443 uint16_t count = aStream.
ReadU16();
445 for( uint16_t i = 0; i < count; i++ )
475 uint8_t type =
v2Prefix( aStream, aStrings );
488 uint16_t aliasCount = aStream.
ReadU16();
490 for( uint16_t i = 0; i < aliasCount; i++ )
493 uint16_t propCount = aStream.
ReadU16();
495 for( uint16_t i = 0; i < propCount; i++ )
542 uint8_t orientation = aStream.
ReadU8();
544 inst.
mirror = ( orientation & 0x4 ) != 0;
554 uint16_t pinCount = aStream.
ReadU16();
556 for( uint16_t i = 0; i < pinCount; i++ )
585 uint16_t primCount = aStream.
ReadU16();
587 for( uint16_t i = 0; i < primCount; i++ )
608 uint8_t type = aType;
664 uint16_t count = aStream.
ReadU16();
667 for( uint16_t i = 0; i < count; i++ )
683 int16_t nProp = aStream.
ReadI16();
685 for(
int i = 0; i < std::max<int>( nProp, 0 ); i++ )
695 uint16_t nested = aStream.
ReadU16();
698 for( uint16_t i = 0; i < nested; i++ )
700 uint8_t nestedType = aStream.
ReadU8();
701 aStream.
ExpectByte( 0x00, wxS(
"v2 vector prim pad" ) );
731 uint32_t dataSize = aStream.
ReadU32();
754 uint16_t nameIdx = aStream.
ReadU16();
755 uint16_t sourceLibraryIdx = aStream.
ReadU16();
760 if( std::string sourceLibrary =
v2Resolve( aStrings, sourceLibraryIdx ); !sourceLibrary.empty() )
761 inst.
props[
"Source Library"] = std::move( sourceLibrary );
777 uint8_t orientation = aStream.
ReadU8();
779 inst.
mirror = ( orientation & 0x4 ) != 0;
787 inst.
nested = std::make_unique<ORCAD_SYMBOL_DEF>(
v2SymbolDef( aStream, aStrings ) );
795 switch( aStream.
PeekU8() )
821 if( aStream.
PeekU8() == 0x00 )
827 uint8_t type =
v2Prefix( aStream, aStrings );
837 aStream.
ExpectByte( type, wxS(
"v2 pin type echo" ) );
840 uint16_t dispCount = aStream.
ReadU16();
843 for( uint16_t i = 0; i < dispCount; i++ )
859 uint16_t primCount = aStream.
ReadU16();
862 for( uint16_t i = 0; i < primCount; i++ )
872 uint16_t pinCount = aStream.
ReadU16();
875 for( uint16_t i = 0; i < pinCount; i++ )
880 def.
pins.push_back( std::move(
pin ) );
883 uint16_t dispCount = aStream.
ReadU16();
886 for( uint16_t i = 0; i < dispCount; i++ )
895 std::string implementationPath = aStream.
ReadLzt();
897 if( !implementationPath.empty() )
898 aDef.
props[
"Implementation Path"] = std::move( implementationPath );
914 std::map<std::string, std::string>
props;
920 std::map<std::string, std::string> cellProps;
921 v2Prefix( aStream, aStrings, &cellProps );
924 cell.
props = cellProps;
928 uint16_t viewCount = aStream.
ReadU16();
931 for( uint16_t i = 0; i < viewCount; i++ )
934 uint16_t symbolCount = aStream.
ReadU16();
937 for( uint16_t i = 0; i < symbolCount; i++ )
939 std::map<std::string, std::string> symbolProps;
940 v2Prefix( aStream, aStrings, &symbolProps );
943 for(
const auto& [
name, value] : symbolProps )
946 std::string implementationPath = aStream.
ReadLzt();
948 if( !implementationPath.empty() )
949 def.
props[
"Implementation Path"] = std::move( implementationPath );
956 cell.
symbols.push_back( std::move( def ) );
971 uint16_t pinCount = aStream.
ReadU16();
974 static const uint8_t emptySlot[2] = { 0xFF, 0xFF };
976 for( uint16_t i = 0; i < pinCount; i++ )
1004 uint16_t deviceCount = aStream.
ReadU16();
1007 for( uint16_t i = 0; i < deviceCount; i++ )
1019 uint16_t nameIdx = aStream.
ReadU16();
1034 uint8_t orientation = aStream.
ReadU8();
1040 std::map<std::string, std::string> nestedProps;
1041 uint8_t nestedType =
v2Prefix( aStream, aStrings, &nestedProps );
1045 THROW_IO_ERRORF( wxS(
"v2 drawn instance: unexpected nested type %d" ),
static_cast<int>( nestedType ) );
1049 block.
props.insert( nestedProps.begin(), nestedProps.end() );
1051 bool quarterTurn = ( orientation & 1 ) != 0;
1052 block.
w = quarterTurn ? bbox.
y2 - bbox.
y1 : bbox.
x2 - bbox.
x1;
1053 block.
h = quarterTurn ? bbox.
x2 - bbox.
x1 : bbox.
y2 - bbox.
y1;
1057 uint16_t valueIdx = aStream.
ReadU16();
1059 uint16_t implementationIdx = aStream.
ReadU16();
1062 block.
props[
"Implementation"] =
v2Resolve( aStrings, implementationIdx );
1064 uint16_t pinCount = aStream.
ReadU16();
1067 std::vector<ORCAD_PIN_INST> pinInsts;
1069 for( uint16_t i = 0; i < pinCount; i++ )
1070 pinInsts.push_back(
v2PinInst( aStream, aStrings ) );
1072 std::set<std::pair<int, int>> placedPoints;
1073 std::set<std::pair<int, int>> definitionPoints;
1076 placedPoints.emplace(
pin.x,
pin.y );
1079 definitionPoints.emplace(
pin.hotptX,
pin.hotptY );
1081 bool useDefinitionGeometry = placedPoints.size() <= 1 && definitionPoints.size() > 1;
1083 for(
size_t i = 0; i < pinInsts.size() && i < nested.
pins.size(); i++ )
1086 pin.name = nested.
pins[i].name;
1087 pin.portType = nested.
pins[i].portType;
1088 pin.x = useDefinitionGeometry ? block.
x1 + nested.
pins[i].hotptX - bbox.
x1 : pinInsts[i].x;
1089 pin.y = useDefinitionGeometry ? block.
y1 + nested.
pins[i].hotptY - bbox.
y1 : pinInsts[i].y;
1090 pin.noConnect = pinInsts[i].IsNoConnect();
1091 block.
pins.push_back( std::move(
pin ) );
1108 THROW_IO_ERRORF( wxS(
"v2 page: unexpected root type %d" ), (
int) type );
1130 uint16_t titleBlockCount = stream.
ReadU16();
1132 for( uint16_t i = 0; i < titleBlockCount; i++ )
1138 uint16_t allNetCount = stream.
ReadU16();
1140 for( uint16_t i = 0; i < allNetCount; i++ )
1146 uint16_t netGroupCount = stream.
ReadU16();
1148 for( uint16_t i = 0; i < netGroupCount; i++ )
1154 uint16_t memberCount = stream.
ReadU16();
1157 for( uint16_t j = 0; j < memberCount; j++ )
1163 uint16_t netmapCount = stream.
ReadU16();
1165 for( uint16_t i = 0; i < netmapCount; i++ )
1167 std::string netName = stream.
ReadLzt();
1168 uint32_t netId = stream.
ReadU32();
1170 page.
netmap[netId] = std::move( netName );
1173 uint16_t wireCount = stream.
ReadU16();
1175 for( uint16_t i = 0; i < wireCount; i++ )
1176 page.
wires.push_back(
v2Wire( stream, aStrings ) );
1178 uint16_t instanceCount = stream.
ReadU16();
1180 for( uint16_t i = 0; i < instanceCount; i++ )
1188 uint16_t portCount = stream.
ReadU16();
1190 for( uint16_t i = 0; i < portCount; i++ )
1196 uint16_t globalCount = stream.
ReadU16();
1198 for( uint16_t i = 0; i < globalCount; i++ )
1204 uint16_t offPageCount = stream.
ReadU16();
1206 for( uint16_t i = 0; i < offPageCount; i++ )
1212 uint16_t ercCount = stream.
ReadU16();
1214 for( uint16_t i = 0; i < ercCount; i++ )
1222 uint16_t busEntryCount = stream.
ReadU16();
1224 for( uint16_t i = 0; i < busEntryCount; i++ )
1230 uint16_t graphicCount = stream.
ReadU16();
1232 for( uint16_t i = 0; i < graphicCount; i++ )
1240 std::map<std::string, ORCAD_SYMBOL_DEF>& aSymbols,
bool aShortDisplayProp )
1245 std::map<std::string, std::string> props;
1246 uint8_t type =
v2Prefix( stream, aStrings, &props );
1248 def.
props = std::move( props );
1256 if( def.
name.empty() )
1259 auto existing = aSymbols.find( def.
name );
1261 if( existing == aSymbols.end() )
1262 aSymbols.emplace( def.
name, std::move( def ) );
1264 existing->second.variants.push_back( std::move( def ) );
1269 const std::vector<std::string>& aStrings )
1286 uint16_t viewCount = aStream.
ReadU16();
1290 for( uint16_t i = 0; i < viewCount; ++i )
1296 const ORCAD_WARN_FN& aWarn, std::map<std::string, ORCAD_SYMBOL_DEF>& aSymbols,
1297 std::map<std::string, ORCAD_PACKAGE>& aPackages )
1307 for(
int section = 0; section < 4; ++section )
1309 uint16_t groupCount = stream.
ReadU16();
1317 uint16_t variantCount = stream.
ReadU16();
1321 for( uint16_t variant = 0; variant < variantCount; ++variant )
1327 int typeId = stream.
ReadU8();
1329 stream.
ExpectByte( 0, wxS(
"legacy Cache entry pad" ) );
1338 auto existing = aPackages.find( pkg.
name );
1340 if( existing == aPackages.end() )
1341 aPackages.emplace( pkg.
name, std::move( pkg ) );
1343 existing->second.variants.push_back( std::move( pkg ) );
1347 std::map<std::string, std::string> props;
1348 uint8_t bodyType =
v2Prefix( stream, aStrings, &props );
1350 def.
props = std::move( props );
1357 if( !def.
name.empty() )
1359 auto existing = aSymbols.find( def.
name );
1361 if( existing == aSymbols.end() )
1363 aSymbols.emplace( def.
name, std::move( def ) );
1367 if( existing->second.generalFlags < 0 && def.
generalFlags >= 0 )
1370 existing->second.variants.push_back( std::move( def ) );
1378 if( !stream.
AtEnd() )
1387 aWarn( wxString::Format(
_(
"The legacy design cache could not be read past 0x%zx (%s); the "
1388 "remaining symbols fall back to placeholders." ),
1396 std::map<std::string, ORCAD_SYMBOL_DEF>& aSymbols,
1397 std::map<std::string, ORCAD_PACKAGE>& aPackages,
bool aShortDisplayProp )
1402 uint16_t partCount = stream.
ReadU16();
1404 std::vector<V2_PART_CELL> cells;
1406 for( uint16_t i = 0; i < partCount; i++ )
1407 cells.push_back(
v2PartCell( stream, aStrings ) );
1419 if( def.
name.empty() )
1422 auto existing = aSymbols.find( def.
name );
1424 if( existing == aSymbols.end() )
1425 aSymbols.emplace( def.
name, def );
1427 existing->second.variants.push_back( def );
1430 if( pkg.
refDes.empty() && !cell.refDesPrefix.empty() )
1431 pkg.
refDes = cell.refDesPrefix;
1434 if( pkg.
name.empty() )
1437 auto it = aPackages.find( pkg.
name );
1439 if( it == aPackages.end() )
1440 aPackages.emplace( pkg.
name, std::move( pkg ) );
1442 it->second.variants.push_back( std::move( pkg ) );
1455 uint16_t netCount = aStream.
ReadU16();
1458 for( uint16_t i = 0; i < netCount; i++ )
1460 if(
v2Prefix( aStream, aStrings ) != 0x43 )
1461 THROW_IO_ERROR( wxS(
"v2 occurrence scope: unexpected net record" ) );
1463 uint32_t occurrenceId = aStream.
ReadU32();
1469 uint16_t titleBlockCount = aStream.
ReadU16();
1472 for( uint16_t i = 0; i < titleBlockCount; i++ )
1474 if(
v2Prefix( aStream, aStrings ) != 0x52 )
1475 THROW_IO_ERROR( wxS(
"v2 occurrence scope: unexpected title-block record" ) );
1481 uint16_t occurrenceCount = aStream.
ReadU16();
1484 for( uint16_t i = 0; i < occurrenceCount; i++ )
1494 std::map<std::string, std::string> props;
1496 if(
v2Prefix( aStream, aStrings, &props ) != 0x42 )
1500 uint32_t targetDbId = aStream.
ReadU32();
1501 std::string child = aStream.
ReadLzt();
1502 std::string ref = aStream.
ReadLzt();
1503 uint16_t unitRefIdx = aStream.
ReadU16();
1505 uint16_t pinCount = aStream.
ReadU16();
1507 for( uint16_t i = 0; i < pinCount; i++ )
1509 uint8_t type =
v2Prefix( aStream, aStrings );
1511 if( type != 0x44 && type != 0x45 )
1520 if( !child.empty() )
1525 block.
scope = std::move( nested );
1526 aScope.
blocks.push_back( std::move( block ) );
1533 if( !props.empty() )
1534 aScope.
partProps[targetDbId] = std::move( props );
1536 if( unitRefIdx < aStrings.size() && !aStrings[unitRefIdx].empty() )
1538 aScope.
partUnitRefs[targetDbId] = aStrings[unitRefIdx];
1550 uint16_t powerCount = stream.
ReadU16();
1553 for( uint16_t i = 0; i < powerCount; ++i )
1555 if(
v2Prefix( stream, aStrings ) != 0x44 )
1556 THROW_IO_ERROR( wxS(
"v2 occurrence tree: unexpected power record" ) );
1576 if( aData.size() < 9 || (uint8_t) aData[0] != 0x42 || aData[5] || aData[6] || aData[7] || aData[8] )
1591 uint16_t powerCount = stream.
ReadU16();
1593 for( uint16_t i = 0; i < powerCount; ++i )
1604 aWarn( wxString::Format( wxS(
"The design occurrence tree could not be fully read (%s); "
1605 "reference designators fall back to the placed instances." ),
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
Bound shared parser recursion; entering a level above MAX_NESTING throws IO_ERROR.
The caller owns the buffer.
size_t Remaining() const
Bytes left; 0 when the cursor is at or past the end.
int PeekU8(size_t aAhead=0) const
– non-throwing lookahead ---------------------------------------------------—
bool AtPreamble(size_t aAhead=0) const
True when the 4 preamble bytes FF E4 5C 39 sit at cursor + aAhead.
uint8_t ReadU8()
– scalars (little-endian, bounds-checked, throw IO_ERROR on overrun) ----—
static constexpr size_t npos
Generic invalid offset sentinel.
std::vector< uint8_t > ReadBytes(size_t aCount)
– buffers / cursor ---------------------------------------------------------—
void Skip(size_t aCount)
Advance the cursor; throws IO_ERROR when aCount exceeds the remaining bytes.
std::string ReadLzt()
– strings ----------------------------------------------------------------—
bool PeekMatches(const uint8_t *aBytes, size_t aCount, size_t aAhead=0) const
Returns false if fewer than aCount bytes remain; does not advance the cursor.
void ExpectByte(uint8_t aValue, const wxString &aWhat)
Consume one byte and require the given value.
ReadStructure can recover from a body error when the prefix supplies a valid end offset.
std::map< std::string, std::string > PropsDict(const ORCAD_PREFIXES &aPrefixes) const
Resolve the short-prefix (nameIdx, valueIdx) pairs; empty names are dropped.
ORCAD_PREFIXES ReadPrefixes(int aExpectedType=-1, size_t aEnclosingEnd=ORCAD_STREAM::npos, size_t aLongPrefixCount=ORCAD_STREAM::npos)
aLongPrefixCount overrides the type depth; aEnclosingEnd bounds all stops.
ORCAD_READ_RESULT ReadStructure()
Skip unknown bodies.
V2_DISPLAY_PROP_SCOPE(bool aShort)
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_ERRORF(msg,...)
ORCAD_PAGE_SETTINGS OrcadParsePageSettings(ORCAD_STREAM &aStream)
Consumes 156 bytes; throws IO_ERROR on overrun.
static ORCAD_PRIMITIVE v2PrimBody(ORCAD_STREAM &aStream, uint8_t aType)
static ORCAD_PIN_INST v2PinInst(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_OCC_SCOPE v2ReadOccScope(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static std::string v2Resolve(const std::vector< std::string > &aStrings, uint16_t aIdx)
static ORCAD_OCC_SCOPE readOccScope(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static void v2Structure(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static void readOccurrence(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, ORCAD_OCC_SCOPE &aScope)
std::vector< std::string > OrcadParsePageOrderV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings)
Returns display order; throws IO_ERROR for invalid legacy framing.
static ORCAD_PORT_TYPE v2PortType(uint32_t aRaw)
void OrcadParseCacheV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &aWarn, std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols, std::map< std::string, ORCAD_PACKAGE > &aPackages)
Keep decoded entries if a framing error ends the legacy cache.
void OrcadParseOlbSymbolStreamV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings, std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols, bool aShortDisplayProp)
aShortDisplayProp selects the version 1 display-property layout.
ORCAD_RAW_PAGE OrcadParsePageV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &, bool aShortDisplayProp)
Legacy records have no stop offsets.
static ORCAD_DISPLAY_PROP v2DisplayProp(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_PACKAGE v2Package(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_SYMBOL_DEF v2LibSymbolDef(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, int aTypeId)
static ORCAD_DRAWN_INSTANCE v2DrawnInstance(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static void v2CheckCount(ORCAD_STREAM &aStream, uint32_t aCount)
static ORCAD_SYMBOL_DEF v2SymbolDef(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_WIRE v2Wire(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_GRAPHIC_INST v2GraphicInst(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_PRIMITIVE v2Primitive(ORCAD_STREAM &aStream)
static void v2ReadOccurrence(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, ORCAD_OCC_SCOPE &aScope)
static V2_PART_CELL v2PartCell(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
void OrcadParseOlbPackageStreamV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings, std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols, std::map< std::string, ORCAD_PACKAGE > &aPackages, bool aShortDisplayProp)
aShortDisplayProp selects the version 1 display-property layout.
static ORCAD_ALIAS v2Alias(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static uint8_t v2Prefix(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, std::map< std::string, std::string > *aProps=nullptr)
std::vector< std::string > OrcadParsePageOrder(const std::vector< char > &aData)
Returns display order.
ORCAD_OCC_SCOPE OrcadReadOccurrenceTree(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &aWarn)
Returns occurrence references and child scopes.
static std::vector< std::string > pageOrderBody(ORCAD_STREAM &aStream)
static ORCAD_PLACED_INSTANCE v2PlacedInstance(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static uint8_t readOccHeader(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, int aExpectType, std::map< std::string, std::string > *aProps=nullptr)
static bool v2SymbolPin(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings, ORCAD_SYMBOL_PIN &aOut)
ORCAD_OCC_SCOPE OrcadReadOccurrenceTreeV2(const std::vector< char > &aData, const std::vector< std::string > &aStrings)
Parse a short-prefix-only v2.0 Hierarchy stream without scan recovery.
static thread_local bool g_v2ShortDisplayProp
static std::vector< ORCAD_DISPLAY_PROP > v2DisplayPropList(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static ORCAD_DEVICE v2Device(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
std::vector< std::string > OrcadParseSchematicFolderOrder(const std::vector< char > &aData)
Unlisted Views storages can be stale.
ORCAD_RAW_PAGE OrcadParsePage(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &aWarn)
A body failure skips that structure.
static void v2CachePartCell(ORCAD_STREAM &aStream, const std::vector< std::string > &aStrings)
static void v2LibraryPartTail(ORCAD_STREAM &aStream, ORCAD_SYMBOL_DEF &aDef)
std::function< void(const wxString &aMsg)> ORCAD_WARN_FN
Coordinates use DBU with Y down.
@ ORCAD_PRIM_COMMENT_TEXT
@ ORCAD_PRIM_BITMAP
plain DIB (BITMAPINFOHEADER + pixels)
@ ORCAD_PRIM_SYMBOL_VECTOR
nested prefix-framed vector graphic
ORCAD_PORT_TYPE
Map unknown electrical type codes to PASSIVE.
@ ORCAD_ST_STH_IN_PAGES0
nested symbol body inside Graphic*Inst
@ ORCAD_ST_T0X10
scalar pin instance (absolute pos)
@ ORCAD_ST_PLACED_INSTANCE
@ ORCAD_ST_DRAWN_INSTANCE
hierarchical block instance
@ ORCAD_ST_ALIAS
net alias attached to a wire
@ ORCAD_ST_SYMBOL_DISPLAY_PROP
@ ORCAD_ST_T0X11
bus pin instance (absolute pos)
ORCAD_NET_GROUP OrcadReadT0x34Raw(ORCAD_STREAM &aStream)
T0x34 records have no prefixes; consume their fixed layout to preserve alignment.
ORCAD_BUS_ENTRY OrcadReadBusEntryBody(ORCAD_STREAM &aStream)
ORCAD_NET_GROUP OrcadReadT0x35Raw(ORCAD_STREAM &aStream)
T0x35 = the T0x34 raw layout followed by u16 n and 4 * n bytes.
The owning wire defines the connection.
int rotation
0..3 quarter turns
Axis-aligned box in OrCAD DBU; corner order as stored (not normalized).
One interface pin of a hierarchical block, at its absolute page position.
Device unit names omit the view suffix.
std::vector< std::string > pinNumbers
std::vector< bool > pinIgnore
Display positions use symbol coordinates; rotFont combines the font index and quarter turns.
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)
The inline LibraryPart defines the block interface; placed pin records supply absolute positions.
std::string name
intrinsic Name property used for flat-net scoping
int x1
block rectangle top-left, page DBU
std::vector< ORCAD_BLOCK_PIN > pins
std::vector< ORCAD_DISPLAY_PROP > displayProps
std::map< std::string, std::string > props
Free graphics use nested primitive coordinates.
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.
Repeated child folders have separate scopes and reference designators.
uint32_t targetDbId
type-12 drawn-instance dbId on the parent page
ORCAD_OCC_SCOPE scope
the child's occurrences under this path
std::string childFolder
child schematic folder name
Each scope holds the references and child blocks for one instantiation path.
std::vector< ORCAD_OCC_BLOCK > blocks
hierarchical block occurrences
std::map< uint32_t, std::map< std::string, std::string > > partProps
dbId -> occurrence properties
std::map< uint32_t, std::string > netNames
occurrence net id -> effective net name
std::map< uint32_t, std::string > partRefs
type-13 dbId -> occurrence refdes
std::map< uint32_t, std::string > partUnitRefs
dbId -> package unit reference
std::map< std::string, std::string > props
Part-level properties shared by every placement (Description, Tolerance, ...).
std::vector< ORCAD_DEVICE > devices
Dimensions use mils when isMetric is zero, otherwise micrometres.
Pin positions are absolute page connection points.
The placed box includes displayed text.
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
uint16_t unitIndex
zero-based package device index
std::map< std::string, std::string > props
short-prefix property pairs
bool mirror
orientation bit 2
std::string sourceLibrary
source library path from the placed-instance header
std::string value
resolved Part Value
std::vector< ORCAD_PIN_INST > pins
successfully parsed T0x10 records
Integer point in OrCAD DBU.
Prefix lengths supply structure bounds.
int typeId
ORCAD_ST value (u8 in the stream)
size_t end
offset right after the whole structure
Primitive byte lengths can include or exclude the eight-byte size envelope.
int fillStyle
0 solid, 1 none, 2 hatch pattern
std::string text
kind == TEXT
std::vector< ORCAD_PRIMITIVE > children
kind == GROUP, translated by (x1, y1)
std::vector< ORCAD_POINT > points
polygon/polyline/bezier vertices
std::optional< ORCAD_POINT > textBoundsStart
std::vector< uint8_t > data
kind == IMAGE: raw embedded payload
int lineStyle
0 solid, 1 dash, 2 dot, 3 dash-dot, 4 dash-dot-dot, 5 default
std::optional< ORCAD_POINT > start
arc start point
std::optional< ORCAD_POINT > end
arc end point
int lineWidth
Capture width enum: 0 thin, 1 medium, 2 wide, 3 default.
Wire IDs refer to netmap, which supplies the source net names.
std::vector< ORCAD_GRAPHIC_INST > ports
std::map< uint32_t, std::vector< std::string > > netAliases
every name recorded for a net db id
std::vector< ORCAD_GRAPHIC_INST > globals
placed power symbols
std::map< uint32_t, std::string > netmap
net db id -> net name
std::map< std::string, std::string > props
std::vector< ORCAD_WIRE > wires
uint32_t width
mils, or um when isMetric
std::vector< ORCAD_NET_GROUP > netGroups
bus net id -> member net ids
std::vector< ORCAD_DRAWN_INSTANCE > blocks
hierarchical blocks (detection only)
std::vector< ORCAD_PLACED_INSTANCE > instances
std::vector< ORCAD_GRAPHIC_INST > graphics
free comment text/shapes/images
std::vector< ORCAD_GRAPHIC_INST > offpage
off-page connectors
std::vector< ORCAD_GRAPHIC_INST > titleBlocks
std::vector< ORCAD_BUS_ENTRY > busEntries
std::string pageSize
page-size name string, e.g. "B"
std::vector< ORCAD_GRAPHIC_INST > ercObjects
saved design-rule-check markers
ORCAD_RECORD_VARIANT record
The bounding box occupies the final eight bytes before the next prefix stop.
std::string name
cache name, e.g. "C.Normal"
std::vector< ORCAD_SYMBOL_PIN > pins
std::vector< ORCAD_PRIMITIVE > primitives
std::map< std::string, std::string > props
int typeId
ORCAD_ST value.
std::optional< ORCAD_BBOX > bbox
symbol-space body box
int generalFlags
LibraryPart GeneralProperties flags (-1 = absent); bit0 = pin names visible, bit1 = pin text rotates ...
Pin coordinates use symbol space with Y down.
std::vector< ORCAD_DISPLAY_PROP > displayProps
The wire ID refers to the page net table.
bool isBus
true for structure type 21
std::vector< ORCAD_ALIAS > aliases
std::map< std::string, std::string > props
std::vector< std::string > viewNames
std::vector< ORCAD_SYMBOL_DEF > symbols
one per view, keyed positionally
wxString result
Test unit parsing edge cases and error handling.