KiCad PCB EDA Suite
asset_archive.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <wx/tarstrm.h>
21#include <wx/wfstream.h>
22#include <wx/zstream.h>
23
24#include <asset_archive.h>
25
26
27ASSET_ARCHIVE::ASSET_ARCHIVE( const wxString& aFilePath, bool aLoadNow ) :
28 m_filePath( aFilePath )
29{
30 if( aLoadNow )
31 Load();
32}
33
34
36{
37 // We don't support hot-reloading yet
38 if( !m_fileInfoCache.empty() )
39 return false;
40
41 wxFFileInputStream zipFile( m_filePath );
42
43 if( !zipFile.IsOk() )
44 return false;
45
46 wxZlibInputStream stream( zipFile, wxZLIB_GZIP );
47 wxTarInputStream tarStream( stream );
48 wxTarEntry* entry;
49
50 // Avoid realloc while reading: we're not going to get better than 2:1 compression
51 m_cache.resize( 2 * zipFile.GetLength() );
52
53 size_t offset = 0;
54
55 while( ( entry = tarStream.GetNextEntry() ) )
56 {
57 if( entry->IsDir() )
58 {
59 delete entry;
60 continue;
61 }
62
63 size_t length = entry->GetSize();
64
65 FILE_INFO fi;
66 fi.offset = offset;
67 fi.length = length;
68
69 if( offset + length > m_cache.size() )
70 m_cache.resize( m_cache.size() * 2 );
71
72 tarStream.Read( &m_cache[offset], length );
73
74 m_fileInfoCache[entry->GetName()] = fi;
75
76 offset += length;
77
78 delete entry;
79 }
80
81 m_cache.resize( offset );
82
83 return true;
84}
85
86
87long ASSET_ARCHIVE::GetFileContents( const wxString& aFilePath, const unsigned char* aDest,
88 size_t aMaxLen )
89{
90 wxFAIL_MSG( wxS( "Unimplemented" ) );
91 return 0;
92}
93
94
95long ASSET_ARCHIVE::GetFilePointer( const wxString& aFilePath, const unsigned char** aDest )
96{
97 if( aFilePath.IsEmpty() )
98 return -1;
99
100 wxASSERT( aDest );
101
102 if( !m_fileInfoCache.count( aFilePath ) )
103 return -1;
104
105 const FILE_INFO& fi = m_fileInfoCache.at( aFilePath );
106
107 *aDest = &m_cache[fi.offset];
108
109 return fi.length;
110}
std::unordered_map< wxString, FILE_INFO > m_fileInfoCache
Cache of file info for a given file path.
Definition: asset_archive.h:69
long GetFileContents(const wxString &aFilePath, const unsigned char *aDest, size_t aMaxLen)
Retrieves a file with the given path from the cached archive.
long GetFilePointer(const wxString &aFilePath, const unsigned char **aDest)
Retrieves a pointer to a file with the given path from the cached archive.
wxString m_filePath
Path to the source archive file.
Definition: asset_archive.h:75
ASSET_ARCHIVE(const wxString &aFilePath, bool aLoadNow=true)
std::vector< unsigned char > m_cache
The full file contents.
Definition: asset_archive.h:72