Branch data TLA Line data Source code
1 : : // Copyright (c) 2016-2022 Thomas Fussell
2 : : // Copyright (c) 2024-2025 xlnt-community
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 : : // @license: http://www.opensource.org/licenses/mit-license.php
23 : : // @author: see AUTHORS file
24 : :
25 : : #include <xlnt/utils/exceptions.hpp>
26 : : #include <detail/serialization/vector_streambuf.hpp>
27 : : #include <algorithm>
28 : :
29 : : namespace xlnt {
30 : : namespace detail {
31 : :
32 :CBC 125 : vector_istreambuf::vector_istreambuf(const std::vector<std::uint8_t> &data)
33 : 125 : : data_(data),
34 : 125 : position_(0)
35 : : {
36 : 125 : }
37 : :
38 : 2621867 : vector_istreambuf::int_type vector_istreambuf::underflow()
39 : : {
40 [ + + ]: 2621867 : if (position_ == data_.size())
41 : : {
42 : 43 : return traits_type::eof();
43 : : }
44 : :
45 : 2621824 : return traits_type::to_int_type(static_cast<char>(data_[position_]));
46 : : }
47 : :
48 : 6170584 : vector_istreambuf::int_type vector_istreambuf::uflow()
49 : : {
50 [ - + ]: 6170584 : if (position_ == data_.size())
51 : : {
52 :UBC 0 : return traits_type::eof();
53 : : }
54 : :
55 :CBC 6170584 : return traits_type::to_int_type(static_cast<char>(data_[position_++]));
56 : : }
57 : :
58 :UBC 0 : std::streamsize vector_istreambuf::showmanyc()
59 : : {
60 [ # # ]: 0 : if (position_ == data_.size())
61 : : {
62 : 0 : return static_cast<std::streamsize>(-1);
63 : : }
64 : :
65 : 0 : return static_cast<std::streamsize>(data_.size() - position_);
66 : : }
67 : :
68 :CBC 299 : std::streampos vector_istreambuf::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode)
69 : : {
70 [ + + ]: 299 : if (way == std::ios_base::beg)
71 : : {
72 : 177 : position_ = 0;
73 : : }
74 [ + + ]: 122 : else if (way == std::ios_base::end)
75 : : {
76 : 61 : position_ = data_.size();
77 : : }
78 : :
79 [ - + ]: 299 : if (off < 0)
80 : : {
81 [ # # ]:UBC 0 : if (static_cast<std::size_t>(-off) > position_)
82 : : {
83 : 0 : position_ = 0;
84 : 0 : return static_cast<std::ptrdiff_t>(-1);
85 : : }
86 : : else
87 : : {
88 : 0 : position_ -= static_cast<std::size_t>(-off);
89 : : }
90 : : }
91 [ + + ]:CBC 299 : else if (off > 0)
92 : : {
93 [ - + ]: 156 : if (static_cast<std::size_t>(off) + position_ > data_.size())
94 : : {
95 :UBC 0 : position_ = data_.size();
96 : 0 : return static_cast<std::ptrdiff_t>(-1);
97 : : }
98 : : else
99 : : {
100 :CBC 156 : position_ += static_cast<std::size_t>(off);
101 : : }
102 : : }
103 : :
104 : 299 : return static_cast<std::ptrdiff_t>(position_);
105 : : }
106 : :
107 : 3567 : std::streampos vector_istreambuf::seekpos(std::streampos sp, std::ios_base::openmode)
108 : : {
109 [ - + ]: 3567 : if (sp < 0)
110 : : {
111 :UBC 0 : position_ = 0;
112 : : }
113 [ - + ]:CBC 3567 : else if (static_cast<std::size_t>(sp) > data_.size())
114 : : {
115 :UBC 0 : position_ = data_.size();
116 : : }
117 : : else
118 : : {
119 :CBC 3567 : position_ = static_cast<std::size_t>(sp);
120 : : }
121 : :
122 : 3567 : return static_cast<std::ptrdiff_t>(position_);
123 : : }
124 : :
125 : 76 : vector_ostreambuf::vector_ostreambuf(std::vector<std::uint8_t> &data)
126 : 76 : : data_(data),
127 : 76 : position_(0)
128 : : {
129 : 76 : }
130 : :
131 :UBC 0 : vector_ostreambuf::int_type vector_ostreambuf::overflow(int_type c)
132 : : {
133 [ # # ]: 0 : if (c != traits_type::eof())
134 : : {
135 [ # ]: 0 : data_.push_back(static_cast<std::uint8_t>(c));
136 : 0 : position_ = data_.size() - 1;
137 : : }
138 : :
139 : 0 : return traits_type::to_int_type(static_cast<char>(data_[position_]));
140 : : }
141 : :
142 :CBC 40355 : std::streamsize vector_ostreambuf::xsputn(const char *s, std::streamsize n)
143 : : {
144 [ + + ]: 40355 : if (data_.empty())
145 : : {
146 : 32 : data_.resize(static_cast<std::size_t>(n));
147 : : }
148 : : else
149 : : {
150 : 40323 : auto position_size = data_.size();
151 : 40323 : auto required_size = static_cast<std::size_t>(position_ + static_cast<std::size_t>(n));
152 [ + ]: 40323 : data_.resize(std::max(position_size, required_size));
153 : : }
154 : :
155 [ + ]: 40355 : std::copy(s, s + n, data_.begin() + static_cast<std::ptrdiff_t>(position_));
156 : 40355 : position_ += static_cast<std::size_t>(n);
157 : :
158 : 40355 : return n;
159 : : }
160 : :
161 : 4525 : std::streampos vector_ostreambuf::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode)
162 : : {
163 [ + + ]: 4525 : if (way == std::ios_base::beg)
164 : : {
165 : 4107 : position_ = 0;
166 : : }
167 [ - + ]: 418 : else if (way == std::ios_base::end)
168 : : {
169 :UBC 0 : position_ = data_.size();
170 : : }
171 : :
172 [ - + ]:CBC 4525 : if (off < 0)
173 : : {
174 [ # # ]:UBC 0 : if (static_cast<std::size_t>(-off) > position_)
175 : : {
176 : 0 : position_ = 0;
177 : 0 : return static_cast<std::ptrdiff_t>(-1);
178 : : }
179 : : else
180 : : {
181 : 0 : position_ -= static_cast<std::size_t>(-off);
182 : : }
183 : : }
184 [ + + ]:CBC 4525 : else if (off > 0)
185 : : {
186 [ - + ]: 4012 : if (static_cast<std::size_t>(off) + position_ > data_.size())
187 : : {
188 :UBC 0 : position_ = data_.size();
189 : 0 : return static_cast<std::ptrdiff_t>(-1);
190 : : }
191 : : else
192 : : {
193 :CBC 4012 : position_ += static_cast<std::size_t>(off);
194 : : }
195 : : }
196 : :
197 : 4525 : return static_cast<std::ptrdiff_t>(position_);
198 : : }
199 : :
200 : 11039 : std::streampos vector_ostreambuf::seekpos(std::streampos sp, std::ios_base::openmode)
201 : : {
202 [ - + ]: 11039 : if (sp < 0)
203 : : {
204 :UBC 0 : position_ = 0;
205 : : }
206 [ - + ]:CBC 11039 : else if (static_cast<std::size_t>(sp) > data_.size())
207 : : {
208 :UBC 0 : position_ = data_.size();
209 : : }
210 : : else
211 : : {
212 :CBC 11039 : position_ = static_cast<std::size_t>(sp);
213 : : }
214 : :
215 : 11039 : return static_cast<std::ptrdiff_t>(position_);
216 : : }
217 : :
218 : 271 : std::vector<std::uint8_t> to_vector(std::istream &in_stream)
219 : : {
220 [ - + ]: 271 : if (!in_stream)
221 : : {
222 [ # # ]:UBC 0 : throw xlnt::exception("bad stream");
223 : : }
224 : :
225 : : return std::vector<std::uint8_t>(
226 :CBC 271 : std::istreambuf_iterator<char>(in_stream),
227 [ + ]: 542 : std::istreambuf_iterator<char>());
228 : : }
229 : :
230 :UBC 0 : void to_stream(const std::vector<std::uint8_t> &bytes, std::ostream &out_stream)
231 : : {
232 [ # # ]: 0 : if (!out_stream)
233 : : {
234 [ # # ]: 0 : throw xlnt::exception("bad stream");
235 : : }
236 : :
237 : 0 : out_stream.write(reinterpret_cast<const char *>(bytes.data()), static_cast<std::ptrdiff_t>(bytes.size()));
238 : 0 : }
239 : :
240 : 0 : std::ostream &operator<<(std::ostream &out_stream, const std::vector<std::uint8_t> &bytes)
241 : : {
242 : 0 : to_stream(bytes, out_stream);
243 : 0 : return out_stream;
244 : : }
245 : :
246 : : } // namespace detail
247 : : } // namespace xlnt
|