21#include <boost/lexical_cast.hpp>
68 wxFileName fn( aPath );
70 m_path = fn.GetAbsolutePath();
72 if( !fn.FileExists() )
80 if( fn.GetSize() <= 1 )
87 tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR> ir = parser.
Parse(
m_path.ToStdString() );
118 tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR> ir = parser.
ParseBuffer( aBuffer.ToStdString() );
122 m_ok = initFromIR( *ir );
127 m_errorDescription = ir.error().description;
150 catch(
const boost::bad_lexical_cast & )
167 row.
m_uri = wxString::FromUTF8( aIR.
uri );
176 m_rows.emplace_back( row );
183 static const std::map<LIBRARY_TABLE_TYPE, wxString> types = {
189 if( !types.contains(
Type() ) )
191 THROW_IO_ERROR(
"Unknown library table type: " + std::to_string(
static_cast<int>(
Type() ) ) );
194 XNODE self( wxXML_ELEMENT_NODE, types.at(
Type() ) );
201 wxString uri = row.URI();
202 uri.Replace(
'\\',
'/' );
204 XNODE* rowNode =
new XNODE( wxXML_ELEMENT_NODE,
"lib" );
212 rowNode->AddChild(
new XNODE( wxXML_ELEMENT_NODE,
"disabled" ) );
215 rowNode->AddChild(
new XNODE( wxXML_ELEMENT_NODE,
"hidden" ) );
217 self.AddChild( rowNode );
245 if( row.Nickname() == aNickname )
254 bool aSubstituted )
const
258 if( !aSubstituted && row.URI() == aUri )
273 if( row.Nickname() == aNickname )
285 if( row.Nickname() == aNickname )
296 wxFileName fn(
Path() );
302 wxFFile existing( fn.GetFullPath(), wxT(
"rb" ) );
304 if( existing.IsOpened() )
306 wxFileOffset rawLen = existing.Length();
309 &&
static_cast<uint64_t
>( rawLen ) <= std::numeric_limits<size_t>::max() )
311 size_t len =
static_cast<size_t>( rawLen );
313 void* dst = len > 0 ? buf.GetWriteBuf( len ) :
nullptr;
315 if( len == 0 || existing.Read( dst, len ) == len )
317 buf.SetDataLen( len );
320 wxString bakPath = fn.GetFullPath() + wxT(
".bak" );
328 "Could not rotate library table backup to '%s': %s", bakPath,
355 std::map<std::string, UTF8> props;
357 if( aOptionsList.size() )
359 const char* cp = &aOptionsList[0];
360 const char*
end = cp + aOptionsList.size();
370 while( cp <
end && isspace( *cp ) )
376 if( *cp ==
'\\' && cp + 1 <
end && cp[1] ==
OPT_SEP )
396 size_t eqNdx = pair.find(
'=' );
398 if( eqNdx != pair.npos )
400 std::string
name = pair.substr( 0, eqNdx );
401 std::string value = pair.substr( eqNdx + 1 );
422 for( std::map<std::string, UTF8>::const_iterator it = aProperties->begin();
423 it != aProperties->end(); ++it )
425 const std::string&
name = it->first;
427 const UTF8& value = it->second;
439 for( std::string::const_iterator si = value.
begin(); si != value.
end(); ++si )
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
static wxString ExpandURI(const wxString &aShortURI, const PROJECT &aProject)
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > ParseBuffer(const std::string &aBuffer)
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > Parse(const std::filesystem::path &aPath)
LIBRARY_TABLE_ROW()=default
void SetOk(bool aOk=true)
bool operator==(const LIBRARY_TABLE_ROW &aOther) const
std::map< std::string, UTF8 > GetOptionsMap() const
static const wxString TABLE_TYPE_NAME
void SetScope(LIBRARY_TABLE_SCOPE aScope)
LIBRARY_TABLE_SCOPE m_scope
LIBRARY_RESULT< void > Save()
bool operator==(const LIBRARY_TABLE &aOther) const
void Format(OUTPUTFORMATTER *aOutput) const
static std::map< std::string, UTF8 > ParseOptions(const std::string &aOptionsList)
LIBRARY_TABLE_TYPE Type() const
LIBRARY_TABLE_TYPE m_type
What type of content this table contains (footprint, symbol, design block, etc)
std::optional< LIBRARY_TABLE_ROW * > Row(const wxString &aNickname)
LIBRARY_TABLE_ROW & InsertRow()
Builds a new row and inserts it at the end of the table; returning a reference to the row.
static UTF8 FormatOptions(const std::map< std::string, UTF8 > *aProperties)
const wxString & Path() const
wxString m_path
The full path to the file this table was parsed from, if any.
wxString m_errorDescription
LIBRARY_TABLE_ROW MakeRow() const
Builds a new row that is suitable for this table (does not insert it)
bool HasRow(const wxString &aNickname) const
bool HasRowWithURI(const wxString &aUri, const PROJECT &aProject, bool aSubstituted=false) const
Returns true if the given (fully-expanded) URI exists as a library in this table.
const std::deque< LIBRARY_TABLE_ROW > & Rows() const
LIBRARY_TABLE(const wxFileName &aPath, LIBRARY_TABLE_SCOPE aScope, LIBRARY_TABLE_TYPE aExpectedType=LIBRARY_TABLE_TYPE::UNINITIALIZED)
Creates a library table from a file on disk.
std::optional< int > m_version
The format version, if present in the parsed file.
std::deque< LIBRARY_TABLE_ROW > m_rows
bool addRowFromIR(const LIBRARY_TABLE_ROW_IR &aIR)
LIBRARY_TABLE_SCOPE m_scope
bool initFromIR(const LIBRARY_TABLE_IR &aIR)
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
std::string::const_iterator begin() const
std::string::size_type size() const
std::string::const_iterator end() const
static void ResolvePossibleSymlinks(wxFileName &aFilename)
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
void Format(OUTPUTFORMATTER *out) const
Write this object as UTF8 out to an OUTPUTFORMATTER as an S-expression.
void AddAttribute(const wxString &aName, const wxString &aValue) override
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define OPT_SEP
options separator character
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
The intermediate representation that a library table is parsed into.
std::vector< LIBRARY_TABLE_ROW_IR > rows
wxLogTrace helper definitions.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().