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
|
/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved. Released under a BSD (revised)
license as described in the file LICENSE.
*/
#include <string.h>
#include "io_buf.h"
size_t buf_read(io_buf &i, char* &pointer, size_t n)
{//return a pointer to the next n bytes. n must be smaller than the maximum size.
if (i.space.end + n <= i.endloaded)
{
pointer = i.space.end;
i.space.end += n;
return n;
}
else // out of bytes, so refill.
{
if (i.space.end != i.space.begin) //There exists room to shift.
{ // Out of buffer so swap to beginning.
size_t left = i.endloaded - i.space.end;
memmove(i.space.begin, i.space.end, left);
i.space.end = i.space.begin;
i.endloaded = i.space.begin+left;
}
if (i.fill(i.files[i.current]) > 0)
return buf_read(i,pointer,n);// more bytes are read.
else if (++i.current < i.files.size())
return buf_read(i,pointer,n);// No more bytes, so go to next file and try again.
else
{//no more bytes to read, return all that we have left.
pointer = i.space.end;
i.space.end = i.endloaded;
return i.endloaded - pointer;
}
}
}
bool isbinary(io_buf &i) {
if (i.endloaded == i.space.end)
if (i.fill(i.files[i.current]) <= 0)
return false;
bool ret = (*i.space.end == 0);
if (ret)
i.space.end++;
return ret;
}
size_t readto(io_buf &i, char* &pointer, char terminal)
{//Return a pointer to the bytes before the terminal. Must be less than the buffer size.
pointer = i.space.end;
while (pointer != i.endloaded && *pointer != terminal)
pointer++;
if (pointer != i.endloaded)
{
size_t n = pointer - i.space.end;
i.space.end = pointer+1;
pointer -= n;
return n+1;
}
else
{
if (i.endloaded == i.space.end_array)
{
size_t left = i.endloaded - i.space.end;
memmove(i.space.begin, i.space.end, left);
i.space.end = i.space.begin;
i.endloaded = i.space.begin+left;
pointer = i.endloaded;
}
if (i.current < i.files.size() && i.fill(i.files[i.current]) > 0)// more bytes are read.
return readto(i,pointer,terminal);
else if (++i.current < i.files.size()) //no more bytes, so go to next file.
return readto(i,pointer,terminal);
else //no more bytes to read, return everything we have.
{
size_t n = pointer - i.space.end;
i.space.end = pointer;
pointer -= n;
return n;
}
}
}
void buf_write(io_buf &o, char* &pointer, size_t n)
{//return a pointer to the next n bytes to write into.
if (o.space.end + n <= o.space.end_array)
{
pointer = o.space.end;
o.space.end += n;
}
else // Time to dump the file
{
if (o.space.end != o.space.begin)
o.flush();
else // Array is short, so increase size.
{
o.space.resize(2*(o.space.end_array - o.space.begin));
o.endloaded = o.space.begin;
}
buf_write (o, pointer,n);
}
}
|