]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/PackableStream.h
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / base / PackableStream.h
CommitLineData
7e10ac87 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
7e10ac87
AJ
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
f212d110
AR
16// TODO: Move to src/base/AppendingStreamBuf.h
17/// write-only std::streambuf that append()s all writes to a given Buffer
18template <class Buffer>
19class AppendingStreamBuf : public std::streambuf
7e10ac87
AJ
20{
21public:
f212d110 22 explicit AppendingStreamBuf(Buffer &p): buf_(p) { postInit(); }
337b9aa4 23 ~AppendingStreamBuf() override = default;
7e10ac87
AJ
24
25protected:
f212d110
AR
26 /* std::streambuf API */
27
337b9aa4 28 int_type overflow(int_type aChar = traits_type::eof()) override {
7e10ac87
AJ
29 std::streamsize pending(pptr() - pbase());
30
31 if (pending && sync())
32 return traits_type::eof();
33
34 if (aChar != traits_type::eof()) {
35 const char C = static_cast<char>(aChar);
36 lowAppend(&C, 1);
37 }
38
39 pbump(-pending); // Reset pptr().
40 return aChar;
41 }
42
337b9aa4 43 int sync() override {
7e10ac87
AJ
44 std::streamsize pending(pptr() - pbase());
45 lowAppend(pbase(), pending);
f212d110 46 postSync();
7e10ac87
AJ
47 return 0;
48 }
49
337b9aa4 50 std::streamsize xsputn(const char * chars, std::streamsize number) override {
7e10ac87
AJ
51 lowAppend(chars, number);
52 return number;
53 }
54
55private:
f212d110
AR
56 /// for specializations that must customize the last construction step
57 void postInit() {}
58
59 /// for specializations that must customize the last sync() step
60 void postSync() {}
61
7e10ac87
AJ
62 void lowAppend(const char *s, const std::streamsize n) {buf_.append(s,n);}
63
f212d110 64 Buffer &buf_; ///< the associated character sequence (a.k.a. the sink)
7e10ac87
AJ
65};
66
f212d110
AR
67/**
68 * Provides a streambuf interface for writing to Packable objects.
69 * Typical use is via a PackableStream rather than direct manipulation
70 */
71using PackableStreamBuf = AppendingStreamBuf<Packable>;
72template <> inline void PackableStreamBuf::postInit() { buf_.buffer(); }
73template <> inline void PackableStreamBuf::postSync() { buf_.flush(); }
74
7e10ac87
AJ
75class PackableStream : public std::ostream
76{
77public:
78 /* create a stream for writing text etc into theBuffer */
79 // See http://www.codecomments.com/archive292-2005-2-396222.html
aee3523a 80 explicit PackableStream(Packable &p) : std::ostream(nullptr), theBuffer(p) {
7e10ac87
AJ
81 rdbuf(&theBuffer); // set the buffer to now-initialized theBuffer
82 clear(); //clear badbit set by calling init(0)
83 }
84
85private:
86 PackableStreamBuf theBuffer;
87};
88
89#endif /* SQUID_SRC_BASE_PACKABLESTREAM_H */
90