update to File_Extractor-1.0.0
This commit is contained in:
parent
f03677d0ac
commit
dc394a3baa
|
@ -8,11 +8,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance", "VBA2008
|
|||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0} = {7AEC599C-7C82-4F00-AA60-411E0A359CB0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "..\..\..\dependencies\File_Extractor-0.4.3\File_Extractor2008.vcproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{8B814174-883E-43D0-969E-3A17D8EDE080}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\dependencies\zlib\zlib.vcproj", "{3E03C179-8251-46E4-81F4-466F114BAC63}"
|
||||
|
@ -24,6 +19,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\..\..\dependen
|
|||
{3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "..\..\..\dependencies\File_Extractor-1.0.0\File_Extractor2008.vcproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -34,10 +31,6 @@ Global
|
|||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.Build.0 = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
|
||||
{3E03C179-8251-46E4-81F4-466F114BAC63}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3E03C179-8251-46E4-81F4-466F114BAC63}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3E03C179-8251-46E4-81F4-466F114BAC63}.Release|Win32.ActiveCfg = Release|Win32
|
||||
|
@ -50,14 +43,18 @@ Global
|
|||
{0008960E-E0DD-41A6-8265-00B31DDB4C21}.Debug|Win32.Build.0 = LIB Debug|Win32
|
||||
{0008960E-E0DD-41A6-8265-00B31DDB4C21}.Release|Win32.ActiveCfg = LIB Release|Win32
|
||||
{0008960E-E0DD-41A6-8265-00B31DDB4C21}.Release|Win32.Build.0 = LIB Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0} = {8B814174-883E-43D0-969E-3A17D8EDE080}
|
||||
{3E03C179-8251-46E4-81F4-466F114BAC63} = {8B814174-883E-43D0-969E-3A17D8EDE080}
|
||||
{823DDC98-42D5-4A38-88CF-9DC06C788AE4} = {8B814174-883E-43D0-969E-3A17D8EDE080}
|
||||
{0008960E-E0DD-41A6-8265-00B31DDB4C21} = {8B814174-883E-43D0-969E-3A17D8EDE080}
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0} = {8B814174-883E-43D0-969E-3A17D8EDE080}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""..\..\..\dependencies\File_Extractor-0.4.3\fex";..\..\..\dependencies\lpng140;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\zlib"
|
||||
AdditionalIncludeDirectories=""..\..\..\dependencies\File_Extractor-1.0.0";..\..\..\dependencies\lpng140;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\zlib"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;DEV_VERSION;BKPT_SUPPORT;GBA_LOGGING;MMX;ASM;_CRT_SECURE_NO_WARNINGS;HAS_FILE_EXTRACTOR;NO_OAL"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="true"
|
||||
|
@ -167,7 +167,7 @@
|
|||
InlineFunctionExpansion="2"
|
||||
FavorSizeOrSpeed="1"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories=""..\..\..\dependencies\File_Extractor-0.4.3\fex";..\..\..\dependencies\lpng140;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\zlib"
|
||||
AdditionalIncludeDirectories=""..\..\..\dependencies\File_Extractor-1.0.0";..\..\..\dependencies\lpng140;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\zlib"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;GBA_LOGGING;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE;HAS_FILE_EXTRACTOR;NO_OAL"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
|
|
17
src/Util.cpp
17
src/Util.cpp
|
@ -18,7 +18,7 @@ extern "C" {
|
|||
#include "gba/RTC.h"
|
||||
#include "common/Port.h"
|
||||
|
||||
#include "common/fex.h"
|
||||
#include "fex/fex.h"
|
||||
|
||||
extern "C" {
|
||||
#include "common/memgzio.h"
|
||||
|
@ -387,13 +387,13 @@ void utilStripDoubleExtension(const char *file, char *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
// Opens and scans archive using accept(). Returns File_Extractor if found.
|
||||
// Opens and scans archive using accept(). Returns fex_t if found.
|
||||
// If error or not found, displays message and returns NULL.
|
||||
static File_Extractor* scan_arc(const char *file, bool (*accept)(const char *),
|
||||
static fex_t* scan_arc(const char *file, bool (*accept)(const char *),
|
||||
char (&buffer) [2048] )
|
||||
{
|
||||
fex_err_t err;
|
||||
File_Extractor* fe = fex_open( file, &err );
|
||||
fex_t* fe;
|
||||
fex_err_t err = fex_open( &fe, file );
|
||||
if(!fe)
|
||||
{
|
||||
systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s: %s"), file, err);
|
||||
|
@ -440,7 +440,7 @@ IMAGE_TYPE utilFindType(const char *file)
|
|||
char buffer [2048];
|
||||
if ( !utilIsImage( file ) ) // TODO: utilIsArchive() instead?
|
||||
{
|
||||
File_Extractor* fe = scan_arc(file,utilIsImage,buffer);
|
||||
fex_t* fe = scan_arc(file,utilIsImage,buffer);
|
||||
if(!fe)
|
||||
return IMAGE_UNKNOWN;
|
||||
fex_close(fe);
|
||||
|
@ -465,11 +465,12 @@ u8 *utilLoad(const char *file,
|
|||
{
|
||||
// find image file
|
||||
char buffer [2048];
|
||||
File_Extractor *fe = scan_arc(file,accept,buffer);
|
||||
fex_t *fe = scan_arc(file,accept,buffer);
|
||||
if(!fe)
|
||||
return NULL;
|
||||
|
||||
// Allocate space for image
|
||||
fex_err_t err = fex_stat(fe);
|
||||
int fileSize = fex_size(fe);
|
||||
if(size == 0)
|
||||
size = fileSize;
|
||||
|
@ -490,7 +491,7 @@ u8 *utilLoad(const char *file,
|
|||
|
||||
// Read image
|
||||
int read = fileSize <= size ? fileSize : size; // do not read beyond file
|
||||
fex_err_t err = fex_read_once(fe, image, read);
|
||||
err = fex_read(fe, image, read);
|
||||
fex_close(fe);
|
||||
if(err) {
|
||||
systemMessage(MSG_ERROR_READING_IMAGE,
|
||||
|
|
140
src/common/fex.h
140
src/common/fex.h
|
@ -1,140 +0,0 @@
|
|||
/* Compressed file archive C interface (also usable from C++) */
|
||||
|
||||
/* File_Extractor 0.4.3 */
|
||||
#ifndef FEX_H
|
||||
#define FEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Error string returned by library functions, or NULL if no error (success).
|
||||
If function takes fex_err_t* err_out, it sets *err_out to NULL on success,
|
||||
otherwise error string, or you can pass NULL if you don't care about exact
|
||||
cause of error (these functions still report error by returning NULL). */
|
||||
typedef const char* fex_err_t;
|
||||
|
||||
/* First parameter of most extractor_ functions is a pointer to the
|
||||
File_Extractor being acted on. */
|
||||
typedef struct File_Extractor File_Extractor;
|
||||
|
||||
|
||||
/**** Basics ****/
|
||||
|
||||
/* Opens archive and returns pointer to it, or NULL if error. */
|
||||
File_Extractor* fex_open( const char* path, fex_err_t* err_out );
|
||||
|
||||
/* True if at end of archive. */
|
||||
int fex_done( File_Extractor const* );
|
||||
|
||||
/* Name of current file. */
|
||||
const char* fex_name( File_Extractor* );
|
||||
|
||||
/* Size of current file. */
|
||||
long fex_size( File_Extractor const* );
|
||||
|
||||
/* Extracts n bytes and writes them to *out. Returns error if all n
|
||||
bytes couldn't be extracted (due to end of file or read error). */
|
||||
fex_err_t fex_read( File_Extractor*, void* out, long n );
|
||||
|
||||
/* Goes to next file in archive (skips directories). */
|
||||
fex_err_t fex_next( File_Extractor* );
|
||||
|
||||
/* Closes archive and frees memory. */
|
||||
void fex_close( File_Extractor* );
|
||||
|
||||
|
||||
/**** Advanced ****/
|
||||
|
||||
/* Goes back to first file in archive. */
|
||||
fex_err_t fex_rewind( File_Extractor* );
|
||||
|
||||
/* Hints to fex_next() that no file extraction will occur, speeding scanning
|
||||
of some archive types. */
|
||||
void fex_scan_only( File_Extractor* );
|
||||
|
||||
/* Modification date of current file (MS-DOS format). */
|
||||
unsigned long fex_dos_date( File_Extractor const* );
|
||||
|
||||
/* Number of bytes remaining to be read from current file. */
|
||||
long fex_remain( File_Extractor const* );
|
||||
|
||||
/* Reads at most n bytes and returns number actually read, or negative if error. */
|
||||
long fex_read_avail( File_Extractor*, void* out, long n );
|
||||
|
||||
/* Extracts first n bytes and ignores rest. Faster than a normal read since it
|
||||
doesn't need to read any more data. Must not be called twice in a row. */
|
||||
fex_err_t fex_read_once( File_Extractor*, void* out, long n );
|
||||
|
||||
/* Loads file data into memory (if not already) and returns pointer to it, or
|
||||
NULL if error. Pointer is valid until fex_next(), fex_rewind(), or fex_close() are
|
||||
called. Will return same pointer if called more than once. */
|
||||
const unsigned char* fex_data( File_Extractor*, fex_err_t* err_out );
|
||||
|
||||
|
||||
/**** Archive types ****/
|
||||
|
||||
/* fex_type_t is a pointer to this structure. For example, fex_zip_type->extension is
|
||||
"ZIP" and ex_zip_type->new_fex() is equilvant to 'new Zip_Extractor' (in C++). */
|
||||
struct fex_type_t_
|
||||
{
|
||||
const char* extension; /* file extension/type */
|
||||
File_Extractor* (*new_fex)();
|
||||
};
|
||||
|
||||
/* Archive type constants for each supported file type */
|
||||
extern struct fex_type_t_ const
|
||||
fex_7z_type [1], /* .7z (7-zip) */
|
||||
fex_gz_type [1], /* .gz (gzip) */
|
||||
/*fex_rar_type [1],*/ /* .rar */
|
||||
fex_zip_type [1], /* .zip */
|
||||
fex_bin_type [1]; /* binary file, possibly gzipped */
|
||||
typedef struct fex_type_t_ const* fex_type_t;
|
||||
|
||||
/* Array of supported archive types, with NULL entry at end. */
|
||||
fex_type_t const* fex_type_list();
|
||||
|
||||
/* Type of archive this extractor handles. */
|
||||
fex_type_t fex_type( File_Extractor const* );
|
||||
|
||||
|
||||
/******** Advanced opening ********/
|
||||
|
||||
/* Error returned if file is wrong type */
|
||||
extern const char fex_wrong_file_type [29];
|
||||
|
||||
/* Determines likely archive type based on first four bytes of file. Returns string
|
||||
containing proper file suffix (i.e. "ZIP", "GZ", etc.) or "" (empty string) if file
|
||||
header is not recognized. */
|
||||
const char* fex_identify_header( void const* header );
|
||||
|
||||
/* Gets corresponding archive type for file path or extension passed in. Returns NULL
|
||||
if type isn't recognized. */
|
||||
fex_type_t fex_identify_extension( const char* path_or_extension );
|
||||
|
||||
/* Determines file type based on filename extension, or file header (if extension
|
||||
isn't recognized). Returns NULL if unrecognized or error. */
|
||||
fex_type_t fex_identify_file( const char* path, fex_err_t* err_out );
|
||||
|
||||
/* Opens archive of specific type and returns pointer to it, or NULL if error. */
|
||||
File_Extractor* fex_open_type( fex_type_t, const char* path, fex_err_t* err_out );
|
||||
|
||||
|
||||
/******** User data ********/
|
||||
|
||||
/* Sets/gets pointer to data you want to associate with this extractor.
|
||||
You can use this for whatever you want. */
|
||||
void fex_set_user_data( File_Extractor*, void* new_user_data );
|
||||
void* fex_user_data( File_Extractor const* );
|
||||
|
||||
/* Registers cleanup function to be called when closing extractor, or NULL to
|
||||
clear it. Passes user_data (see above) to cleanup function. */
|
||||
typedef void (*fex_user_cleanup_t)( void* user_data );
|
||||
void fex_set_user_cleanup( File_Extractor*, fex_user_cleanup_t func );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,226 +0,0 @@
|
|||
// Minimal implementation of fex.h. Supports gzipped files if you have zlib
|
||||
// available and HAVE_ZLIB_H is defined.
|
||||
|
||||
// File_Extractor 0.4.3. http://www.slack.net/~ant/
|
||||
|
||||
#include "fex.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. 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 */
|
||||
|
||||
#ifndef HAVE_ZLIB_H
|
||||
#define FILE_GZ( norm, gz ) norm
|
||||
#define FILE_READ( ptr, size, file ) fread( ptr, 1, size, file )
|
||||
#else
|
||||
#define FILE_GZ( norm, gz ) gz
|
||||
#define FILE_READ( ptr, size, file ) gzread( file, ptr, size )
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
static const char* get_gzip_size( const char* path, long* eof )
|
||||
{
|
||||
FILE* file = fopen( path, "rb" );
|
||||
if ( !file )
|
||||
return "Couldn't open file";
|
||||
|
||||
unsigned char buf [4];
|
||||
if ( fread( buf, 2, 1, file ) > 0 && buf [0] == 0x1F && buf [1] == 0x8B )
|
||||
{
|
||||
fseek( file, -4, SEEK_END );
|
||||
if ( !fread( buf, 4, 1, file ) )
|
||||
{
|
||||
fclose( file );
|
||||
return "Couldn't get file size";
|
||||
}
|
||||
*eof = buf [3] * 0x1000000 + buf [2] * 0x10000 + buf [1] * 0x100 + buf [0];
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek( file, 0, SEEK_END );
|
||||
*eof = ftell( file );
|
||||
}
|
||||
const char* err = (ferror( file ) || feof( file )) ? "Couldn't get file size" : 0;
|
||||
fclose( file );
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char fex_wrong_file_type [] = "Archive format not supported";
|
||||
|
||||
struct File_Extractor
|
||||
{
|
||||
FILE_GZ(FILE*,gzFile) file;
|
||||
int done;
|
||||
long size;
|
||||
void* data; // file data read into memory, ot 0 if not read
|
||||
void* user_data;
|
||||
fex_user_cleanup_t user_cleanup;
|
||||
|
||||
char* name() const { return (char*) (this + 1); }
|
||||
};
|
||||
|
||||
// Always identify as single file extractor
|
||||
fex_type_t_ const fex_bin_type [1] = {{ "" , 0 }};
|
||||
const char* fex_identify_header ( void const* ) { return ""; }
|
||||
fex_type_t fex_identify_extension( const char* ) { return fex_bin_type; }
|
||||
fex_type_t fex_identify_file ( const char*, fex_err_t* e ) { if ( e ) *e = 0; return fex_bin_type; }
|
||||
|
||||
static fex_err_t fex_open_( const char* path, File_Extractor** fe_out )
|
||||
{
|
||||
*fe_out = 0;
|
||||
|
||||
// name
|
||||
const char* name = strrchr( path, '\\' ); // DOS
|
||||
if ( !name )
|
||||
name = strrchr( path, '/' ); // UNIX
|
||||
if ( !name )
|
||||
name = strrchr( path, ':' ); // Mac
|
||||
if ( !name )
|
||||
name = path;
|
||||
|
||||
// allocate space for struct and name
|
||||
long name_size = strlen( name ) + 1;
|
||||
File_Extractor* fe = (File_Extractor*) malloc( sizeof (File_Extractor) + name_size );
|
||||
if ( !fe ) return "Out of memory";
|
||||
|
||||
fe->done = 0;
|
||||
fe->data = 0;
|
||||
fe->user_data = 0;
|
||||
fe->user_cleanup = 0;
|
||||
memcpy( fe->name(), name, name_size );
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
// get gzip size BEFORE opening file
|
||||
const char* err = get_gzip_size( path, &fe->size );
|
||||
if ( err )
|
||||
{
|
||||
free( fe );
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
// open file
|
||||
fe->file = FILE_GZ(fopen,gzopen)( path, "rb" );
|
||||
if ( !fe->file )
|
||||
{
|
||||
free( fe );
|
||||
return "Couldn't open file";
|
||||
}
|
||||
|
||||
// get normal size
|
||||
#ifndef HAVE_ZLIB_H
|
||||
fseek( fe->file, 0, SEEK_END );
|
||||
fe->size = ftell( fe->file );
|
||||
rewind( fe->file );
|
||||
#endif
|
||||
|
||||
*fe_out = fe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
File_Extractor* fex_open( const char* path, fex_err_t* err_out )
|
||||
{
|
||||
File_Extractor* fe;
|
||||
fex_err_t err = fex_open_( path, &fe );
|
||||
if ( err_out )
|
||||
*err_out = err;
|
||||
return fe;
|
||||
}
|
||||
|
||||
File_Extractor* fex_open_type( fex_type_t, const char* path, fex_err_t* err_out )
|
||||
{
|
||||
return fex_open( path, err_out );
|
||||
}
|
||||
|
||||
void* fex_user_data ( File_Extractor const* fe ) { return fe->user_data; }
|
||||
void fex_set_user_data ( File_Extractor* fe, void* new_user_data ) { fe->user_data = new_user_data; }
|
||||
void fex_set_user_cleanup ( File_Extractor* fe, fex_user_cleanup_t func ) { fe->user_cleanup = func; }
|
||||
|
||||
fex_type_t fex_type ( File_Extractor const* ) { return fex_bin_type; }
|
||||
int fex_done ( File_Extractor const* fe ) { return fe->done; }
|
||||
const char* fex_name ( File_Extractor* fe ) { return fe->name(); }
|
||||
unsigned long fex_dos_date ( File_Extractor const* ) { return 0; }
|
||||
long fex_size ( File_Extractor const* fe ) { return fe->size; }
|
||||
long fex_remain ( File_Extractor const* fe ) { return fe->size - FILE_GZ(ftell,gztell)( fe->file ); }
|
||||
void fex_scan_only ( File_Extractor* ) { }
|
||||
fex_err_t fex_read_once ( File_Extractor* fe, void* out, long count ) { return fex_read( fe, out, count ); }
|
||||
long fex_read_avail ( File_Extractor* fe, void* out, long count ) { return FILE_READ( out, count, fe->file ); }
|
||||
|
||||
fex_err_t fex_read( File_Extractor* fe, void* out, long count )
|
||||
{
|
||||
if ( count == (long) FILE_READ( out, count, fe->file ) )
|
||||
return 0;
|
||||
|
||||
if ( FILE_GZ(feof,gzeof)( fe->file ) )
|
||||
return "Unexpected end of file";
|
||||
|
||||
return "Couldn't read from file";
|
||||
}
|
||||
|
||||
fex_err_t fex_next( File_Extractor* fe )
|
||||
{
|
||||
fe->done = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fex_err_t fex_rewind( File_Extractor* fe )
|
||||
{
|
||||
fe->done = 0;
|
||||
FILE_GZ(rewind,gzrewind)( fe->file );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fex_err_t fex_data_( File_Extractor* fe )
|
||||
{
|
||||
if ( !fe->data )
|
||||
{
|
||||
fe->data = malloc( fe->size );
|
||||
if ( !fe->data ) return "Out of memory";
|
||||
|
||||
fex_err_t err = fex_read( fe, fe->data, fe->size );
|
||||
if ( err )
|
||||
{
|
||||
free( fe->data );
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const unsigned char* fex_data( File_Extractor* fe, fex_err_t* err_out )
|
||||
{
|
||||
fex_err_t err = fex_data_( fe );
|
||||
if ( err_out )
|
||||
*err_out = err;
|
||||
return (const unsigned char*) fe->data;
|
||||
}
|
||||
|
||||
void fex_close( File_Extractor* fe )
|
||||
{
|
||||
if ( fe )
|
||||
{
|
||||
free( fe->data );
|
||||
FILE_GZ(fclose,gzclose)( fe->file );
|
||||
|
||||
if ( fe->user_cleanup )
|
||||
fe->user_cleanup( fe->user_data );
|
||||
|
||||
free( fe );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue