diff options
Diffstat (limited to 'lib/sqfs/src')
-rw-r--r-- | lib/sqfs/src/istream.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/sqfs/src/istream.c b/lib/sqfs/src/istream.c new file mode 100644 index 0000000..3d89461 --- /dev/null +++ b/lib/sqfs/src/istream.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#define SQFS_BUILDING_DLL +#include "config.h" + +#include "sqfs/io.h" + +#include <string.h> + +sqfs_s32 sqfs_istream_read(sqfs_istream_t *strm, void *data, size_t size) +{ + sqfs_s32 total = 0; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + const sqfs_u8 *ptr; + size_t diff; + int ret; + + ret = strm->get_buffered_data(strm, &ptr, &diff, size); + if (ret > 0) + break; + if (ret < 0) + return ret; + + if (diff > size) + diff = size; + + memcpy(data, ptr, diff); + strm->advance_buffer(strm, diff); + data = (char *)data + diff; + size -= diff; + total += diff; + } + + return total; +} + +int sqfs_istream_skip(sqfs_istream_t *strm, sqfs_u64 size) +{ + while (size > 0) { + const sqfs_u8 *ptr; + size_t diff; + int ret; + + ret = strm->get_buffered_data(strm, &ptr, &diff, size); + if (ret < 0) + return ret; + if (ret > 0) + break; + + if ((sqfs_u64)diff > size) + diff = size; + + size -= diff; + strm->advance_buffer(strm, diff); + } + + return 0; +} + +sqfs_s32 sqfs_istream_splice(sqfs_istream_t *in, sqfs_ostream_t *out, + sqfs_u32 size) +{ + sqfs_s32 total = 0; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + const sqfs_u8 *ptr; + size_t diff; + int ret; + + ret = in->get_buffered_data(in, &ptr, &diff, size); + if (ret < 0) + return ret; + if (ret > 0) + break; + + if (diff > size) + diff = size; + + ret = out->append(out, ptr, diff); + if (ret) + return ret; + + total += diff; + size -= diff; + in->advance_buffer(in, diff); + } + + return total; +} |