KiCad PCB EDA Suite
FP_CACHE Class Reference

Public Member Functions

 FP_CACHE (PCB_PLUGIN *aOwner, const wxString &aLibraryPath)
 
wxString GetPath () const
 
bool IsWritable () const
 
bool Exists () const
 
FOOTPRINT_MAPGetFootprints ()
 
void Save (FOOTPRINT *aFootprint=nullptr)
 Save the footprint cache or a single footprint from it to disk. More...
 
void Load ()
 
void Remove (const wxString &aFootprintName)
 
bool IsModified ()
 Return true if the cache is not up-to-date. More...
 
bool IsPath (const wxString &aPath) const
 Check if aPath is the same as the current cache path. More...
 

Static Public Member Functions

static long long GetTimestamp (const wxString &aLibPath)
 Generate a timestamp representing all source files in the cache (including the parent directory). More...
 

Private Attributes

PCB_PLUGINm_owner
 
wxFileName m_lib_path
 
wxString m_lib_raw_path
 
FOOTPRINT_MAP m_footprints
 
bool m_cache_dirty
 
long long m_cache_timestamp
 

Detailed Description

Definition at line 91 of file pcb_plugin.cpp.

Constructor & Destructor Documentation

◆ FP_CACHE()

FP_CACHE::FP_CACHE ( PCB_PLUGIN aOwner,
const wxString &  aLibraryPath 
)

Definition at line 156 of file pcb_plugin.cpp.

157 {
158  m_owner = aOwner;
159  m_lib_raw_path = aLibraryPath;
160  m_lib_path.SetPath( aLibraryPath );
161  m_cache_timestamp = 0;
162  m_cache_dirty = true;
163 }
wxFileName m_lib_path
Definition: pcb_plugin.cpp:94
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95
long long m_cache_timestamp
Definition: pcb_plugin.cpp:100
PCB_PLUGIN * m_owner
Definition: pcb_plugin.cpp:93
bool m_cache_dirty
Definition: pcb_plugin.cpp:98

References m_cache_dirty, m_cache_timestamp, m_lib_path, m_lib_raw_path, and m_owner.

Member Function Documentation

◆ Exists()

bool FP_CACHE::Exists ( ) const
inline

Definition at line 110 of file pcb_plugin.cpp.

110 { return m_lib_path.IsOk() && m_lib_path.DirExists(); }
wxFileName m_lib_path
Definition: pcb_plugin.cpp:94

References m_lib_path.

Referenced by PCB_PLUGIN::FootprintSave().

◆ GetFootprints()

FOOTPRINT_MAP& FP_CACHE::GetFootprints ( )
inline

Definition at line 112 of file pcb_plugin.cpp.

112 { return m_footprints; }
FOOTPRINT_MAP m_footprints
Definition: pcb_plugin.cpp:96

References m_footprints.

Referenced by PCB_PLUGIN::FootprintEnumerate(), PCB_PLUGIN::FootprintSave(), and PCB_PLUGIN::getFootprint().

◆ GetPath()

wxString FP_CACHE::GetPath ( ) const
inline

Definition at line 106 of file pcb_plugin.cpp.

106 { return m_lib_raw_path; }
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95

References m_lib_raw_path.

◆ GetTimestamp()

long long FP_CACHE::GetTimestamp ( const wxString &  aLibPath)
static

Generate a timestamp representing all source files in the cache (including the parent directory).

Timestamps should not be considered ordered. They either match or they don't.

Definition at line 330 of file pcb_plugin.cpp.

331 {
332  wxString fileSpec = wxT( "*." ) + KiCadFootprintFileExtension;
333 
334  return TimestampDir( aLibPath, fileSpec );
335 }
const std::string KiCadFootprintFileExtension
long long TimestampDir(const wxString &aDirPath, const wxString &aFilespec)
A copy of ConvertFileTimeToWx() because wxWidgets left it as a static function private to src/common/...
Definition: common.cpp:504

References KiCadFootprintFileExtension, and TimestampDir().

Referenced by PCB_PLUGIN::GetLibraryTimestamp(), IsModified(), and Load().

◆ IsModified()

bool FP_CACHE::IsModified ( )

Return true if the cache is not up-to-date.

Definition at line 322 of file pcb_plugin.cpp.

323 {
325 
326  return m_cache_dirty;
327 }
wxFileName m_lib_path
Definition: pcb_plugin.cpp:94
long long m_cache_timestamp
Definition: pcb_plugin.cpp:100
bool m_cache_dirty
Definition: pcb_plugin.cpp:98
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).
Definition: pcb_plugin.cpp:330

References GetTimestamp(), m_cache_dirty, m_cache_timestamp, and m_lib_path.

Referenced by PCB_PLUGIN::validateCache().

◆ IsPath()

bool FP_CACHE::IsPath ( const wxString &  aPath) const

Check if aPath is the same as the current cache path.

This tests paths by converting aPath using the native separators. Internally FP_CACHE stores the current path using native separators. This prevents path miscompares on Windows due to the fact that paths can be stored with / instead of \ in the footprint library table.

Parameters
aPathis the library path to test against.
Returns
true if aPath is the same as the cache path.

Definition at line 316 of file pcb_plugin.cpp.

317 {
318  return aPath == m_lib_raw_path;
319 }
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95

References m_lib_raw_path.

Referenced by PCB_PLUGIN::FootprintLibDelete(), and PCB_PLUGIN::validateCache().

◆ IsWritable()

bool FP_CACHE::IsWritable ( ) const
inline

Definition at line 108 of file pcb_plugin.cpp.

108 { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
wxFileName m_lib_path
Definition: pcb_plugin.cpp:94

References m_lib_path.

Referenced by PCB_PLUGIN::FootprintDelete(), PCB_PLUGIN::FootprintSave(), and PCB_PLUGIN::IsFootprintLibWritable().

◆ Load()

void FP_CACHE::Load ( )

Definition at line 233 of file pcb_plugin.cpp.

234 {
235  m_cache_dirty = false;
236  m_cache_timestamp = 0;
237 
238  wxDir dir( m_lib_raw_path );
239 
240  if( !dir.IsOpened() )
241  {
242  wxString msg = wxString::Format( _( "Footprint library '%s' not found." ),
243  m_lib_raw_path );
244  THROW_IO_ERROR( msg );
245  }
246 
247  wxString fullName;
248  wxString fileSpec = wxT( "*." ) + KiCadFootprintFileExtension;
249 
250  // wxFileName construction is egregiously slow. Construct it once and just swap out
251  // the filename thereafter.
252  WX_FILENAME fn( m_lib_raw_path, wxT( "dummyName" ) );
253 
254  if( dir.GetFirst( &fullName, fileSpec ) )
255  {
256  wxString cacheError;
257 
258  do
259  {
260  fn.SetFullName( fullName );
261 
262  // Queue I/O errors so only files that fail to parse don't get loaded.
263  try
264  {
265  FILE_LINE_READER reader( fn.GetFullPath() );
266 
267  m_owner->m_parser->SetLineReader( &reader );
268 
269  // For better or worse (mostly worse), the parser is a long-lived object.
270  // Make sure we start with a fresh state.
271  m_owner->m_parser->InitParserState();
272  m_owner->m_parser->SetBoard( nullptr ); // calls PCB_PARSER::init()
273 
274  FOOTPRINT* footprint = (FOOTPRINT*) m_owner->m_parser->Parse();
275  wxString fpName = fn.GetName();
276 
277  footprint->SetFPID( LIB_ID( wxEmptyString, fpName ) );
278  m_footprints.insert( fpName, new FP_CACHE_ITEM( footprint, fn ) );
279  }
280  catch( const IO_ERROR& ioe )
281  {
282  if( !cacheError.IsEmpty() )
283  cacheError += wxT( "\n\n" );
284 
285  cacheError += ioe.What();
286  }
287  } while( dir.GetNext( &fullName ) );
288 
290 
291  if( !cacheError.IsEmpty() )
292  THROW_IO_ERROR( cacheError );
293  }
294 }
const std::string KiCadFootprintFileExtension
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
PCB_PARSER * m_parser
Definition: pcb_plugin.h:296
FOOTPRINT_MAP m_footprints
Definition: pcb_plugin.cpp:96
long long m_cache_timestamp
Definition: pcb_plugin.cpp:100
A LINE_READER that reads from an open file.
Definition: richio.h:172
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:102
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
PCB_PLUGIN * m_owner
Definition: pcb_plugin.cpp:93
#define _(s)
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:627
Helper class for creating a footprint library cache.
Definition: pcb_plugin.cpp:69
LINE_READER * SetLineReader(LINE_READER *aReader)
Set aLineReader into the parser, and returns the previous one, if any.
Definition: pcb_parser.h:95
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void SetFPID(const LIB_ID &aFPID)
Definition: footprint.h:196
A wrapper around a wxFileName which is much more performant with a subset of the API.
Definition: wx_filename.h:36
bool m_cache_dirty
Definition: pcb_plugin.cpp:98
static long long GetTimestamp(const wxString &aLibPath)
Generate a timestamp representing all source files in the cache (including the parent directory).
Definition: pcb_plugin.cpp:330
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), WX_FILENAME::GetFullPath(), WX_FILENAME::GetName(), GetTimestamp(), KiCadFootprintFileExtension, m_cache_dirty, m_cache_timestamp, m_footprints, m_lib_raw_path, m_owner, PCB_PLUGIN::m_parser, PCB_PARSER::Parse(), PCB_PARSER::SetBoard(), FOOTPRINT::SetFPID(), WX_FILENAME::SetFullName(), PCB_PARSER::SetLineReader(), THROW_IO_ERROR, and IO_ERROR::What().

Referenced by PCB_PLUGIN::validateCache().

◆ Remove()

void FP_CACHE::Remove ( const wxString &  aFootprintName)

Definition at line 297 of file pcb_plugin.cpp.

298 {
299  FOOTPRINT_MAP::const_iterator it = m_footprints.find( aFootprintName );
300 
301  if( it == m_footprints.end() )
302  {
303  wxString msg = wxString::Format( _( "Library '%s' has no footprint '%s'." ),
305  aFootprintName );
306  THROW_IO_ERROR( msg );
307  }
308 
309  // Remove the footprint from the cache and delete the footprint file from the library.
310  wxString fullPath = it->second->GetFileName().GetFullPath();
311  m_footprints.erase( aFootprintName );
312  wxRemoveFile( fullPath );
313 }
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95
FOOTPRINT_MAP m_footprints
Definition: pcb_plugin.cpp:96
#define _(s)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), m_footprints, m_lib_raw_path, and THROW_IO_ERROR.

Referenced by PCB_PLUGIN::FootprintDelete().

◆ Save()

void FP_CACHE::Save ( FOOTPRINT aFootprint = nullptr)

Save the footprint cache or a single footprint from it to disk.

Parameters
aFootprintif set, save only this footprint, otherwise, save the full library

Definition at line 166 of file pcb_plugin.cpp.

167 {
168  m_cache_timestamp = 0;
169 
170  if( !m_lib_path.DirExists() && !m_lib_path.Mkdir() )
171  {
172  THROW_IO_ERROR( wxString::Format( _( "Cannot create footprint library '%s'." ),
173  m_lib_raw_path ) );
174  }
175 
176  if( !m_lib_path.IsDirWritable() )
177  {
178  THROW_IO_ERROR( wxString::Format( _( "Footprint library '%s' is read only." ),
179  m_lib_raw_path ) );
180  }
181 
182  for( FOOTPRINT_MAP::iterator it = m_footprints.begin(); it != m_footprints.end(); ++it )
183  {
184  if( aFootprint && aFootprint != it->second->GetFootprint() )
185  continue;
186 
187  WX_FILENAME fn = it->second->GetFileName();
188 
189  wxString tempFileName =
190 #ifdef USE_TMP_FILE
191  wxFileName::CreateTempFileName( fn.GetPath() );
192 #else
193  fn.GetFullPath();
194 #endif
195  // Allow file output stream to go out of scope to close the file stream before
196  // renaming the file.
197  {
198  wxLogTrace( traceKicadPcbPlugin, wxT( "Creating temporary library file '%s'." ),
199  tempFileName );
200 
201  FILE_OUTPUTFORMATTER formatter( tempFileName );
202 
203  m_owner->SetOutputFormatter( &formatter );
204  m_owner->Format( (BOARD_ITEM*) it->second->GetFootprint() );
205  }
206 
207 #ifdef USE_TMP_FILE
208  wxRemove( fn.GetFullPath() ); // it is not an error if this does not exist
209 
210  // Even on Linux you can see an _intermittent_ error when calling wxRename(),
211  // and it is fully inexplicable. See if this dodges the error.
212  wxMilliSleep( 250L );
213 
214  if( !wxRenameFile( tempFileName, fn.GetFullPath() ) )
215  {
216  wxString msg = wxString::Format( _( "Cannot rename temporary file '%s' to '%s'" ),
217  tempFileName,
218  fn.GetFullPath() );
219  THROW_IO_ERROR( msg );
220  }
221 #endif
223  }
224 
225  m_cache_timestamp += m_lib_path.GetModificationTime().GetValue().GetValue();
226 
227  // If we've saved the full cache, we clear the dirty flag.
228  if( !aFootprint )
229  m_cache_dirty = false;
230 }
wxFileName m_lib_path
Definition: pcb_plugin.cpp:94
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
wxString m_lib_raw_path
Definition: pcb_plugin.cpp:95
FOOTPRINT_MAP m_footprints
Definition: pcb_plugin.cpp:96
long long m_cache_timestamp
Definition: pcb_plugin.cpp:100
long long GetTimestamp()
Definition: wx_filename.cpp:74
PCB_PLUGIN * m_owner
Definition: pcb_plugin.cpp:93
const wxChar *const traceKicadPcbPlugin
Flag to enable GEDA PCB plugin debug output.
#define _(s)
void Format(const BOARD_ITEM *aItem, int aNestLevel=0) const
Output aItem to aFormatter in s-expression format.
Definition: pcb_plugin.cpp:400
wxString GetPath() const
Definition: wx_filename.cpp:53
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxString GetFullPath() const
Definition: wx_filename.cpp:59
A wrapper around a wxFileName which is much more performant with a subset of the API.
Definition: wx_filename.h:36
void SetOutputFormatter(OUTPUTFORMATTER *aFormatter)
Definition: pcb_plugin.h:221
Used for text file output.
Definition: richio.h:456
bool m_cache_dirty
Definition: pcb_plugin.cpp:98
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38

References _, Format(), PCB_PLUGIN::Format(), WX_FILENAME::GetFullPath(), WX_FILENAME::GetPath(), WX_FILENAME::GetTimestamp(), m_cache_dirty, m_cache_timestamp, m_footprints, m_lib_path, m_lib_raw_path, m_owner, PCB_PLUGIN::SetOutputFormatter(), THROW_IO_ERROR, and traceKicadPcbPlugin.

Referenced by PCB_PLUGIN::FootprintLibCreate(), and PCB_PLUGIN::FootprintSave().

Member Data Documentation

◆ m_cache_dirty

bool FP_CACHE::m_cache_dirty
private

Definition at line 98 of file pcb_plugin.cpp.

Referenced by FP_CACHE(), IsModified(), Load(), and Save().

◆ m_cache_timestamp

long long FP_CACHE::m_cache_timestamp
private

Definition at line 100 of file pcb_plugin.cpp.

Referenced by FP_CACHE(), IsModified(), Load(), and Save().

◆ m_footprints

FOOTPRINT_MAP FP_CACHE::m_footprints
private

Definition at line 96 of file pcb_plugin.cpp.

Referenced by GetFootprints(), Load(), Remove(), and Save().

◆ m_lib_path

wxFileName FP_CACHE::m_lib_path
private

Definition at line 94 of file pcb_plugin.cpp.

Referenced by Exists(), FP_CACHE(), IsModified(), IsWritable(), and Save().

◆ m_lib_raw_path

wxString FP_CACHE::m_lib_raw_path
private

Definition at line 95 of file pcb_plugin.cpp.

Referenced by FP_CACHE(), GetPath(), IsPath(), Load(), Remove(), and Save().

◆ m_owner

PCB_PLUGIN* FP_CACHE::m_owner
private

Definition at line 93 of file pcb_plugin.cpp.

Referenced by FP_CACHE(), Load(), and Save().


The documentation for this class was generated from the following file: