• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MikkelSchubert / adapterremoval / #42

24 Aug 2024 03:21PM UTC coverage: 79.763% (+0.2%) from 79.602%
#42

push

travis-ci

MikkelSchubert
update changelog

add v2.3.4 and fix some minor issues

2286 of 2866 relevant lines covered (79.76%)

14253.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.41
/src/json.cpp
1
/*************************************************************************\
2
 * AdapterRemoval - cleaning next-generation sequencing reads            *
3
 *                                                                       *
4
 * Copyright (C) 2015 by Mikkel Schubert - mikkelsch@gmail.com           *
5
 *                                                                       *
6
 * This program 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
#include "json.hpp"
20
#include "debug.hpp"    // for AR_REQUIRE
21
#include "strutils.hpp" // for join_text
22
#include <algorithm>    // for max, find
23
#include <cmath>        // for isinf, isnan
24
#include <memory>       // for make_shared, __shared_ptr_access, shar...
25
#include <sstream>      // for ostringstream
26
#include <utility>      // for pair
27

28
namespace adapterremoval {
29

30
std::string
31
_escape(std::string_view value)
49✔
32
{
33
  std::ostringstream stream;
49✔
34

35
  stream << '"';
49✔
36

37
  for (char c : value) {
325✔
38
    switch (c) {
178✔
39
      case '"':
2✔
40
        stream << "\\\"";
2✔
41
        break;
42
      case '\\':
2✔
43
        stream << "\\\\";
2✔
44
        break;
45
      case '\b':
×
46
        stream << "\\b";
×
47
        break;
48
      case '\f':
×
49
        stream << "\\f";
×
50
        break;
51
      case '\n':
2✔
52
        stream << "\\n";
2✔
53
        break;
54
      case '\r':
×
55
        stream << "\\r";
×
56
        break;
57
      case '\t':
5✔
58
        stream << "\\t";
5✔
59
        break;
60
      default: {
167✔
61
        if (c <= 0x1F) {
167✔
62
          stream << "\\u" << std::hex << static_cast<int>(c);
×
63
        } else {
64
          stream << c;
178✔
65
        }
66
      }
67
    }
68
  }
69

70
  stream << '"';
49✔
71

72
  return stream.str();
98✔
73
}
49✔
74

75
std::string
76
format_f64(double value)
18✔
77
{
78
  AR_REQUIRE(!std::isinf(value));
18✔
79
  if (std::isnan(value)) {
18✔
80
    return "null";
4✔
81
  }
82

83
  std::ostringstream out;
16✔
84
  out.precision(3);
16✔
85
  out << std::fixed << value;
32✔
86

87
  return out.str();
16✔
88
}
16✔
89

90
////////////////////////////////////////////////////////////////////////////////
91

92
std::string
93
json_value::to_string() const
22✔
94
{
95
  std::ostringstream ss;
22✔
96

97
  write(ss);
22✔
98

99
  return ss.str();
44✔
100
}
22✔
101

102
////////////////////////////////////////////////////////////////////////////////
103

104
json_token::json_token(std::string value)
56✔
105
  : m_value(std::move(value))
112✔
106
{
107
}
4✔
108

109
json_ptr
110
json_token::from_str(std::string_view value)
10✔
111
{
112
  return std::make_shared<json_token>(_escape(value));
40✔
113
}
114

115
json_ptr
116
json_token::from_str_vec(const string_vec& values)
3✔
117
{
118
  string_vec escaped;
3✔
119
  for (const auto& it : values) {
36✔
120
    escaped.push_back(_escape(it));
24✔
121
  }
122

123
  return json_token::from_raw_vec(escaped);
6✔
124
}
3✔
125

126
json_ptr
127
json_token::from_i64(const int64_t value)
13✔
128
{
129
  return std::make_shared<json_token>(std::to_string(value));
52✔
130
}
131

132
json_ptr
133
json_token::from_i64_vec(const counts& values)
3✔
134
{
135
  string_vec strings;
3✔
136
  for (size_t i = 0; i < values.size(); ++i) {
24✔
137
    strings.push_back(std::to_string(values.get(i)));
36✔
138
  }
139

140
  return json_token::from_raw_vec(strings);
6✔
141
}
3✔
142

143
json_ptr
144
json_token::from_u64(const uint64_t value)
4✔
145
{
146
  return std::make_shared<json_token>(std::to_string(value));
16✔
147
}
148

149
json_ptr
150
json_token::from_f64(const double value)
6✔
151
{
152
  return std::make_shared<json_token>(format_f64(value));
24✔
153
}
154

155
json_ptr
156
json_token::from_f64_vec(const rates& values)
4✔
157
{
158
  string_vec strings;
4✔
159
  for (size_t i = 0; i < values.size(); ++i) {
32✔
160
    strings.push_back(format_f64(values.get(i)));
48✔
161
  }
162

163
  return json_token::from_raw_vec(strings);
8✔
164
}
4✔
165

166
json_ptr
167
json_token::from_boolean(const bool value)
5✔
168
{
169
  return std::make_shared<json_token>(value ? "true" : "false");
19✔
170
}
171

172
json_ptr
173
json_token::from_null()
4✔
174
{
175
  return std::make_shared<json_token>("null");
12✔
176
}
177

178
void
179
json_token::write(std::ostream& out, size_t /* indent */) const
32✔
180
{
181
  out << m_value;
32✔
182
}
32✔
183

184
json_ptr
185
json_token::from_raw_vec(const string_vec& values)
10✔
186
{
187
  std::ostringstream ss;
10✔
188
  ss << "[" << join_text(values, ", ") << "]";
50✔
189

190
  return std::make_shared<json_token>(ss.str());
60✔
191
}
10✔
192

193
////////////////////////////////////////////////////////////////////////////////
194

195
void
196
json_list::write(std::ostream& out, size_t indent_) const
5✔
197
{
198
  const auto indent = std::string(indent_, ' ');
10✔
199

200
  if (m_values.empty()) {
10✔
201
    out << "[]";
2✔
202
  } else {
203
    out << "[\n";
3✔
204

205
    for (size_t i = 0; i < m_values.size(); ++i) {
14✔
206
      out << indent << "  ";
8✔
207
      m_values.at(i)->write(out, indent_ + 2);
12✔
208

209
      if (i < m_values.size() - 1) {
8✔
210
        out << ",";
1✔
211
      }
212

213
      out << "\n";
4✔
214
    }
215

216
    out << indent << "]";
6✔
217
  }
218
}
5✔
219

220
json_dict_ptr
221
json_list::dict()
4✔
222
{
223
  auto ptr = std::make_shared<json_dict>();
4✔
224
  m_values.push_back(ptr);
16✔
225

226
  return ptr;
4✔
227
}
×
228

229
////////////////////////////////////////////////////////////////////////////////
230

231
void
232
json_dict::write(std::ostream& out, size_t indent_) const
32✔
233
{
234
  const auto indent = std::string(m_multi_line ? indent_ : 0, ' ');
64✔
235
  const char spacer = m_multi_line ? '\n' : ' ';
32✔
236

237
  if (m_items.empty()) {
64✔
238
    out << "{}";
5✔
239
  } else {
240
    out << "{" << spacer;
27✔
241

242
    for (size_t i = 0; i < m_items.size(); ++i) {
120✔
243
      const auto it = m_items.at(i);
66✔
244

245
      out << indent << (m_multi_line ? "  " : "") << _escape(it.first) << ": ";
173✔
246
      it.second->write(out, indent_ + 2);
66✔
247
      if (i + 1 < m_items.size()) {
66✔
248
        out << ",";
6✔
249
      }
250

251
      out << spacer;
33✔
252
    }
33✔
253

254
    out << indent << "}";
54✔
255
  }
256
}
32✔
257

258
json_dict_ptr
259
json_dict::dict(std::string_view key)
9✔
260
{
261
  auto ptr = std::make_shared<json_dict>();
9✔
262
  ptr->m_multi_line = m_multi_line;
18✔
263
  _set(key, ptr);
27✔
264

265
  return ptr;
9✔
266
}
×
267

268
json_dict_ptr
269
json_dict::inline_dict(std::string_view key)
6✔
270
{
271
  auto ptr = dict(key);
6✔
272
  ptr->m_multi_line = false;
12✔
273

274
  return ptr;
6✔
275
}
276

277
json_list_ptr
278
json_dict::list(std::string_view key)
2✔
279
{
280
  auto ptr = std::make_shared<json_list>();
2✔
281
  _set(key, ptr);
6✔
282

283
  return ptr;
2✔
284
}
×
285

286
void
287
json_dict::str(std::string_view key, std::string_view value)
6✔
288
{
289
  _set(key, json_token::from_str(value));
12✔
290
}
6✔
291

292
void
293
json_dict::str_vec(std::string_view key, const string_vec& values)
1✔
294
{
295
  _set(key, json_token::from_str_vec(values));
2✔
296
}
1✔
297

298
void
299
json_dict::i64(std::string_view key, const int64_t value)
7✔
300
{
301
  _set(key, json_token::from_i64(value));
14✔
302
}
7✔
303

304
void
305
json_dict::i64_vec(std::string_view key, const counts& values)
1✔
306
{
307
  _set(key, json_token::from_i64_vec(values));
2✔
308
}
1✔
309

310
void
311
json_dict::u64(std::string_view key, const uint64_t value)
×
312
{
313
  _set(key, json_token::from_u64(value));
×
314
}
315

316
void
317
json_dict::f64(std::string_view key, const double value)
2✔
318
{
319
  _set(key, json_token::from_f64(value));
4✔
320
}
2✔
321

322
void
323
json_dict::f64_vec(std::string_view key, const rates& values)
1✔
324
{
325
  _set(key, json_token::from_f64_vec(values));
2✔
326
}
1✔
327

328
void
329
json_dict::boolean(std::string_view key, const bool value)
2✔
330
{
331
  _set(key, json_token::from_boolean(value));
4✔
332
}
2✔
333

334
void
335
json_dict::null(std::string_view key)
2✔
336
{
337
  _set(key, json_token::from_null());
6✔
338
}
2✔
339

340
void
341
json_dict::_set(std::string_view key, const json_ptr& ptr)
33✔
342
{
343
  for (auto& it : m_items) {
164✔
344
    if (it.first == key) {
16✔
345
      it.second = ptr;
×
346
      return;
×
347
    }
348
  }
349

350
  m_items.emplace_back(key, ptr);
33✔
351
}
352

353
} // namespace adapterremoval
15✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc