11 #include "libfmemopen.h"
15 #include "gpak_helper.h"
27 strcpy(_header.
format_,
"gpak\0");
36 int _pak_validate_header(
gpak_t* _pak)
46 long bytes_writen = 0u;
49 short name_size = strlen(_path);
50 bytes_writen += _fwriteb(&name_size,
sizeof(
short), 1ull, _pak->
stream_);
51 bytes_writen += _fwriteb(_path, 1ull, name_size, _pak->
stream_);
59 long bytes_readed = 0u;
62 bytes_readed += _freadb(&name_size,
sizeof(
short), 1ull, _pak->
stream_);
63 bytes_readed += _freadb(_path, 1ull, name_size, _pak->
stream_);
65 _path[name_size] =
'\0';
70 int _update_entry_header(
gpak_t* _pak,
size_t _commressed_size,
size_t _uncompressed_size,
long _entry_size, uint32_t _crc32)
78 if (_uncompressed_size == _commressed_size)
79 _shift = _uncompressed_size;
81 _shift = _commressed_size;
83 long _cur_pos = ftell(_pak->
stream_);
84 fseek(_pak->
stream_, -((
long)_shift), SEEK_CUR);
85 long _offset = ftell(_pak->
stream_);
86 fseek(_pak->
stream_, -_entry_size, SEEK_CUR);
88 char _entry_path[256];
89 _read_entry_header(_pak, _entry_path, &_entry);
96 fseek(_pak->
stream_, -_entry_size, SEEK_CUR);
98 _write_entry_header(_pak, _entry_path, &_entry);
100 fseek(_pak->
stream_, 0l, SEEK_END);
102 if (_cur_pos != ftell(_pak->
stream_))
108 int _update_pak_header(
gpak_t* _pak)
110 fseek(_pak->
stream_, 0, SEEK_SET);
115 fseek(_pak->
stream_, 0l, SEEK_END);
127 int _gpak_archivate_file_tree(
gpak_t* _pak)
139 long header_size = _write_entry_header(_pak, _pak->
current_file_, &_entry);
141 FILE* _infile = fopen(next_file->
path_,
"rb");
142 FILE* _outfile = NULL;
146 long cursor = ftell(_pak->
stream_);
148 uint32_t _crc32 = 0u;
156 long position = ftell(_pak->
stream_);
157 size_t uncompressed_size = ftell(_infile);
158 size_t compressed_size = position - cursor;
162 _update_entry_header(_pak, compressed_size, uncompressed_size, header_size, _crc32);
174 int _gpak_parse_dictionary(
gpak_t* _pak)
190 int _gpak_parse_file_tree(
gpak_t* _pak)
196 size_t readed = _read_entry_header(_pak, _filename, &_entry);
224 const char* open_mode_;
238 pak->
stream_ = fopen(_path, open_mode_);
250 pak->
header_ = _pak_make_header();
260 fseek(pak->
stream_, 0, SEEK_SET);
269 _gpak_parse_dictionary(pak);
270 _gpak_parse_file_tree(pak);
272 fseek(pak->
stream_, 0, SEEK_END);
283 _gpak_parse_dictionary(pak);
284 _gpak_parse_file_tree(pak);
306 _gpak_archivate_file_tree(_pak);
311 _update_pak_header(_pak);
404 mfile->
data_ = (
char*)malloc(uncompressed_size + 1);
405 mfile->
data_[uncompressed_size] =
'\0';
407 mfile->
stream_ = fmemopen(mfile->
data_, uncompressed_size,
"wb+");
419 fseek(mfile->
stream_, 0, SEEK_SET);
442 return fgets(_buffer, _max, _file->
stream_);
447 return ungetc(_character, _file->
stream_);
452 return fread(_buffer, _elemSize, _elemCount, _file->
stream_);
462 return fseek(_file->
stream_, _offset, _origin);
GPAK_API filesystem_tree_node_t * filesystem_tree_find_directory(filesystem_tree_node_t *_root, const char *_path)
GPAK_API char * filesystem_tree_file_path(filesystem_tree_node_t *_node, filesystem_tree_file_t *_file)
GPAK_API filesystem_tree_node_t * filesystem_tree_create()
GPAK_API filesystem_tree_node_t * filesystem_iterator_next_directory(filesystem_tree_iterator_t *_iterator)
GPAK_API void filesystem_iterator_free(filesystem_tree_iterator_t *_iterator)
GPAK_API void filesystem_tree_delete(filesystem_tree_node_t *_root)
GPAK_API void filesystem_tree_add_file(filesystem_tree_node_t *_root, const char *_path, const char *_file_path, pak_entry_t _entry)
GPAK_API void filesystem_tree_add_directory(filesystem_tree_node_t *_root, const char *_path)
GPAK_API filesystem_tree_iterator_t * filesystem_iterator_create(filesystem_tree_node_t *_root)
GPAK_API filesystem_tree_file_t * filesystem_iterator_next_file(filesystem_tree_iterator_t *_iterator)
GPAK_API filesystem_tree_file_t * filesystem_tree_find_file(filesystem_tree_node_t *_root, const char *_path)
GPAK_API struct filesystem_tree_file * gpak_find_file(gpak_t *_pak, const char *_path)
GPAK_API void gpak_set_compression_algorithm(gpak_t *_pak, int _algorithm)
GPAK_API long gpak_feof(gpak_file_t *_file)
GPAK_API int gpak_fgetc(gpak_file_t *_file)
GPAK_API int gpak_add_file(gpak_t *_pak, const char *_external_path, const char *_internal_path)
GPAK_API gpak_t * gpak_open(const char *_path, int _mode)
GPAK_API char * gpak_fgets(gpak_file_t *_file, char *_buffer, int _max)
GPAK_API size_t gpak_fread(void *_buffer, size_t _elemSize, size_t _elemCount, gpak_file_t *_file)
GPAK_API void gpak_set_error_handler(gpak_t *_pak, gpak_error_handler_t _error_handler)
GPAK_API int gpak_close(gpak_t *_pak)
GPAK_API int gpak_ungetc(gpak_file_t *_file, int _character)
GPAK_API void gpak_set_user_data(gpak_t *_pak, void *_user_data)
GPAK_API void gpak_set_compression_level(gpak_t *_pak, int _level)
GPAK_API gpak_file_t * gpak_fopen(gpak_t *_pak, const char *_path)
GPAK_API struct filesystem_tree_node * gpak_find_directory(gpak_t *_pak, const char *_path)
GPAK_API long gpak_fseek(gpak_file_t *_file, long _offset, int _origin)
GPAK_API long gpak_ftell(gpak_file_t *_file)
GPAK_API struct filesystem_tree_node * gpak_get_root(gpak_t *_pak)
GPAK_API int gpak_add_directory(gpak_t *_pak, const char *_internal_path)
GPAK_API void gpak_fclose(gpak_file_t *_file)
GPAK_API void gpak_set_process_handler(gpak_t *_pak, gpak_progress_handler_t _progress_handler)
GPAK_API uint32_t _gpak_compressor_deflate(gpak_t *_pak, FILE *_infile, FILE *_outfile)
GPAK_API uint32_t _gpak_compressor_none(gpak_t *_pak, FILE *_infile, FILE *_outfile)
GPAK_API uint32_t _gpak_decompressor_none(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API uint32_t _gpak_decompressor_inflate(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API uint32_t _gpak_decompressor_zstd(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API int32_t _gpak_compressor_generate_dictionary(gpak_t *_pak)
GPAK_API uint32_t _gpak_compressor_zstd(gpak_t *_pak, FILE *_infile, FILE *_outfile)
@ GPAK_HEADER_COMPRESSION_NONE
@ GPAK_HEADER_COMPRESSION_ZST
@ GPAK_HEADER_COMPRESSION_DEFLATE
void(* gpak_error_handler_t)(const char *, int32_t, void *)
void(* gpak_progress_handler_t)(const char *, size_t, size_t, int32_t, void *)
@ GPAK_ERROR_INVALID_DICTIONARY
@ GPAK_ERROR_STREAM_IS_NULL
@ GPAK_ERROR_FILE_NOT_FOUND
@ GPAK_ERROR_INCORRECT_HEADER
@ GPAK_ERROR_FILE_CRC_NOT_MATCH
gpak_progress_handler_t progress_handler_
struct filesystem_tree_node * root_
gpak_error_handler_t error_handler_