PLYwoot
Header-only C++17 library for parsing and writing PLY files
Loading...
Searching...
No Matches
buffered_ostream.hpp
Go to the documentation of this file.
1/*
2 This file is part of PLYwoot, a header-only PLY parser.
3
4 Copyright (C) 2023-2025, Ton van den Heuvel
5
6 PLYwoot is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef PLYWOOT_BUFFERED_OSTREAM_HPP
21#define PLYWOOT_BUFFERED_OSTREAM_HPP
22
24
25#include "type_traits.hpp"
26
27#include <charconv>
28#include <cstring>
29#include <memory>
30#include <ostream>
31#include <type_traits>
32
33namespace {
34
36constexpr std::size_t OStreamBufferSize{1024 * 1024};
37
38}
39
40namespace plywoot::detail {
41
48class BufferedOStream
49{
50public:
53 explicit BufferedOStream(std::ostream &os) : os_{os} {}
54
57 ~BufferedOStream() { flush(); }
58
60 BufferedOStream(const BufferedOStream &) = delete;
61 BufferedOStream &operator=(const BufferedOStream &) = delete;
62
64 void put(char c)
65 {
66 *c_++ = c;
67 if (c_ == eob_) flush();
68 }
69
72 void write(const char *src, std::size_t n)
73 {
74 if (n >= OStreamBufferSize)
75 {
76 flush();
77 os_.write(src, n);
78 }
79 else
80 {
81 if (c_ + n >= eob_) { flush(); }
82 std::memcpy(c_, src, n);
83 c_ += n;
84 }
85 }
86
88 template<typename T>
89 void writeAscii(T t)
90 {
91 constexpr int MIN_BUFFER_SIZE = 100;
92 if (c_ + MIN_BUFFER_SIZE >= eob_) { flush(); }
93 c_ = std::to_chars(c_, c_ + MIN_BUFFER_SIZE, t).ptr;
94 }
95
97 template<typename T>
98 void write(T t)
99 {
100 if (c_ + sizeof(T) >= eob_) { flush(); }
101 std::memcpy(c_, reinterpret_cast<const char *>(&t), sizeof(T));
102 c_ += sizeof(T);
103 }
104
105private:
107 void flush()
108 {
109 os_.write(buffer_.get(), c_ - buffer_.get());
110 c_ = buffer_.get();
111 }
112
114 std::unique_ptr<char[]> buffer_{new char[OStreamBufferSize]};
115
120 char *c_{buffer_.get()};
122 const char *eob_{buffer_.get() + OStreamBufferSize};
123
125 std::ostream &os_;
126};
127
128}
129
130#endif