altium: Don't use string concatenation for paths pointing in the compound file

* std::vector do not need to be split apart again
* supports backslash in footprint names
This commit is contained in:
Thomas Pointhuber 2022-02-19 16:45:55 +01:00
parent 6ce63d66e8
commit 8ef7252330
8 changed files with 144 additions and 105 deletions

View File

@ -27,12 +27,24 @@
#include <compoundfilereader.h> #include <compoundfilereader.h>
#include <ki_exception.h> #include <ki_exception.h>
#include <math/util.h> #include <math/util.h>
#include <numeric>
#include <sstream> #include <sstream>
#include <utf.h> #include <utf.h>
#include <wx/log.h> #include <wx/log.h>
#include <wx/translation.h> #include <wx/translation.h>
// Helper for debug logging
std::string FormatPath( const std::vector<std::string>& aVectorPath )
{
return std::accumulate( aVectorPath.cbegin(), aVectorPath.cend(), std::string(),
[]( const std::string& ss, const std::string& s )
{
return ss.empty() ? s : ss + '\\' + s;
} );
}
ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath ) ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
{ {
// Open file // Open file
@ -96,13 +108,12 @@ FindStreamSingleLevel( const CFB::CompoundFileReader& aReader,
} }
} }
} ); } );
return ret; return ret;
} }
const CFB::COMPOUND_FILE_ENTRY* const CFB::COMPOUND_FILE_ENTRY*
ALTIUM_COMPOUND_FILE::FindStream( const std::string& aStreamPath ) const ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath ) const
{ {
if( !m_reader ) if( !m_reader )
{ {
@ -111,24 +122,23 @@ ALTIUM_COMPOUND_FILE::FindStream( const std::string& aStreamPath ) const
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry(); const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry();
size_t startCh = 0; auto it = aStreamPath.cbegin();
size_t delimiter = aStreamPath.find( '\\', startCh ); while( currentDirEntry != nullptr )
while( delimiter != std::string::npos )
{ {
std::string directoryName = aStreamPath.substr( startCh, delimiter ); const std::string& name = *it;
currentDirEntry =
FindStreamSingleLevel( *m_reader.get(), currentDirEntry, directoryName, false );
if( currentDirEntry == nullptr )
{
return nullptr;
}
startCh = delimiter + 1; if( ++it == aStreamPath.cend() )
delimiter = aStreamPath.find( '\\', startCh ); {
return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, true );
}
else
{
currentDirEntry =
FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, false );
}
} }
std::string fileName = aStreamPath.substr( startCh, delimiter ); return nullptr;
return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, fileName, true );
} }

View File

@ -27,6 +27,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <numeric>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <math/vector2d.h> #include <math/vector2d.h>
@ -39,6 +40,13 @@ class CompoundFileReader;
struct COMPOUND_FILE_ENTRY; struct COMPOUND_FILE_ENTRY;
} // namespace CFB } // namespace CFB
/**
* Helper for debug logging (vector -> string)
* @param aVectorPath path
* @return path formated as string
*/
std::string FormatPath( const std::vector<std::string>& aVectorPath );
class ALTIUM_COMPOUND_FILE class ALTIUM_COMPOUND_FILE
{ {
@ -55,7 +63,7 @@ public:
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; } const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::string& aStreamPath ) const; const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
private: private:
std::unique_ptr<CFB::CompoundFileReader> m_reader; std::unique_ptr<CFB::CompoundFileReader> m_reader;

View File

@ -306,7 +306,7 @@ void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName )
void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{ {
const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( "Storage" ); const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Storage" } );
if( file == nullptr ) if( file == nullptr )
return; return;
@ -342,7 +342,7 @@ void SCH_ALTIUM_PLUGIN::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ) void SCH_ALTIUM_PLUGIN::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{ {
const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( "FileHeader" ); const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } );
if( file == nullptr ) if( file == nullptr )
THROW_IO_ERROR( "FileHeader not found" ); THROW_IO_ERROR( "FileHeader not found" );

View File

@ -77,25 +77,25 @@ BOARD* ALTIUM_CIRCUIT_MAKER_PLUGIN::Load( const wxString& aFileName, BOARD* aApp
// clang-format off // clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> mapping = { const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
{ ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" },
{ ALTIUM_PCB_DIR::ARCS6, "1CEEB63FB33847F8AFC4485F64735E\\" }, { ALTIUM_PCB_DIR::ARCS6, "1CEEB63FB33847F8AFC4485F64735E" },
{ ALTIUM_PCB_DIR::BOARD6, "96B09F5C6CEE434FBCE0DEB3E88E70\\" }, { ALTIUM_PCB_DIR::BOARD6, "96B09F5C6CEE434FBCE0DEB3E88E70" },
{ ALTIUM_PCB_DIR::BOARDREGIONS, "E3A544335C30403A991912052C936F\\" }, { ALTIUM_PCB_DIR::BOARDREGIONS, "E3A544335C30403A991912052C936F" },
{ ALTIUM_PCB_DIR::CLASSES6, "4F71DD45B09143988210841EA1C28D\\" }, { ALTIUM_PCB_DIR::CLASSES6, "4F71DD45B09143988210841EA1C28D" },
{ ALTIUM_PCB_DIR::COMPONENTS6, "F9D060ACC7DD4A85BC73CB785BAC81\\" }, { ALTIUM_PCB_DIR::COMPONENTS6, "F9D060ACC7DD4A85BC73CB785BAC81" },
{ ALTIUM_PCB_DIR::COMPONENTBODIES6, "44D9487C98CE4F0EB46AB6E9CDAF40\\" }, // or: A0DB41FBCB0D49CE8C32A271AA7EF5 ? { ALTIUM_PCB_DIR::COMPONENTBODIES6, "44D9487C98CE4F0EB46AB6E9CDAF40" }, // or: A0DB41FBCB0D49CE8C32A271AA7EF5 ?
{ ALTIUM_PCB_DIR::DIMENSIONS6, "068B9422DBB241258BA2DE9A6BA1A6\\" }, { ALTIUM_PCB_DIR::DIMENSIONS6, "068B9422DBB241258BA2DE9A6BA1A6" },
{ ALTIUM_PCB_DIR::FILLS6, "6FFE038462A940E9B422EFC8F5D85E\\" }, { ALTIUM_PCB_DIR::FILLS6, "6FFE038462A940E9B422EFC8F5D85E" },
{ ALTIUM_PCB_DIR::MODELS, "0DB009C021D946C88F1B3A32DAE94B\\" }, { ALTIUM_PCB_DIR::MODELS, "0DB009C021D946C88F1B3A32DAE94B" },
{ ALTIUM_PCB_DIR::NETS6, "35D7CF51BB9B4875B3A138B32D80DC\\" }, { ALTIUM_PCB_DIR::NETS6, "35D7CF51BB9B4875B3A138B32D80DC" },
{ ALTIUM_PCB_DIR::PADS6, "4F501041A9BC4A06BDBDAB67D3820E\\" }, { ALTIUM_PCB_DIR::PADS6, "4F501041A9BC4A06BDBDAB67D3820E" },
{ ALTIUM_PCB_DIR::POLYGONS6, "A1931C8B0B084A61AA45146575FDD3\\" }, { ALTIUM_PCB_DIR::POLYGONS6, "A1931C8B0B084A61AA45146575FDD3" },
{ ALTIUM_PCB_DIR::REGIONS6, "F513A5885418472886D3EF18A09E46\\" }, { ALTIUM_PCB_DIR::REGIONS6, "F513A5885418472886D3EF18A09E46" },
{ ALTIUM_PCB_DIR::RULES6, "C27718A40C94421388FAE5BD7785D7\\" }, { ALTIUM_PCB_DIR::RULES6, "C27718A40C94421388FAE5BD7785D7" },
{ ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,"BDAA2C70289849078C8EBEEC7F0848\\" }, { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6,"BDAA2C70289849078C8EBEEC7F0848" },
{ ALTIUM_PCB_DIR::TEXTS6, "A34BC67C2A5F408D8F377378C5C5E2\\" }, { ALTIUM_PCB_DIR::TEXTS6, "A34BC67C2A5F408D8F377378C5C5E2" },
{ ALTIUM_PCB_DIR::TRACKS6, "412A754DBB864645BF01CD6A80C358\\" }, { ALTIUM_PCB_DIR::TRACKS6, "412A754DBB864645BF01CD6A80C358" },
{ ALTIUM_PCB_DIR::VIAS6, "C87A685A0EFA4A90BEEFD666198B56\\" }, { ALTIUM_PCB_DIR::VIAS6, "C87A685A0EFA4A90BEEFD666198B56" },
{ ALTIUM_PCB_DIR::WIDESTRINGS6, "C1C6540EA23C48D3BF8F9A4ABB9D6D\\" } { ALTIUM_PCB_DIR::WIDESTRINGS6, "C1C6540EA23C48D3BF8F9A4ABB9D6D" }
}; };
// clang-format on // clang-format on

View File

@ -77,25 +77,25 @@ BOARD* ALTIUM_CIRCUIT_STUDIO_PLUGIN::Load( const wxString& aFileName, BOARD* aAp
// clang-format off // clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> mapping = { const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
{ ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" },
{ ALTIUM_PCB_DIR::ARCS6, "00C595EB90524FFC8C3BD9670020A2\\" }, { ALTIUM_PCB_DIR::ARCS6, "00C595EB90524FFC8C3BD9670020A2" },
{ ALTIUM_PCB_DIR::BOARD6, "88857D7F1DF64F7BBB61848C965636\\" }, { ALTIUM_PCB_DIR::BOARD6, "88857D7F1DF64F7BBB61848C965636" },
{ ALTIUM_PCB_DIR::BOARDREGIONS, "8957CF30F167408D9D263D23FE7C89\\" }, { ALTIUM_PCB_DIR::BOARDREGIONS, "8957CF30F167408D9D263D23FE7C89" },
{ ALTIUM_PCB_DIR::CLASSES6, "847EFBF87A5149B1AA326A52AD6357\\" }, { ALTIUM_PCB_DIR::CLASSES6, "847EFBF87A5149B1AA326A52AD6357" },
{ ALTIUM_PCB_DIR::COMPONENTS6, "465416896A15486999A39C643935D2\\" }, { ALTIUM_PCB_DIR::COMPONENTS6, "465416896A15486999A39C643935D2" },
{ ALTIUM_PCB_DIR::COMPONENTBODIES6, "1849D9B5512D452A93EABF4E40B122\\" }, // or B6AD30D75241498BA2536EBF001752 ? { ALTIUM_PCB_DIR::COMPONENTBODIES6, "1849D9B5512D452A93EABF4E40B122" }, // or B6AD30D75241498BA2536EBF001752 ?
{ ALTIUM_PCB_DIR::DIMENSIONS6, "16C81DBC13C447FF8B42A426677F3C\\" }, { ALTIUM_PCB_DIR::DIMENSIONS6, "16C81DBC13C447FF8B42A426677F3C" },
{ ALTIUM_PCB_DIR::FILLS6, "4E83BDC3253747F08E9006D7F57020\\" }, { ALTIUM_PCB_DIR::FILLS6, "4E83BDC3253747F08E9006D7F57020" },
{ ALTIUM_PCB_DIR::MODELS, "C0F7599ECC6A4D648DF5BB557679AF\\" }, { ALTIUM_PCB_DIR::MODELS, "C0F7599ECC6A4D648DF5BB557679AF" },
{ ALTIUM_PCB_DIR::NETS6, "D95A0DA2FE9047779A5194C127F30B\\" }, { ALTIUM_PCB_DIR::NETS6, "D95A0DA2FE9047779A5194C127F30B" },
{ ALTIUM_PCB_DIR::PADS6, "47D69BC5107A4B8DB8DAA23E39C238\\" }, { ALTIUM_PCB_DIR::PADS6, "47D69BC5107A4B8DB8DAA23E39C238" },
{ ALTIUM_PCB_DIR::POLYGONS6, "D7038392280E4E229B9D9B5426B295\\" }, { ALTIUM_PCB_DIR::POLYGONS6, "D7038392280E4E229B9D9B5426B295" },
{ ALTIUM_PCB_DIR::REGIONS6, "FFDDC21382BB42FE8A7D0C328D272C\\" }, { ALTIUM_PCB_DIR::REGIONS6, "FFDDC21382BB42FE8A7D0C328D272C" },
{ ALTIUM_PCB_DIR::RULES6, "48B2FA96DB7546818752B34373D6C6\\" }, { ALTIUM_PCB_DIR::RULES6, "48B2FA96DB7546818752B34373D6C6" },
{ ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "D5F54B536E124FB89E2D51B1121508\\" }, { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "D5F54B536E124FB89E2D51B1121508" },
{ ALTIUM_PCB_DIR::TEXTS6, "349ABBB211DB4F5B8AE41B1B49555A\\" }, { ALTIUM_PCB_DIR::TEXTS6, "349ABBB211DB4F5B8AE41B1B49555A" },
{ ALTIUM_PCB_DIR::TRACKS6, "530C20C225354B858B2578CAB8C08D\\" }, { ALTIUM_PCB_DIR::TRACKS6, "530C20C225354B858B2578CAB8C08D" },
{ ALTIUM_PCB_DIR::VIAS6, "CA5F5989BCDB404DA70A9D1D3D5758\\" }, { ALTIUM_PCB_DIR::VIAS6, "CA5F5989BCDB404DA70A9D1D3D5758" },
{ ALTIUM_PCB_DIR::WIDESTRINGS6, "87FBF0C5BC194B909FF42199450A76\\" } { ALTIUM_PCB_DIR::WIDESTRINGS6, "87FBF0C5BC194B909FF42199450A76" }
}; };
// clang-format on // clang-format on

View File

@ -77,26 +77,26 @@ BOARD* ALTIUM_DESIGNER_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendTo
// clang-format off // clang-format off
const std::map<ALTIUM_PCB_DIR, std::string> mapping = { const std::map<ALTIUM_PCB_DIR, std::string> mapping = {
{ ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" }, { ALTIUM_PCB_DIR::FILE_HEADER, "FileHeader" },
{ ALTIUM_PCB_DIR::ARCS6, "Arcs6\\" }, { ALTIUM_PCB_DIR::ARCS6, "Arcs6" },
{ ALTIUM_PCB_DIR::BOARD6, "Board6\\" }, { ALTIUM_PCB_DIR::BOARD6, "Board6" },
{ ALTIUM_PCB_DIR::BOARDREGIONS, "BoardRegions\\" }, { ALTIUM_PCB_DIR::BOARDREGIONS, "BoardRegions" },
{ ALTIUM_PCB_DIR::CLASSES6, "Classes6\\" }, { ALTIUM_PCB_DIR::CLASSES6, "Classes6" },
{ ALTIUM_PCB_DIR::COMPONENTS6, "Components6\\" }, { ALTIUM_PCB_DIR::COMPONENTS6, "Components6" },
{ ALTIUM_PCB_DIR::COMPONENTBODIES6, "ComponentBodies6\\" }, { ALTIUM_PCB_DIR::COMPONENTBODIES6, "ComponentBodies6" },
{ ALTIUM_PCB_DIR::DIMENSIONS6, "Dimensions6\\" }, { ALTIUM_PCB_DIR::DIMENSIONS6, "Dimensions6" },
{ ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION, "ExtendedPrimitiveInformation\\" }, { ALTIUM_PCB_DIR::EXTENDPRIMITIVEINFORMATION, "ExtendedPrimitiveInformation" },
{ ALTIUM_PCB_DIR::FILLS6, "Fills6\\" }, { ALTIUM_PCB_DIR::FILLS6, "Fills6" },
{ ALTIUM_PCB_DIR::MODELS, "Models\\" }, { ALTIUM_PCB_DIR::MODELS, "Models" },
{ ALTIUM_PCB_DIR::NETS6, "Nets6\\" }, { ALTIUM_PCB_DIR::NETS6, "Nets6" },
{ ALTIUM_PCB_DIR::PADS6, "Pads6\\" }, { ALTIUM_PCB_DIR::PADS6, "Pads6" },
{ ALTIUM_PCB_DIR::POLYGONS6, "Polygons6\\" }, { ALTIUM_PCB_DIR::POLYGONS6, "Polygons6" },
{ ALTIUM_PCB_DIR::REGIONS6, "Regions6\\" }, { ALTIUM_PCB_DIR::REGIONS6, "Regions6" },
{ ALTIUM_PCB_DIR::RULES6, "Rules6\\" }, { ALTIUM_PCB_DIR::RULES6, "Rules6" },
{ ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "ShapeBasedRegions6\\" }, { ALTIUM_PCB_DIR::SHAPEBASEDREGIONS6, "ShapeBasedRegions6" },
{ ALTIUM_PCB_DIR::TEXTS6, "Texts6\\" }, { ALTIUM_PCB_DIR::TEXTS6, "Texts6" },
{ ALTIUM_PCB_DIR::TRACKS6, "Tracks6\\" }, { ALTIUM_PCB_DIR::TRACKS6, "Tracks6" },
{ ALTIUM_PCB_DIR::VIAS6, "Vias6\\" }, { ALTIUM_PCB_DIR::VIAS6, "Vias6" },
{ ALTIUM_PCB_DIR::WIDESTRINGS6, "WideStrings6\\" } { ALTIUM_PCB_DIR::WIDESTRINGS6, "WideStrings6" }
}; };
// clang-format on // clang-format on
@ -144,11 +144,12 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
try try
{ {
std::string streamName = "Library\\Data"; const std::vector<std::string> streamName = { "Library", "Data" };
const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName ); const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile.FindStream( streamName );
if( libraryData == nullptr ) if( libraryData == nullptr )
{ {
THROW_IO_ERROR( wxString::Format( _( "File not found: '%s'." ), streamName ) ); THROW_IO_ERROR(
wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) );
} }
ALTIUM_PARSER parser( altiumLibFile, libraryData ); ALTIUM_PARSER parser( altiumLibFile, libraryData );
@ -167,12 +168,14 @@ void ALTIUM_DESIGNER_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames
if( parser.HasParsingError() ) if( parser.HasParsingError() )
{ {
THROW_IO_ERROR( wxString::Format( "%s stream was not parsed correctly", streamName ) ); THROW_IO_ERROR( wxString::Format( "%s stream was not parsed correctly",
FormatPath( streamName ) ) );
} }
if( parser.GetRemainingBytes() != 0 ) if( parser.GetRemainingBytes() != 0 )
{ {
THROW_IO_ERROR( wxString::Format( "%s stream is not fully parsed", streamName ) ); THROW_IO_ERROR(
wxString::Format( "%s stream is not fully parsed", FormatPath( streamName ) ) );
} }
} }
catch( CFB::CFBException& exception ) catch( CFB::CFBException& exception )

View File

@ -387,7 +387,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
{ true, ALTIUM_PCB_DIR::MODELS, { true, ALTIUM_PCB_DIR::MODELS,
[this, aFileMapping]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader ) [this, aFileMapping]( const ALTIUM_COMPOUND_FILE& aFile, auto fileHeader )
{ {
wxString dir( aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) ); std::vector<std::string> dir{ aFileMapping.at( ALTIUM_PCB_DIR::MODELS ) };
this->ParseModelsData( aFile, fileHeader, dir ); this->ParseModelsData( aFile, fileHeader, dir );
} }, } },
{ true, ALTIUM_PCB_DIR::COMPONENTBODIES6, { true, ALTIUM_PCB_DIR::COMPONENTBODIES6,
@ -493,8 +493,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
continue; continue;
} }
std::string mappedFile = mappedDirectory->second + "Header"; const std::vector<std::string> mappedFile{ mappedDirectory->second, "Header" };
const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile ); const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile );
if( file == nullptr ) if( file == nullptr )
{ {
@ -506,7 +505,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
if( reader.HasParsingError() ) if( reader.HasParsingError() )
{ {
wxLogError( _( "'%s' was not parsed correctly." ), mappedFile ); wxLogError( _( "'%s' was not parsed correctly." ), FormatPath( mappedFile ) );
continue; continue;
} }
@ -514,7 +513,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
if( reader.GetRemainingBytes() != 0 ) if( reader.GetRemainingBytes() != 0 )
{ {
wxLogError( _( "'%s' was not fully parsed." ), mappedFile ); wxLogError( _( "'%s' was not fully parsed." ), FormatPath( mappedFile ) );
continue; continue;
} }
} }
@ -539,17 +538,16 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
continue; continue;
} }
std::string mappedFile = mappedDirectory->second; std::vector<std::string> mappedFile{ mappedDirectory->second };
if( directory != ALTIUM_PCB_DIR::FILE_HEADER ) if( directory != ALTIUM_PCB_DIR::FILE_HEADER )
mappedFile += "Data"; mappedFile.emplace_back( "Data" );
const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile ); const CFB::COMPOUND_FILE_ENTRY* file = altiumPcbFile.FindStream( mappedFile );
if( file != nullptr ) if( file != nullptr )
fp( altiumPcbFile, file ); fp( altiumPcbFile, file );
else if( isRequired ) else if( isRequired )
wxLogError( _( "File not found: '%s'." ), mappedFile ); wxLogError( _( "File not found: '%s'." ), FormatPath( mappedFile ) );
} }
// fixup zone priorities since Altium stores them in the opposite order // fixup zone priorities since Altium stores them in the opposite order
@ -650,6 +648,7 @@ void ALTIUM_PCB::Parse( const ALTIUM_COMPOUND_FILE& altiumPcbFi
m_board->SetModified(); m_board->SetModified();
} }
FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile, FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile,
const wxString& aFootprintName ) const wxString& aFootprintName )
{ {
@ -669,11 +668,12 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
// ParseWideStrings6Data( altiumLibFile, unicodeStringsData ); // ParseWideStrings6Data( altiumLibFile, unicodeStringsData );
// } // }
std::string streamName = aFootprintName.ToStdString() + "\\Data"; const std::vector<std::string> streamName{ aFootprintName.ToStdString(), "Data" };
const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.FindStream( streamName ); const CFB::COMPOUND_FILE_ENTRY* footprintData = altiumLibFile.FindStream( streamName );
if( footprintData == nullptr ) if( footprintData == nullptr )
{ {
THROW_IO_ERROR( wxString::Format( _( "File not found: '%s'." ), streamName ) ); THROW_IO_ERROR(
wxString::Format( _( "File not found: '%s'." ), FormatPath( streamName ) ) );
} }
ALTIUM_PARSER parser( altiumLibFile, footprintData ); ALTIUM_PARSER parser( altiumLibFile, footprintData );
@ -685,7 +685,8 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
LIB_ID fpID = AltiumToKiCadLibID( "", footprintName ); // TODO: library name LIB_ID fpID = AltiumToKiCadLibID( "", footprintName ); // TODO: library name
footprint->SetFPID( fpID ); footprint->SetFPID( fpID );
std::string parametersStreamName = aFootprintName.ToStdString() + "\\Parameters"; const std::vector<std::string> parametersStreamName{ aFootprintName.ToStdString(),
"Parameters" };
const CFB::COMPOUND_FILE_ENTRY* parametersData = const CFB::COMPOUND_FILE_ENTRY* parametersData =
altiumLibFile.FindStream( parametersStreamName ); altiumLibFile.FindStream( parametersStreamName );
if( parametersData != nullptr ) if( parametersData != nullptr )
@ -698,10 +699,20 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
} }
else else
{ {
wxLogError( _( "File not found: '%s'." ), parametersStreamName ); wxLogError( _( "File not found: '%s'." ), FormatPath( parametersStreamName ) );
footprint->SetDescription( wxT( "" ) ); footprint->SetDescription( wxT( "" ) );
} }
const std::vector<std::string> extendedPrimitiveInformationStreamName{
aFootprintName.ToStdString(), "ExtendedPrimitiveInformation", "Data"
};
const CFB::COMPOUND_FILE_ENTRY* extendedPrimitiveInformationData =
altiumLibFile.FindStream( extendedPrimitiveInformationStreamName );
if( extendedPrimitiveInformationData != nullptr )
{
// TODO: implement
}
footprint->SetReference( wxT( "REF**" ) ); footprint->SetReference( wxT( "REF**" ) );
footprint->SetValue( footprintName ); footprint->SetValue( footprintName );
footprint->Reference().SetVisible( true ); // TODO: extract visibility information footprint->Reference().SetVisible( true ); // TODO: extract visibility information
@ -767,12 +778,14 @@ FOOTPRINT* ALTIUM_PCB::ParseFootprint( const ALTIUM_COMPOUND_FILE& altiumLibFile
if( parser.HasParsingError() ) if( parser.HasParsingError() )
{ {
THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ), streamName ) ); THROW_IO_ERROR( wxString::Format( wxT( "%s stream was not parsed correctly" ),
FormatPath( streamName ) ) );
} }
if( parser.GetRemainingBytes() != 0 ) if( parser.GetRemainingBytes() != 0 )
{ {
THROW_IO_ERROR( wxString::Format( wxT( "%s stream is not fully parsed" ), streamName ) ); THROW_IO_ERROR( wxString::Format( wxT( "%s stream is not fully parsed" ),
FormatPath( streamName ) ) );
} }
return footprint.release(); return footprint.release();
@ -1156,9 +1169,10 @@ void ALTIUM_PCB::ParseComponentsBodies6Data( const ALTIUM_COMPOUND_FILE& aAl
if( modelTuple == m_models.end() ) if( modelTuple == m_models.end() )
{ {
THROW_IO_ERROR( wxString::Format( wxT( "ComponentsBodies6 stream tries to access " wxLogError( wxT( "ComponentsBodies6 stream tries to access model id %s which does not "
"model id %s which does not exist" ), "exist" ),
elem.modelId ) ); elem.modelId );
continue;
} }
FOOTPRINT* footprint = m_components.at( elem.component ); FOOTPRINT* footprint = m_components.at( elem.component );
@ -1538,7 +1552,8 @@ void ALTIUM_PCB::ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPc
void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString& aRootDir ) const CFB::COMPOUND_FILE_ENTRY* aEntry,
const std::vector<std::string>& aRootDir )
{ {
if( m_progressReporter ) if( m_progressReporter )
m_progressReporter->Report( _( "Loading 3D models..." ) ); m_progressReporter->Report( _( "Loading 3D models..." ) );
@ -1583,7 +1598,9 @@ void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile
checkpoint(); checkpoint();
AMODEL elem( reader ); AMODEL elem( reader );
wxString stepPath = wxString::Format( aRootDir + wxT( "%d" ), idx ); std::vector<std::string> stepPath = aRootDir;
stepPath.emplace_back( std::to_string( idx ) );
bool validName = !elem.name.IsEmpty() && elem.name.IsAscii() && bool validName = !elem.name.IsEmpty() && elem.name.IsAscii() &&
wxString::npos == elem.name.find_first_of( invalidChars ); wxString::npos == elem.name.find_first_of( invalidChars );
wxString storageName = !validName ? wxString::Format( wxT( "model_%d" ), idx ) wxString storageName = !validName ? wxString::Format( wxT( "model_%d" ), idx )
@ -1592,12 +1609,12 @@ void ALTIUM_PCB::ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile
idx++; idx++;
const CFB::COMPOUND_FILE_ENTRY* stepEntry = const CFB::COMPOUND_FILE_ENTRY* stepEntry = aAltiumPcbFile.FindStream( stepPath );
aAltiumPcbFile.FindStream( stepPath.ToStdString() );
if( stepEntry == nullptr ) if( stepEntry == nullptr )
{ {
wxLogError( _( "File not found: '%s'. 3D-model not imported." ), stepPath ); wxLogError( _( "File not found: '%s'. 3D-model not imported." ),
FormatPath( stepPath ) );
continue; continue;
} }

View File

@ -136,7 +136,8 @@ private:
void ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void ParseDimensions6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry ); const CFB::COMPOUND_FILE_ENTRY* aEntry );
void ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void ParseModelsData( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry, const wxString& aRootDir ); const CFB::COMPOUND_FILE_ENTRY* aEntry,
const std::vector<std::string>& aRootDir );
void ParseNets6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void ParseNets6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry ); const CFB::COMPOUND_FILE_ENTRY* aEntry );
void ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile, void ParsePolygons6Data( const ALTIUM_COMPOUND_FILE& aAltiumPcbFile,