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
|
#include "stringstream.h"
#include <assert.h>
static int StringStreamClose(Stream *base)
{
StringStream *ss = (StringStream *) base;
bdestroy(ss->buffer);
ss->buffer = NULL;
return 0;
}
static int64_t StringStreamRead(void *ptr, size_t size, Stream *stream)
{
StringStream *ss = (StringStream *) stream;
int64_t available = blength(ss->buffer) - ss->pos;
void *bufptr;
if (available <= 0)
{
return -1;
}
if (size > (size_t) available)
size = available;
/* Use a temp buffer pointer to make some warnings disappear when using
GCC */
bufptr = bdataofs(ss->buffer, ss->pos);
memcpy(ptr, bufptr, size);
ss->pos += size;
return size;
}
static int64_t StringStreamWrite(const void *ptr, size_t size, Stream *stream)
{
StringStream *ss = (StringStream *) stream;
struct tagbstring buf;
if (ss->buffer->mlen <= 0)
return -1;
btfromblk(buf, ptr, size);
bsetstr(ss->buffer, ss->pos, &buf, '\0');
ss->pos += size;
return size;
}
int StringStreamSeek(Stream *base, int64_t offset, int whence)
{
StringStream *ss = (StringStream *) base;
int64_t newpos = 0;
if (whence == SEEK_SET)
{
newpos = offset;
}
else if (whence == SEEK_CUR)
{
newpos = ss->pos + offset;
}
else if (whence == SEEK_END)
{
newpos = blength(ss->buffer) - offset;
}
else
{
return -1;
}
if (newpos > blength(ss->buffer))
return -1;
if (newpos < 0)
return -1;
ss->pos = newpos;
return 0;
}
int64_t StringStreamTell(Stream *base)
{
StringStream *ss = (StringStream *) base;
return ss->pos;
}
static const StreamOps StringStreamOps =
{
StringStreamRead,
StringStreamWrite,
StringStreamClose,
StringStreamSeek,
StringStreamTell
};
int StringStreamInit(StringStream *stream)
{
assert(stream != NULL);
memset(stream, 0, sizeof(*stream));
stream->pos = 0;
stream->buffer = bfromcstr("");
stream->base.ops = &StringStreamOps;
return 0;
}
int StringStreamInitFromBstring(StringStream *stream, bstring buffer)
{
assert(stream != NULL);
memset(stream, 0, sizeof(*stream));
stream->pos = 0;
stream->buffer = buffer;
stream->base.ops = &StringStreamOps;
return 0;
}
|