]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/PackableStream.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / base / PackableStream.h
1 /*
2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_SRC_BASE_PACKABLESTREAM_H
10 #define SQUID_SRC_BASE_PACKABLESTREAM_H
11
12 #include "base/Packable.h"
13
14 #include <ostream>
15
16 /**
17 * Provides a streambuf interface for writing to Packable objects.
18 * Typical use is via a PackableStream rather than direct manipulation
19 */
20 class PackableStreamBuf : public std::streambuf
21 {
22 public:
23 explicit PackableStreamBuf(Packable &p) : buf_(p) { buf_.buffer(); }
24 virtual ~PackableStreamBuf() = default;
25
26 protected:
27 /** flush the current buffer and the character that is overflowing
28 * to the Packable.
29 */
30 virtual int_type overflow(int_type aChar = traits_type::eof()) override {
31 std::streamsize pending(pptr() - pbase());
32
33 if (pending && sync())
34 return traits_type::eof();
35
36 if (aChar != traits_type::eof()) {
37 const char C = static_cast<char>(aChar);
38 lowAppend(&C, 1);
39 }
40
41 pbump(-pending); // Reset pptr().
42 return aChar;
43 }
44
45 /** push the buffer to the Packable */
46 virtual int sync() override {
47 std::streamsize pending(pptr() - pbase());
48 lowAppend(pbase(), pending);
49 buf_.flush();
50 return 0;
51 }
52
53 /** write multiple characters to the Packable
54 * - this is an optimisation method.
55 */
56 virtual std::streamsize xsputn(const char * chars, std::streamsize number) override {
57 lowAppend(chars, number);
58 return number;
59 }
60
61 private:
62 void lowAppend(const char *s, const std::streamsize n) {buf_.append(s,n);}
63
64 Packable &buf_;
65 };
66
67 class PackableStream : public std::ostream
68 {
69 public:
70 /* create a stream for writing text etc into theBuffer */
71 // See http://www.codecomments.com/archive292-2005-2-396222.html
72 explicit PackableStream(Packable &p) : std::ostream(0), theBuffer(p) {
73 rdbuf(&theBuffer); // set the buffer to now-initialized theBuffer
74 clear(); //clear badbit set by calling init(0)
75 }
76
77 private:
78 PackableStreamBuf theBuffer;
79 };
80
81 #endif /* SQUID_SRC_BASE_PACKABLESTREAM_H */
82