diff --git a/common/io/altium/altium_binary_parser.cpp b/common/io/altium/altium_binary_parser.cpp index af2940f489..131e09a391 100644 --- a/common/io/altium/altium_binary_parser.cpp +++ b/common/io/altium/altium_binary_parser.cpp @@ -47,6 +47,11 @@ std::string FormatPath( const std::vector<std::string>& aVectorPath ) } +ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE() +{ +} + + ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath ) { // Open file @@ -91,6 +96,12 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath ) ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const void* aBuffer, size_t aLen ) +{ + InitFromBuffer( aBuffer, aLen ); +} + + +void ALTIUM_COMPOUND_FILE::InitFromBuffer( const void* aBuffer, size_t aLen ) { m_buffer.resize( aLen ); memcpy( m_buffer.data(), aBuffer, aLen ); @@ -106,10 +117,11 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const void* aBuffer, size_t aLen ) } -std::unique_ptr<ALTIUM_COMPOUND_FILE> -ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe ) +bool ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe, + ALTIUM_COMPOUND_FILE* aOutput ) { - wxCHECK( cfe.size >= 1, nullptr ); + wxCHECK( aOutput, false ); + wxCHECK( cfe.size >= 1, false ); size_t streamSize = cfe.size; wxMemoryBuffer buffer( streamSize ); @@ -130,14 +142,13 @@ ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe ) decodedPcbLibStream << zlibInputStream; wxStreamBuffer* outStream = decodedPcbLibStream.GetOutputStreamBuffer(); - - return std::make_unique<ALTIUM_COMPOUND_FILE>( outStream->GetBufferStart(), - outStream->GetIntPosition() ); + aOutput->InitFromBuffer( outStream->GetBufferStart(), outStream->GetIntPosition() ); + return true; } else if( buffer[0] == 0x00 ) { - return std::make_unique<ALTIUM_COMPOUND_FILE>( - reinterpret_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 ); + aOutput->InitFromBuffer( static_cast<uint8_t*>( buffer.GetData() ) + 1, streamSize - 1 ); + return true; } else { @@ -145,7 +156,7 @@ ALTIUM_COMPOUND_FILE::DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe ) buffer[0], buffer[1], buffer[2], buffer[3], buffer[4] ) ); } - return nullptr; + return false; } diff --git a/common/io/altium/altium_binary_parser.h b/common/io/altium/altium_binary_parser.h index 0318039ff0..4018c84414 100644 --- a/common/io/altium/altium_binary_parser.h +++ b/common/io/altium/altium_binary_parser.h @@ -70,6 +70,9 @@ class ALTIUM_COMPOUND_FILE friend class ALTIUM_PCB_COMPOUND_FILE; public: + /// Create an uninitialized file for two-step initialization (e.g. with InitFromBuffer) + ALTIUM_COMPOUND_FILE(); + /** * Open a CFB file. Constructor might throw an IO_ERROR. * @@ -90,9 +93,18 @@ public: ALTIUM_COMPOUND_FILE& operator=( const ALTIUM_COMPOUND_FILE& temp_obj ) = delete; ~ALTIUM_COMPOUND_FILE() = default; + /** + * Load a CFB file from memory; may throw an IO_ERROR. + * Data is copied. + * + * @param aBuffer data buffer + * @param aLen data length + */ + void InitFromBuffer( const void* aBuffer, size_t aLen ); + const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; } - std::unique_ptr<ALTIUM_COMPOUND_FILE> DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe ); + bool DecodeIntLibStream( const CFB::COMPOUND_FILE_ENTRY& cfe, ALTIUM_COMPOUND_FILE* aOutput ); const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const; diff --git a/pcbnew/pcb_io/altium/altium_pcb_compound_file.h b/pcbnew/pcb_io/altium/altium_pcb_compound_file.h index 3cc62043fd..f0f844f30e 100644 --- a/pcbnew/pcb_io/altium/altium_pcb_compound_file.h +++ b/pcbnew/pcb_io/altium/altium_pcb_compound_file.h @@ -32,6 +32,8 @@ class ALTIUM_PCB_COMPOUND_FILE : public ALTIUM_COMPOUND_FILE { public: + ALTIUM_PCB_COMPOUND_FILE() : ALTIUM_COMPOUND_FILE() {} + ALTIUM_PCB_COMPOUND_FILE( const wxString& aFilePath ); ALTIUM_PCB_COMPOUND_FILE( const void* aBuffer, size_t aLen ); ~ALTIUM_PCB_COMPOUND_FILE(); diff --git a/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp b/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp index e7b1e5d0fc..bcb5f23f26 100644 --- a/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp +++ b/pcbnew/pcb_io/altium/pcb_io_altium_designer.cpp @@ -197,14 +197,13 @@ void PCB_IO_ALTIUM_DESIGNER::loadAltiumLibrary( const wxString& aLibraryPath ) std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> pcbLibFiles = intCom->EnumDir( L"PCBLib" ); + for( const auto& [pcbLibName, pcbCfe] : pcbLibFiles ) { - auto decodedStream = intCom->DecodeIntLibStream( *pcbCfe ); - m_fplibFiles[aLibraryPath].push_back( - std::unique_ptr<ALTIUM_PCB_COMPOUND_FILE>( - static_cast<ALTIUM_PCB_COMPOUND_FILE*>(decodedStream.release()) - ) - ); + auto decodedStream = std::make_unique<ALTIUM_PCB_COMPOUND_FILE>(); + + if( intCom->DecodeIntLibStream( *pcbCfe, decodedStream.get() ) ) + m_fplibFiles[aLibraryPath].emplace_back( std::move( decodedStream ) ); } } }