40#include <wx/txtstrm.h> 
   41#include <wx/wfstream.h> 
   42#include <wx/mstream.h> 
   43#include <wx/zipstrm.h> 
   54    std::map<wxString, EASYEDAPRO::BLOB>                            
m_Blobs;
 
   55    std::map<wxString, std::multimap<wxString, EASYEDAPRO::POURED>> 
m_Poured;
 
 
   73    if( aFileName.Lower().EndsWith( wxS( 
".epro" ) ) )
 
   77    else if( aFileName.Lower().EndsWith( wxS( 
".zip" ) ) )
 
   79        std::shared_ptr<wxZipEntry> entry;
 
   80        wxFFileInputStream          in( aFileName );
 
   81        wxZipInputStream            
zip( in );
 
   86        while( entry.reset( 
zip.GetNextEntry() ), entry.get() != NULL )
 
   88            wxString 
name = entry->GetName();
 
   90            if( 
name == wxS( 
"project.json" ) )
 
 
  102                                     const std::map<std::string, UTF8>* aProperties, 
PROJECT* aProject )
 
  110        m_board->SetFileName( aFileName );
 
  124    wxFileName fname( aFileName );
 
  127    if( fname.GetExt() == wxS( 
"epro" ) || fname.GetExt() == wxS( 
"zip" ) )
 
  135            pcbToLoad = wxString::FromUTF8( 
m_props->at( 
"pcb_id" ) );
 
  139            std::map<wxString, wxString> prjPcbNames = 
project.at( 
"pcbs" );
 
  141            if( prjPcbNames.size() == 1 )
 
  143                pcbToLoad = prjPcbNames.begin()->first;
 
  150                if( chosen.size() > 0 )
 
  151                    pcbToLoad = chosen[0].PCBId;
 
  155        if( pcbToLoad.empty() )
 
  163        auto cb = [&]( 
const wxString& 
name, 
const wxString& pcbUuid, wxInputStream& 
zip ) -> 
bool 
  165            if( !
name.EndsWith( wxS( 
".epcb" ) ) )
 
  168            if( pcbUuid != pcbToLoad )
 
  171            std::vector<nlohmann::json>* pcbLines = 
nullptr;
 
  173            std::vector<std::vector<nlohmann::json>> lineBlocks =
 
  176            if( lineBlocks.empty() )
 
  179            if( lineBlocks.size() > 1 )
 
  181                for( std::vector<nlohmann::json>& block : lineBlocks )
 
  184                    nlohmann::json headData;
 
  186                    for( 
const nlohmann::json& line : block )
 
  188                        if( line.size() < 2 )
 
  191                        if( !line.at( 0 ).is_string() )
 
  194                        wxString lineType = line.at( 0 ).get<wxString>();
 
  196                        if( lineType == wxS( 
"DOCTYPE" ) )
 
  198                            if( !line.at( 1 ).is_string() )
 
  201                            docType = line.at( 1 ).get<wxString>();
 
  203                        else if( lineType == wxS( 
"HEAD" ) )
 
  205                            if( !line.at( 1 ).is_object() )
 
  208                            headData = line.at( 1 );
 
  212                    if( docType == wxS( 
"FOOTPRINT" ) )
 
  214                        wxString fpUuid = headData.at( 
"uuid" );
 
  215                        wxString fpTitle = headData.at( 
"title" );
 
  227                    else if( docType == wxS( 
"PCB" ) )
 
  234            if( pcbLines == 
nullptr )
 
  235                pcbLines = &lineBlocks[0];
 
  237            wxString           boardKey = pcbUuid + wxS( 
"_0" );
 
  238            wxScopedCharBuffer cb = boardKey.ToUTF8();
 
  239            wxString           boardPouredKey = wxBase64Encode( cb.data(), cb.length() );
 
  241            const std::multimap<wxString, EASYEDAPRO::POURED>& boardPoured =
 
 
  264                                            const wxString& aLibraryPath, 
bool aBestEfforts,
 
  265                                            const std::map<std::string, UTF8>* aProperties )
 
  267    wxFileName fname( aLibraryPath );
 
  269    if( fname.GetExt() == wxS( 
"efoo" ) )
 
  271        wxFFileInputStream ffis( aLibraryPath );
 
  272        wxTextInputStream  txt( ffis, wxS( 
" " ), wxConvUTF8 );
 
  274        while( ffis.CanRead() )
 
  276            wxString line = txt.ReadLine();
 
  278            if( !line.Contains( wxS( 
"ATTR" ) ) )
 
  281            nlohmann::json js = nlohmann::json::parse( line );
 
  282            if( js.at( 0 ) == 
"ATTR" && js.at( 7 ) == 
"Footprint" )
 
  284                aFootprintNames.Add( js.at( 8 ).get<wxString>() );
 
  288    else if( fname.GetExt() == wxS( 
"elibz" ) || fname.GetExt() == wxS( 
"epro" )
 
  289             || fname.GetExt() == wxS( 
"zip" ) )
 
  292        std::map<wxString, nlohmann::json> footprintMap = 
project.at( 
"footprints" );
 
  294        for( 
auto& [key, value] : footprintMap )
 
  298            if( value.contains( 
"display_title" ) )
 
  299                title = value.at( 
"display_title" ).get<wxString>();
 
  301                title = value.at( 
"title" ).get<wxString>();
 
  303            aFootprintNames.Add( title );
 
 
  310                                                const nlohmann::json& aProject )
 
  318    wxFileName            fname( aProjectPath );
 
  321    std::map<wxString, std::unique_ptr<FOOTPRINT>> 
result;
 
  323    auto cb = [&]( 
const wxString& 
name, 
const wxString& baseName, wxInputStream& 
zip ) -> 
bool 
  325        if( !
name.EndsWith( wxS( 
".efoo" ) ) && !
name.EndsWith( wxS( 
".eblob" ) )
 
  326            && !
name.EndsWith( wxS( 
".ecop" ) ) )
 
  333        if( 
name.EndsWith( wxS( 
".efoo" ) ) )
 
  335            nlohmann::json fpData = aProject.at( 
"footprints" ).at( baseName );
 
  336            wxString       fpTitle = fpData.at( 
"title" );
 
  348        else if( 
name.EndsWith( wxS( 
".eblob" ) ) )
 
  350            for( 
const nlohmann::json& line : lines )
 
  352                if( line.at( 0 ) == 
"BLOB" )
 
  361            for( 
const nlohmann::json& line : lines )
 
  363                if( line.at( 0 ) == 
"POURED" )
 
  365                    if( !line.at( 2 ).is_string() )
 
 
  380                                             const wxString& aFootprintName, 
bool aKeepUUID,
 
  381                                             const std::map<std::string, UTF8>* aProperties )
 
  388    wxFileName libFname( aLibraryPath );
 
  390    if( libFname.GetExt() == wxS( 
"efoo" ) )
 
  392        wxFFileInputStream ffis( aLibraryPath );
 
  393        wxTextInputStream  txt( ffis, wxS( 
" " ), wxConvUTF8 );
 
  397        for( 
const nlohmann::json& js : lines )
 
  399            if( js.at( 0 ) == 
"ATTR" )
 
  403                if( attr.
key == wxS( 
"Footprint" ) && attr.
value != aFootprintName )
 
  408        footprint = parser.
ParseFootprint( nlohmann::json(), wxEmptyString, lines );
 
  412            THROW_IO_ERROR( wxString::Format( 
_( 
"Cannot load footprint '%s' from '%s'" ),
 
  413                                              aFootprintName, aLibraryPath ) );
 
  424    else if( libFname.GetExt() == wxS( 
"elibz" ) || libFname.GetExt() == wxS( 
"epro" )
 
  425             || libFname.GetExt() == wxS( 
"zip" ) )
 
  431        std::map<wxString, nlohmann::json> footprintMap = 
project.at( 
"footprints" );
 
  432        for( 
auto& [uuid, data] : footprintMap )
 
  436            if( data.contains( 
"display_title" ) )
 
  437                title = data.at( 
"display_title" ).get<wxString>();
 
  439                title = data.at( 
"title" ).get<wxString>();
 
  441            if( title == aFootprintName )
 
  450            THROW_IO_ERROR( wxString::Format( 
_( 
"Footprint '%s' not found in project '%s'" ),
 
  451                                              aFootprintName, aLibraryPath ) );
 
  454        auto cb = [&]( 
const wxString& 
name, 
const wxString& baseName, wxInputStream& 
zip ) -> 
bool 
  456            if( !
name.EndsWith( wxS( 
".efoo" ) ) )
 
  459            if( baseName != fpUuid )
 
  468                THROW_IO_ERROR( wxString::Format( 
_( 
"Cannot load footprint '%s' from '%s'" ),
 
  469                                                  aFootprintName, aLibraryPath ) );
 
 
  491    std::vector<FOOTPRINT*> 
result;
 
  496    for( 
auto& [fpUuid, footprint] : 
m_projectData->m_Footprints )
 
 
Information pertinent to a Pcbnew printed circuit board.
 
virtual void SetVisible(bool aVisible)
 
virtual void SetText(const wxString &aText)
 
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
 
A logical library item identifier and consists of various portions much like a URI.
 
void ParseBoard(BOARD *aBoard, const nlohmann::json &aProject, std::map< wxString, std::unique_ptr< FOOTPRINT > > &aFootprintMap, const std::map< wxString, EASYEDAPRO::BLOB > &aBlobMap, const std::multimap< wxString, EASYEDAPRO::POURED > &aPouredMap, const std::vector< nlohmann::json > &aLines, const wxString &aFpLibName)
 
FOOTPRINT * ParseFootprint(const nlohmann::json &aProject, const wxString &aFpUuid, const std::vector< nlohmann::json > &aLines)
 
void LoadAllDataFromProject(const wxString &aLibraryPath, const nlohmann::json &aProject)
 
std::vector< FOOTPRINT * > GetImportedCachedLibraryFootprints() override
Return a container with the cached library footprints generated in the last call to Load.
 
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
 
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
 
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
 
FOOTPRINT * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, bool aKeepUUID=false, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a footprint having aFootprintName from the aLibraryPath containing a library format that this PC...
 
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, bool aBestEfforts, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Return a list of footprint names contained within the library at aLibraryPath.
 
BOARD * m_board
The board BOARD being worked on, no ownership here.
 
PCB_IO(const wxString &aName)
 
const std::map< std::string, UTF8 > * m_props
Properties passed via Save() or Load(), no ownership, may be NULL.
 
CHOOSE_PROJECT_HANDLER m_choose_project_handler
Callback to choose projects to import.
 
Container for project specific data.
 
static REPORTER & GetInstance()
 
static void SetReporter(REPORTER *aReporter)
Set the reporter to use for reporting font substitution warnings.
 
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
 
This file contains miscellaneous commonly used macros and functions.
 
wxString get_def(const std::map< wxString, wxString > &aMap, const char *aKey, const char *aDefval="")
 
LIB_ID ToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
 
void IterateZipFiles(const wxString &aFileName, std::function< bool(const wxString &, const wxString &, wxInputStream &)> aCallback)
 
std::vector< nlohmann::json > ParseJsonLines(wxInputStream &aInput, const wxString &aSource)
 
static const bool IMPORT_POURED_ECOP
 
std::vector< std::vector< nlohmann::json > > ParseJsonLinesWithSeparation(wxInputStream &aInput, const wxString &aSource)
Multiple document types (e.g.
 
std::vector< IMPORT_PROJECT_DESC > ProjectToSelectorDialog(const nlohmann::json &aProject, bool aPcbOnly=false, bool aSchOnly=false)
 
nlohmann::json ReadProjectOrDeviceFile(const wxString &aZipFileName)
 
wxString ShortenLibName(wxString aProjectName)
 
std::map< wxString, std::multimap< wxString, EASYEDAPRO::POURED > > m_Poured
 
std::map< wxString, EASYEDAPRO::BLOB > m_Blobs
 
std::map< wxString, std::unique_ptr< FOOTPRINT > > m_Footprints
 
wxString result
Test unit parsing edge cases and error handling.