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 OFStreamBase : public std::streambuf { 22 public: 23 explicit OFStreamBase(FILE* f); 24 virtual ~OFStreamBase(); 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 virtual ~OFStream(); 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 class StdoutStream : public OFStream { 65 public: 66 StdoutStream() : OFStream(stdout) {} 67 }; 68 #endif 69 70 // Wrappers to disambiguate uint16_t and uc16. 71 struct AsUC16 { 72 explicit AsUC16(uint16_t v) : value(v) {} 73 uint16_t value; 74 }; 75 76 77 struct AsUC32 { 78 explicit AsUC32(int32_t v) : value(v) {} 79 int32_t value; 80 }; 81 82 83 struct AsReversiblyEscapedUC16 { 84 explicit AsReversiblyEscapedUC16(uint16_t v) : value(v) {} 85 uint16_t value; 86 }; 87 88 struct AsEscapedUC16ForJSON { 89 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 : 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 : 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 std::ostream& operator<<(std::ostream& os, const PrintIteratorRange<T>& range) { 158 const char* comma = ""; 159 os << "["; 160 for (T it = range.start; it != range.end; ++it, comma = ", ") { 161 os << comma << *it; 162 } 163 os << "]"; 164 return os; 165 } 166 167 } // namespace internal 168 } // namespace v8 169 170 #endif // V8_OSTREAMS_H_ 171