|
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <set>
#include <wx/string.h>
#include <wx/filename.h>
#include <mmh3_hash.h>
#include <picosha2.h>
#include <wildcards_and_files_ext.h>
#include <functional>
class OUTPUTFORMATTER;
namespace KIFONT{ class OUTLINE_FONT;}
class EMBEDDED_FILES{public: struct EMBEDDED_FILE { enum class FILE_TYPE { FONT, MODEL, WORKSHEET, DATASHEET, OTHER };
EMBEDDED_FILE() : type( FILE_TYPE::OTHER ), is_valid( false ) {}
bool Validate() { MMH3_HASH hash( EMBEDDED_FILES::Seed() ); hash.add( decompressedData );
is_valid = ( hash.digest().ToString() == data_hash ); return is_valid; }
// This is the old way of validating the file. It is deprecated and retained only
// to validate files that were previously embedded.
bool Validate_SHA256() { std::string new_sha; picosha2::hash256_hex_string( decompressedData, new_sha );
is_valid = ( new_sha == data_hash ); return is_valid; }
wxString GetLink() const { return wxString::Format( "%s://%s", FILEEXT::KiCadUriPrefix, name ); }
wxString name; FILE_TYPE type; bool is_valid; std::string compressedEncodedData; std::vector<char> decompressedData; std::string data_hash; };
enum class RETURN_CODE : int { OK, ///< Success.
FILE_NOT_FOUND, ///< File not found on disk.
PERMISSIONS_ERROR, ///< Could not read/write file.
FILE_ALREADY_EXISTS, ///< File already exists in the collection.
OUT_OF_MEMORY, ///< Could not allocate memory.
CHECKSUM_ERROR, ///< Checksum in file does not match data.
};
EMBEDDED_FILES() = default;
EMBEDDED_FILES( EMBEDDED_FILES&& other ) noexcept; EMBEDDED_FILES( const EMBEDDED_FILES& other );
~EMBEDDED_FILES() { for( auto& file : m_files ) delete file.second; }
using FileAddedCallback = std::function<void(EMBEDDED_FILE*)>;
void SetFileAddedCallback(FileAddedCallback callback) { m_fileAddedCallback = callback; }
FileAddedCallback GetFileAddedCallback() const { return m_fileAddedCallback; }
/**
* Load a file from disk and adds it to the collection. * * @param aName is the name of the file to load. * @param aOverwrite is true if the file should be overwritten if it already exists. */ EMBEDDED_FILE* AddFile( const wxFileName& aName, bool aOverwrite );
/**
* Append a file to the collection. */ void AddFile( EMBEDDED_FILE* aFile );
/**
* Remove a file from the collection and frees the memory. * * @param aName is the name of the file to remove. */ void RemoveFile( const wxString& name, bool aErase = true );
/**
* Output formatter for the embedded files. * * @param aOut is the output formatter. * @param aWriteData is true if the actual data should be written. This is false when writing * an element that is already embedded in a file that itself has embedded * files (boards, schematics, etc.). */ void WriteEmbeddedFiles( OUTPUTFORMATTER& aOut, bool aWriteData ) const;
/**
* Return the link for an embedded file. * * @param aFile is the file to get the link for. * @return the link for the file to be used in a hyperlink. */ wxString GetEmbeddedFileLink( const EMBEDDED_FILE& aFile ) const { return aFile.GetLink(); }
bool HasFile( const wxString& name ) const { wxFileName fileName( name );
return m_files.find( fileName.GetFullName() ) != m_files.end(); }
bool IsEmpty() const { return m_files.empty(); }
/**
* Helper function to get a list of fonts for fontconfig to add to the library. * * This is necessary because EMBEDDED_FILES lives in common at the moment and * fontconfig is in libkicommon. This will create the cache files in the KiCad * cache directory (if they do not already exist) and return the temp files names */ const std::vector<wxString>* UpdateFontFiles();
/**
* If we just need the cached version of the font files, we can use this function which * is const and will not update the font files. */ const std::vector<wxString>* GetFontFiles() const;
/**
* Remove all embedded fonts from the collection. */ void ClearEmbeddedFonts();
/**
* Take data from the #decompressedData buffer and compresses it using ZSTD * into the #compressedEncodedData buffer. * * The data is then Base64 encoded. This call is used when adding a new file to the * collection from disk. */ static RETURN_CODE CompressAndEncode( EMBEDDED_FILE& aFile );
/**
* Takes data from the #compressedEncodedData buffer and Base64 decodes it. * * The data is then decompressed using ZSTD and stored in the #decompressedData buffer. * This call is used when loading the embedded files using the parsers. */ static RETURN_CODE DecompressAndDecode( EMBEDDED_FILE& aFile );
/**
* Returns the embedded file with the given name or nullptr if it does not exist. */ EMBEDDED_FILE* GetEmbeddedFile( const wxString& aName ) const { auto it = m_files.find( aName );
return it == m_files.end() ? nullptr : it->second; }
const std::map<wxString, EMBEDDED_FILE*>& EmbeddedFileMap() const { return m_files; }
wxFileName GetTemporaryFileName( const wxString& aName ) const;
wxFileName GetTemporaryFileName( EMBEDDED_FILE* aFile ) const;
void ClearEmbeddedFiles( bool aDeleteFiles = true ) { for( auto& file : m_files ) { if( aDeleteFiles ) delete file.second; }
m_files.clear(); }
virtual void EmbedFonts() {};
virtual std::set<KIFONT::OUTLINE_FONT*> GetFonts() const { return std::set<KIFONT::OUTLINE_FONT*>(); };
void SetAreFontsEmbedded( bool aEmbedFonts ) { m_embedFonts = aEmbedFonts; }
bool GetAreFontsEmbedded() const { return m_embedFonts; }
static uint32_t Seed() { return 0xABBA2345; }
EMBEDDED_FILES& operator=(EMBEDDED_FILES&& other) noexcept; EMBEDDED_FILES& operator=( const EMBEDDED_FILES& other );
private: std::map<wxString, EMBEDDED_FILE*> m_files; std::vector<wxString> m_fontFiles; FileAddedCallback m_fileAddedCallback;
protected: bool m_embedFonts = false; ///< If set, fonts will be embedded in the element on save.
///< Otherwise, font files embedded in the element will be
///< removed on save.
};
|