Initial tar support

Initial tar support
This commit is contained in:
Andy Vandijck 2025-07-13 09:39:38 +02:00
parent 15612c2bcc
commit d0463ddb5e
7 changed files with 179 additions and 5 deletions

View File

@ -71,6 +71,8 @@ target_sources(vbam-fex
fex/LZ_Reader.h
fex/Rar_Extractor.cpp
fex/Rar_Extractor.h
fex/Tar_Extractor.cpp
fex/Tar_Extractor.h
fex/Zip7_Extractor.cpp
fex/Zip7_Extractor.h
fex/Zip_Extractor.cpp

View File

@ -213,7 +213,7 @@ struct fex_type_t_ {
blargg_err_t (*init)(); // Called by fex_init(). Can be NULL.
};
extern const fex_type_t_ fex_7z_type[1], fex_gz_type[1], fex_bz2_type[1], fex_xz_type[1], fex_lz_type[1], fex_rar_type[1], fex_zip_type[1],
extern const fex_type_t_ fex_7z_type[1], fex_gz_type[1], fex_bz2_type[1], fex_xz_type[1], fex_lz_type[1], fex_tar_type[1], fex_rar_type[1], fex_zip_type[1],
fex_bin_type[1];
inline blargg_err_t File_Extractor::open_v()

View File

@ -0,0 +1,94 @@
// File_Extractor 1.0.0. http://www.slack.net/~ant/
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
#include "Tar_Extractor.h"
/* Copyright (C) 2025 Andy Vandijck. This module is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This
module 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 Lesser General Public License for more
details. You should have received a copy of the GNU Lesser General Public
License along with this module; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "blargg_source.h"
// TODO: could close file once data has been read into memory
static blargg_err_t init_tar_file()
{
get_crc_table(); // initialize zlib's CRC-32 tables
return blargg_ok;
}
static File_Extractor* new_tar()
{
return BLARGG_NEW Tar_Extractor;
}
fex_type_t_ const fex_tar_type [1] = {{
".tar",
&new_tar,
"tar file",
&init_tar_file
}};
Tar_Extractor::Tar_Extractor() :
File_Extractor( fex_tar_type )
{ }
Tar_Extractor::~Tar_Extractor()
{
close();
}
blargg_err_t Tar_Extractor::open_path_v()
{
RETURN_ERR( open_arc_file(true) );
RETURN_ERR( arc().seek( 0 ) );
return open_v();
}
blargg_err_t Tar_Extractor::stat_v()
{
set_info( arc().remain(), 0, 0 );
return blargg_ok;
}
blargg_err_t Tar_Extractor::open_v()
{
arc().read(&header, BLOCKSIZE);
set_name( header.name );
sscanf(header.size, "%o", &tarsize);
return blargg_ok;
}
void Tar_Extractor::close_v()
{
name.clear();
}
blargg_err_t Tar_Extractor::next_v()
{
arc().read(&header, BLOCKSIZE);
set_name( header.name );
sscanf(header.size, "%o", &tarsize);
return blargg_ok;
}
blargg_err_t Tar_Extractor::rewind_v()
{
arc().seek(0);
return blargg_ok;
}
blargg_err_t Tar_Extractor::extract_v( void* p, int n )
{
return arc().read( p, n );
}

View File

@ -0,0 +1,76 @@
// Presents a gzipped file as an "archive" of just that file.
// Also handles non-gzipped files.
// File_Extractor 1.0.0
#ifndef TAR_EXTRACTOR_H
#define TAR_EXTRACTOR_H
#include "File_Extractor.h"
typedef struct posix_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[155]; /* 345 */
char padding[12]; /* 500 */
/* 512 */
} posix_header;
#define BLOCKSIZE 512
#define TMAGIC "ustar" /* ustar and a null */
#define TMAGLEN 6
#define TVERSION "00" /* 00 and no null */
#define TVERSLEN 2
/* Values used in typeflag field. */
#define REGTYPE '0' /* regular file */
#define AREGTYPE '\0' /* regular file */
#define LNKTYPE '1' /* link */
#define SYMTYPE '2' /* reserved */
#define CHRTYPE '3' /* character special */
#define BLKTYPE '4' /* block special */
#define DIRTYPE '5' /* directory */
#define FIFOTYPE '6' /* FIFO special */
#define CONTTYPE '7' /* reserved */
class Tar_Extractor : public File_Extractor
{
public:
Tar_Extractor();
virtual ~Tar_Extractor();
protected:
virtual blargg_err_t open_path_v();
virtual blargg_err_t open_v();
virtual void close_v();
virtual blargg_err_t next_v();
virtual blargg_err_t rewind_v();
virtual blargg_err_t stat_v();
virtual blargg_err_t extract_v(void *, int);
private:
File_Reader *gr;
posix_header header;
unsigned int tarsize;
blargg_vector<char> name;
void set_info_();
};
#endif

View File

@ -33,7 +33,7 @@
#define FEX_TYPE_LZMA
#endif
#define FEX_TYPE_LIST fex_7z_type, fex_gz_type, fex_zip_type, fex_rar_type, FEX_TYPE_BZ2 FEX_TYPE_LZMA
#define FEX_TYPE_LIST fex_7z_type, fex_gz_type, fex_zip_type, fex_tar_type, fex_rar_type, FEX_TYPE_BZ2 FEX_TYPE_LZMA
// Use standard config.h if present
#ifdef HAVE_CONFIG_H

View File

@ -33,6 +33,7 @@ BLARGG_EXPORT const fex_type_t* fex_type_list( void )
// Modify blargg_config.h to change type list, NOT this file
fex_7z_type,
fex_gz_type,
fex_tar_type,
#if FEX_ENABLE_LZMA
fex_xz_type,
fex_lz_type,
@ -148,6 +149,7 @@ static int is_archive_extension( const char str [] )
".rar",
".sit",
".sitx",
".tar",
".tgz",
".tlz",
".z",

View File

@ -145,7 +145,7 @@ EVT_HANDLER(wxID_OPEN, "Open ROM...")
"*.dmg.bz2;*.gb.bz2;*.gbc.bz2;*.cgb.bz2;*.sgb.bz2;"
"*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;"
"*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;"
"*.zip;*.7z;*.rar|");
"*.tar;*.zip;*.7z;*.rar|");
pats.append(wxALL_FILES);
wxFileDialog dlg(this, _("Open ROM file"), gba_rom_dir, "",
@ -179,7 +179,7 @@ EVT_HANDLER(OpenGB, "Open GB...")
"*.dmg.bz2;*.gb.bz2;*.gbc.bz2;*.cgb.bz2;*.sgb.bz2;"
"*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;"
"*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;"
"*.zip;*.7z;*.rar|");
"*.tar;*.zip;*.7z;*.rar|");
pats.append(wxALL_FILES);
wxFileDialog dlg(this, _("Open GB ROM file"), gb_rom_dir, "",
pats,
@ -211,7 +211,7 @@ EVT_HANDLER(OpenGBC, "Open GBC...")
"*.dmg.bz2;*.gb.bz2;*.gbc.bz2;*.cgb.bz2;*.sgb.bz2;"
"*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;"
"*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;"
"*.zip;*.7z;*.rar|");
"*.tar;*.zip;*.7z;*.rar|");
pats.append(wxALL_FILES);
wxFileDialog dlg(this, _("Open GBC ROM file"), gbc_rom_dir, "",
pats,