GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/tracing/traced_value.cc Lines: 116 121 95.9 %
Date: 2019-01-07 12:15:22 Branches: 39 58 67.2 %

Line Branch Exec Source
1
// Copyright 2016 the V8 project authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
#include "tracing/traced_value.h"
6
7
#include <cmath>
8
#include <sstream>
9
#include <stdio.h>
10
#include <string>
11
12
#if defined(NODE_HAVE_I18N_SUPPORT)
13
#include <unicode/utf8.h>
14
#include <unicode/utypes.h>
15
#endif
16
17
#if defined(_STLP_VENDOR_CSTD)
18
// STLPort doesn't import fpclassify into the std namespace.
19
#define FPCLASSIFY_NAMESPACE
20
#else
21
#define FPCLASSIFY_NAMESPACE std
22
#endif
23
24
namespace node {
25
namespace tracing {
26
27
namespace {
28
29
1309
std::string EscapeString(const char* value) {
30
1309
  std::string result;
31
1309
  result += '"';
32
  char number_buffer[10];
33
#if defined(NODE_HAVE_I18N_SUPPORT)
34
1309
  int32_t len = strlen(value);
35
1309
  int32_t p = 0;
36
1309
  int32_t i = 0;
37
9684
  for (; i < len; p = i) {
38
    UChar32 c;
39






8375
    U8_NEXT_OR_FFFD(value, i, len, c);
40


8375
    switch (c) {
41
2
      case '\b': result += "\\b"; break;
42
2
      case '\f': result += "\\f"; break;
43
2
      case '\n': result += "\\n"; break;
44
2
      case '\r': result += "\\r"; break;
45
2
      case '\t': result += "\\t"; break;
46
2
      case '\\': result += "\\\\"; break;
47
10
      case '"': result += "\\\""; break;
48
      default:
49

8353
        if (c < 32 || c > 126) {
50
          snprintf(
51
              number_buffer, arraysize(number_buffer), "\\u%04X",
52
4
              static_cast<uint16_t>(static_cast<uint16_t>(c)));
53
4
          result += number_buffer;
54
        } else {
55
8349
          result.append(value + p, i - p);
56
        }
57
    }
58
  }
59
#else
60
  // If we do not have ICU, use a modified version of the non-UTF8 aware
61
  // code from V8's own TracedValue implementation. Note, however, This
62
  // will not produce correctly serialized results for UTF8 values.
63
  while (*value) {
64
    char c = *value++;
65
    switch (c) {
66
      case '\b': result += "\\b"; break;
67
      case '\f': result += "\\f"; break;
68
      case '\n': result += "\\n"; break;
69
      case '\r': result += "\\r"; break;
70
      case '\t': result += "\\t"; break;
71
      case '\\': result += "\\\\"; break;
72
      case '"': result += "\\\""; break;
73
      default:
74
        if (c < '\x20') {
75
          snprintf(
76
              number_buffer, arraysize(number_buffer), "\\u%04X",
77
              static_cast<unsigned>(static_cast<unsigned char>(c)));
78
          result += number_buffer;
79
        } else {
80
          result += c;
81
        }
82
    }
83
  }
84
#endif  // defined(NODE_HAVE_I18N_SUPPORT)
85
1309
  result += '"';
86
1309
  return result;
87
}
88
89
10
std::string DoubleToCString(double v) {
90

10
  switch (FPCLASSIFY_NAMESPACE::fpclassify(v)) {
91
2
    case FP_NAN: return "\"NaN\"";
92
4
    case FP_INFINITE: return (v < 0.0 ? "\"-Infinity\"" : "\"Infinity\"");
93
    case FP_ZERO: return "0";
94
    default:
95
      // This is a far less sophisticated version than the one used inside v8.
96
4
      std::ostringstream stream;
97
4
      stream.imbue(std::locale("C"));  // Ignore locale
98
4
      stream << v;
99
4
      return stream.str();
100
  }
101
}
102
103
}  // namespace
104
105
88
std::unique_ptr<TracedValue> TracedValue::Create() {
106
88
  return std::unique_ptr<TracedValue>(new TracedValue(false));
107
}
108
109
2
std::unique_ptr<TracedValue> TracedValue::CreateArray() {
110
2
  return std::unique_ptr<TracedValue>(new TracedValue(true));
111
}
112
113
90
TracedValue::TracedValue(bool root_is_array) :
114
90
    first_item_(true), root_is_array_(root_is_array) {}
115
116
180
TracedValue::~TracedValue() {}
117
118
23
void TracedValue::SetInteger(const char* name, int value) {
119
23
  WriteName(name);
120
23
  data_ += std::to_string(value);
121
23
}
122
123
5
void TracedValue::SetDouble(const char* name, double value) {
124
5
  WriteName(name);
125
5
  data_ += DoubleToCString(value);
126
5
}
127
128
2
void TracedValue::SetBoolean(const char* name, bool value) {
129
2
  WriteName(name);
130
2
  data_ += value ? "true" : "false";
131
2
}
132
133
1
void TracedValue::SetNull(const char* name) {
134
1
  WriteName(name);
135
1
  data_ += "null";
136
1
}
137
138
1276
void TracedValue::SetString(const char* name, const char* value) {
139
1276
  WriteName(name);
140
1276
  data_ += EscapeString(value);
141
1276
}
142
143
135
void TracedValue::BeginDictionary(const char* name) {
144
135
  WriteName(name);
145
135
  data_ += '{';
146
135
  first_item_ = true;
147
135
}
148
149
17
void TracedValue::BeginArray(const char* name) {
150
17
  WriteName(name);
151
17
  data_ += '[';
152
17
  first_item_ = true;
153
17
}
154
155
1
void TracedValue::AppendInteger(int value) {
156
1
  WriteComma();
157
1
  data_ += std::to_string(value);
158
1
}
159
160
5
void TracedValue::AppendDouble(double value) {
161
5
  WriteComma();
162
5
  data_ += DoubleToCString(value);
163
5
}
164
165
2
void TracedValue::AppendBoolean(bool value) {
166
2
  WriteComma();
167
2
  data_ += value ? "true" : "false";
168
2
}
169
170
1
void TracedValue::AppendNull() {
171
1
  WriteComma();
172
1
  data_ += "null";
173
1
}
174
175
33
void TracedValue::AppendString(const char* value) {
176
33
  WriteComma();
177
33
  data_ += EscapeString(value);
178
33
}
179
180
1
void TracedValue::BeginDictionary() {
181
1
  WriteComma();
182
1
  data_ += '{';
183
1
  first_item_ = true;
184
1
}
185
186
void TracedValue::BeginArray() {
187
  WriteComma();
188
  data_ += '[';
189
  first_item_ = true;
190
}
191
192
136
void TracedValue::EndDictionary() {
193
136
  data_ += '}';
194
136
  first_item_ = false;
195
136
}
196
197
17
void TracedValue::EndArray() {
198
17
  data_ += ']';
199
17
  first_item_ = false;
200
17
}
201
202
1502
void TracedValue::WriteComma() {
203
1502
  if (first_item_) {
204
240
    first_item_ = false;
205
  } else {
206
1262
    data_ += ',';
207
  }
208
1502
}
209
210
1459
void TracedValue::WriteName(const char* name) {
211
1459
  WriteComma();
212
1459
  data_ += '"';
213
1459
  data_ += name;
214
1459
  data_ += "\":";
215
1459
}
216
217
167
void TracedValue::AppendAsTraceFormat(std::string* out) const {
218
167
  *out += root_is_array_ ? '[' : '{';
219
167
  *out += data_;
220
167
  *out += root_is_array_ ? ']' : '}';
221
167
}
222
223
}  // namespace tracing
224
}  // namespace node