41 if(
T* record = std::get_if<T>( &aResult.
record ) )
43 aTarget.push_back( std::move( *record ) );
56 for( uint16_t i = 0; i < count; i++ )
59 takeRecord(
result, aTarget );
86 uint16_t count = stream.
ReadU16();
88 for( uint16_t i = 0; i < count; i++ )
96 for( uint16_t i = 0; i < count; i++ )
102 uint16_t memberCount = reader.
ReadCount();
104 for( uint16_t j = 0; j < memberCount; j++ )
113 uint16_t count = stream.
ReadU16();
115 for( uint16_t i = 0; i < count; i++ )
120 for( uint16_t i = 0; i < count; i++ )
125 uint16_t count = stream.
ReadU16();
127 for( uint16_t i = 0; i < count; i++ )
129 std::string netName = stream.
ReadLzt();
130 uint32_t netId = stream.
ReadU32();
132 page.
netmap[netId] = std::move( netName );
135 readStructureList( reader, page.
wires );
140 for( uint16_t i = 0; i < count; i++ )
148 readStructureList( reader, page.
ports );
153 for( uint16_t i = 0; i < count; i++ )
162 for( uint16_t i = 0; i < count; i++ )
171 readStructureList( reader, page.
graphics );
174 THROW_IO_ERROR( wxS(
"OrCAD page stream: page body exceeds its outer stop" ) );
185 uint16_t count = aStream.
ReadU16();
187 std::vector<std::string> names;
188 names.reserve( count );
190 for( uint16_t i = 0; i < count; i++ )
191 names.push_back( aStream.
ReadLzt() );
193 std::reverse( names.begin(), names.end() );
216 uint16_t count = stream.
ReadU16();
217 std::vector<std::string> names;
218 names.reserve( count );
220 for( uint16_t i = 0; i < count; ++i )
222 names.push_back( stream.
ReadLzt() );
225 THROW_IO_ERROR( wxS(
"OrCAD Views Directory: invalid folder record" ) );
230 if( !stream.
AtEnd() )
239 std::map<std::string, std::string>* aProps =
nullptr )
246 return static_cast<uint8_t
>( prefixes.
typeId );
256 std::map<std::string, std::string> props;
259 uint32_t occurrenceId = stream.
ReadU32();
260 uint32_t blockObjectId = stream.
ReadU32();
264 stream.
ExpectByte( 0x42, wxS(
"occurrence inner marker" ) );
270 std::string child = stream.
ReadLzt();
271 std::string ref = stream.
ReadLzt();
277 for( uint16_t i = 0; i < pinCount; i++ )
291 block.
scope = std::move( nested );
292 aScope.
blocks.push_back( std::move( block ) );
297 aScope.
partRefs[blockObjectId] = ref;
300 aScope.
partProps[blockObjectId] = std::move( props );
302 if( !unitRef.empty() )
303 aScope.
partUnitRefs[blockObjectId] = std::move( unitRef );
321 for( uint16_t i = 0; i < netCount; i++ )
324 uint32_t occurrenceId = stream.
ReadU32();
329 uint16_t titleBlockCount = aReader.
ReadCount();
331 for( uint16_t i = 0; i < titleBlockCount; i++ )
341 uint32_t globalCount = stream.
ReadU32();
343 for( uint32_t i = 0; i < globalCount; i++ )
359 for( uint16_t i = 0; i < occCount; i++ )
373 uint16_t powerCount = aReader.
ReadCount();
375 for( uint16_t i = 0; i < powerCount; ++i )
405 if( aData.size() < 9 || (uint8_t) aData[0] != 0x42 || aData[5] || aData[6] || aData[7] || aData[8] )
420 aWarn( wxString::Format( wxS(
"The design occurrence tree could not be fully read (%s); "
421 "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.
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.
void Skip(size_t aCount)
Advance the cursor; throws IO_ERROR when aCount exceeds the remaining bytes.
std::string ReadLzt()
– strings ----------------------------------------------------------------—
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.
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.
const ORCAD_DIALECT & Dialect() const
uint32_t ReadStrIdx()
A string-table index in the dialect's width.
std::string Resolve(uint32_t aIndex) const
String-table lookup; returns "" for out-of-range indices and the legacy sentinel.
uint16_t ReadCount()
A u16 list count.
ORCAD_READ_RESULT ReadStructure()
Always resumes at the prefix end, skipping unknown bodies and undecoded trailers.
#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_OCC_SCOPE readOccScope(ORCAD_STRUCT_READER &aReader)
static void readOccurrence(ORCAD_STRUCT_READER &aReader, ORCAD_OCC_SCOPE &aScope)
ORCAD_OCC_SCOPE OrcadReadOccurrenceTree(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &aWarn, ORCAD_DIALECT aDialect)
Returns occurrence references and child scopes.
ORCAD_RAW_PAGE OrcadParsePage(const std::vector< char > &aData, const std::vector< std::string > &aStrings, const ORCAD_WARN_FN &aWarn, ORCAD_DIALECT aDialect)
A modern body failure skips that structure.
static ORCAD_OCC_SCOPE readOccTree(ORCAD_STRUCT_READER &aReader)
static std::vector< std::string > pageOrderBody(ORCAD_STREAM &aStream)
std::vector< std::string > OrcadParseSchematicFolderOrder(const std::vector< char > &aData)
Unlisted Views storages can be stale.
std::vector< std::string > OrcadParsePageOrder(const std::vector< char > &aData, ORCAD_DIALECT aDialect)
Returns display order.
static uint8_t readOccHeader(ORCAD_STRUCT_READER &aReader, int aExpectType, std::map< std::string, std::string > *aProps=nullptr)
std::function< void(const wxString &aMsg)> ORCAD_WARN_FN
Coordinates use DBU with Y down.
ORCAD_NET_GROUP OrcadReadT0x34Raw(ORCAD_STREAM &aStream)
T0x34 records have no prefixes; consume their fixed layout to preserve alignment.
ORCAD_NET_GROUP OrcadReadT0x35Raw(ORCAD_STREAM &aStream)
T0x35 = the T0x34 raw layout followed by u16 n and 4 * n bytes.
Legacy (pre-v3) files have short prefixes only, u16 string indices with a 0xFFFF sentinel and nested ...
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, uint32_t > partOccurrenceIds
dbId -> part occurrence id
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
Prefix lengths supply structure bounds.
int typeId
ORCAD_ST value (u8 in the stream)
size_t end
offset right after the whole structure
One parsed 'Views/<folder>/Pages/<page>' stream, raw structure lists in stream order.
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
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"
ORCAD_PAGE_SETTINGS settings
std::vector< ORCAD_GRAPHIC_INST > ercObjects
saved design-rule-check markers
ORCAD_RECORD_VARIANT record
wxString result
Test unit parsing edge cases and error handling.