38#include <wx/translation.h>
40#include <compoundfilereader.h>
65 std::string
name = aName;
66 std::replace(
name.begin(),
name.end(),
'\x02',
'/' );
67 std::replace(
name.begin(),
name.end(),
'\x03',
':' );
75void assignPostImportUuids(
SCHEMATIC* aSchematic,
const std::string& aSourceId )
77 std::set<SCH_SCREEN*> screens;
78 size_t screenOrdinal = 0;
84 if( !screen || !screens.insert( screen ).second )
87 std::map<std::string, size_t> ordinals;
91 std::string uuid = item->m_Uuid.AsStdString();
93 if( uuid.size() > 14 && uuid[14] ==
'5' )
96 VECTOR2I position = item->GetPosition();
97 std::string role = std::to_string(
static_cast<int>( item->Type() ) ) +
":" + std::to_string( position.
x )
98 +
":" + std::to_string( position.
y );
99 size_t ordinal = ordinals[role]++;
100 const_cast<KIID&
>( item->m_Uuid ) =
101 KIID::FromName(
"orcad-import:" + aSourceId +
":post:" + std::to_string( screenOrdinal ) +
":"
102 + role +
":" + std::to_string( ordinal ) );
109std::vector<char> readStream(
const ALTIUM_COMPOUND_FILE& aFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry )
114 uint64_t size = reader.GetStreamSize( aEntry );
116 if( size > reader.GetBufferLen() )
119 std::vector<char> data(
static_cast<size_t>( size ) );
122 reader.ReadFile( aEntry, 0, data.data(), data.size() );
128bool isLongFramedPackageStream(
const std::vector<char>& aData )
130 if( aData.size() < 11 )
133 auto byte = [&](
size_t aOffset )
135 return static_cast<uint8_t
>( aData[aOffset] );
137 uint32_t bodyLength = byte( 3 ) |
static_cast<uint32_t
>( byte( 4 ) ) << 8 |
static_cast<uint32_t
>(
byte( 5 ) ) << 16
138 |
static_cast<uint32_t
>( byte( 6 ) ) << 24;
140 return byte( 7 ) == 0 && byte( 8 ) == 0 && byte( 9 ) == 0 && byte( 10 ) == 0 && bodyLength <= aData.size() - 11;
145std::vector<std::pair<std::string, const CFB::COMPOUND_FILE_ENTRY*>>
146enumChildren(
const ALTIUM_COMPOUND_FILE& aFile,
const CFB::COMPOUND_FILE_ENTRY* aParent,
bool aStreams )
148 std::vector<std::pair<std::string, const CFB::COMPOUND_FILE_ENTRY*>> out;
152 reader.EnumFiles( aParent, 1,
153 [&](
const CFB::COMPOUND_FILE_ENTRY* aEntry,
const CFB::utf16string&,
int ) ->
int
155 if( reader.IsStream( aEntry ) == aStreams )
165std::string lowerCopy(
const std::string& aText )
167 std::string out = aText;
169 std::transform( out.begin(), out.end(), out.begin(),
170 [](
unsigned char c )
172 return static_cast<char>( std::tolower( c ) );
180 const std::map<std::string, std::string>& aProperties,
bool& aMatched )
182 if( aScope.
partRefs.count( aOccurrence ) || aScope.
partProps.count( aOccurrence ) )
184 auto& target = aScope.
partProps[aOccurrence];
186 for(
const auto& [
name, value] : aProperties )
187 target.insert_or_assign(
name, value );
193 mergeCisProperties( block.
scope, aOccurrence, aProperties, aMatched );
205 const CFB::COMPOUND_FILE_ENTRY* variantStore = aFile.
FindStreamSingleLevel( cisStorage,
"VariantStore",
false );
210 const CFB::COMPOUND_FILE_ENTRY* bomStorage = aFile.
FindStreamSingleLevel( variantStore,
"BOM",
false );
215 const CFB::COMPOUND_FILE_ENTRY* bomData = aFile.
FindStreamSingleLevel( bomStorage,
"BOMDataStream",
true );
221 std::optional<std::string> requested;
225 auto request = aProperties->find(
"orcad_cis_variant" );
227 if( request != aProperties->end() )
228 requested = request->second;
233 if( selected.empty() )
236 auto applyVariantName = [&]( std::vector<ORCAD_RAW_PAGE>& aPages )
238 constexpr std::string_view placeholder =
"<Core Design>";
244 for(
auto& [
name, value] : titleBlock.
props )
248 while( ( offset = value.find( placeholder, offset ) ) != std::string::npos )
250 value.replace( offset, placeholder.size(), selected );
251 offset += selected.size();
258 applyVariantName( aDesign.
pages );
261 applyVariantName( pages );
264 applyVariantName( pages );
266 std::map<std::string, const CFB::COMPOUND_FILE_ENTRY*> variantEntries;
268 for(
const auto& [
name, entry] : enumChildren( aFile, bomStorage,
false ) )
269 variantEntries.emplace(
name, entry );
271 auto selectedEntry = variantEntries.find( selected );
273 if( selectedEntry == variantEntries.end() )
274 THROW_IO_ERROR(
_(
"The selected OrCAD CIS variant has no definition storage." ) );
276 const CFB::COMPOUND_FILE_ENTRY* definition = aFile.
FindStreamSingleLevel( selectedEntry->second, selected,
true );
279 THROW_IO_ERROR(
_(
"The selected OrCAD CIS variant has no definition stream." ) );
282 const CFB::COMPOUND_FILE_ENTRY* groupsStorage = aFile.
FindStreamSingleLevel( variantStore,
"Groups",
false );
283 std::map<std::string, const CFB::COMPOUND_FILE_ENTRY*> updateStreams;
284 std::map<std::string, std::string> schematicGroupNames;
288 for(
const auto& [groupName, groupEntry] : enumChildren( aFile, groupsStorage,
false ) )
290 schematicGroupNames.emplace( groupName, groupName );
292 if(
const CFB::COMPOUND_FILE_ENTRY* update =
295 updateStreams.emplace( groupName, update );
298 for(
const auto& [subgroupName, subgroupEntry] : enumChildren( aFile, groupEntry,
false ) )
300 schematicGroupNames.emplace( groupName +
"_" + subgroupName, groupName +
"-" + subgroupName );
302 if(
const CFB::COMPOUND_FILE_ENTRY* update =
305 updateStreams.emplace( groupName +
"_" + subgroupName, update );
311 for(
const std::string& groupName : selectedGroups )
313 if( groupName ==
"Common" || groupName ==
"CommonNI" )
316 auto stream = updateStreams.find( groupName );
318 if( stream == updateStreams.end() )
320 if( schematicGroupNames.count( groupName ) )
323 THROW_IO_ERROR(
_(
"The selected OrCAD CIS variant references an unknown property group." ) );
334 for(
const auto& [folderName, folderEntry] : enumChildren( aFile, viewsStorage,
false ) )
336 const CFB::COMPOUND_FILE_ENTRY* cisSchematic =
342 const CFB::COMPOUND_FILE_ENTRY* infoStorage =
348 for(
const auto& [streamName, streamEntry] : enumChildren( aFile, infoStorage,
true ) )
350 if( streamName ==
"SchematicInfoStream" )
355 for(
auto& [groupName, occurrences] : pageInfo )
357 auto& target = schematicInfo[groupName];
359 for(
auto& [occurrence, properties] : occurrences )
360 target.insert_or_assign( occurrence, std::move( properties ) );
366 for(
const std::string& selectedGroup : selectedGroups )
368 auto groupName = schematicGroupNames.find( selectedGroup );
370 if( groupName == schematicGroupNames.end() )
373 auto group = schematicInfo.find( groupName->second );
375 if(
group == schematicInfo.end() )
378 for(
const auto& [occurrence, properties] :
group->second )
380 bool matched =
false;
381 mergeCisProperties( aDesign.
occurrenceRoot, occurrence, properties, matched );
387 for(
const auto& [
name, value] : properties )
388 target.insert_or_assign(
name, value );
395 aReporter->
Report( wxString::Format(
_(
"Using OrCAD CIS variant '%s'." ), wxString::FromUTF8( selected ) ),
417 const CFB::COMPOUND_FILE_ENTRY* root = reader.GetRootEntry();
432 catch(
const CFB::CFBException& )
436 catch(
const std::exception& )
455 const CFB::COMPOUND_FILE_ENTRY* root = reader.GetRootEntry();
459 catch(
const std::exception& )
467 const std::map<std::string, UTF8>* aProperties )
469 wxASSERT( !aFileName.IsEmpty() && aSchematic );
476 std::string sourceId( sourceHash->ToUTF8() );
482 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr, wxS(
"Can't append to a schematic with no root!" ) );
483 rootSheet = aAppendToMe;
525 const CFB::COMPOUND_FILE_ENTRY* root = reader.GetRootEntry();
528 const CFB::COMPOUND_FILE_ENTRY* libraryEntry = cfbFile.
FindStreamSingleLevel( root,
"Library",
true );
532 THROW_IO_ERROR(
_(
"The file does not contain the 'Library' stream of an OrCAD "
533 "Capture design." ) );
543 if(
const CFB::COMPOUND_FILE_ENTRY* cacheEntry = cfbFile.
FindStreamSingleLevel( root,
"Cache",
true ) )
558 warnFn(
_(
"The design has no 'Cache' stream; placeholder symbols will be "
559 "synthesized for all parts." ) );
563 if(
const CFB::COMPOUND_FILE_ENTRY* packagesStorage =
566 for(
const auto& [streamName, entry] : enumChildren( cfbFile, packagesStorage,
true ) )
568 std::map<std::string, ORCAD_SYMBOL_DEF> extraSymbols;
569 std::map<std::string, ORCAD_PACKAGE> extraPackages;
573 std::vector<char> data = readStream( cfbFile, entry );
575 if( isV2 || !isLongFramedPackageStream( data ) )
588 warnFn( wxString::Format(
_(
"Package stream '%s' could not be parsed: %s" ),
589 wxString::FromUTF8( streamName ), e.
What() ) );
597 std::move( extraPackages ) );
602 const CFB::COMPOUND_FILE_ENTRY* viewsStorage = cfbFile.
FindStreamSingleLevel( root,
"Views",
false );
606 THROW_IO_ERROR(
_(
"The file does not contain a 'Views' storage; it is not a "
607 "supported OrCAD Capture design." ) );
610 std::vector<std::string> folders;
611 std::map<std::string, const CFB::COMPOUND_FILE_ENTRY*> folderEntries;
613 for(
const auto& [folderName, entry] : enumChildren( cfbFile, viewsStorage,
false ) )
615 if( folderEntries.emplace( folderName, entry ).second )
616 folders.push_back( folderName );
619 if(
const CFB::COMPOUND_FILE_ENTRY* directoryEntry =
624 std::vector<std::string> visibleFolders;
630 if( folderEntries.count( folder )
631 && std::find( visibleFolders.begin(), visibleFolders.end(), folder ) == visibleFolders.end() )
633 visibleFolders.push_back( std::move( folder ) );
637 folders = std::move( visibleFolders );
641 warnFn( wxString::Format(
_(
"The schematic folder directory could not be read (%s); all stored "
642 "folders are imported." ),
644 std::sort( folders.begin(), folders.end() );
649 std::sort( folders.begin(), folders.end() );
652 if( folders.empty() )
657 std::string rootFolder;
660 if( !schematicName.empty() )
662 for(
const std::string& folder : folders )
664 if( lowerCopy( folder ) == schematicName )
672 if( rootFolder.empty() )
677 warnFn(
_(
"The design does not name its root schematic; the first schematic "
678 "folder is used instead." ) );
682 warnFn( wxString::Format(
_(
"The design names '%s' as its root schematic, but no such "
683 "folder is present; the first schematic folder is used "
688 rootFolder = folders.front();
694 std::map<uint32_t, std::string> hierarchyLinks;
696 auto parseFolderPages = [&](
const std::string& aFolderName,
const CFB::COMPOUND_FILE_ENTRY* aFolderEntry,
697 std::vector<ORCAD_RAW_PAGE>& aOutPages )
699 const CFB::COMPOUND_FILE_ENTRY* pagesStorage =
702 std::vector<std::string> available;
703 std::map<std::string, const CFB::COMPOUND_FILE_ENTRY*> pageEntries;
707 for(
const auto& [pageName, entry] : enumChildren( cfbFile, pagesStorage,
true ) )
709 if( pageEntries.emplace( pageName, entry ).second )
710 available.push_back( pageName );
715 std::vector<std::string> ordered;
716 bool orderKnown =
false;
718 if(
const CFB::COMPOUND_FILE_ENTRY* orderEntry =
723 std::vector<char> orderData = readStream( cfbFile, orderEntry );
728 if( pageEntries.count( pageName )
729 && std::find( ordered.begin(), ordered.end(), pageName ) == ordered.end() )
731 ordered.push_back( pageName );
739 warnFn( wxString::Format(
_(
"The page display order for schematic folder '%s' could not be "
740 "read (%s); pages are imported in name order." ),
741 wxString::FromUTF8( aFolderName ), e.
What() ) );
748 for(
const std::string& pageName : available )
750 if( std::find( ordered.begin(), ordered.end(), pageName ) == ordered.end() )
751 ordered.push_back( pageName );
757 std::sort( ordered.begin(), ordered.end() );
760 for(
size_t pageIndex = 0; pageIndex < ordered.size(); ++pageIndex )
762 const std::string& pageName = ordered[pageIndex];
766 std::vector<char> pageData = readStream( cfbFile, pageEntries[pageName] );
772 aOutPages.push_back( std::move( page ) );
776 warnFn( wxString::Format(
_(
"Page '%s' could not be parsed and was "
778 wxString::FromUTF8( pageName ), e.
What() ) );
783 parseFolderPages( rootFolder, folderEntries[rootFolder], design.
pages );
786 if(
const CFB::COMPOUND_FILE_ENTRY* hierarchyEntry =
787 cfbFile.
FindStream( folderEntries[rootFolder], {
"Hierarchy",
"Hierarchy" } ) )
789 std::vector<char> hierarchyData = readStream( cfbFile, hierarchyEntry );
800 collectLinks( block.
scope );
808 if( design.
pages.empty() )
809 THROW_IO_ERROR(
_(
"No schematic pages could be read from the design." ) );
813 std::map<std::string, std::string> folderByLowerName;
815 for(
const auto& folderEntry : folderEntries )
816 folderByLowerName.emplace( lowerCopy( folderEntry.first ), folderEntry.first );
818 for(
const auto& [dbId, childName] : hierarchyLinks )
820 std::string key = lowerCopy( childName );
822 if( key == lowerCopy( rootFolder ) || design.
childFolderPages.count( key ) )
825 auto childIt = folderByLowerName.find( key );
827 if( childIt != folderByLowerName.end() )
828 parseFolderPages( childIt->second, folderEntries[childIt->second], design.
childFolderPages[key] );
831 for(
const std::string& folder : folders )
833 std::string key = lowerCopy( folder );
835 if( key == lowerCopy( rootFolder ) || design.
childFolderPages.count( key ) )
839 parseFolderPages( folder, folderEntries[folder], pages );
854 auto it = hierarchyLinks.find( block.
dbId );
856 if( it != hierarchyLinks.end() )
862 applyCisVariant( cfbFile, root, aProperties, design,
m_reporter );
864 catch(
const CFB::CFBException& e )
871 converter.
Convert( rootSheet );
881 assignPostImportUuids( aSchematic, sourceId );
905 const CFB::COMPOUND_FILE_ENTRY* root = reader.GetRootEntry();
907 const CFB::COMPOUND_FILE_ENTRY* libraryEntry = cfbFile.
FindStreamSingleLevel( root,
"Library",
true );
910 THROW_IO_ERROR(
_(
"The file is not an OrCAD Capture library (no 'Library' stream)." ) );
920 auto parseStream = [&](
const CFB::COMPOUND_FILE_ENTRY* aEntry,
const std::string& aStreamName,
921 bool aIsPackage,
bool aIsCache = false )
923 std::map<std::string, ORCAD_SYMBOL_DEF> extraSymbols;
924 std::map<std::string, ORCAD_PACKAGE> extraPackages;
928 std::vector<char> data = readStream( cfbFile, aEntry );
930 if( aIsPackage && ( isV2 || !isLongFramedPackageStream( data ) ) )
943 else if( aIsPackage )
952 catch(
const std::exception& e )
956 warnFn( wxString::Format(
_(
"The library stream '%s' could not be read and was skipped (%s)." ),
957 wxString::FromUTF8( aStreamName ), wxString::FromUTF8( e.what() ) ) );
962 std::move( extraPackages ) );
968 if(
const CFB::COMPOUND_FILE_ENTRY* cacheEntry = cfbFile.
FindStreamSingleLevel( root,
"Cache",
true ) )
970 parseStream( cacheEntry,
"Cache",
false,
true );
975 for(
const char* storageName : {
"Symbols",
"Packages" } )
977 bool isPackage = std::string( storageName ) ==
"Packages";
983 for(
const auto& [streamName, entry] : enumChildren( cfbFile, storage,
true ) )
986 if( !streamName.empty() && streamName.front() ==
'$' )
989 parseStream( entry, streamName, isPackage );
994 catch(
const CFB::CFBException& e )
1003 catch(
const std::exception& e )
1006 warnFn( wxString::Format(
_(
"The OrCAD library could not be fully parsed (%s); some "
1007 "symbols may be missing." ),
1008 wxString::FromUTF8( e.what() ) ) );
1014 std::vector<std::unique_ptr<LIB_SYMBOL>> built;
1017 built.emplace_back( symbol );
1019 return m_libCache[aLibraryPath] = std::move( built );
1024 const std::map<std::string, UTF8>* )
1026 for(
const std::unique_ptr<LIB_SYMBOL>& symbol :
loadOlbSymbols( aLibraryPath ) )
1027 aSymbolNameList.Add( symbol->GetName() );
1032 const std::map<std::string, UTF8>* )
1034 for(
const std::unique_ptr<LIB_SYMBOL>& symbol :
loadOlbSymbols( aLibraryPath ) )
1035 aSymbolList.push_back( symbol.get() );
1040 const std::map<std::string, UTF8>* )
1042 for(
const std::unique_ptr<LIB_SYMBOL>& symbol :
loadOlbSymbols( aLibraryPath ) )
1044 if( symbol->GetName() == aAliasName )
1045 return symbol.get();
const CFB::CompoundFileReader & GetCompoundFileReader() const
const CFB::COMPOUND_FILE_ENTRY * FindStreamSingleLevel(const CFB::COMPOUND_FILE_ENTRY *aEntry, const std::string aName, const bool aIsStream) const
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
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()
static KIID FromName(const std::string &aName)
Return a KIID derived from a name, the same name always gives the same KIID.
Define a library symbol object.
SCH_SHEET * Convert(SCH_SHEET *aRootSheet)
aRootSheet must have a screen and be registered on the schematic.
std::vector< LIB_SYMBOL * > BuildSymbolLibrary()
The caller owns the returned library symbols.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
double m_DashedLineGapRatio
double m_DashedLineDashRatio
Holds all the data relating to one schematic.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
SCHEMATIC_SETTINGS & Settings() const
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
Replace the top level sheets, rebuilding the hierarchy and connectivity around them.
SCH_SHEET_PATH & CurrentSheet() const
const std::vector< std::unique_ptr< LIB_SYMBOL > > & loadOlbSymbols(const wxString &aLibraryPath)
Parse an .OLB and build its KiCad library symbols, cached by library path.
std::map< wxString, std::vector< std::unique_ptr< LIB_SYMBOL > > > m_libCache
bool CanReadSchematicFile(const wxString &aFileName) const override
The .dsn extension also identifies SPECCTRA files.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
Base class for any item which can be embedded within the SCHEMATIC container class,...
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void UpdateAllScreenReferences() const
Update all the symbol references for this sheet path.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
void SyncUuidToScreen()
Take the identity of the screen this sheet owns.
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_IO_CANCELLED()
std::optional< wxString > fileHashMMH3(const wxString &aFilePath)
Calculates an MMH3 hash of a given file.
const std::vector< uint8_t > COMPOUND_FILE_HEADER
bool fileHasBinaryHeader(const wxString &aFilePath, const std::vector< uint8_t > &aHeader, size_t aOffset)
Check if a file starts with a defined binary header.
void OrcadMergeSymbolGeneralProperties(std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols, const std::map< std::string, ORCAD_SYMBOL_DEF > &aMetadataSymbols)
void OrcadMergeCacheStreams(std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols, std::map< std::string, ORCAD_PACKAGE > &aPackages, std::map< std::string, ORCAD_SYMBOL_DEF > &&aExtraSymbols, std::map< std::string, ORCAD_PACKAGE > &&aExtraPackages)
Existing symbols gain variants.
void OrcadParseSymbolStream(const std::vector< char > &aData, const std::vector< std::string > &aStrings, std::map< std::string, ORCAD_SYMBOL_DEF > &aSymbols)
Throws IO_ERROR for invalid framing or trailing bytes.
void OrcadParseCache(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)
The first entry is the default; later entries become variants.
void OrcadParsePackageStream(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)
Package streams contain counted PartCells and LibraryParts, followed by one Package.
std::map< uint32_t, std::map< std::string, std::string > > OrcadCisParsePropertyUpdates(const std::vector< char > &aData)
std::string OrcadCisSelectVariant(const std::vector< std::string > &aNames, const std::optional< std::string > &aRequested)
ORCAD_CIS_SCHEMATIC_INFO OrcadCisParseSchematicInfo(const std::vector< char > &aData)
std::vector< std::string > OrcadCisParseCountedList(const std::vector< char > &aData, uint8_t aSeparator)
std::map< std::string, std::map< uint32_t, ORCAD_CIS_PROPERTIES > > ORCAD_CIS_SCHEMATIC_INFO
std::pair< double, double > OrcadDashRatios(int aFormatVersionMajor)
ORCAD_LIBRARY_INFO OrcadParseLibrary(const std::vector< char > &aData)
The Library version selects the string-count width.
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.
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.
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.
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.
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.
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.
bool OrcadPageHasHierarchyBlocks(const ORCAD_RAW_PAGE &aPage)
True when the page contains hierarchical block instances (DrawnInstance, type 12).
std::function< void(const wxString &aMsg)> ORCAD_WARN_FN
Coordinates use DBU with Y down.
std::string OrcadNormalizeCfbName(const std::string &aName)
std::string OrcadNormalizeCfbName(const std::string &aName)
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Child-folder pages are instantiated for each occurrence, with that occurrence's references.
ORCAD_LIBRARY_INFO library
std::string sourceId
stable checksum of the input file
ORCAD_OCC_SCOPE occurrenceRoot
Occurrence references distinguish repeated placements of a child schematic.
std::map< std::string, ORCAD_SYMBOL_DEF > symbols
cache, keyed by cache name
std::map< std::string, std::vector< ORCAD_RAW_PAGE > > unreferencedFolderPages
Schematic folder pages not instantiated by the active hierarchy.
std::map< std::string, ORCAD_PACKAGE > packages
keyed by package name
std::string name
design (root schematic) name
std::map< std::string, std::vector< ORCAD_RAW_PAGE > > childFolderPages
Child schematic folder pages, keyed by lower-cased folder name; instantiated once per hierarchical bl...
std::vector< ORCAD_RAW_PAGE > pages
root schematic folder pages
The inline LibraryPart defines the block interface; placed pin records supply absolute positions.
std::string childName
child folder, when embedded
Free graphics use nested primitive coordinates.
std::map< std::string, std::string > props
std::vector< std::string > strings
global string table
std::string schematicName
root schematic folder name
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 > partRefs
type-13 dbId -> occurrence refdes
Wire IDs refer to netmap, which supplies the source net names.
size_t sourcePageCount
pages in the OrCAD folder
size_t sourcePageNumber
1-based within the OrCAD folder
std::vector< ORCAD_DRAWN_INSTANCE > blocks
hierarchical blocks (detection only)
VECTOR2< int32_t > VECTOR2I