1 | // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors |
2 | // Licensed under the MIT License: |
3 | // |
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | // of this software and associated documentation files (the "Software"), to deal |
6 | // in the Software without restriction, including without limitation the rights |
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
8 | // copies of the Software, and to permit persons to whom the Software is |
9 | // furnished to do so, subject to the following conditions: |
10 | // |
11 | // The above copyright notice and this permission notice shall be included in |
12 | // all copies or substantial portions of the Software. |
13 | // |
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
20 | // THE SOFTWARE. |
21 | |
22 | #pragma once |
23 | |
24 | #if defined(__GNUC__) && !KJ_HEADER_WARNINGS |
25 | #pragma GCC system_header |
26 | #endif |
27 | |
28 | #include <stddef.h> |
29 | #include "common.h" |
30 | #include "array.h" |
31 | #include "exception.h" |
32 | #include <stdint.h> |
33 | |
34 | namespace kj { |
35 | |
36 | // ======================================================================================= |
37 | // Abstract interfaces |
38 | |
39 | class InputStream { |
40 | public: |
41 | virtual ~InputStream() noexcept(false); |
42 | |
43 | size_t read(void* buffer, size_t minBytes, size_t maxBytes); |
44 | // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns |
45 | // the size read. Throws an exception on errors. Implemented in terms of tryRead(). |
46 | // |
47 | // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount |
48 | // needed by the caller before it can start doing useful processing. If the stream returns less |
49 | // than maxBytes, the caller will usually call read() again later to get the rest. Returning |
50 | // less than maxBytes is useful when it makes sense for the caller to parallelize processing |
51 | // with I/O. |
52 | // |
53 | // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may |
54 | // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. |
55 | // To detect EOF without throwing an exception, use tryRead(). |
56 | // |
57 | // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not |
58 | // expected to understand how to deal with partial reads. |
59 | |
60 | virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; |
61 | // Like read(), but may return fewer than minBytes on EOF. |
62 | |
63 | inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } |
64 | // Convenience method for reading an exact number of bytes. |
65 | |
66 | virtual void skip(size_t bytes); |
67 | // Skips past the given number of bytes, discarding them. The default implementation read()s |
68 | // into a scratch buffer. |
69 | |
70 | String readAllText(uint64_t limit = kj::maxValue); |
71 | Array<byte> readAllBytes(uint64_t limit = kj::maxValue); |
72 | // Read until EOF and return as one big byte array or string. Throw an exception if EOF is not |
73 | // seen before reading `limit` bytes. |
74 | // |
75 | // To prevent runaway memory allocation, consider using a more conservative value for `limit` than |
76 | // the default, particularly on untrusted data streams which may never see EOF. |
77 | }; |
78 | |
79 | class OutputStream { |
80 | public: |
81 | virtual ~OutputStream() noexcept(false); |
82 | |
83 | virtual void write(const void* buffer, size_t size) = 0; |
84 | // Always writes the full size. Throws exception on error. |
85 | |
86 | virtual void write(ArrayPtr<const ArrayPtr<const byte>> pieces); |
87 | // Equivalent to write()ing each byte array in sequence, which is what the default implementation |
88 | // does. Override if you can do something better, e.g. use writev() to do the write in a single |
89 | // syscall. |
90 | }; |
91 | |
92 | class BufferedInputStream: public InputStream { |
93 | // An input stream which buffers some bytes in memory to reduce system call overhead. |
94 | // - OR - |
95 | // An input stream that actually reads from some in-memory data structure and wants to give its |
96 | // caller a direct pointer to that memory to potentially avoid a copy. |
97 | |
98 | public: |
99 | virtual ~BufferedInputStream() noexcept(false); |
100 | |
101 | ArrayPtr<const byte> getReadBuffer(); |
102 | // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the |
103 | // caller consumes any bytes, it should then call skip() to indicate this. This always returns a |
104 | // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). |
105 | |
106 | virtual ArrayPtr<const byte> tryGetReadBuffer() = 0; |
107 | // Like getReadBuffer() but may return an empty buffer on EOF. |
108 | }; |
109 | |
110 | class BufferedOutputStream: public OutputStream { |
111 | // An output stream which buffers some bytes in memory to reduce system call overhead. |
112 | // - OR - |
113 | // An output stream that actually writes into some in-memory data structure and wants to give its |
114 | // caller a direct pointer to that memory to potentially avoid a copy. |
115 | |
116 | public: |
117 | virtual ~BufferedOutputStream() noexcept(false); |
118 | |
119 | virtual ArrayPtr<byte> getWriteBuffer() = 0; |
120 | // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of |
121 | // this buffer and then pass it to write(), in which case write() may avoid a copy. It is |
122 | // incorrect to pass to write any slice of this buffer which is not a prefix. |
123 | }; |
124 | |
125 | // ======================================================================================= |
126 | // Buffered streams implemented as wrappers around regular streams |
127 | |
128 | class BufferedInputStreamWrapper: public BufferedInputStream { |
129 | // Implements BufferedInputStream in terms of an InputStream. |
130 | // |
131 | // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, |
132 | // unless the entire stream was consumed. To read a predictable number of bytes in a buffered |
133 | // way without going over, you'd need this wrapper to wrap some other wrapper which itself |
134 | // implements an artificial EOF at the desired point. Such a stream should be trivial to write |
135 | // but is not provided by the library at this time. |
136 | |
137 | public: |
138 | explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr<byte> buffer = nullptr); |
139 | // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about |
140 | // the position of the inner stream after a buffered wrapper has been created unless the entire |
141 | // input is read. |
142 | // |
143 | // If the second parameter is non-null, the stream uses the given buffer instead of allocating |
144 | // its own. This may improve performance if the buffer can be reused. |
145 | |
146 | KJ_DISALLOW_COPY(BufferedInputStreamWrapper); |
147 | ~BufferedInputStreamWrapper() noexcept(false); |
148 | |
149 | // implements BufferedInputStream ---------------------------------- |
150 | ArrayPtr<const byte> tryGetReadBuffer() override; |
151 | size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; |
152 | void skip(size_t bytes) override; |
153 | |
154 | private: |
155 | InputStream& inner; |
156 | Array<byte> ownedBuffer; |
157 | ArrayPtr<byte> buffer; |
158 | ArrayPtr<byte> bufferAvailable; |
159 | }; |
160 | |
161 | class BufferedOutputStreamWrapper: public BufferedOutputStream { |
162 | // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the |
163 | // underlying stream may be delayed until flush() is called or the wrapper is destroyed. |
164 | |
165 | public: |
166 | explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr<byte> buffer = nullptr); |
167 | // Creates a buffered stream wrapping the given non-buffered stream. |
168 | // |
169 | // If the second parameter is non-null, the stream uses the given buffer instead of allocating |
170 | // its own. This may improve performance if the buffer can be reused. |
171 | |
172 | KJ_DISALLOW_COPY(BufferedOutputStreamWrapper); |
173 | ~BufferedOutputStreamWrapper() noexcept(false); |
174 | |
175 | void flush(); |
176 | // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that |
177 | // this only flushes this object's buffer; this object has no idea how to flush any other buffers |
178 | // that may be present in the underlying stream. |
179 | |
180 | // implements BufferedOutputStream --------------------------------- |
181 | ArrayPtr<byte> getWriteBuffer() override; |
182 | void write(const void* buffer, size_t size) override; |
183 | |
184 | private: |
185 | OutputStream& inner; |
186 | Array<byte> ownedBuffer; |
187 | ArrayPtr<byte> buffer; |
188 | byte* bufferPos; |
189 | UnwindDetector unwindDetector; |
190 | }; |
191 | |
192 | // ======================================================================================= |
193 | // Array I/O |
194 | |
195 | class ArrayInputStream: public BufferedInputStream { |
196 | public: |
197 | explicit ArrayInputStream(ArrayPtr<const byte> array); |
198 | KJ_DISALLOW_COPY(ArrayInputStream); |
199 | ~ArrayInputStream() noexcept(false); |
200 | |
201 | // implements BufferedInputStream ---------------------------------- |
202 | ArrayPtr<const byte> tryGetReadBuffer() override; |
203 | size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; |
204 | void skip(size_t bytes) override; |
205 | |
206 | private: |
207 | ArrayPtr<const byte> array; |
208 | }; |
209 | |
210 | class ArrayOutputStream: public BufferedOutputStream { |
211 | public: |
212 | explicit ArrayOutputStream(ArrayPtr<byte> array); |
213 | KJ_DISALLOW_COPY(ArrayOutputStream); |
214 | ~ArrayOutputStream() noexcept(false); |
215 | |
216 | ArrayPtr<byte> getArray() { |
217 | // Get the portion of the array which has been filled in. |
218 | return arrayPtr(array.begin(), fillPos); |
219 | } |
220 | |
221 | // implements BufferedInputStream ---------------------------------- |
222 | ArrayPtr<byte> getWriteBuffer() override; |
223 | void write(const void* buffer, size_t size) override; |
224 | |
225 | private: |
226 | ArrayPtr<byte> array; |
227 | byte* fillPos; |
228 | }; |
229 | |
230 | class VectorOutputStream: public BufferedOutputStream { |
231 | public: |
232 | explicit VectorOutputStream(size_t initialCapacity = 4096); |
233 | KJ_DISALLOW_COPY(VectorOutputStream); |
234 | ~VectorOutputStream() noexcept(false); |
235 | |
236 | ArrayPtr<byte> getArray() { |
237 | // Get the portion of the array which has been filled in. |
238 | return arrayPtr(vector.begin(), fillPos); |
239 | } |
240 | |
241 | // implements BufferedInputStream ---------------------------------- |
242 | ArrayPtr<byte> getWriteBuffer() override; |
243 | void write(const void* buffer, size_t size) override; |
244 | |
245 | private: |
246 | Array<byte> vector; |
247 | byte* fillPos; |
248 | |
249 | void grow(size_t minSize); |
250 | }; |
251 | |
252 | // ======================================================================================= |
253 | // File descriptor I/O |
254 | |
255 | class AutoCloseFd { |
256 | // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. |
257 | // The wrapper supports move construction for transferring ownership of the descriptor. If |
258 | // close() returns an error, the destructor throws an exception, UNLESS the destructor is being |
259 | // called during unwind from another exception, in which case the close error is ignored. |
260 | // |
261 | // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will |
262 | // have to call close() yourself and handle errors appropriately. |
263 | |
264 | public: |
265 | inline AutoCloseFd(): fd(-1) {} |
266 | inline AutoCloseFd(decltype(nullptr)): fd(-1) {} |
267 | inline explicit AutoCloseFd(int fd): fd(fd) {} |
268 | inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } |
269 | KJ_DISALLOW_COPY(AutoCloseFd); |
270 | ~AutoCloseFd() noexcept(false); |
271 | |
272 | inline AutoCloseFd& operator=(AutoCloseFd&& other) { |
273 | AutoCloseFd old(kj::mv(*this)); |
274 | fd = other.fd; |
275 | other.fd = -1; |
276 | return *this; |
277 | } |
278 | |
279 | inline AutoCloseFd& operator=(decltype(nullptr)) { |
280 | AutoCloseFd old(kj::mv(*this)); |
281 | return *this; |
282 | } |
283 | |
284 | inline operator int() const { return fd; } |
285 | inline int get() const { return fd; } |
286 | |
287 | operator bool() const = delete; |
288 | // Deleting this operator prevents accidental use in boolean contexts, which |
289 | // the int conversion operator above would otherwise allow. |
290 | |
291 | inline bool operator==(decltype(nullptr)) { return fd < 0; } |
292 | inline bool operator!=(decltype(nullptr)) { return fd >= 0; } |
293 | |
294 | inline int release() { |
295 | // Release ownership of an FD. Not recommended. |
296 | int result = fd; |
297 | fd = -1; |
298 | return result; |
299 | } |
300 | |
301 | private: |
302 | int fd; |
303 | UnwindDetector unwindDetector; |
304 | }; |
305 | |
306 | inline auto KJ_STRINGIFY(const AutoCloseFd& fd) |
307 | -> decltype(kj::toCharSequence(implicitCast<int>(fd))) { |
308 | return kj::toCharSequence(implicitCast<int>(fd)); |
309 | } |
310 | |
311 | class FdInputStream: public InputStream { |
312 | // An InputStream wrapping a file descriptor. |
313 | |
314 | public: |
315 | explicit FdInputStream(int fd): fd(fd) {} |
316 | explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} |
317 | KJ_DISALLOW_COPY(FdInputStream); |
318 | ~FdInputStream() noexcept(false); |
319 | |
320 | size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; |
321 | |
322 | inline int getFd() const { return fd; } |
323 | |
324 | private: |
325 | int fd; |
326 | AutoCloseFd autoclose; |
327 | }; |
328 | |
329 | class FdOutputStream: public OutputStream { |
330 | // An OutputStream wrapping a file descriptor. |
331 | |
332 | public: |
333 | explicit FdOutputStream(int fd): fd(fd) {} |
334 | explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} |
335 | KJ_DISALLOW_COPY(FdOutputStream); |
336 | ~FdOutputStream() noexcept(false); |
337 | |
338 | void write(const void* buffer, size_t size) override; |
339 | void write(ArrayPtr<const ArrayPtr<const byte>> pieces) override; |
340 | |
341 | inline int getFd() const { return fd; } |
342 | |
343 | private: |
344 | int fd; |
345 | AutoCloseFd autoclose; |
346 | }; |
347 | |
348 | // ======================================================================================= |
349 | // Win32 Handle I/O |
350 | |
351 | #ifdef _WIN32 |
352 | |
353 | class AutoCloseHandle { |
354 | // A wrapper around a Win32 HANDLE which automatically closes the handle when destroyed. |
355 | // The wrapper supports move construction for transferring ownership of the handle. If |
356 | // CloseHandle() returns an error, the destructor throws an exception, UNLESS the destructor is |
357 | // being called during unwind from another exception, in which case the close error is ignored. |
358 | // |
359 | // If your code is not exception-safe, you should not use AutoCloseHandle. In this case you will |
360 | // have to call close() yourself and handle errors appropriately. |
361 | |
362 | public: |
363 | inline AutoCloseHandle(): handle((void*)-1) {} |
364 | inline AutoCloseHandle(decltype(nullptr)): handle((void*)-1) {} |
365 | inline explicit AutoCloseHandle(void* handle): handle(handle) {} |
366 | inline AutoCloseHandle(AutoCloseHandle&& other) noexcept: handle(other.handle) { |
367 | other.handle = (void*)-1; |
368 | } |
369 | KJ_DISALLOW_COPY(AutoCloseHandle); |
370 | ~AutoCloseHandle() noexcept(false); |
371 | |
372 | inline AutoCloseHandle& operator=(AutoCloseHandle&& other) { |
373 | AutoCloseHandle old(kj::mv(*this)); |
374 | handle = other.handle; |
375 | other.handle = (void*)-1; |
376 | return *this; |
377 | } |
378 | |
379 | inline AutoCloseHandle& operator=(decltype(nullptr)) { |
380 | AutoCloseHandle old(kj::mv(*this)); |
381 | return *this; |
382 | } |
383 | |
384 | inline operator void*() const { return handle; } |
385 | inline void* get() const { return handle; } |
386 | |
387 | operator bool() const = delete; |
388 | // Deleting this operator prevents accidental use in boolean contexts, which |
389 | // the void* conversion operator above would otherwise allow. |
390 | |
391 | inline bool operator==(decltype(nullptr)) { return handle != (void*)-1; } |
392 | inline bool operator!=(decltype(nullptr)) { return handle == (void*)-1; } |
393 | |
394 | inline void* release() { |
395 | // Release ownership of an FD. Not recommended. |
396 | void* result = handle; |
397 | handle = (void*)-1; |
398 | return result; |
399 | } |
400 | |
401 | private: |
402 | void* handle; // -1 (aka INVALID_HANDLE_VALUE) if not valid. |
403 | }; |
404 | |
405 | class HandleInputStream: public InputStream { |
406 | // An InputStream wrapping a Win32 HANDLE. |
407 | |
408 | public: |
409 | explicit HandleInputStream(void* handle): handle(handle) {} |
410 | explicit HandleInputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} |
411 | KJ_DISALLOW_COPY(HandleInputStream); |
412 | ~HandleInputStream() noexcept(false); |
413 | |
414 | size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; |
415 | |
416 | private: |
417 | void* handle; |
418 | AutoCloseHandle autoclose; |
419 | }; |
420 | |
421 | class HandleOutputStream: public OutputStream { |
422 | // An OutputStream wrapping a Win32 HANDLE. |
423 | |
424 | public: |
425 | explicit HandleOutputStream(void* handle): handle(handle) {} |
426 | explicit HandleOutputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} |
427 | KJ_DISALLOW_COPY(HandleOutputStream); |
428 | ~HandleOutputStream() noexcept(false); |
429 | |
430 | void write(const void* buffer, size_t size) override; |
431 | |
432 | private: |
433 | void* handle; |
434 | AutoCloseHandle autoclose; |
435 | }; |
436 | |
437 | #endif // _WIN32 |
438 | |
439 | } // namespace kj |
440 | |