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/translation.h>
const CFB::COMPOUND_FILE_ENTRY* FindStream( const CFB::CompoundFileReader& aReader,
const char* aStreamName )
static const CFB::COMPOUND_FILE_ENTRY*
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;
aReader.EnumFiles( aReader.GetRootEntry(), -1,
[&]( const CFB::COMPOUND_FILE_ENTRY* aEntry, const CFB::utf16string& aU16dir,
int level ) -> void
{
if( aReader.IsStream( aEntry ) )
{
std::string name = UTF16ToUTF8( aEntry->name );
if( aU16dir.length() > 0 )
{
std::string dir = UTF16ToUTF8( aU16dir.c_str() );
if( strncmp( aStreamName, dir.c_str(), dir.length() ) == 0
&& aStreamName[dir.length()] == '\\'
&& strcmp( aStreamName + dir.length() + 1, name.c_str() ) == 0 )
{
ret = aEntry;
}
}
else
{
if( strcmp( aStreamName, name.c_str() ) == 0 )
{
ret = aEntry;
}
}
}
} );
aReader.EnumFiles( aEntry, 1,
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
int level ) -> void
{
if( aReader.IsStream( entry ) == aIsStream )
{
std::string name = UTF16ToUTF8( entry->name );
if( name == aName.c_str() )
{
ret = entry;
}
}
} );
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,
const CFB::COMPOUND_FILE_ENTRY* aEntry )

View File

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

View File

@ -480,7 +480,7 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
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 )
{
continue;
@ -528,7 +528,7 @@ void ALTIUM_PCB::Parse( const CFB::CompoundFileReader& aReader,
if( directory != ALTIUM_PCB_DIR::FILE_HEADER )
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 )
fp( aReader, file );
@ -1445,7 +1445,7 @@ void ALTIUM_PCB::ParseModelsData( const CFB::CompoundFileReader& aReader,
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 )
{