You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							110 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							110 lines
						
					
					
						
							2.6 KiB
						
					
					
				| /* | |
|  * This program source code file is part of KiCad, a free EDA CAD application. | |
|  * | |
|  * Copyright (C) 2021 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/>. | |
|  */ | |
| 
 | |
| #include <wx/tarstrm.h> | |
| #include <wx/wfstream.h> | |
| #include <wx/zstream.h> | |
|  | |
| #include <asset_archive.h> | |
|  | |
| 
 | |
| ASSET_ARCHIVE::ASSET_ARCHIVE( const wxString& aFilePath, bool aLoadNow ) : | |
|         m_filePath( aFilePath ) | |
| { | |
|     if( aLoadNow ) | |
|         Load(); | |
| } | |
| 
 | |
| 
 | |
| bool ASSET_ARCHIVE::Load() | |
| { | |
|     // We don't support hot-reloading yet | |
|     if( !m_fileInfoCache.empty() ) | |
|         return false; | |
| 
 | |
|     wxFFileInputStream zipFile( m_filePath ); | |
| 
 | |
|     if( !zipFile.IsOk() ) | |
|         return false; | |
| 
 | |
|     wxZlibInputStream stream( zipFile, wxZLIB_GZIP ); | |
|     wxTarInputStream tarStream( stream ); | |
|     wxTarEntry* entry; | |
| 
 | |
|     // Avoid realloc while reading: we're not going to get better than 2:1 compression | |
|     m_cache.resize( 2 * zipFile.GetLength() ); | |
| 
 | |
|     size_t offset = 0; | |
| 
 | |
|     while( ( entry = tarStream.GetNextEntry() ) ) | |
|     { | |
|         if( entry->IsDir() ) | |
|         { | |
|             delete entry; | |
|             continue; | |
|         } | |
| 
 | |
|         size_t length = entry->GetSize(); | |
| 
 | |
|         FILE_INFO fi; | |
|         fi.offset = offset; | |
|         fi.length = length; | |
| 
 | |
|         if( offset + length > m_cache.size() ) | |
|             m_cache.resize( m_cache.size() * 2 ); | |
| 
 | |
|         tarStream.Read( &m_cache[offset], length ); | |
| 
 | |
|         m_fileInfoCache[entry->GetName()] = fi; | |
| 
 | |
|         offset += length; | |
| 
 | |
|         delete entry; | |
|     } | |
| 
 | |
|     m_cache.resize( offset ); | |
| 
 | |
|     return true; | |
| } | |
| 
 | |
| 
 | |
| long ASSET_ARCHIVE::GetFileContents( const wxString& aFilePath, const unsigned char* aDest, | |
|                                      size_t aMaxLen ) | |
| { | |
|     wxFAIL_MSG( "Unimplemented" ); | |
|     return 0; | |
| } | |
| 
 | |
| 
 | |
| long ASSET_ARCHIVE::GetFilePointer( const wxString& aFilePath, const unsigned char** aDest ) | |
| { | |
|     if( aFilePath.IsEmpty() ) | |
|         return -1; | |
| 
 | |
|     wxASSERT( aDest ); | |
| 
 | |
|     if( !m_fileInfoCache.count( aFilePath ) ) | |
|         return -1; | |
| 
 | |
|     const FILE_INFO& fi = m_fileInfoCache.at( aFilePath ); | |
| 
 | |
|     *aDest = &m_cache[fi.offset]; | |
| 
 | |
|     return fi.length; | |
| }
 |