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 "src/inspector/string-util.h" 6 7 #include "src/base/platform/platform.h" 8 #include "src/conversions.h" 9 #include "src/inspector/protocol/Protocol.h" 10 #include "src/unicode-cache.h" 11 12 namespace v8_inspector { 13 14 v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string) { 15 if (string.isEmpty()) return v8::String::Empty(isolate); 16 DCHECK_GT(v8::String::kMaxLength, string.length()); 17 return v8::String::NewFromTwoByte( 18 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), 19 v8::NewStringType::kNormal, static_cast<int>(string.length())) 20 .ToLocalChecked(); 21 } 22 23 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, 24 const String16& string) { 25 if (string.isEmpty()) return v8::String::Empty(isolate); 26 DCHECK_GT(v8::String::kMaxLength, string.length()); 27 return v8::String::NewFromTwoByte( 28 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), 29 v8::NewStringType::kInternalized, 30 static_cast<int>(string.length())) 31 .ToLocalChecked(); 32 } 33 34 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, 35 const char* str) { 36 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized) 37 .ToLocalChecked(); 38 } 39 40 v8::Local<v8::String> toV8String(v8::Isolate* isolate, 41 const StringView& string) { 42 if (!string.length()) return v8::String::Empty(isolate); 43 DCHECK_GT(v8::String::kMaxLength, string.length()); 44 if (string.is8Bit()) 45 return v8::String::NewFromOneByte( 46 isolate, reinterpret_cast<const uint8_t*>(string.characters8()), 47 v8::NewStringType::kNormal, static_cast<int>(string.length())) 48 .ToLocalChecked(); 49 return v8::String::NewFromTwoByte( 50 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), 51 v8::NewStringType::kNormal, static_cast<int>(string.length())) 52 .ToLocalChecked(); 53 } 54 55 String16 toProtocolString(v8::Isolate* isolate, v8::Local<v8::String> value) { 56 if (value.IsEmpty() || value->IsNullOrUndefined()) return String16(); 57 std::unique_ptr<UChar[]> buffer(new UChar[value->Length()]); 58 value->Write(isolate, reinterpret_cast<uint16_t*>(buffer.get()), 0, 59 value->Length()); 60 return String16(buffer.get(), value->Length()); 61 } 62 63 String16 toProtocolStringWithTypeCheck(v8::Isolate* isolate, 64 v8::Local<v8::Value> value) { 65 if (value.IsEmpty() || !value->IsString()) return String16(); 66 return toProtocolString(isolate, value.As<v8::String>()); 67 } 68 69 String16 toString16(const StringView& string) { 70 if (!string.length()) return String16(); 71 if (string.is8Bit()) 72 return String16(reinterpret_cast<const char*>(string.characters8()), 73 string.length()); 74 return String16(reinterpret_cast<const UChar*>(string.characters16()), 75 string.length()); 76 } 77 78 StringView toStringView(const String16& string) { 79 if (string.isEmpty()) return StringView(); 80 return StringView(reinterpret_cast<const uint16_t*>(string.characters16()), 81 string.length()); 82 } 83 84 bool stringViewStartsWith(const StringView& string, const char* prefix) { 85 if (!string.length()) return !(*prefix); 86 if (string.is8Bit()) { 87 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) { 88 if (string.characters8()[i] != prefix[j]) return false; 89 } 90 } else { 91 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) { 92 if (string.characters16()[i] != prefix[j]) return false; 93 } 94 } 95 return true; 96 } 97 98 namespace protocol { 99 100 // static 101 double StringUtil::toDouble(const char* s, size_t len, bool* isOk) { 102 v8::internal::UnicodeCache unicode_cache; 103 int flags = v8::internal::ALLOW_HEX | v8::internal::ALLOW_OCTAL | 104 v8::internal::ALLOW_BINARY; 105 double result = StringToDouble(&unicode_cache, s, flags); 106 *isOk = !std::isnan(result); 107 return result; 108 } 109 110 std::unique_ptr<protocol::Value> StringUtil::parseJSON( 111 const StringView& string) { 112 if (!string.length()) return nullptr; 113 if (string.is8Bit()) { 114 return parseJSONCharacters(string.characters8(), 115 static_cast<int>(string.length())); 116 } 117 return parseJSONCharacters(string.characters16(), 118 static_cast<int>(string.length())); 119 } 120 121 std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) { 122 if (!string.length()) return nullptr; 123 return parseJSONCharacters(string.characters16(), 124 static_cast<int>(string.length())); 125 } 126 127 // static 128 void StringUtil::builderAppendQuotedString(StringBuilder& builder, 129 const String& str) { 130 builder.append('"'); 131 if (!str.isEmpty()) { 132 escapeWideStringForJSON( 133 reinterpret_cast<const uint16_t*>(str.characters16()), 134 static_cast<int>(str.length()), &builder); 135 } 136 builder.append('"'); 137 } 138 139 } // namespace protocol 140 141 // static 142 std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) { 143 String16 owner = toString16(string); 144 return StringBufferImpl::adopt(owner); 145 } 146 147 // static 148 std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) { 149 return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(string)); 150 } 151 152 StringBufferImpl::StringBufferImpl(String16& string) { 153 m_owner.swap(string); 154 m_string = toStringView(m_owner); 155 } 156 157 String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId) { 158 const size_t kBufferSize = 35; 159 160 char buffer[kBufferSize]; 161 v8::base::OS::SNPrintF(buffer, kBufferSize, "(%08" PRIX64 "%08" PRIX64 ")", 162 debuggerId.first, debuggerId.second); 163 return String16(buffer); 164 } 165 166 String16 stackTraceIdToString(uintptr_t id) { 167 String16Builder builder; 168 builder.appendNumber(static_cast<size_t>(id)); 169 return builder.toString(); 170 } 171 172 } // namespace v8_inspector 173