GPAK  1.0.0
A general-purpose archive library

◆ gpak_open()

GPAK_API gpak_t* gpak_open ( const char *  _path,
int  _mode 
)
Brief Description:\n Opens a G-PAK archive.

This function opens a G-PAK archive at the specified _path and with the given _mode.

Parameters
_pathA string containing the path to the G-PAK archive.
_modeThe mode in which to open the G-PAK archive.
Returns
A pointer to the opened gpak_t or NULL if an error occurred.

Definition at line 213 of file gpak.c.

214 {
215  gpak_t* pak;
216  pak = (gpak_t*)calloc(1, sizeof(gpak_t));
217  pak->mode_ = _mode;
218  pak->current_file_ = NULL;
219  pak->error_handler_ = NULL;
220  pak->progress_handler_ = NULL;
221  pak->user_data_ = NULL;
222  pak->dictionary_ = NULL;
223 
224  const char* open_mode_;
225  if (_mode & GPAK_MODE_CREATE)
226  open_mode_ = "wb+";
227  else if (_mode & GPAK_MODE_READ_ONLY)
228  open_mode_ = "rb+";
229  else if (_mode & GPAK_MODE_UPDATE)
230  open_mode_ = "ab+";
231  else
232  {
233  gpak_close(pak);
234  return NULL;
235  }
236 
237  // Trying to open pak file
238  pak->stream_ = fopen(_path, open_mode_);
239 
240  if (pak->stream_ == NULL)
241  {
242  gpak_close(pak);
243  return NULL;
244  }
245 
246  pak->root_ = filesystem_tree_create();
247 
248  if (_mode & GPAK_MODE_CREATE)
249  {
250  pak->header_ = _pak_make_header();
251  size_t res = _fwriteb(&pak->header_, sizeof(pak_header_t), 1ull, pak->stream_);
252  if (res != sizeof(pak_header_t))
253  {
254  gpak_close(pak);
255  return NULL;
256  }
257  }
258  else if (_mode & GPAK_MODE_UPDATE)
259  {
260  fseek(pak->stream_, 0, SEEK_SET);
261 
262  size_t res = _freadb(&pak->header_, sizeof(pak_header_t), 1ull, pak->stream_);
263  if (_pak_validate_header(pak) != GPAK_ERROR_OK || res != sizeof(pak_header_t))
264  {
265  gpak_close(pak);
266  return NULL;
267  }
268 
269  _gpak_parse_dictionary(pak);
270  _gpak_parse_file_tree(pak);
271 
272  fseek(pak->stream_, 0, SEEK_END);
273  }
274  else if (_mode & GPAK_MODE_READ_ONLY)
275  {
276  size_t res = _freadb(&pak->header_, sizeof(pak_header_t), 1ull, pak->stream_);
277  if (_pak_validate_header(pak) != GPAK_ERROR_OK || res != sizeof(pak_header_t))
278  {
279  gpak_close(pak);
280  return NULL;
281  }
282 
283  _gpak_parse_dictionary(pak);
284  _gpak_parse_file_tree(pak);
285  }
286 
287  return pak;
288 }
GPAK_API filesystem_tree_node_t * filesystem_tree_create()
GPAK_API int gpak_close(gpak_t *_pak)
Definition: gpak.c:290
@ GPAK_MODE_READ_ONLY
Definition: gpak_data.h:208
@ GPAK_MODE_CREATE
Definition: gpak_data.h:207
@ GPAK_MODE_UPDATE
Definition: gpak_data.h:209
@ GPAK_ERROR_OK
Definition: gpak_data.h:155
gpak_progress_handler_t progress_handler_
Definition: gpak_data.h:265
char * current_file_
Definition: gpak_data.h:263
char * dictionary_
Definition: gpak_data.h:262
struct filesystem_tree_node * root_
Definition: gpak_data.h:260
void * user_data_
Definition: gpak_data.h:266
gpak_error_handler_t error_handler_
Definition: gpak_data.h:264
FILE * stream_
Definition: gpak_data.h:259
int mode_
Definition: gpak_data.h:257
pak_header_t header_
Definition: gpak_data.h:258

References gpak::current_file_, gpak::dictionary_, gpak::error_handler_, filesystem_tree_create(), gpak_close(), GPAK_ERROR_OK, GPAK_MODE_CREATE, GPAK_MODE_READ_ONLY, GPAK_MODE_UPDATE, gpak::header_, gpak::mode_, gpak::progress_handler_, gpak::root_, gpak::stream_, and gpak::user_data_.