-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstream.cpp
119 lines (107 loc) · 3.14 KB
/
stream.cpp
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
#include "stream.h"
#include "objects/string.h"
#include "utils.h"
#include "value.h"
StringStream::StringStream() : str(NULL), size(0), capacity(0), closed(false) {}
std::size_t StringStream::write(const double &value) {
// from
// https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value
static char val[1079];
size_t written = snprintf(val, 1079, "%0.14g", value);
return writebytes(val, written);
}
std::size_t StringStream::write(const int64_t &value) {
static char val[22];
size_t written = snprintf(val, 22, "%" PRId64, value);
return writebytes(val, written);
}
std::size_t StringStream::write(const size_t &value) {
static char val[22];
size_t written = snprintf(val, 22, "%" PRIu64, value);
return writebytes(val, written);
}
std::size_t StringStream::writebytes(const void *const &data, size_t bytes) {
if(size + bytes > capacity) {
size_t oldc = capacity;
capacity = Utils::nextAllocationSize(capacity, size + bytes);
str = Gc_realloc(str, oldc, capacity);
}
std::memcpy((char *)str + size, data, bytes);
size += bytes;
return bytes;
}
std::size_t WritableStream::write(const Utf8Source &w) {
return writebytes(w.source, utf8size(w.source));
}
std::size_t WritableStream::write(const utf8_int32_t &val) {
uint8_t bytes[4] = {0};
utf8catcodepoint(bytes, val, 4);
return writebytes(bytes, utf8codepointsize(val));
}
Value StringStream::toString() {
return String::from(str, size);
}
StringStream::~StringStream() {
if(capacity) {
Gc_free(str, capacity);
}
}
std::size_t ReadableStream::read(std::size_t n, Utf8Source &source) {
size_t totallen = 0;
char * buf = NULL;
for(size_t i = 0; i < n; i++) {
utf8_int32_t val;
size_t l = read(val);
size_t cpsize = utf8codepointsize(val);
if(l == 0 || l != cpsize) {
if(totallen) {
Gc_free(buf, totallen);
}
return l;
}
buf = (char *)Gc_realloc(buf, totallen, totallen + l);
utf8catcodepoint(&buf[totallen], val, l);
totallen += l;
}
buf = (char *)Gc_realloc(buf, totallen, totallen + 1);
buf[totallen] = 0;
source = Utf8Source(buf);
return totallen;
}
std::size_t FileStream::read(Utf8Source &source) {
int64_t pos = ftell(file);
fseek(file, 0, SEEK_END);
int64_t end = ftell(file);
fseek(file, pos, SEEK_SET);
int64_t length = end - pos;
char * buffer = (char *)Gc_malloc(length + 1);
size_t out;
if((out = fread(buffer, length, 1, file)) != 1) {
return out;
}
buffer[length] = 0;
source = Utf8Source(buffer);
return length;
}
std::size_t StdInputStream::read(Utf8Source &source) {
char * buf = NULL;
size_t totallen = 0;
while(true) {
utf8_int32_t val = 0;
ReadableStream::read(val);
if(val == 0 || val == (utf8_int32_t)EOF) {
eof = true;
break;
} else if(val == '\n') {
break;
}
size_t cpsize = utf8codepointsize(val);
buf = (char *)Gc_realloc(buf, totallen, totallen + cpsize);
utf8catcodepoint(&buf[totallen], val, cpsize);
totallen += cpsize;
}
buf = (char *)Gc_realloc(buf, totallen, totallen + 1);
buf[totallen] = 0;
source = Utf8Source(buf);
return totallen;
}