aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/src/io/stream_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/src/io/stream_api.c')
-rw-r--r--lib/sqfs/src/io/stream_api.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/lib/sqfs/src/io/stream_api.c b/lib/sqfs/src/io/stream_api.c
new file mode 100644
index 0000000..60e8472
--- /dev/null
+++ b/lib/sqfs/src/io/stream_api.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: LGPL-3.0-or-later */
+/*
+ * stream_api.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;
+}