| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/inspector_protocol/InspectorProtocol.h" | 5 #include "platform/v8_inspector/String16.h" |
| 6 |
| 7 #include "platform/v8_inspector/ProtocolPlatform.h" |
| 6 | 8 |
| 7 #include <algorithm> | 9 #include <algorithm> |
| 8 #include <cctype> | 10 #include <cctype> |
| 9 #include <cstdio> | 11 #include <cstdio> |
| 12 #include <cstdlib> |
| 13 #include <cstring> |
| 10 #include <locale> | 14 #include <locale> |
| 15 #include <string> |
| 11 | 16 |
| 12 namespace blink { | 17 namespace v8_inspector { |
| 13 namespace protocol { | 18 |
| 19 namespace { |
| 20 |
| 21 bool isASCII(UChar c) |
| 22 { |
| 23 return !(c & ~0x7F); |
| 24 } |
| 25 |
| 26 bool isSpaceOrNewLine(UChar c) |
| 27 { |
| 28 return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); |
| 29 } |
| 30 |
| 31 int charactersToInteger(const UChar* characters, size_t length, bool* ok = nullp
tr) |
| 32 { |
| 33 std::vector<char> buffer; |
| 34 buffer.reserve(length + 1); |
| 35 for (size_t i = 0; i < length; ++i) { |
| 36 if (!isASCII(characters[i])) { |
| 37 if (ok) |
| 38 *ok = false; |
| 39 return 0; |
| 40 } |
| 41 buffer.push_back(static_cast<char>(characters[i])); |
| 42 } |
| 43 buffer.push_back('\0'); |
| 44 |
| 45 char* endptr; |
| 46 int result = std::strtol(buffer.data(), &endptr, 10); |
| 47 if (ok) |
| 48 *ok = !(*endptr); |
| 49 return result; |
| 50 } |
| 14 | 51 |
| 15 const UChar replacementCharacter = 0xFFFD; | 52 const UChar replacementCharacter = 0xFFFD; |
| 16 using UChar32 = uint32_t; | 53 using UChar32 = uint32_t; |
| 17 | 54 |
| 18 inline int inlineUTF8SequenceLengthNonASCII(char b0) | 55 inline int inlineUTF8SequenceLengthNonASCII(char b0) |
| 19 { | 56 { |
| 20 if ((b0 & 0xC0) != 0xC0) | 57 if ((b0 & 0xC0) != 0xC0) |
| 21 return 0; | 58 return 0; |
| 22 if ((b0 & 0xE0) == 0xC0) | 59 if ((b0 & 0xE0) == 0xC0) |
| 23 return 2; | 60 return 2; |
| 24 if ((b0 & 0xF0) == 0xE0) | 61 if ((b0 & 0xF0) == 0xE0) |
| 25 return 3; | 62 return 3; |
| 26 if ((b0 & 0xF8) == 0xF0) | 63 if ((b0 & 0xF8) == 0xF0) |
| 27 return 4; | 64 return 4; |
| 28 return 0; | 65 return 0; |
| 29 } | 66 } |
| 30 | 67 |
| 31 inline int inlineUTF8SequenceLength(char b0) | 68 inline int inlineUTF8SequenceLength(char b0) |
| 32 { | 69 { |
| 33 return String16::isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); | 70 return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); |
| 34 } | 71 } |
| 35 | 72 |
| 36 // Once the bits are split out into bytes of UTF-8, this is a mask OR-ed | 73 // Once the bits are split out into bytes of UTF-8, this is a mask OR-ed |
| 37 // into the first byte, depending on how many bytes follow. There are | 74 // into the first byte, depending on how many bytes follow. There are |
| 38 // as many entries in this table as there are UTF-8 sequence types. | 75 // as many entries in this table as there are UTF-8 sequence types. |
| 39 // (I.e., one byte sequence, two byte... etc.). Remember that sequences | 76 // (I.e., one byte sequence, two byte... etc.). Remember that sequences |
| 40 // for *legal* UTF-8 will be 4 or fewer bytes total. | 77 // for *legal* UTF-8 will be 4 or fewer bytes total. |
| 41 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x
F8, 0xFC }; | 78 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x
F8, 0xFC }; |
| 42 | 79 |
| 43 typedef enum { | 80 typedef enum { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 | 362 |
| 326 if (sourceAllASCII) | 363 if (sourceAllASCII) |
| 327 *sourceAllASCII = !(orAllData & ~0x7f); | 364 *sourceAllASCII = !(orAllData & ~0x7f); |
| 328 | 365 |
| 329 return result; | 366 return result; |
| 330 } | 367 } |
| 331 | 368 |
| 332 // Helper to write a three-byte UTF-8 code point to the buffer, caller must chec
k room is available. | 369 // Helper to write a three-byte UTF-8 code point to the buffer, caller must chec
k room is available. |
| 333 static inline void putUTF8Triple(char*& buffer, UChar ch) | 370 static inline void putUTF8Triple(char*& buffer, UChar ch) |
| 334 { | 371 { |
| 335 DCHECK_GE(ch, 0x0800); | |
| 336 *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); | 372 *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); |
| 337 *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); | 373 *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); |
| 338 *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); | 374 *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); |
| 339 } | 375 } |
| 340 | 376 |
| 377 } // namespace |
| 378 |
| 379 // static |
| 380 String16 String16::fromInteger(int number) |
| 381 { |
| 382 const size_t kBufferSize = 50; |
| 383 char buffer[kBufferSize]; |
| 384 std::snprintf(buffer, kBufferSize, "%d", number); |
| 385 return String16(buffer); |
| 386 } |
| 387 |
| 388 // static |
| 389 String16 String16::fromDouble(double number) |
| 390 { |
| 391 const size_t kBufferSize = 100; |
| 392 char buffer[kBufferSize]; |
| 393 std::snprintf(buffer, kBufferSize, "%f", number); |
| 394 return String16(buffer); |
| 395 } |
| 396 |
| 397 // static |
| 398 String16 String16::fromDoublePrecision3(double number) |
| 399 { |
| 400 const size_t kBufferSize = 100; |
| 401 char buffer[kBufferSize]; |
| 402 std::snprintf(buffer, kBufferSize, "%.3g", number); |
| 403 return String16(buffer); |
| 404 } |
| 405 |
| 406 // static |
| 407 String16 String16::fromDoublePrecision6(double number) |
| 408 { |
| 409 const size_t kBufferSize = 100; |
| 410 char buffer[kBufferSize]; |
| 411 std::snprintf(buffer, kBufferSize, "%.6g", number); |
| 412 return String16(buffer); |
| 413 } |
| 414 |
| 415 int String16::toInteger(bool* ok) const |
| 416 { |
| 417 return charactersToInteger(characters16(), length(), ok); |
| 418 } |
| 419 |
| 420 String16 String16::stripWhiteSpace() const |
| 421 { |
| 422 if (!length()) |
| 423 return String16(); |
| 424 |
| 425 unsigned start = 0; |
| 426 unsigned end = length() - 1; |
| 427 |
| 428 // skip white space from start |
| 429 while (start <= end && isSpaceOrNewLine(characters16()[start])) |
| 430 ++start; |
| 431 |
| 432 // only white space |
| 433 if (start > end) |
| 434 return String16(); |
| 435 |
| 436 // skip white space from end |
| 437 while (end && isSpaceOrNewLine(characters16()[end])) |
| 438 --end; |
| 439 |
| 440 if (!start && end == length() - 1) |
| 441 return *this; |
| 442 return String16(characters16() + start, end + 1 - start); |
| 443 } |
| 444 |
| 445 String16Builder::String16Builder() |
| 446 { |
| 447 } |
| 448 |
| 449 void String16Builder::append(const String16& s) |
| 450 { |
| 451 m_buffer.insert(m_buffer.end(), s.characters16(), s.characters16() + s.lengt
h()); |
| 452 } |
| 453 |
| 454 void String16Builder::append(UChar c) |
| 455 { |
| 456 m_buffer.push_back(c); |
| 457 } |
| 458 |
| 459 void String16Builder::append(char c) |
| 460 { |
| 461 UChar u = c; |
| 462 m_buffer.push_back(u); |
| 463 } |
| 464 |
| 465 void String16Builder::append(const UChar* characters, size_t length) |
| 466 { |
| 467 m_buffer.insert(m_buffer.end(), characters, characters + length); |
| 468 } |
| 469 |
| 470 void String16Builder::append(const char* characters, size_t length) |
| 471 { |
| 472 m_buffer.insert(m_buffer.end(), characters, characters + length); |
| 473 } |
| 474 |
| 475 String16 String16Builder::toString() |
| 476 { |
| 477 return String16(m_buffer.data(), m_buffer.size()); |
| 478 } |
| 479 |
| 480 void String16Builder::reserveCapacity(size_t capacity) |
| 481 { |
| 482 m_buffer.reserve(capacity); |
| 483 } |
| 484 |
| 341 String16 String16::fromUTF8(const char* stringStart, size_t length) | 485 String16 String16::fromUTF8(const char* stringStart, size_t length) |
| 342 { | 486 { |
| 343 if (!stringStart || !length) | 487 if (!stringStart || !length) |
| 344 return String16(); | 488 return String16(); |
| 345 | 489 |
| 346 std::vector<UChar> buffer(length); | 490 std::vector<UChar> buffer(length); |
| 347 UChar* bufferStart = buffer.data(); | 491 UChar* bufferStart = buffer.data(); |
| 348 | 492 |
| 349 UChar* bufferCurrent = bufferStart; | 493 UChar* bufferCurrent = bufferStart; |
| 350 const char* stringCurrent = stringStart; | 494 const char* stringCurrent = stringStart; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 DCHECK((*characters >= 0xD800) && (*characters <= 0xDBFF)); | 538 DCHECK((*characters >= 0xD800) && (*characters <= 0xDBFF)); |
| 395 // There should be room left, since one UChar hasn't been | 539 // There should be room left, since one UChar hasn't been |
| 396 // converted. | 540 // converted. |
| 397 DCHECK((buffer + 3) <= (buffer + bufferVector.size())); | 541 DCHECK((buffer + 3) <= (buffer + bufferVector.size())); |
| 398 putUTF8Triple(buffer, *characters); | 542 putUTF8Triple(buffer, *characters); |
| 399 } | 543 } |
| 400 | 544 |
| 401 return std::string(bufferVector.data(), buffer - bufferVector.data()); | 545 return std::string(bufferVector.data(), buffer - bufferVector.data()); |
| 402 } | 546 } |
| 403 | 547 |
| 404 } // namespace protocol | 548 } // namespace v8_inspector |
| 405 } // namespace blink | |
| OLD | NEW |