-
Notifications
You must be signed in to change notification settings - Fork 63
/
mistream.cc
121 lines (101 loc) · 3.17 KB
/
mistream.cc
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
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <[email protected]>
// This file is free software, distributed under the MIT License.
#include "mistream.h"
#include "sostream.h"
#include "ustring.h"
#include "ualgo.h"
namespace ustl {
//--------------------------------------------------------------------
/// Checks that \p n bytes are available in the stream, or else throws.
void ios_base::overrun (const char* op, const char* type, uint32_t n, uint32_t pos, uint32_t rem)
{
if (set_and_throw (rem ? failbit : (failbit | eofbit)))
throw stream_bounds_exception (op, type, pos, n, rem);
}
//--------------------------------------------------------------------
/// Attaches to the block pointed to by source of size source.pos()
istream::istream (const ostream& source) noexcept
: cmemlink (source.begin(), source.pos()),
m_Pos (0)
{
}
void istream::unlink (void) noexcept { cmemlink::unlink(); m_Pos = 0; }
void ostream::unlink (void) noexcept { memlink::unlink(); m_Pos = 0; }
/// Writes all unread bytes into \p os.
void istream::write (ostream& os) const
{
os.write (ipos(), remaining());
}
/// Writes the object to stream \p os.
void istream::text_write (ostringstream& os) const
{
os.write (ipos(), remaining());
}
/// Reads a null-terminated string into \p str.
void istream::read_strz (string& str)
{
const_iterator zp = find (ipos(), end(), '\0');
if (zp == end())
zp = ipos();
const size_type strl = distance (ipos(), zp);
str.assign (ipos(), strl);
m_Pos += strl + 1;
}
/// Reads at most \p n bytes into \p s.
istream::size_type istream::readsome (void* s, size_type n)
{
if (remaining() < n)
underflow (n);
const size_type ntr (min (n, remaining()));
read (s, ntr);
return (ntr);
}
//--------------------------------------------------------------------
/// Aligns the write pointer on \p grain. The skipped bytes are zeroed.
void ostream::align (size_type grain)
{
assert (!((grain-1)&grain) && "grain must be a power of 2");
iterator ip = ipos();
iterator ipa = iterator((uintptr_t(ip) + (grain-1)) & ~(grain-1));
size_t nb = distance (ip, ipa);
#if WANT_STREAM_BOUNDS_CHECKING
if (!verify_remaining ("align", "padding", nb))
return;
#else
assert (remaining() >= nb && "Buffer overrun. Check your stream size calculations.");
#endif
memset (ip, '\x0', nb);
m_Pos += nb;
}
/// Writes \p str as a null-terminated string.
void ostream::write_strz (const char* str)
{
write (str, strlen(str)+1);
}
/// Writes all available data from \p is.
void ostream::read (istream& is)
{
write (is.ipos(), is.remaining());
is.seek (is.size());
}
/// Writes all written data to \p os.
void ostream::text_write (ostringstream& os) const
{
os.write (begin(), pos());
}
/// Inserts an empty area of \p size, at \p start.
void ostream::insert (iterator start, size_type s)
{
m_Pos += s;
memlink::insert (start, s);
}
/// Erases an area of \p size, at \p start.
void ostream::erase (iterator start, size_type s)
{
m_Pos -= s;
memlink::erase (start, s);
}
//--------------------------------------------------------------------
} // namespace ustl