Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Stream.cpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2021 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#include "Stream.hpp"
18
19namespace toolbox {
20inline namespace http {
21using namespace std;
22
23void StreamBuf::set_content_length(std::streamsize pos, std::streamsize len) noexcept
24{
25 auto* it = pbase_ + pos;
26 do {
27 --it;
28 *it = '0' + len % 10;
29 len /= 10;
30 } while (len > 0);
31}
32
33StreamBuf::~StreamBuf() = default;
34
35StreamBuf::int_type StreamBuf::overflow(int_type c) noexcept
36{
37 if (c != traits_type::eof()) {
38 auto buf = buf_.prepare(pcount_ + 1);
39 pbase_ = buffer_cast<char*>(buf);
40 pbase_[pcount_++] = c;
41 }
42 return c;
43}
44
46{
47 auto buf = buf_.prepare(pcount_ + count);
48 pbase_ = buffer_cast<char*>(buf);
49 memcpy(pbase_ + pcount_, s, count);
50 pcount_ += count;
51 return count;
52}
53
54OStream::~OStream() = default;
55
57{
58 if (cloff_ > 0) {
59 buf_.set_content_length(cloff_, buf_.pcount() - hcount_);
60 }
61 buf_.commit();
62}
63
65{
66 buf_.reset();
67 *this << reset_state;
68
69 *this << "HTTP/1.1 " << status << ' ' << enum_string(status);
70 if (no_cache == NoCache::Yes) {
71 *this << "\r\nCache-Control: no-cache";
72 }
73 if (content_type) {
74 // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF. Use 10 space
75 // place-holder for content length. RFC2616 states that field value MAY be preceded by any
76 // amount of LWS, though a single SP is preferred.
77 *this << "\r\nContent-Type: " << content_type //
78 << "\r\nContent-Length: 0";
79 cloff_ = buf_.pcount();
80 } else {
81 cloff_ = 0;
82 }
83 *this << "\r\n\r\n";
84 hcount_ = buf_.pcount();
85}
86
87} // namespace http
88} // namespace toolbox
void reset() noexcept
Definition Stream.hpp:85
void commit() noexcept
Definition Stream.cpp:56
int_type overflow(int_type c) noexcept override
Definition Stream.cpp:35
std::streamsize xsputn(const char_type *s, std::streamsize count) noexcept override
void set_content_length(std::streamsize pos, std::streamsize len) noexcept
Definition Stream.cpp:23
void reset() noexcept
Definition Stream.hpp:49
void commit() noexcept
Definition Stream.hpp:48
std::streamsize pcount() const noexcept
Definition Stream.hpp:47
STL namespace.
const char * enum_string(Status status) noexcept
Definition Types.cpp:22
constexpr detail::ResetState reset_state
I/O manipulator that resets I/O state.
Definition Stream.hpp:34
constexpr auto bind() noexcept
Definition Slot.hpp:92