/src/mcl/include/cybozu/stream.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | /** |
3 | | @file |
4 | | @brief stream and line stream class |
5 | | |
6 | | @author MITSUNARI Shigeo(@herumi) |
7 | | */ |
8 | | #ifndef CYBOZU_DONT_USE_STRING |
9 | | #include <string> |
10 | | #include <iosfwd> |
11 | | #endif |
12 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
13 | | #include <cybozu/exception.hpp> |
14 | | #endif |
15 | | #include <memory.h> |
16 | | |
17 | | namespace cybozu { |
18 | | |
19 | | namespace stream_local { |
20 | | |
21 | | template <typename From, typename To> |
22 | | struct is_convertible { |
23 | | typedef char yes; |
24 | | typedef int no; |
25 | | |
26 | | static no test(...); |
27 | | static yes test(const To*); |
28 | | static const bool value = sizeof(test(static_cast<const From*>(0))) == sizeof(yes); |
29 | | }; |
30 | | |
31 | | template <bool b, class T = void> |
32 | | struct enable_if { typedef T type; }; |
33 | | |
34 | | template <class T> |
35 | | struct enable_if<false, T> {}; |
36 | | |
37 | | #ifndef CYBOZU_DONT_USE_STRING |
38 | | /* specialization for istream */ |
39 | | template<class InputStream> |
40 | | size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<is_convertible<InputStream, std::istream>::value>::type* = 0) |
41 | 0 | { |
42 | 0 | if (size > 0x7fffffff) size = 0x7fffffff; |
43 | 0 | is.read(static_cast<char *>(buf), size); |
44 | 0 | const int64_t readSize = is.gcount(); |
45 | 0 | if (readSize < 0) return 0; |
46 | 0 | if (size == 1 && readSize == 0) is.clear(); |
47 | 0 | return static_cast<size_t>(readSize); |
48 | 0 | } |
49 | | |
50 | | /* generic version for size_t readSome(void *, size_t) */ |
51 | | template<class InputStream> |
52 | | size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<!is_convertible<InputStream, std::istream>::value>::type* = 0) |
53 | 4.46M | { |
54 | 4.46M | return is.readSome(buf, size); |
55 | 4.46M | } _ZN6cybozu12stream_local14readSome_innerINS_17MemoryInputStreamEEEmPvmRT_PNS0_9enable_ifIXntsr14is_convertibleIS4_NSt3__113basic_istreamIcNS7_11char_traitsIcEEEEEE5valueEvE4typeE Line | Count | Source | 53 | 31.3k | { | 54 | 31.3k | return is.readSome(buf, size); | 55 | 31.3k | } |
_ZN6cybozu12stream_local14readSome_innerINS_17StringInputStreamEEEmPvmRT_PNS0_9enable_ifIXntsr14is_convertibleIS4_NSt3__113basic_istreamIcNS7_11char_traitsIcEEEEEE5valueEvE4typeE Line | Count | Source | 53 | 4.43M | { | 54 | 4.43M | return is.readSome(buf, size); | 55 | 4.43M | } |
|
56 | | #else |
57 | | template<class InputStream> |
58 | | size_t readSome_inner(void *buf, size_t size, InputStream& is) |
59 | | { |
60 | | return is.readSome(buf, size); |
61 | | } |
62 | | #endif |
63 | | |
64 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
65 | | /* specialization for ostream */ |
66 | | template<class OutputStream> |
67 | | void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0) |
68 | | { |
69 | | if (!os.write(static_cast<const char *>(buf), size)) throw cybozu::Exception("stream:writeSub") << size; |
70 | | } |
71 | | #endif |
72 | | |
73 | | #ifndef CYBOZU_DONT_USE_STRING |
74 | | /* generic version for void write(const void*, size_t), which writes all data */ |
75 | | template<class OutputStream> |
76 | | void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0) |
77 | | { |
78 | | os.write(buf, size); |
79 | | } |
80 | | |
81 | | template<class OutputStream> |
82 | | void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0) |
83 | 66.2k | { |
84 | 66.2k | *pb = !!os.write(static_cast<const char *>(buf), size); |
85 | 66.2k | } |
86 | | |
87 | | /* generic version for void write(const void*, size_t), which writes all data */ |
88 | | template<class OutputStream> |
89 | | void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0) |
90 | 42.6k | { |
91 | 42.6k | os.write(pb, buf, size); |
92 | 42.6k | } Unexecuted instantiation: _ZN6cybozu12stream_local8writeSubINS_18MemoryOutputStreamEEEvPbRT_PKvmPNS0_9enable_ifIXntsr14is_convertibleIS4_NSt3__113basic_ostreamIcNS9_11char_traitsIcEEEEEE5valueEvE4typeE _ZN6cybozu12stream_local8writeSubINS_18StringOutputStreamEEEvPbRT_PKvmPNS0_9enable_ifIXntsr14is_convertibleIS4_NSt3__113basic_ostreamIcNS9_11char_traitsIcEEEEEE5valueEvE4typeE Line | Count | Source | 90 | 42.6k | { | 91 | 42.6k | os.write(pb, buf, size); | 92 | 42.6k | } |
|
93 | | #else |
94 | | template<class OutputStream> |
95 | | void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size) |
96 | | { |
97 | | os.write(pb, buf, size); |
98 | | } |
99 | | #endif |
100 | | |
101 | | } // stream_local |
102 | | |
103 | | /* |
104 | | make a specializaiton of class to use new InputStream, OutputStream |
105 | | */ |
106 | | template<class InputStream> |
107 | | struct InputStreamTag { |
108 | | static size_t readSome(void *buf, size_t size, InputStream& is) |
109 | | { |
110 | | return stream_local::readSome_inner<InputStream>(buf, size, is); |
111 | | } |
112 | | static bool readChar(char *c, InputStream& is) |
113 | | { |
114 | | return readSome(c, 1, is) == 1; |
115 | | } |
116 | | }; |
117 | | |
118 | | template<class OutputStream> |
119 | | struct OutputStreamTag { |
120 | | static void write(OutputStream& os, const void *buf, size_t size) |
121 | | { |
122 | | stream_local::writeSub<OutputStream>(os, buf, size); |
123 | | } |
124 | | }; |
125 | | |
126 | | class MemoryInputStream { |
127 | | const char *p_; |
128 | | size_t size_; |
129 | | size_t pos; |
130 | | public: |
131 | 332 | MemoryInputStream(const void *p, size_t size) : p_(static_cast<const char *>(p)), size_(size), pos(0) {} |
132 | | size_t readSome(void *buf, size_t size) |
133 | 31.3k | { |
134 | 31.3k | if (size > size_ - pos) size = size_ - pos; |
135 | 31.3k | memcpy(buf, p_ + pos, size); |
136 | 31.3k | pos += size; |
137 | 31.3k | return size; |
138 | 31.3k | } |
139 | 332 | size_t getPos() const { return pos; } |
140 | | }; |
141 | | |
142 | | class MemoryOutputStream { |
143 | | char *p_; |
144 | | size_t size_; |
145 | | size_t pos; |
146 | | public: |
147 | 0 | MemoryOutputStream(void *p, size_t size) : p_(static_cast<char *>(p)), size_(size), pos(0) {} |
148 | | void write(bool *pb, const void *buf, size_t size) |
149 | 0 | { |
150 | 0 | if (size > size_ - pos) { |
151 | 0 | *pb = false; |
152 | 0 | return; |
153 | 0 | } |
154 | 0 | memcpy(p_ + pos, buf, size); |
155 | 0 | pos += size; |
156 | 0 | *pb = true; |
157 | 0 | } |
158 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
159 | | void write(const void *buf, size_t size) |
160 | 0 | { |
161 | 0 | bool b; |
162 | 0 | write(&b, buf, size); |
163 | 0 | if (!b) throw cybozu::Exception("MemoryOutputStream:write") << size << size_ << pos; |
164 | 0 | } |
165 | | #endif |
166 | 0 | size_t getPos() const { return pos; } |
167 | | }; |
168 | | |
169 | | #ifndef CYBOZU_DONT_USE_STRING |
170 | | class StringInputStream { |
171 | | const std::string& str_; |
172 | | size_t pos; |
173 | | StringInputStream(const StringInputStream&); |
174 | | void operator=(const StringInputStream&); |
175 | | public: |
176 | 104k | explicit StringInputStream(const std::string& str) : str_(str), pos(0) {} |
177 | | size_t readSome(void *buf, size_t size) |
178 | 4.43M | { |
179 | 4.43M | const size_t remainSize = str_.size() - pos; |
180 | 4.43M | if (size > remainSize) size = remainSize; |
181 | 4.43M | memcpy(buf, &str_[pos], size); |
182 | 4.43M | pos += size; |
183 | 4.43M | return size; |
184 | 4.43M | } |
185 | 0 | size_t getPos() const { return pos; } |
186 | | }; |
187 | | |
188 | | class StringOutputStream { |
189 | | std::string& str_; |
190 | | StringOutputStream(const StringOutputStream&); |
191 | | void operator=(const StringOutputStream&); |
192 | | public: |
193 | 7.98k | explicit StringOutputStream(std::string& str) : str_(str) {} |
194 | | void write(bool *pb, const void *buf, size_t size) |
195 | 42.6k | { |
196 | 42.6k | str_.append(static_cast<const char *>(buf), size); |
197 | 42.6k | *pb = true; |
198 | 42.6k | } |
199 | | void write(const void *buf, size_t size) |
200 | 0 | { |
201 | 0 | str_.append(static_cast<const char *>(buf), size); |
202 | 0 | } |
203 | 0 | size_t getPos() const { return str_.size(); } |
204 | | }; |
205 | | #endif |
206 | | |
207 | | template<class InputStream> |
208 | | size_t readSome(void *buf, size_t size, InputStream& is) |
209 | 4.46M | { |
210 | 4.46M | return stream_local::readSome_inner(buf, size, is); |
211 | 4.46M | } unsigned long cybozu::readSome<cybozu::MemoryInputStream>(void*, unsigned long, cybozu::MemoryInputStream&) Line | Count | Source | 209 | 31.3k | { | 210 | 31.3k | return stream_local::readSome_inner(buf, size, is); | 211 | 31.3k | } |
unsigned long cybozu::readSome<cybozu::StringInputStream>(void*, unsigned long, cybozu::StringInputStream&) Line | Count | Source | 209 | 4.43M | { | 210 | 4.43M | return stream_local::readSome_inner(buf, size, is); | 211 | 4.43M | } |
Unexecuted instantiation: unsigned long cybozu::readSome<std::__1::basic_istream<char, std::__1::char_traits<char> > >(void*, unsigned long, std::__1::basic_istream<char, std::__1::char_traits<char> >&) |
212 | | |
213 | | template<class OutputStream> |
214 | | void write(OutputStream& os, const void *buf, size_t size) |
215 | | { |
216 | | stream_local::writeSub(os, buf, size); |
217 | | } |
218 | | |
219 | | template<class OutputStream> |
220 | | void write(bool *pb, OutputStream& os, const void *buf, size_t size) |
221 | 108k | { |
222 | 108k | stream_local::writeSub(pb, os, buf, size); |
223 | 108k | } void cybozu::write<std::__1::basic_ostream<char, std::__1::char_traits<char> > >(bool*, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, void const*, unsigned long) Line | Count | Source | 221 | 66.2k | { | 222 | 66.2k | stream_local::writeSub(pb, os, buf, size); | 223 | 66.2k | } |
Unexecuted instantiation: void cybozu::write<cybozu::MemoryOutputStream>(bool*, cybozu::MemoryOutputStream&, void const*, unsigned long) void cybozu::write<cybozu::StringOutputStream>(bool*, cybozu::StringOutputStream&, void const*, unsigned long) Line | Count | Source | 221 | 42.6k | { | 222 | 42.6k | stream_local::writeSub(pb, os, buf, size); | 223 | 42.6k | } |
|
224 | | |
225 | | template<typename InputStream> |
226 | | void read(bool *pb, void *buf, size_t size, InputStream& is) |
227 | | { |
228 | | char *p = static_cast<char*>(buf); |
229 | | while (size > 0) { |
230 | | size_t readSize = cybozu::readSome(p, size, is); |
231 | | if (readSize == 0) { |
232 | | *pb = false; |
233 | | return; |
234 | | } |
235 | | p += readSize; |
236 | | size -= readSize; |
237 | | } |
238 | | *pb = true; |
239 | | } |
240 | | |
241 | | #ifndef CYBOZU_DONT_USE_EXCEPTION |
242 | | template<typename InputStream> |
243 | | void read(void *buf, size_t size, InputStream& is) |
244 | | { |
245 | | bool b; |
246 | | read(&b, buf, size, is); |
247 | | if (!b) throw cybozu::Exception("stream:read"); |
248 | | } |
249 | | #endif |
250 | | |
251 | | template<class InputStream> |
252 | | bool readChar(char *c, InputStream& is) |
253 | 4.46M | { |
254 | 4.46M | return readSome(c, 1, is) == 1; |
255 | 4.46M | } bool cybozu::readChar<cybozu::MemoryInputStream>(char*, cybozu::MemoryInputStream&) Line | Count | Source | 253 | 31.3k | { | 254 | 31.3k | return readSome(c, 1, is) == 1; | 255 | 31.3k | } |
bool cybozu::readChar<cybozu::StringInputStream>(char*, cybozu::StringInputStream&) Line | Count | Source | 253 | 4.43M | { | 254 | 4.43M | return readSome(c, 1, is) == 1; | 255 | 4.43M | } |
Unexecuted instantiation: bool cybozu::readChar<std::__1::basic_istream<char, std::__1::char_traits<char> > >(char*, std::__1::basic_istream<char, std::__1::char_traits<char> >&) |
256 | | |
257 | | template<class OutputStream> |
258 | | void writeChar(OutputStream& os, char c) |
259 | | { |
260 | | cybozu::write(os, &c, 1); |
261 | | } |
262 | | |
263 | | template<class OutputStream> |
264 | | void writeChar(bool *pb, OutputStream& os, char c) |
265 | 39.5k | { |
266 | 39.5k | cybozu::write(pb, os, &c, 1); |
267 | 39.5k | } void cybozu::writeChar<std::__1::basic_ostream<char, std::__1::char_traits<char> > >(bool*, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char) Line | Count | Source | 265 | 17.4k | { | 266 | 17.4k | cybozu::write(pb, os, &c, 1); | 267 | 17.4k | } |
void cybozu::writeChar<cybozu::StringOutputStream>(bool*, cybozu::StringOutputStream&, char) Line | Count | Source | 265 | 22.1k | { | 266 | 22.1k | cybozu::write(pb, os, &c, 1); | 267 | 22.1k | } |
Unexecuted instantiation: void cybozu::writeChar<cybozu::MemoryOutputStream>(bool*, cybozu::MemoryOutputStream&, char) |
268 | | |
269 | | } // cybozu |