git-subtree-dir: external/unarr git-subtree-split: f243d72fb3fe418c26a19514609ac7167d089df4
115 lines
2.7 KiB
C
115 lines
2.7 KiB
C
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
|
License: LGPLv3 */
|
|
|
|
#include "unarr-imp.h"
|
|
|
|
ar_archive *ar_open_archive(ar_stream *stream, size_t struct_size, ar_archive_close_fn close, ar_parse_entry_fn parse_entry,
|
|
ar_entry_get_name_fn get_name, ar_entry_uncompress_fn uncompress, ar_get_global_comment_fn get_comment,
|
|
off64_t first_entry_offset)
|
|
{
|
|
ar_archive *ar = malloc(struct_size);
|
|
if (!ar)
|
|
return NULL;
|
|
memset(ar, 0, struct_size);
|
|
ar->close = close;
|
|
ar->parse_entry = parse_entry;
|
|
ar->get_name = get_name;
|
|
ar->uncompress = uncompress;
|
|
ar->get_comment = get_comment;
|
|
ar->stream = stream;
|
|
ar->entry_offset_first = first_entry_offset;
|
|
ar->entry_offset_next = first_entry_offset;
|
|
return ar;
|
|
}
|
|
|
|
void ar_close_archive(ar_archive *ar)
|
|
{
|
|
if (ar)
|
|
ar->close(ar);
|
|
free(ar);
|
|
}
|
|
|
|
bool ar_at_eof(ar_archive *ar)
|
|
{
|
|
return ar->at_eof;
|
|
}
|
|
|
|
bool ar_parse_entry(ar_archive *ar)
|
|
{
|
|
return ar->parse_entry(ar, ar->entry_offset_next);
|
|
}
|
|
|
|
bool ar_parse_entry_at(ar_archive *ar, off64_t offset)
|
|
{
|
|
ar->at_eof = false;
|
|
return ar->parse_entry(ar, offset ? offset : ar->entry_offset_first);
|
|
}
|
|
|
|
bool ar_parse_entry_for(ar_archive *ar, const char *entry_name)
|
|
{
|
|
ar->at_eof = false;
|
|
if (!entry_name)
|
|
return false;
|
|
if (!ar_parse_entry_at(ar, ar->entry_offset_first))
|
|
return false;
|
|
do {
|
|
const char *name = ar_entry_get_name(ar);
|
|
if (name && strcmp(name, entry_name) == 0)
|
|
return true;
|
|
} while (ar_parse_entry(ar));
|
|
return false;
|
|
}
|
|
|
|
const char *ar_entry_get_name(ar_archive *ar)
|
|
{
|
|
return ar->get_name(ar, false);
|
|
}
|
|
|
|
const char *ar_entry_get_raw_name(ar_archive *ar)
|
|
{
|
|
return ar->get_name(ar, true);
|
|
}
|
|
|
|
off64_t ar_entry_get_offset(ar_archive *ar)
|
|
{
|
|
return ar->entry_offset;
|
|
}
|
|
|
|
size_t ar_entry_get_size(ar_archive *ar)
|
|
{
|
|
return ar->entry_size_uncompressed;
|
|
}
|
|
|
|
time64_t ar_entry_get_filetime(ar_archive *ar)
|
|
{
|
|
return ar->entry_filetime;
|
|
}
|
|
|
|
bool ar_entry_uncompress(ar_archive *ar, void *buffer, size_t count)
|
|
{
|
|
return ar->uncompress(ar, buffer, count);
|
|
}
|
|
|
|
size_t ar_get_global_comment(ar_archive *ar, void *buffer, size_t count)
|
|
{
|
|
if (!ar->get_comment)
|
|
return 0;
|
|
return ar->get_comment(ar, buffer, count);
|
|
}
|
|
|
|
void ar_log(const char *prefix, const char *file, int line, const char *msg, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, msg);
|
|
if (prefix)
|
|
fprintf(stderr, "%s ", prefix);
|
|
if (strrchr(file, '/'))
|
|
file = strrchr(file, '/') + 1;
|
|
if (strrchr(file, '\\'))
|
|
file = strrchr(file, '\\') + 1;
|
|
fprintf(stderr, "%s:%d: ", file, line);
|
|
vfprintf(stderr, msg, args);
|
|
fprintf(stderr, "\n");
|
|
va_end(args);
|
|
}
|