OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 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 "src/inspector/String16.h" | 5 #include "src/inspector/String16.h" |
6 | 6 |
7 #include "src/inspector/ProtocolPlatform.h" | 7 #include "src/inspector/ProtocolPlatform.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cctype> | 10 #include <cctype> |
11 #include <cstdio> | 11 #include <cstdio> |
12 #include <cstdlib> | 12 #include <cstdlib> |
13 #include <cstring> | 13 #include <cstring> |
14 #include <limits> | |
15 #include <locale> | 14 #include <locale> |
16 #include <string> | 15 #include <string> |
17 | 16 |
18 namespace v8_inspector { | 17 namespace v8_inspector { |
19 | 18 |
20 namespace { | 19 namespace { |
21 | 20 |
22 bool isASCII(UChar c) { return !(c & ~0x7F); } | 21 bool isASCII(UChar c) { return !(c & ~0x7F); } |
23 | 22 |
24 bool isSpaceOrNewLine(UChar c) { | 23 bool isSpaceOrNewLine(UChar c) { |
25 return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); | 24 return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); |
26 } | 25 } |
27 | 26 |
28 int charactersToInteger(const UChar* characters, size_t length, | 27 int charactersToInteger(const UChar* characters, size_t length, |
29 bool* ok = nullptr) { | 28 bool* ok = nullptr) { |
30 std::vector<char> buffer; | 29 std::vector<char> buffer; |
31 buffer.reserve(length + 1); | 30 buffer.reserve(length + 1); |
32 for (size_t i = 0; i < length; ++i) { | 31 for (size_t i = 0; i < length; ++i) { |
33 if (!isASCII(characters[i])) { | 32 if (!isASCII(characters[i])) { |
34 if (ok) *ok = false; | 33 if (ok) *ok = false; |
35 return 0; | 34 return 0; |
36 } | 35 } |
37 buffer.push_back(static_cast<char>(characters[i])); | 36 buffer.push_back(static_cast<char>(characters[i])); |
38 } | 37 } |
39 buffer.push_back('\0'); | 38 buffer.push_back('\0'); |
40 | 39 |
41 char* endptr; | 40 char* endptr; |
42 long result = std::strtol(buffer.data(), &endptr, 10); | 41 int result = std::strtol(buffer.data(), &endptr, 10); |
43 if (ok) { | 42 if (ok) *ok = !(*endptr); |
44 *ok = !(*endptr) && result <= std::numeric_limits<int>::max() && | 43 return result; |
45 result >= std::numeric_limits<int>::min(); | |
46 } | |
47 return static_cast<int>(result); | |
48 } | 44 } |
49 | 45 |
50 const UChar replacementCharacter = 0xFFFD; | 46 const UChar replacementCharacter = 0xFFFD; |
51 using UChar32 = uint32_t; | 47 using UChar32 = uint32_t; |
52 | 48 |
53 inline int inlineUTF8SequenceLengthNonASCII(char b0) { | 49 inline int inlineUTF8SequenceLengthNonASCII(char b0) { |
54 if ((b0 & 0xC0) != 0xC0) return 0; | 50 if ((b0 & 0xC0) != 0xC0) return 0; |
55 if ((b0 & 0xE0) == 0xC0) return 2; | 51 if ((b0 & 0xE0) == 0xC0) return 2; |
56 if ((b0 & 0xF0) == 0xE0) return 3; | 52 if ((b0 & 0xF0) == 0xE0) return 3; |
57 if ((b0 & 0xF8) == 0xF0) return 4; | 53 if ((b0 & 0xF8) == 0xF0) return 4; |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 // Magic values subtracted from a buffer value during UTF8 conversion. | 242 // Magic values subtracted from a buffer value during UTF8 conversion. |
247 // This table contains as many values as there might be trailing bytes | 243 // This table contains as many values as there might be trailing bytes |
248 // in a UTF-8 sequence. | 244 // in a UTF-8 sequence. |
249 static const UChar32 offsetsFromUTF8[6] = {0x00000000UL, | 245 static const UChar32 offsetsFromUTF8[6] = {0x00000000UL, |
250 0x00003080UL, | 246 0x00003080UL, |
251 0x000E2080UL, | 247 0x000E2080UL, |
252 0x03C82080UL, | 248 0x03C82080UL, |
253 static_cast<UChar32>(0xFA082080UL), | 249 static_cast<UChar32>(0xFA082080UL), |
254 static_cast<UChar32>(0x82082080UL)}; | 250 static_cast<UChar32>(0x82082080UL)}; |
255 | 251 |
256 static inline UChar32 readUTF8Sequence(const char*& sequence, size_t length) { | 252 static inline UChar32 readUTF8Sequence(const char*& sequence, unsigned length) { |
257 UChar32 character = 0; | 253 UChar32 character = 0; |
258 | 254 |
259 // The cases all fall through. | 255 // The cases all fall through. |
260 switch (length) { | 256 switch (length) { |
261 case 6: | 257 case 6: |
262 character += static_cast<unsigned char>(*sequence++); | 258 character += static_cast<unsigned char>(*sequence++); |
263 character <<= 6; | 259 character <<= 6; |
264 case 5: | 260 case 5: |
265 character += static_cast<unsigned char>(*sequence++); | 261 character += static_cast<unsigned char>(*sequence++); |
266 character <<= 6; | 262 character <<= 6; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 360 |
365 // static | 361 // static |
366 String16 String16::fromInteger(int number) { | 362 String16 String16::fromInteger(int number) { |
367 const size_t kBufferSize = 50; | 363 const size_t kBufferSize = 50; |
368 char buffer[kBufferSize]; | 364 char buffer[kBufferSize]; |
369 std::snprintf(buffer, kBufferSize, "%d", number); | 365 std::snprintf(buffer, kBufferSize, "%d", number); |
370 return String16(buffer); | 366 return String16(buffer); |
371 } | 367 } |
372 | 368 |
373 // static | 369 // static |
374 String16 String16::fromInteger(size_t number) { | |
375 const size_t kBufferSize = 50; | |
376 char buffer[kBufferSize]; | |
377 std::snprintf(buffer, kBufferSize, "%zu", number); | |
378 return String16(buffer); | |
379 } | |
380 | |
381 // static | |
382 String16 String16::fromDouble(double number) { | 370 String16 String16::fromDouble(double number) { |
383 const size_t kBufferSize = 100; | 371 const size_t kBufferSize = 100; |
384 char buffer[kBufferSize]; | 372 char buffer[kBufferSize]; |
385 std::snprintf(buffer, kBufferSize, "%f", number); | 373 std::snprintf(buffer, kBufferSize, "%f", number); |
386 return String16(buffer); | 374 return String16(buffer); |
387 } | 375 } |
388 | 376 |
389 // static | 377 // static |
390 String16 String16::fromDoublePrecision3(double number) { | 378 String16 String16::fromDoublePrecision3(double number) { |
391 const size_t kBufferSize = 100; | 379 const size_t kBufferSize = 100; |
(...skipping 10 matching lines...) Expand all Loading... |
402 return String16(buffer); | 390 return String16(buffer); |
403 } | 391 } |
404 | 392 |
405 int String16::toInteger(bool* ok) const { | 393 int String16::toInteger(bool* ok) const { |
406 return charactersToInteger(characters16(), length(), ok); | 394 return charactersToInteger(characters16(), length(), ok); |
407 } | 395 } |
408 | 396 |
409 String16 String16::stripWhiteSpace() const { | 397 String16 String16::stripWhiteSpace() const { |
410 if (!length()) return String16(); | 398 if (!length()) return String16(); |
411 | 399 |
412 size_t start = 0; | 400 unsigned start = 0; |
413 size_t end = length() - 1; | 401 unsigned end = length() - 1; |
414 | 402 |
415 // skip white space from start | 403 // skip white space from start |
416 while (start <= end && isSpaceOrNewLine(characters16()[start])) ++start; | 404 while (start <= end && isSpaceOrNewLine(characters16()[start])) ++start; |
417 | 405 |
418 // only white space | 406 // only white space |
419 if (start > end) return String16(); | 407 if (start > end) return String16(); |
420 | 408 |
421 // skip white space from end | 409 // skip white space from end |
422 while (end && isSpaceOrNewLine(characters16()[end])) --end; | 410 while (end && isSpaceOrNewLine(characters16()[end])) --end; |
423 | 411 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 std::vector<UChar> buffer(length); | 449 std::vector<UChar> buffer(length); |
462 UChar* bufferStart = buffer.data(); | 450 UChar* bufferStart = buffer.data(); |
463 | 451 |
464 UChar* bufferCurrent = bufferStart; | 452 UChar* bufferCurrent = bufferStart; |
465 const char* stringCurrent = stringStart; | 453 const char* stringCurrent = stringStart; |
466 if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &bufferCurrent, | 454 if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &bufferCurrent, |
467 bufferCurrent + buffer.size(), 0, | 455 bufferCurrent + buffer.size(), 0, |
468 true) != conversionOK) | 456 true) != conversionOK) |
469 return String16(); | 457 return String16(); |
470 | 458 |
471 size_t utf16Length = bufferCurrent - bufferStart; | 459 unsigned utf16Length = bufferCurrent - bufferStart; |
472 return String16(bufferStart, utf16Length); | 460 return String16(bufferStart, utf16Length); |
473 } | 461 } |
474 | 462 |
475 std::string String16::utf8() const { | 463 std::string String16::utf8() const { |
476 size_t length = this->length(); | 464 unsigned length = this->length(); |
477 | 465 |
478 if (!length) return std::string(""); | 466 if (!length) return std::string(""); |
479 | 467 |
480 // Allocate a buffer big enough to hold all the characters | 468 // Allocate a buffer big enough to hold all the characters |
481 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). | 469 // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). |
482 // Optimization ideas, if we find this function is hot: | 470 // Optimization ideas, if we find this function is hot: |
483 // * We could speculatively create a CStringBuffer to contain 'length' | 471 // * We could speculatively create a CStringBuffer to contain 'length' |
484 // characters, and resize if necessary (i.e. if the buffer contains | 472 // characters, and resize if necessary (i.e. if the buffer contains |
485 // non-ascii characters). (Alternatively, scan the buffer first for | 473 // non-ascii characters). (Alternatively, scan the buffer first for |
486 // ascii characters, so we know this will be sufficient). | 474 // ascii characters, so we know this will be sufficient). |
(...skipping 26 matching lines...) Expand all Loading... |
513 // There should be room left, since one UChar hasn't been | 501 // There should be room left, since one UChar hasn't been |
514 // converted. | 502 // converted. |
515 DCHECK((buffer + 3) <= (buffer + bufferVector.size())); | 503 DCHECK((buffer + 3) <= (buffer + bufferVector.size())); |
516 putUTF8Triple(buffer, *characters); | 504 putUTF8Triple(buffer, *characters); |
517 } | 505 } |
518 | 506 |
519 return std::string(bufferVector.data(), buffer - bufferVector.data()); | 507 return std::string(bufferVector.data(), buffer - bufferVector.data()); |
520 } | 508 } |
521 | 509 |
522 } // namespace v8_inspector | 510 } // namespace v8_inspector |
OLD | NEW |