Line data Source code
1 : // Copyright 2014 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 : #ifndef V8_OSTREAMS_H_
6 : #define V8_OSTREAMS_H_
7 :
8 : #include <cstddef>
9 : #include <cstdio>
10 : #include <cstring>
11 : #include <ostream> // NOLINT
12 : #include <streambuf>
13 :
14 : #include "include/v8config.h"
15 : #include "src/base/macros.h"
16 : #include "src/globals.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : class V8_EXPORT_PRIVATE OFStreamBase : public std::streambuf {
22 : public:
23 : explicit OFStreamBase(FILE* f);
24 73445 : ~OFStreamBase() override = default;
25 :
26 : protected:
27 : FILE* const f_;
28 :
29 : int sync() override;
30 : int_type overflow(int_type c) override;
31 : std::streamsize xsputn(const char* s, std::streamsize n) override;
32 : };
33 :
34 : // An output stream writing to a file.
35 : class V8_EXPORT_PRIVATE OFStream : public std::ostream {
36 : public:
37 : explicit OFStream(FILE* f);
38 148619 : ~OFStream() override = default;
39 :
40 : private:
41 : OFStreamBase buf_;
42 : };
43 :
44 : #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
45 : class V8_EXPORT_PRIVATE AndroidLogStream : public std::streambuf {
46 : public:
47 : virtual ~AndroidLogStream();
48 :
49 : protected:
50 : std::streamsize xsputn(const char* s, std::streamsize n) override;
51 :
52 : private:
53 : std::string line_buffer_;
54 : };
55 :
56 : class StdoutStream : public std::ostream {
57 : public:
58 : StdoutStream() : std::ostream(&stream_) {}
59 :
60 : private:
61 : AndroidLogStream stream_;
62 : };
63 : #else
64 3456 : class StdoutStream : public OFStream {
65 : public:
66 3456 : StdoutStream() : OFStream(stdout) {}
67 : };
68 : #endif
69 :
70 : // Wrappers to disambiguate uint16_t and uc16.
71 : struct AsUC16 {
72 7638 : explicit AsUC16(uint16_t v) : value(v) {}
73 : uint16_t value;
74 : };
75 :
76 :
77 : struct AsUC32 {
78 505 : explicit AsUC32(int32_t v) : value(v) {}
79 : int32_t value;
80 : };
81 :
82 :
83 : struct AsReversiblyEscapedUC16 {
84 0 : explicit AsReversiblyEscapedUC16(uint16_t v) : value(v) {}
85 : uint16_t value;
86 : };
87 :
88 : struct AsEscapedUC16ForJSON {
89 45701 : explicit AsEscapedUC16ForJSON(uint16_t v) : value(v) {}
90 : uint16_t value;
91 : };
92 :
93 : // Output the given value as hex, with a minimum width and optional prefix (0x).
94 : // E.g. AsHex(23, 3, true) produces "0x017". Produces an empty string if both
95 : // {min_width} and the value are 0.
96 : struct AsHex {
97 : explicit AsHex(uint64_t v, uint8_t min_width = 1, bool with_prefix = false)
98 181612 : : value(v), min_width(min_width), with_prefix(with_prefix) {}
99 : uint64_t value;
100 : uint8_t min_width;
101 : bool with_prefix;
102 : };
103 :
104 : // Output the given value as hex, separated in individual bytes.
105 : // E.g. AsHexBytes(0x231712, 4) produces "12 17 23 00" if output as little
106 : // endian (default), and "00 23 17 12" as big endian. Produces an empty string
107 : // if both {min_bytes} and the value are 0.
108 : struct AsHexBytes {
109 : enum ByteOrder { kLittleEndian, kBigEndian };
110 : explicit AsHexBytes(uint64_t v, uint8_t min_bytes = 1,
111 : ByteOrder byte_order = kLittleEndian)
112 18 : : value(v), min_bytes(min_bytes), byte_order(byte_order) {}
113 : uint64_t value;
114 : uint8_t min_bytes;
115 : ByteOrder byte_order;
116 : };
117 :
118 : template <typename T>
119 : struct PrintIteratorRange {
120 : T start;
121 : T end;
122 : PrintIteratorRange(T start, T end) : start(start), end(end) {}
123 : };
124 :
125 : // Print any collection which can be iterated via std::begin and std::end.
126 : // {Iterator} is the common type of {std::begin} and {std::end} called on a
127 : // {const T&}. This function is only instantiable if that type exists.
128 : template <typename T, typename Iterator = typename std::common_type<
129 : decltype(std::begin(std::declval<const T&>())),
130 : decltype(std::end(std::declval<const T&>()))>::type>
131 : PrintIteratorRange<Iterator> PrintCollection(const T& collection) {
132 : return {std::begin(collection), std::end(collection)};
133 : }
134 :
135 : // Writes the given character to the output escaping everything outside of
136 : // printable/space ASCII range. Additionally escapes '\' making escaping
137 : // reversible.
138 : std::ostream& operator<<(std::ostream& os, const AsReversiblyEscapedUC16& c);
139 :
140 : // Same as AsReversiblyEscapedUC16 with additional escaping of \n, \r, " and '.
141 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
142 : const AsEscapedUC16ForJSON& c);
143 :
144 : // Writes the given character to the output escaping everything outside
145 : // of printable ASCII range.
146 : std::ostream& operator<<(std::ostream& os, const AsUC16& c);
147 :
148 : // Writes the given character to the output escaping everything outside
149 : // of printable ASCII range.
150 : std::ostream& operator<<(std::ostream& os, const AsUC32& c);
151 :
152 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const AsHex& v);
153 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
154 : const AsHexBytes& v);
155 :
156 : template <typename T>
157 0 : std::ostream& operator<<(std::ostream& os, const PrintIteratorRange<T>& range) {
158 : const char* comma = "";
159 0 : os << "[";
160 0 : for (T it = range.start; it != range.end; ++it, comma = ", ") {
161 0 : os << comma << *it;
162 : }
163 0 : os << "]";
164 0 : return os;
165 : }
166 :
167 : } // namespace internal
168 : } // namespace v8
169 :
170 : #endif // V8_OSTREAMS_H_
|