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#include "src/ostreams.h" 6 7#include <algorithm> 8#include <cmath> 9 10#include "src/base/platform/platform.h" // For isinf/isnan with MSVC 11 12#if V8_OS_WIN 13#define snprintf sprintf_s 14#endif 15 16namespace v8 { 17namespace internal { 18 19// Be lazy and delegate the value=>char conversion to snprintf. 20template<class T> 21OStream& OStream::print(const char* format, T x) { 22 char buf[32]; 23 int n = snprintf(buf, sizeof(buf), format, x); 24 return (n < 0) ? *this : write(buf, n); 25} 26 27 28OStream& OStream::operator<<(short x) { // NOLINT(runtime/int) 29 return print(hex_ ? "%hx" : "%hd", x); 30} 31 32 33OStream& OStream::operator<<(unsigned short x) { // NOLINT(runtime/int) 34 return print(hex_ ? "%hx" : "%hu", x); 35} 36 37 38OStream& OStream::operator<<(int x) { 39 return print(hex_ ? "%x" : "%d", x); 40} 41 42 43OStream& OStream::operator<<(unsigned int x) { 44 return print(hex_ ? "%x" : "%u", x); 45} 46 47 48OStream& OStream::operator<<(long x) { // NOLINT(runtime/int) 49 return print(hex_ ? "%lx" : "%ld", x); 50} 51 52 53OStream& OStream::operator<<(unsigned long x) { // NOLINT(runtime/int) 54 return print(hex_ ? "%lx" : "%lu", x); 55} 56 57 58OStream& OStream::operator<<(long long x) { // NOLINT(runtime/int) 59 return print(hex_ ? "%llx" : "%lld", x); 60} 61 62 63OStream& OStream::operator<<(unsigned long long x) { // NOLINT(runtime/int) 64 return print(hex_ ? "%llx" : "%llu", x); 65} 66 67 68OStream& OStream::operator<<(double x) { 69 if (std::isinf(x)) return *this << (x < 0 ? "-inf" : "inf"); 70 if (std::isnan(x)) return *this << "nan"; 71 return print("%g", x); 72} 73 74 75OStream& OStream::operator<<(void* x) { 76 return print("%p", x); 77} 78 79 80OStream& OStream::operator<<(char x) { 81 return put(x); 82} 83 84 85OStream& OStream::operator<<(signed char x) { 86 return put(x); 87} 88 89 90OStream& OStream::operator<<(unsigned char x) { 91 return put(x); 92} 93 94 95OStream& OStream::dec() { 96 hex_ = false; 97 return *this; 98} 99 100 101OStream& OStream::hex() { 102 hex_ = true; 103 return *this; 104} 105 106 107OStream& flush(OStream& os) { // NOLINT(runtime/references) 108 return os.flush(); 109} 110 111 112OStream& endl(OStream& os) { // NOLINT(runtime/references) 113 return flush(os.put('\n')); 114} 115 116 117OStream& hex(OStream& os) { // NOLINT(runtime/references) 118 return os.hex(); 119} 120 121 122OStream& dec(OStream& os) { // NOLINT(runtime/references) 123 return os.dec(); 124} 125 126 127OStringStream& OStringStream::write(const char* s, size_t n) { 128 size_t new_size = size_ + n; 129 if (new_size < size_) return *this; // Overflow => no-op. 130 reserve(new_size + 1); 131 memcpy(data_ + size_, s, n); 132 size_ = new_size; 133 data_[size_] = '\0'; 134 return *this; 135} 136 137 138OStringStream& OStringStream::flush() { 139 return *this; 140} 141 142 143void OStringStream::reserve(size_t requested_capacity) { 144 if (requested_capacity <= capacity_) return; 145 size_t new_capacity = // Handle possible overflow by not doubling. 146 std::max(std::max(capacity_ * 2, capacity_), requested_capacity); 147 char * new_data = allocate(new_capacity); 148 memcpy(new_data, data_, size_); 149 deallocate(data_, capacity_); 150 capacity_ = new_capacity; 151 data_ = new_data; 152} 153 154 155OFStream& OFStream::write(const char* s, size_t n) { 156 if (f_) fwrite(s, n, 1, f_); 157 return *this; 158} 159 160 161OFStream& OFStream::flush() { 162 if (f_) fflush(f_); 163 return *this; 164} 165 166 167// Locale-independent predicates. 168static bool IsPrint(uint16_t c) { return 0x20 <= c && c <= 0x7e; } 169static bool IsSpace(uint16_t c) { return (0x9 <= c && c <= 0xd) || c == 0x20; } 170static bool IsOK(uint16_t c) { return (IsPrint(c) || IsSpace(c)) && c != '\\'; } 171 172 173static OStream& PrintUC16(OStream& os, uint16_t c, bool (*pred)(uint16_t)) { 174 char buf[10]; 175 const char* format = pred(c) ? "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x"; 176 snprintf(buf, sizeof(buf), format, c); 177 return os << buf; 178} 179 180 181OStream& operator<<(OStream& os, const AsReversiblyEscapedUC16& c) { 182 return PrintUC16(os, c.value, IsOK); 183} 184 185 186OStream& operator<<(OStream& os, const AsUC16& c) { 187 return PrintUC16(os, c.value, IsPrint); 188} 189} } // namespace v8::internal 190