summaryrefslogtreecommitdiff
path: root/deps/v8/src/utils/ostreams.h
blob: e87675d54185f66db6d55dd187db5c9523f53e96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_UTILS_OSTREAMS_H_
#define V8_UTILS_OSTREAMS_H_

#include <cstddef>
#include <cstdio>
#include <cstring>
#include <ostream>  // NOLINT
#include <streambuf>

#include "include/v8config.h"
#include "src/base/macros.h"
#include "src/common/globals.h"

namespace v8 {
namespace internal {

class V8_EXPORT_PRIVATE OFStreamBase : public std::streambuf {
 public:
  explicit OFStreamBase(FILE* f);
  ~OFStreamBase() override = default;

 protected:
  FILE* const f_;

  int sync() override;
  int_type overflow(int_type c) override;
  std::streamsize xsputn(const char* s, std::streamsize n) override;
};

// Output buffer and stream writing into debugger's command window.
class V8_EXPORT_PRIVATE DbgStreamBuf : public std::streambuf {
 public:
  DbgStreamBuf();
  ~DbgStreamBuf();

 private:
  int sync() override;
  int overflow(int c) override;

  char data_[256];
};

class DbgStdoutStream : public std::ostream {
 public:
  DbgStdoutStream();
  ~DbgStdoutStream() = default;

 private:
  DbgStreamBuf streambuf_;
};

// An output stream writing to a file.
class V8_EXPORT_PRIVATE OFStream : public std::ostream {
 public:
  explicit OFStream(FILE* f);
  ~OFStream() override = default;

 private:
  OFStreamBase buf_;
};

#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
class V8_EXPORT_PRIVATE AndroidLogStream : public std::streambuf {
 public:
  virtual ~AndroidLogStream();

 protected:
  std::streamsize xsputn(const char* s, std::streamsize n) override;

 private:
  std::string line_buffer_;
};

class StdoutStream : public std::ostream {
 public:
  StdoutStream() : std::ostream(&stream_) {}

 private:
  AndroidLogStream stream_;
};
#else
class StdoutStream : public OFStream {
 public:
  StdoutStream() : OFStream(stdout) {}
};
#endif

// Wrappers to disambiguate uint16_t and uc16.
struct AsUC16 {
  explicit AsUC16(uint16_t v) : value(v) {}
  uint16_t value;
};

struct AsUC32 {
  explicit AsUC32(int32_t v) : value(v) {}
  int32_t value;
};

struct AsReversiblyEscapedUC16 {
  explicit AsReversiblyEscapedUC16(uint16_t v) : value(v) {}
  uint16_t value;
};

struct AsEscapedUC16ForJSON {
  explicit AsEscapedUC16ForJSON(uint16_t v) : value(v) {}
  uint16_t value;
};

// Output the given value as hex, with a minimum width and optional prefix (0x).
// E.g. AsHex(23, 3, true) produces "0x017". Produces an empty string if both
// {min_width} and the value are 0.
struct AsHex {
  explicit AsHex(uint64_t v, uint8_t min_width = 1, bool with_prefix = false)
      : value(v), min_width(min_width), with_prefix(with_prefix) {}
  uint64_t value;
  uint8_t min_width;
  bool with_prefix;

  static AsHex Address(Address a) {
    return AsHex(a, kSystemPointerHexDigits, true);
  }
};

// Output the given value as hex, separated in individual bytes.
// E.g. AsHexBytes(0x231712, 4) produces "12 17 23 00" if output as little
// endian (default), and "00 23 17 12" as big endian. Produces an empty string
// if both {min_bytes} and the value are 0.
struct AsHexBytes {
  enum ByteOrder { kLittleEndian, kBigEndian };
  explicit AsHexBytes(uint64_t v, uint8_t min_bytes = 1,
                      ByteOrder byte_order = kLittleEndian)
      : value(v), min_bytes(min_bytes), byte_order(byte_order) {}
  uint64_t value;
  uint8_t min_bytes;
  ByteOrder byte_order;
};

template <typename T>
struct PrintIteratorRange {
  T start;
  T end;
  PrintIteratorRange(T start, T end) : start(start), end(end) {}
};

// Print any collection which can be iterated via std::begin and std::end.
// {Iterator} is the common type of {std::begin} and {std::end} called on a
// {const T&}. This function is only instantiable if that type exists.
template <typename T, typename Iterator = typename std::common_type<
                          decltype(std::begin(std::declval<const T&>())),
                          decltype(std::end(std::declval<const T&>()))>::type>
PrintIteratorRange<Iterator> PrintCollection(const T& collection) {
  return {std::begin(collection), std::end(collection)};
}

// Writes the given character to the output escaping everything outside of
// printable/space ASCII range. Additionally escapes '\' making escaping
// reversible.
std::ostream& operator<<(std::ostream& os, const AsReversiblyEscapedUC16& c);

// Same as AsReversiblyEscapedUC16 with additional escaping of \n, \r, " and '.
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           const AsEscapedUC16ForJSON& c);

// Writes the given character to the output escaping everything outside
// of printable ASCII range.
std::ostream& operator<<(std::ostream& os, const AsUC16& c);

// Writes the given character to the output escaping everything outside
// of printable ASCII range.
std::ostream& operator<<(std::ostream& os, const AsUC32& c);

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const AsHex& v);
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           const AsHexBytes& v);

template <typename T>
std::ostream& operator<<(std::ostream& os, const PrintIteratorRange<T>& range) {
  const char* comma = "";
  os << "[";
  for (T it = range.start; it != range.end; ++it, comma = ", ") {
    os << comma << *it;
  }
  os << "]";
  return os;
}

}  // namespace internal
}  // namespace v8

#endif  // V8_UTILS_OSTREAMS_H_