Fuck git
This commit is contained in:
29
external/unarr/common/allocator.h
vendored
Normal file
29
external/unarr/common/allocator.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
|
||||
#ifndef common_allocator_h
|
||||
#define common_allocator_h
|
||||
|
||||
#ifdef USE_CUSTOM_ALLOCATOR
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef void *(* custom_malloc_fn)(void *opaque, size_t size);
|
||||
typedef void (* custom_free_fn)(void *opaque, void *ptr);
|
||||
|
||||
void ar_set_custom_allocator(custom_malloc_fn custom_malloc, custom_free_fn custom_free, void *opaque);
|
||||
|
||||
#define malloc(size) ar_malloc(size)
|
||||
#define calloc(count, size) ar_calloc(count, size)
|
||||
#define free(ptr) ar_free(ptr)
|
||||
|
||||
#define realloc(ptr, size) _use_malloc_memcpy_free_instead(ptr, size)
|
||||
#define strdup(str) _use_malloc_memcpy_instead(str)
|
||||
|
||||
#elif !defined(NDEBUG) && defined(_MSC_VER)
|
||||
|
||||
#include <crtdbg.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
96
external/unarr/common/conv.c
vendored
Normal file
96
external/unarr/common/conv.c
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
|
||||
#include "unarr-imp.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/* data from http://en.wikipedia.org/wiki/Cp437 */
|
||||
static const wchar_t gCp437[256] = {
|
||||
0, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266C, 0x263C,
|
||||
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
|
||||
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x2302,
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
|
||||
};
|
||||
|
||||
size_t ar_conv_rune_to_utf8(wchar_t rune, char *out, size_t size)
|
||||
{
|
||||
if (size < 1)
|
||||
return 0;
|
||||
if (rune < 0x0080) {
|
||||
*out++ = rune & 0x7F;
|
||||
return 1;
|
||||
}
|
||||
if (rune < 0x0800 && size >= 2) {
|
||||
*out++ = 0xC0 | ((rune >> 6) & 0x1F);
|
||||
*out++ = 0x80 | (rune & 0x3F);
|
||||
return 2;
|
||||
}
|
||||
if (size >= 3) {
|
||||
if ((0xD800 <= rune && rune <= 0xDFFF) || rune >= 0x10000)
|
||||
rune = 0xFFFD;
|
||||
*out++ = 0xE0 | ((rune >> 12) & 0x0F);
|
||||
*out++ = 0x80 | ((rune >> 6) & 0x3F);
|
||||
*out++ = 0x80 | (rune & 0x3F);
|
||||
return 3;
|
||||
}
|
||||
*out++ = '?';
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ar_conv_dos_to_utf8(const char *astr)
|
||||
{
|
||||
char *str, *out;
|
||||
const char *in;
|
||||
size_t size;
|
||||
|
||||
size = 0;
|
||||
for (in = astr; *in; in++) {
|
||||
char buf[4];
|
||||
size += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (size == (size_t)-1)
|
||||
return NULL;
|
||||
str = malloc(size + 1);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
for (in = astr, out = str; *in; in++) {
|
||||
out += ar_conv_rune_to_utf8(gCp437[(uint8_t)*in], out, str + size - out);
|
||||
}
|
||||
*out = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
time64_t ar_conv_dosdate_to_filetime(uint32_t dosdate)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t t1, t2;
|
||||
|
||||
tm.tm_sec = (dosdate & 0x1F) * 2;
|
||||
tm.tm_min = (dosdate >> 5) & 0x3F;
|
||||
tm.tm_hour = (dosdate >> 11) & 0x1F;
|
||||
tm.tm_mday = (dosdate >> 16) & 0x1F;
|
||||
tm.tm_mon = ((dosdate >> 21) & 0x0F) - 1;
|
||||
tm.tm_year = ((dosdate >> 25) & 0x7F) + 80;
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
t1 = mktime(&tm);
|
||||
t2 = mktime(gmtime(&t1));
|
||||
|
||||
return (time64_t)(2 * t1 - t2 + 11644473600) * 10000000;
|
||||
}
|
||||
86
external/unarr/common/crc32.c
vendored
Normal file
86
external/unarr/common/crc32.c
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Copyright 2022 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
#include "unarr-imp.h"
|
||||
|
||||
#if !defined HAVE_ZLIB || !defined USE_ZLIB_CRC
|
||||
|
||||
/*
|
||||
crc32 calculation based on Intel slice-by-8 algorithm with lookup-table generation code
|
||||
adapted from https://gnunet.org/svn/gnunet/src/util/crypto_crc.c (public domain) */
|
||||
|
||||
static inline uint32_t uint32le(const uint8_t *data) { return data[0] | data[1] << 8 | data[2] << 16 | (uint32_t)data[3] << 24; }
|
||||
|
||||
static bool crc_table_ready = false;
|
||||
static uint32_t crc_table[8][256];
|
||||
|
||||
uint32_t ar_crc32(uint32_t crc32, const uint8_t * data, size_t data_len)
|
||||
{
|
||||
if (!crc_table_ready) {
|
||||
|
||||
static const uint32_t crc_poly = 0xEDB88320;
|
||||
|
||||
uint32_t h = 1;
|
||||
crc_table[0][0] = 0;
|
||||
|
||||
for (unsigned int i = 128; i; i >>= 1) {
|
||||
h = (h >> 1) ^ ((h & 1) ? crc_poly : 0);
|
||||
for (unsigned int j = 0; j < 256; j += 2 * i) {
|
||||
crc_table[0][i+j] = crc_table[0][j] ^ h;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 256; i++) {
|
||||
for (unsigned int j = 1; j < 8; j++) {
|
||||
crc_table[j][i] = (crc_table[j-1][i] >> 8) ^ crc_table[0][crc_table[j-1][i] & 0xFF];
|
||||
}
|
||||
}
|
||||
|
||||
crc_table_ready = true;
|
||||
}
|
||||
|
||||
crc32 ^= 0xFFFFFFFF;
|
||||
|
||||
while (data_len >= 8) {
|
||||
|
||||
uint32_t tmp = crc32 ^ uint32le(data);
|
||||
|
||||
crc32 = crc_table[7][ tmp & 0xFF ] ^
|
||||
crc_table[6][(tmp >> 8) & 0xFF ] ^
|
||||
crc_table[5][(tmp >> 16) & 0xFF ] ^
|
||||
crc_table[4][ tmp >> 24 ];
|
||||
|
||||
tmp = uint32le(data + 4);
|
||||
|
||||
crc32 ^= crc_table[3][tmp & 0xFF] ^
|
||||
crc_table[2][(tmp >> 8) & 0xFF] ^
|
||||
crc_table[1][(tmp >> 16) & 0xFF] ^
|
||||
crc_table[0][ tmp >> 24 ];
|
||||
|
||||
data += 8;
|
||||
data_len -= 8;
|
||||
}
|
||||
|
||||
while (data_len-- > 0) {
|
||||
crc32 = (crc32 >> 8) ^ crc_table[0][(crc32 ^ *data++) & 0xFF];
|
||||
}
|
||||
|
||||
return crc32 ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
uint32_t ar_crc32(uint32_t crc, const unsigned char *data, size_t data_len)
|
||||
{
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
while (data_len > UINT32_MAX) {
|
||||
crc = crc32(crc, data, UINT32_MAX);
|
||||
data += UINT32_MAX;
|
||||
data_len -= UINT32_MAX;
|
||||
}
|
||||
#endif
|
||||
return crc32(crc, data, (uint32_t)data_len);
|
||||
}
|
||||
|
||||
#endif
|
||||
49
external/unarr/common/custalloc.c
vendored
Normal file
49
external/unarr/common/custalloc.c
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef void *(* custom_malloc_fn)(void *opaque, size_t size);
|
||||
typedef void (* custom_free_fn)(void *opaque, void *ptr);
|
||||
|
||||
static void *default_malloc(void *opaque, size_t size) { (void)opaque; return malloc(size); }
|
||||
static void default_free(void *opaque, void *ptr) { (void)opaque; free(ptr); }
|
||||
|
||||
static struct {
|
||||
custom_malloc_fn malloc;
|
||||
custom_free_fn free;
|
||||
void *opaque;
|
||||
} gAllocator = {
|
||||
default_malloc,
|
||||
default_free,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void *ar_malloc(size_t size)
|
||||
{
|
||||
return gAllocator.malloc(gAllocator.opaque, size);
|
||||
}
|
||||
|
||||
void *ar_calloc(size_t count, size_t size)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
if (size <= SIZE_MAX / count)
|
||||
ptr = ar_malloc(count * size);
|
||||
if (ptr)
|
||||
memset(ptr, 0, count * size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ar_free(void *ptr)
|
||||
{
|
||||
gAllocator.free(gAllocator.opaque, ptr);
|
||||
}
|
||||
|
||||
void ar_set_custom_allocator(custom_malloc_fn custom_malloc, custom_free_fn custom_free, void *opaque)
|
||||
{
|
||||
gAllocator.malloc = custom_malloc ? custom_malloc : default_malloc;
|
||||
gAllocator.free = custom_free ? custom_free : default_free;
|
||||
gAllocator.opaque = opaque;
|
||||
}
|
||||
217
external/unarr/common/stream.c
vendored
Normal file
217
external/unarr/common/stream.c
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
|
||||
#include "unarr-imp.h"
|
||||
|
||||
ar_stream *ar_open_stream(void *data, ar_stream_close_fn close, ar_stream_read_fn read, ar_stream_seek_fn seek, ar_stream_tell_fn tell)
|
||||
{
|
||||
ar_stream *stream = malloc(sizeof(ar_stream));
|
||||
if (!stream) {
|
||||
close(data);
|
||||
return NULL;
|
||||
}
|
||||
stream->data = data;
|
||||
stream->close = close;
|
||||
stream->read = read;
|
||||
stream->seek = seek;
|
||||
stream->tell = tell;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void ar_close(ar_stream *stream)
|
||||
{
|
||||
if (stream)
|
||||
stream->close(stream->data);
|
||||
free(stream);
|
||||
}
|
||||
|
||||
size_t ar_read(ar_stream *stream, void *buffer, size_t count)
|
||||
{
|
||||
return stream->read(stream->data, buffer, count);
|
||||
}
|
||||
|
||||
bool ar_seek(ar_stream *stream, off64_t offset, int origin)
|
||||
{
|
||||
return stream->seek(stream->data, offset, origin);
|
||||
}
|
||||
|
||||
bool ar_skip(ar_stream *stream, off64_t count)
|
||||
{
|
||||
return stream->seek(stream->data, count, SEEK_CUR);
|
||||
}
|
||||
|
||||
off64_t ar_tell(ar_stream *stream)
|
||||
{
|
||||
return stream->tell(stream->data);
|
||||
}
|
||||
|
||||
/***** stream based on FILE *****/
|
||||
|
||||
static void file_close(void *data)
|
||||
{
|
||||
fclose(data);
|
||||
}
|
||||
|
||||
static size_t file_read(void *data, void *buffer, size_t count)
|
||||
{
|
||||
return fread(buffer, 1, count, data);
|
||||
}
|
||||
|
||||
static bool file_seek(void *data, off64_t offset, int origin)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _fseeki64(data, offset, origin) == 0;
|
||||
#else
|
||||
#if _POSIX_C_SOURCE >= 200112L
|
||||
if (sizeof(off_t) == 8)
|
||||
return fseeko(data, offset, origin) == 0;
|
||||
#endif
|
||||
if (offset > INT32_MAX || offset < INT32_MIN)
|
||||
return false;
|
||||
return fseek(data, (long)offset, origin) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static off64_t file_tell(void *data)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _ftelli64(data);
|
||||
#elif _POSIX_C_SOURCE >= 200112L
|
||||
return ftello(data);
|
||||
#else
|
||||
return ftell(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
ar_stream *ar_open_file(const char *path)
|
||||
{
|
||||
FILE *f = path ? fopen(path, "rb") : NULL;
|
||||
if (!f)
|
||||
return NULL;
|
||||
return ar_open_stream(f, file_close, file_read, file_seek, file_tell);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
ar_stream *ar_open_file_w(const wchar_t *path)
|
||||
{
|
||||
FILE *f = path ? _wfopen(path, L"rb") : NULL;
|
||||
if (!f)
|
||||
return NULL;
|
||||
return ar_open_stream(f, file_close, file_read, file_seek, file_tell);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***** stream based on preallocated memory *****/
|
||||
|
||||
struct MemoryStream {
|
||||
const uint8_t *data;
|
||||
size_t length;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
static void memory_close(void *data)
|
||||
{
|
||||
struct MemoryStream *stm = data;
|
||||
free(stm);
|
||||
}
|
||||
|
||||
static size_t memory_read(void *data, void *buffer, size_t count)
|
||||
{
|
||||
struct MemoryStream *stm = data;
|
||||
if (count > stm->length - stm->offset)
|
||||
count = stm->length - stm->offset;
|
||||
memcpy(buffer, stm->data + stm->offset, count);
|
||||
stm->offset += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static bool memory_seek(void *data, off64_t offset, int origin)
|
||||
{
|
||||
struct MemoryStream *stm = data;
|
||||
if (origin == SEEK_CUR)
|
||||
offset += stm->offset;
|
||||
else if (origin == SEEK_END)
|
||||
offset += stm->length;
|
||||
if (offset < 0 || offset > (off64_t)stm->length || (size_t)offset > stm->length)
|
||||
return false;
|
||||
stm->offset = (size_t)offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
static off64_t memory_tell(void *data)
|
||||
{
|
||||
struct MemoryStream *stm = data;
|
||||
return stm->offset;
|
||||
}
|
||||
|
||||
ar_stream *ar_open_memory(const void *data, size_t datalen)
|
||||
{
|
||||
struct MemoryStream *stm = malloc(sizeof(struct MemoryStream));
|
||||
if (!stm)
|
||||
return NULL;
|
||||
stm->data = data;
|
||||
stm->length = datalen;
|
||||
stm->offset = 0;
|
||||
return ar_open_stream(stm, memory_close, memory_read, memory_seek, memory_tell);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/***** stream based on IStream *****/
|
||||
|
||||
#define COBJMACROS
|
||||
#include <windows.h>
|
||||
|
||||
static void stream_close(void *data)
|
||||
{
|
||||
IUnknown_Release((IStream *)data);
|
||||
}
|
||||
|
||||
static size_t stream_read(void *data, void *buffer, size_t count)
|
||||
{
|
||||
size_t read = 0;
|
||||
HRESULT res;
|
||||
ULONG cbRead;
|
||||
#ifdef _WIN64
|
||||
while (count > ULONG_MAX) {
|
||||
res = IStream_Read((IStream *)data, buffer, ULONG_MAX, &cbRead);
|
||||
if (FAILED(res))
|
||||
return read;
|
||||
read += cbRead;
|
||||
buffer = (BYTE *)buffer + ULONG_MAX;
|
||||
count -= ULONG_MAX;
|
||||
}
|
||||
#endif
|
||||
res = IStream_Read((IStream *)data, buffer, (ULONG)count, &cbRead);
|
||||
if (SUCCEEDED(res))
|
||||
read += cbRead;
|
||||
return read;
|
||||
}
|
||||
|
||||
static bool stream_seek(void *data, off64_t offset, int origin)
|
||||
{
|
||||
LARGE_INTEGER off;
|
||||
ULARGE_INTEGER n;
|
||||
HRESULT res;
|
||||
off.QuadPart = offset;
|
||||
res = IStream_Seek((IStream *)data, off, origin, &n);
|
||||
return SUCCEEDED(res);
|
||||
}
|
||||
|
||||
static off64_t stream_tell(void *data)
|
||||
{
|
||||
LARGE_INTEGER zero = { 0 };
|
||||
ULARGE_INTEGER n = { 0 };
|
||||
IStream_Seek((IStream *)data, zero, SEEK_CUR, &n);
|
||||
return (off64_t)n.QuadPart;
|
||||
}
|
||||
|
||||
ar_stream *ar_open_istream(IStream *stream)
|
||||
{
|
||||
LARGE_INTEGER zero = { 0 };
|
||||
HRESULT res = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
|
||||
if (FAILED(res))
|
||||
return NULL;
|
||||
IUnknown_AddRef(stream);
|
||||
return ar_open_stream(stream, stream_close, stream_read, stream_seek, stream_tell);
|
||||
}
|
||||
#endif
|
||||
84
external/unarr/common/unarr-imp.h
vendored
Normal file
84
external/unarr/common/unarr-imp.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/* Copyright 2015 the unarr project authors (see AUTHORS file).
|
||||
License: LGPLv3 */
|
||||
|
||||
/* this is the common private/implementation API of unarr which should only be used by unarr code */
|
||||
|
||||
#ifndef common_unarr_imp_h
|
||||
#define common_unarr_imp_h
|
||||
|
||||
#include "../unarr.h"
|
||||
#include "allocator.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/***** conv ****/
|
||||
|
||||
size_t ar_conv_rune_to_utf8(wchar_t rune, char *out, size_t size);
|
||||
char *ar_conv_dos_to_utf8(const char *astr);
|
||||
time64_t ar_conv_dosdate_to_filetime(uint32_t dosdate);
|
||||
|
||||
/***** crc32 *****/
|
||||
|
||||
uint32_t ar_crc32(uint32_t crc32, const unsigned char *data, size_t data_len);
|
||||
|
||||
/***** stream *****/
|
||||
|
||||
typedef void (* ar_stream_close_fn)(void *data);
|
||||
typedef size_t (* ar_stream_read_fn)(void *data, void *buffer, size_t count);
|
||||
typedef bool (* ar_stream_seek_fn)(void *data, off64_t offset, int origin);
|
||||
typedef off64_t (* ar_stream_tell_fn)(void *data);
|
||||
|
||||
struct ar_stream_s {
|
||||
ar_stream_close_fn close;
|
||||
ar_stream_read_fn read;
|
||||
ar_stream_seek_fn seek;
|
||||
ar_stream_tell_fn tell;
|
||||
void *data;
|
||||
};
|
||||
|
||||
ar_stream *ar_open_stream(void *data, ar_stream_close_fn close, ar_stream_read_fn read, ar_stream_seek_fn seek, ar_stream_tell_fn tell);
|
||||
|
||||
/***** unarr *****/
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
#define warn(...) ar_log("!", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define warn(...) ((void)0)
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
#define log(...) ar_log("-", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define log(...) ((void)0)
|
||||
#endif
|
||||
void ar_log(const char *prefix, const char *file, int line, const char *msg, ...);
|
||||
|
||||
typedef void (* ar_archive_close_fn)(ar_archive *ar);
|
||||
typedef bool (* ar_parse_entry_fn)(ar_archive *ar, off64_t offset);
|
||||
typedef const char *(* ar_entry_get_name_fn)(ar_archive *ar, bool raw);
|
||||
typedef bool (* ar_entry_uncompress_fn)(ar_archive *ar, void *buffer, size_t count);
|
||||
typedef size_t (* ar_get_global_comment_fn)(ar_archive *ar, void *buffer, size_t count);
|
||||
|
||||
struct ar_archive_s {
|
||||
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;
|
||||
|
||||
ar_stream *stream;
|
||||
bool at_eof;
|
||||
off64_t entry_offset;
|
||||
off64_t entry_offset_first;
|
||||
off64_t entry_offset_next;
|
||||
size_t entry_size_uncompressed;
|
||||
time64_t entry_filetime;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
114
external/unarr/common/unarr.c
vendored
Normal file
114
external/unarr/common/unarr.c
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user