altium: Fix Compound File Reader which returned wrong entries

It was possible that we confuse multiple files with the same name. This should not be that relevant for board and schematic import, but is important for library import!
This commit is contained in:
Thomas Pointhuber 2022-01-05 23:35:42 +01:00
parent 05e7f59550
commit c6504628f0
3 changed files with 48 additions and 33 deletions

View File

@ -32,39 +32,54 @@
#include <wx/log.h> #include <wx/log.h>
#include <wx/translation.h> #include <wx/translation.h>
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::CompoundFileReader& aReader, static const CFB::COMPOUND_FILE_ENTRY*
const char* aStreamName ) FindStreamSingleLevel( const CFB::CompoundFileReader& aReader,
const CFB::COMPOUND_FILE_ENTRY* aEntry, const std::string aName,
const bool aIsStream )
{ {
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr; const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
aReader.EnumFiles( aReader.GetRootEntry(), -1,
[&]( const CFB::COMPOUND_FILE_ENTRY* aEntry, const CFB::utf16string& aU16dir, aReader.EnumFiles( aEntry, 1,
int level ) -> void [&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
{ int level ) -> void
if( aReader.IsStream( aEntry ) ) {
{ if( aReader.IsStream( entry ) == aIsStream )
std::string name = UTF16ToUTF8( aEntry->name ); {
if( aU16dir.length() > 0 ) std::string name = UTF16ToUTF8( entry->name );
{ if( name == aName.c_str() )
std::string dir = UTF16ToUTF8( aU16dir.c_str() ); {
if( strncmp( aStreamName, dir.c_str(), dir.length() ) == 0 ret = entry;
&& aStreamName[dir.length()] == '\\' }
&& strcmp( aStreamName + dir.length() + 1, name.c_str() ) == 0 ) }
{ } );
ret = aEntry;
}
}
else
{
if( strcmp( aStreamName, name.c_str() ) == 0 )
{
ret = aEntry;
}
}
}
} );
return ret; return ret;
} }
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::CompoundFileReader& aReader,
const std::string aStreamName )
{
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = aReader.GetRootEntry();
size_t startCh = 0;
size_t delimiter = aStreamName.find( '\\', startCh );
while( delimiter != std::string::npos )
{
std::string directoryName = aStreamName.substr( startCh, delimiter );
currentDirEntry = FindStreamSingleLevel( aReader, currentDirEntry, directoryName, false );
if( currentDirEntry == nullptr )
{
return nullptr;
}
startCh = delimiter + 1;
delimiter = aStreamName.find( '\\', startCh );
}
std::string fileName = aStreamName.substr( startCh, delimiter );
return FindStreamSingleLevel( aReader, currentDirEntry, fileName, true );
}
ALTIUM_PARSER::ALTIUM_PARSER( const CFB::CompoundFileReader& aReader, ALTIUM_PARSER::ALTIUM_PARSER( const CFB::CompoundFileReader& aReader,
const CFB::COMPOUND_FILE_ENTRY* aEntry ) const CFB::COMPOUND_FILE_ENTRY* aEntry )

View File

@ -40,8 +40,8 @@ struct COMPOUND_FILE_ENTRY;
} // namespace CFB } // namespace CFB
// Helper method to find file inside compound file // Helper method to find file inside compound file
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::CompoundFileReader& aReader,
const CFB::CompoundFileReader& aReader, const char* aStreamName ); const std::string aStreamName );
class ALTIUM_PARSER class ALTIUM_PARSER

View File

@ -480,7 +480,7 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
std::string mappedFile = mappedDirectory->second + "Header"; std::string mappedFile = mappedDirectory->second + "Header";
const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile.c_str() ); const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile );
if( file == nullptr ) if( file == nullptr )
{ {
continue; continue;
@ -528,7 +528,7 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
if( directory != ALTIUM_PCB_DIR::FILE_HEADER ) if( directory != ALTIUM_PCB_DIR::FILE_HEADER )
mappedFile += "Data"; mappedFile += "Data";
const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile.c_str() ); const CFB::COMPOUND_FILE_ENTRY* file = FindStream( aReader, mappedFile );
if( file != nullptr ) if( file != nullptr )
fp( aReader, file ); fp( aReader, file );
@ -1445,7 +1445,7 @@ void ALTIUM_PCB::ParseModelsData( const CFB::CompoundFileReader& aReader,
idx++; idx++;
const CFB::COMPOUND_FILE_ENTRY* stepEntry = FindStream( aReader, stepPath.c_str() ); const CFB::COMPOUND_FILE_ENTRY* stepEntry = FindStream( aReader, stepPath.ToStdString() );
if( stepEntry == nullptr ) if( stepEntry == nullptr )
{ {