libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
stream.c
1#include "config.h"
2#include "debug.h"
3#include <clod/stream.h>
4
5int clod_stream_copy(clod_stream *dst, clod_stream *src, void *const buffer, const size_t buffer_size, size_t *total_transferred) {
6 if (buffer_size == 0) {
7 debug(CLOD_DEBUG, "Invalid buffer size for stream copy.");
8 return CLOD_STREAM_INVALID;
9 }
10
11 if (dst->write == nullptr) {
12 debug(CLOD_DEBUG, "Provided stream %ptr doesn't support writing.", (void*)dst);
13 return CLOD_STREAM_INVALID;
14 }
15
16 if (src->read == nullptr) {
17 debug(CLOD_DEBUG, "Provided stream %ptr doesn't support reading.", (void*)src);
18 return CLOD_STREAM_INVALID;
19 }
20
21 size_t transferred = 0;
22 while (1) {
23 struct clod_string buff = (struct clod_string){ .ptr = buffer, .len = 0, .cap = (ptrdiff_t)buffer_size};
24 int read_res = src->read(src, &buff);
25
26 int write_res = 0;
27 if (buff.len > 0) {
28 write_res = dst->write(dst, &buff);
29 transferred += (size_t)buff.ptr - (size_t)buffer;
30 }
31
32 if (buff.len > 0) {
33 debug(CLOD_DEBUG, "Short write to stream %ptr.", (void*)dst);
34 }
35
36 if (read_res == CLOD_STREAM_EOF) {
37 if (total_transferred) *total_transferred = transferred;
38 return 0;
39 }
40
41 if (read_res != CLOD_STREAM_OK) {
42 if (total_transferred) *total_transferred = transferred;
43 return read_res;
44 }
45 if (write_res != CLOD_STREAM_OK) {
46 if (total_transferred) *total_transferred = transferred;
47 return write_res;
48 }
49 }
50}
int(* write)(clod_stream *self, struct clod_string *src)
Definition stream.h:88
int(* read)(clod_stream *self, struct clod_string *dst)
Definition stream.h:72
char * ptr
Definition string.h:28
ptrdiff_t len
Definition string.h:32