staticlib_io  1.2.11
 All Classes Namespaces Files Functions Variables
operations.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015, alex at staticlibs.net
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * File: operations.hpp
19  * Author: alex
20  *
21  * Created on October 9, 2015, 12:07 PM
22  */
23 
24 #ifndef STATICLIB_IO_OPERATIONS_HPP
25 #define STATICLIB_IO_OPERATIONS_HPP
26 
27 #include <cstdint>
28 #include <cstdlib>
29 #include <cerrno>
30 #include <algorithm>
31 #include <array>
32 #include <ios>
33 #include <sstream>
34 #include <string>
35 
36 #include "staticlib/config.hpp"
37 
39 #include "staticlib/io/span.hpp"
43 
44 namespace staticlib {
45 namespace io {
46 
55 template<typename Sink>
56 void write_all(Sink& sink, span<const char> span) {
57  size_t ulen = span.size();
58  size_t result = 0;
59  while (result < ulen) {
60  std::streamsize amt = sink.write({span.data() + result, static_cast<std::streamsize>(ulen - result)});
61  if (!sl::support::is_sizet(amt)) throw io_exception(TRACEMSG(
62  "Invalid result returned by underlying 'write' operation: [" + sl::support::to_string(amt) + "]"));
63  result += static_cast<size_t>(amt);
64  }
65 }
66 
75 template<typename Source>
76 size_t read_all(Source& src, span<char> span) {
77  size_t ulen = span.size();
78  size_t result = 0;
79  while (result < ulen) {
80  std::streamsize amt = src.read({span.data() + result, static_cast<std::streamsize> (ulen - result)});
81  if (std::char_traits<char>::eof() != amt) {
82  if (!sl::support::is_sizet(amt)) throw io_exception(TRACEMSG(
83  "Invalid result returned by underlying 'read' operation: [" + sl::support::to_string(amt) + "]"));
84  result += static_cast<size_t> (amt);
85  } else break;
86  }
87  return result;
88 }
89 
97 template<typename Source>
98 void read_exact(Source& src, span<char> span) {
99  size_t res = read_all(src, span);
100  if (res != span.size()) throw io_exception(TRACEMSG(
101  "Read amount: [" + sl::support::to_string(res) + "]" +
102  " of expected: [" + sl::support::to_string(span.size()) + "]"));
103 }
104 
114 template<typename Source, typename Sink>
115 size_t copy_all(Source& src, Sink& sink, span<char> span) {
116  size_t ulen = span.size();
117  size_t result = 0;
118  size_t amt;
119  while (ulen == (amt = read_all(src, span))) {
120  write_all(sink, {span.data(), amt});
121  result += amt;
122  }
123  // tail
124  if (amt > 0) {
125  write_all(sink, {span.data(), amt});
126  result += amt;
127  }
128  return result;
129 }
130 
139 template<typename Source, typename Sink, uint16_t BufferSize = 4096>
140 size_t copy_all(Source& src, Sink& sink) {
141  std::array<char, BufferSize> buf;
142  span<char> span(buf);
143  return copy_all(src, sink, span);
144 }
145 
154 template<typename Source, typename IntTypeSkip>
155 void skip(Source& src, span<char> span, IntTypeSkip to_skip) {
156  if (!(sl::support::is_sizet(to_skip) && sl::support::is_streamsize(to_skip))) throw io_exception(TRACEMSG(
157  "Invalid 'skip' parameter specified, to_skip: [" + sl::support::to_string(to_skip) + "]"));
158  size_t ulen = span.size();
159  size_t uskip = static_cast<size_t>(to_skip);
160  while (uskip > 0) {
161  size_t chunklen = uskip <= ulen ? uskip : ulen;
162  io::read_exact(src, {span.data(), chunklen});
163  uskip -= chunklen;
164  }
165 }
166 
174 inline std::string str_replace(const std::string& input, std::map<std::string, std::string> values) {
175  auto src = make_replacer_source(string_source(input), std::move(values), [](const std::string& err) {
176  throw io_exception(err);
177  });
178  auto sink = string_sink();
179  copy_all(src, sink);
180  return sink.get_string();
181 }
182 
183 } // namespace
184 }
185 
186 #endif /* STATICLIB_IO_OPERATIONS_HPP */
187