summaryrefslogtreecommitdiff
path: root/src/stream.c
blob: 6780d02866d2490460cd41f669f069570edec315 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "stream.h"
#include "lib.h"

#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static uint64_t longswap(uint64_t ll) {
	if (htons(20) == 20)
		return ll;

	union { uint64_t ll; uint8_t c[8]; } out = {0};
	union { uint64_t ll; uint8_t c[8]; } in = {ll};

	for (int i = 0; i < 8; i++)
		out.c[7-i] = in.c[i];

	return out.ll;
}


stream_t stream_open(const char *path, const char* mode) {
	stream_t stream;

	if (strcmp("-", path) == 0) {
		if (*mode == 'r')
			stream.__file = stdin;
		else
			stream.__file = stdout;
		stream.__alloc = false;
		return stream;
	}

	stream.__file = fopen(path, mode);
	stream.__alloc = true;

	if (stream.__file == NULL) {
		perror_and_die("cannot open '%s'", path);
	};

	return stream;
}

void stream_close(stream_t *stream) {
	if (stream->__alloc)
		fclose(stream->__file);
}

bool stream_read(const stream_t *stream, void *res, size_t amount) {
	size_t read;
	read = fread(res, 1, amount, stream->__file);

	if (read == 0) {
		if (feof(stream->__file) || errno == 0)
			return false;
		else
		    perror_and_die("cannot read from stream");
	}

	return true;
}

bool stream_read_i8(const stream_t *stream, int8_t *res) {
	if (stream_read(stream, res, 1) == false)
		return false;
	return true;
}

bool stream_read_i16(const stream_t *stream, int16_t *res) {
	if (stream_read(stream, res, 2) == false)
		return false;
	*res = ntohs(*res);
	return true;
}

bool stream_read_i32(const stream_t *stream, int32_t *res) {
	if (stream_read(stream, res, 4) == false)
		return false;
	*res = ntohl(*res);
	return true;
}

bool stream_read_i64(const stream_t *stream, int64_t *res) {
	if (stream_read(stream, res, 8) == false)
		return false;
	*res = longswap(*res);
	return true;
}

bool stream_read_u16(const stream_t *stream, uint16_t *res) {
	if (stream_read(stream, res, 2) == false)
		return false;
	*res = ntohs(*res);
	return true;
}

bool stream_write(const stream_t *stream, const void *buf, size_t amount) {
	size_t wrote;
	wrote = fwrite(buf, 1, amount, stream->__file);

	if (wrote == 0)
		perror_and_die("cannot write to stream");

	if (wrote < amount)
		return false;

	return true;
}

bool stream_write_i8(const stream_t *stream, int8_t b) {
	if (stream_write(stream, &b, 1) == false)
		return false;
	return true;
}

bool stream_write_i16(const stream_t *stream, int16_t s) {
	s = htons(s);
	if (stream_write(stream, &s, 2) == false)
		return false;
	return true;
}

bool stream_write_i32(const stream_t *stream, int32_t i) {
	i = htonl(i);
	if (stream_write(stream, &i, 4) == false)
		return false;
	return true;
}

bool stream_write_i64(const stream_t *stream, int64_t l) {
	l = longswap(l);
	if (stream_write(stream, &l, 8) == false)
		return false;
	return true;
}

bool stream_write_u16(const stream_t *stream, uint16_t s) {
	s = htons(s);
	if (stream_write(stream, &s, 2) == false)
		return false;
	return true;
}