Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1144)

Unified Diff: third_party/WebKit/Source/platform/JSONParser.cpp

Issue 2205933002: Add JSON parser to Source/platform (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switch to unique_ptr version of JSONValue classes Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/JSONParser.cpp
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp b/third_party/WebKit/Source/platform/JSONParser.cpp
similarity index 76%
copy from third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp
copy to third_party/WebKit/Source/platform/JSONParser.cpp
index 4193108b279162d232f681cdd0f74ff250c16fff..a9a35d4daf50f4361ae6d8a381126eea1e62c6d5 100644
--- a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp
+++ b/third_party/WebKit/Source/platform/JSONParser.cpp
@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "platform/inspector_protocol/Parser.h"
+#include "platform/JSONParser.h"
-#include "platform/inspector_protocol/String16.h"
-#include "platform/inspector_protocol/Values.h"
+#include "platform/Decimal.h"
+#include "platform/JSONValues.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringToNumber.h"
namespace blink {
-namespace protocol {
namespace {
@@ -33,7 +34,8 @@ const char* const nullString = "null";
const char* const trueString = "true";
const char* const falseString = "false";
-bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token)
+template<typename CharType>
+bool parseConstToken(const CharType* start, const CharType* end, const CharType** tokenEnd, const char* token)
{
while (start < end && *token != '\0' && *start++ == *token++) { }
if (*token != '\0')
@@ -42,7 +44,8 @@ bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEn
return true;
}
-bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool canHaveLeadingZeros)
+template<typename CharType>
+bool readInt(const CharType* start, const CharType* end, const CharType** tokenEnd, bool canHaveLeadingZeros)
{
if (start == end)
return false;
@@ -60,13 +63,14 @@ bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool
return true;
}
-bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenEnd)
+template<typename CharType>
+bool parseNumberToken(const CharType* start, const CharType* end, const CharType** tokenEnd)
{
// We just grab the number here. We validate the size in DecodeNumber.
// According to RFC4627, a valid number is: [minus] int [frac] [exp]
if (start == end)
return false;
- UChar c = *start;
+ CharType c = *start;
if ('-' == c)
++start;
@@ -109,12 +113,13 @@ bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenE
return true;
}
-bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd, int digits)
+template<typename CharType>
+bool readHexDigits(const CharType* start, const CharType* end, const CharType** tokenEnd, int digits)
{
if (end - start < digits)
return false;
for (int i = 0; i < digits; ++i) {
- UChar c = *start++;
+ CharType c = *start++;
if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
return false;
}
@@ -122,10 +127,11 @@ bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd,
return true;
}
-bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenEnd)
+template<typename CharType>
+bool parseStringToken(const CharType* start, const CharType* end, const CharType** tokenEnd)
{
while (start < end) {
- UChar c = *start++;
+ CharType c = *start++;
if ('\\' == c) {
c = *start++;
// Make sure the escaped char is valid.
@@ -159,7 +165,8 @@ bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenE
return false;
}
-bool skipComment(const UChar* start, const UChar* end, const UChar** commentEnd)
+template<typename CharType>
+bool skipComment(const CharType* start, const CharType* end, const CharType** commentEnd)
{
if (start == end)
return false;
@@ -182,7 +189,7 @@ bool skipComment(const UChar* start, const UChar* end, const UChar** commentEnd)
}
if (*start == '*') {
- UChar previous = '\0';
+ CharType previous = '\0';
// Block comment, read until end marker.
for (++start; start < end; previous = *start++) {
if (previous == '*' && *start == '/') {
@@ -197,13 +204,14 @@ bool skipComment(const UChar* start, const UChar* end, const UChar** commentEnd)
return false;
}
-void skipWhitespaceAndComments(const UChar* start, const UChar* end, const UChar** whitespaceEnd)
+template<typename CharType>
+void skipWhitespaceAndComments(const CharType* start, const CharType* end, const CharType** whitespaceEnd)
{
while (start < end) {
if (isSpaceOrNewline(*start)) {
++start;
} else if (*start == '/') {
- const UChar* commentEnd;
+ const CharType* commentEnd;
if (!skipComment(start, end, &commentEnd))
break;
start = commentEnd;
@@ -214,7 +222,8 @@ void skipWhitespaceAndComments(const UChar* start, const UChar* end, const UChar
*whitespaceEnd = start;
}
-Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart, const UChar** tokenEnd)
+template<typename CharType>
+Token parseToken(const CharType* start, const CharType* end, const CharType** tokenStart, const CharType** tokenEnd)
{
skipWhitespaceAndComments(start, end, tokenStart);
start = *tokenStart;
@@ -275,7 +284,8 @@ Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart,
return InvalidToken;
}
-inline int hexToInt(UChar c)
+template<typename CharType>
+inline int hexToInt(CharType c)
{
if ('0' <= c && c <= '9')
return c - '0';
@@ -287,7 +297,8 @@ inline int hexToInt(UChar c)
return 0;
}
-bool decodeString(const UChar* start, const UChar* end, String16Builder* output)
+template<typename CharType>
+bool decodeString(const CharType* start, const CharType* end, StringBuilder* output)
{
while (start < end) {
UChar c = *start++;
@@ -340,7 +351,8 @@ bool decodeString(const UChar* start, const UChar* end, String16Builder* output)
return true;
}
-bool decodeString(const UChar* start, const UChar* end, String16* output)
+template<typename CharType>
+bool decodeString(const CharType* start, const CharType* end, String* output)
{
if (start == end) {
*output = "";
@@ -348,61 +360,67 @@ bool decodeString(const UChar* start, const UChar* end, String16* output)
}
if (start > end)
return false;
- String16Builder buffer;
+ StringBuilder buffer;
buffer.reserveCapacity(end - start);
if (!decodeString(start, end, &buffer))
return false;
*output = buffer.toString();
+ // Validate constructed utf16 string.
+ if (output->utf8(StrictUTF8Conversion).isNull())
+ return false;
return true;
}
-std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth)
+template<typename CharType>
+std::unique_ptr<JSONValue> buildValue(const CharType* start, const CharType* end, const CharType** valueTokenEnd, int depth)
{
if (depth > stackLimit)
return nullptr;
- std::unique_ptr<Value> result;
- const UChar* tokenStart;
- const UChar* tokenEnd;
+ std::unique_ptr<JSONValue> result;
+ const CharType* tokenStart;
+ const CharType* tokenEnd;
Token token = parseToken(start, end, &tokenStart, &tokenEnd);
switch (token) {
case InvalidToken:
return nullptr;
case NullToken:
- result = Value::null();
+ result = JSONValue::null();
break;
case BoolTrue:
- result = FundamentalValue::create(true);
+ result = JSONBasicValue::create(true);
break;
case BoolFalse:
- result = FundamentalValue::create(false);
+ result = JSONBasicValue::create(false);
break;
case Number: {
bool ok;
- double value = String16::charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
+ double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
+ if (Decimal::fromDouble(value).isInfinity())
+ ok = false;
if (!ok)
return nullptr;
int number = static_cast<int>(value);
if (number == value)
- result = FundamentalValue::create(number);
+ result = JSONBasicValue::create(number);
else
- result = FundamentalValue::create(value);
+ result = JSONBasicValue::create(value);
break;
}
case StringLiteral: {
- String16 value;
+ String value;
bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
if (!ok)
return nullptr;
- result = StringValue::create(value);
+ result = JSONString::create(value);
break;
}
case ArrayBegin: {
- std::unique_ptr<ListValue> array = ListValue::create();
+ std::unique_ptr<JSONArray> array = JSONArray::create();
start = tokenEnd;
token = parseToken(start, end, &tokenStart, &tokenEnd);
while (token != ArrayEnd) {
- std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
+ std::unique_ptr<JSONValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
if (!arrayNode)
return nullptr;
array->pushValue(std::move(arrayNode));
@@ -426,13 +444,13 @@ std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UC
break;
}
case ObjectBegin: {
- std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
+ std::unique_ptr<JSONObject> object = JSONObject::create();
start = tokenEnd;
token = parseToken(start, end, &tokenStart, &tokenEnd);
while (token != ObjectEnd) {
if (token != StringLiteral)
return nullptr;
- String16 key;
+ String key;
if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
return nullptr;
start = tokenEnd;
@@ -442,7 +460,7 @@ std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UC
return nullptr;
start = tokenEnd;
- std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
+ std::unique_ptr<JSONValue> value = buildValue(start, end, &tokenEnd, depth + 1);
if (!value)
return nullptr;
object->setValue(key, std::move(value));
@@ -476,11 +494,12 @@ std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UC
return result;
}
-std::unique_ptr<Value> parseJSONInternal(const UChar* start, unsigned length)
+template<typename CharType>
+std::unique_ptr<JSONValue> parseJSONInternal(const CharType* start, unsigned length)
{
- const UChar* end = start + length;
- const UChar *tokenEnd;
- std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
+ const CharType* end = start + length;
+ const CharType *tokenEnd;
+ std::unique_ptr<JSONValue> value = buildValue(start, end, &tokenEnd, 0);
if (!value || tokenEnd != end)
return nullptr;
return value;
@@ -488,12 +507,13 @@ std::unique_ptr<Value> parseJSONInternal(const UChar* start, unsigned length)
} // anonymous namespace
-std::unique_ptr<Value> parseJSON(const String16& json)
+std::unique_ptr<JSONValue> parseJSON(const String& json)
{
if (json.isEmpty())
return nullptr;
+ if (json.is8Bit())
+ return parseJSONInternal(json.characters8(), json.length());
return parseJSONInternal(json.characters16(), json.length());
}
-} // namespace protocol
} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/platform/JSONParser.h ('k') | third_party/WebKit/Source/platform/JSONParserTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698