kicad-source/include/embedded_files.h
Seth Hillbrand 0b2d4d4879 Revise Copyright statement to align with TLF
Recommendation is to avoid using the year nomenclature as this
information is already encoded in the git repo.  Avoids needing to
repeatly update.

Also updates AUTHORS.txt from current repo with contributor names
2025-01-01 14:12:04 -08:00

244 lines
7.0 KiB
C++

/*
* 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 <wx/string.h>
#include <wx/filename.h>
#include <mmh3_hash.h>
#include <picosha2.h>
#include <wildcards_and_files_ext.h>
class OUTPUTFORMATTER;
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()
{
for( auto& file : m_files )
delete file.second;
}
/**
* Loads 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 );
/**
* Appends a file to the collection.
*/
void AddFile( EMBEDDED_FILE* aFile );
/**
* Removes 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;
/**
* Returns 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 neccesary 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;
/**
* Removes all embedded fonts from the collection
*/
void ClearEmbeddedFonts();
/**
* Takes 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() {};
void SetAreFontsEmbedded( bool aEmbedFonts )
{
m_embedFonts = aEmbedFonts;
}
bool GetAreFontsEmbedded() const
{
return m_embedFonts;
}
static uint32_t Seed()
{
return 0xABBA2345;
}
private:
std::map<wxString, EMBEDDED_FILE*> m_files;
std::vector<wxString> m_fontFiles;
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
};