Add JSON parsing support (issue #1188).
This commit is contained in:
parent
373180fef2
commit
d02f03a71a
1
cef.gyp
1
cef.gyp
|
@ -1072,6 +1072,7 @@
|
|||
'libcef/common/drag_data_impl.h',
|
||||
'libcef/common/http_header_utils.cc',
|
||||
'libcef/common/http_header_utils.h',
|
||||
'libcef/common/json_impl.cc',
|
||||
'libcef/common/main_delegate.cc',
|
||||
'libcef/common/main_delegate.h',
|
||||
'libcef/common/net_resource_provider.cc',
|
||||
|
|
|
@ -122,6 +122,26 @@ CEF_EXPORT cef_string_userfree_t cef_uridecode(const cef_string_t* text,
|
|||
CEF_EXPORT int cef_parse_csscolor(const cef_string_t* string, int strict,
|
||||
cef_color_t* color);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this function returns NULL.
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_json(const cef_string_t* json_string,
|
||||
cef_json_parser_options_t options);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this function returns NULL and
|
||||
// populates |error_code_out| and |error_msg_out| with an error code and a
|
||||
// formatted error message respectively.
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_jsonand_return_error(
|
||||
const cef_string_t* json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t* error_code_out, cef_string_t* error_msg_out);
|
||||
|
||||
// Generates a JSON string from the specified root |node| which should be a
|
||||
// dictionary or list value. Returns an NULL string on failure. This function
|
||||
// requires exclusive access to |node| including any underlying data.
|
||||
// The resulting string must be freed by calling cef_string_userfree_free().
|
||||
CEF_EXPORT cef_string_userfree_t cef_write_json(struct _cef_value_t* node,
|
||||
cef_json_writer_options_t options);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -123,4 +123,28 @@ bool CefParseCSSColor(const CefString& string,
|
|||
bool strict,
|
||||
cef_color_t& color);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this method returns NULL.
|
||||
/*--cef()--*/
|
||||
CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this method returns NULL and populates
|
||||
// |error_code_out| and |error_msg_out| with an error code and a formatted error
|
||||
// message respectively.
|
||||
/*--cef()--*/
|
||||
CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string,
|
||||
cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out,
|
||||
CefString& error_msg_out);
|
||||
|
||||
// Generates a JSON string from the specified root |node| which should be a
|
||||
// dictionary or list value. Returns an empty string on failure. This method
|
||||
// requires exclusive access to |node| including any underlying data.
|
||||
/*--cef()--*/
|
||||
CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options);
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_PARSER_H_
|
||||
|
|
|
@ -2130,6 +2130,70 @@ typedef enum {
|
|||
UU_REPLACE_PLUS_WITH_SPACE = 16,
|
||||
} cef_uri_unescape_rule_t;
|
||||
|
||||
///
|
||||
// Options that can be passed to CefParseJSON.
|
||||
///
|
||||
typedef enum {
|
||||
///
|
||||
// Parses the input strictly according to RFC 4627. See comments in Chromium's
|
||||
// base/json/json_reader.h file for known limitations/deviations from the RFC.
|
||||
///
|
||||
JSON_PARSER_RFC = 0,
|
||||
|
||||
///
|
||||
// Allows commas to exist after the last element in structures.
|
||||
///
|
||||
JSON_PARSER_ALLOW_TRAILING_COMMAS = 1 << 0,
|
||||
} cef_json_parser_options_t;
|
||||
|
||||
///
|
||||
// Error codes that can be returned from CefParseJSONAndReturnError.
|
||||
///
|
||||
typedef enum {
|
||||
JSON_NO_ERROR = 0,
|
||||
JSON_INVALID_ESCAPE,
|
||||
JSON_SYNTAX_ERROR,
|
||||
JSON_UNEXPECTED_TOKEN,
|
||||
JSON_TRAILING_COMMA,
|
||||
JSON_TOO_MUCH_NESTING,
|
||||
JSON_UNEXPECTED_DATA_AFTER_ROOT,
|
||||
JSON_UNSUPPORTED_ENCODING,
|
||||
JSON_UNQUOTED_DICTIONARY_KEY,
|
||||
JSON_PARSE_ERROR_COUNT
|
||||
} cef_json_parser_error_t;
|
||||
|
||||
///
|
||||
// Options that can be passed to CefWriteJSON.
|
||||
///
|
||||
typedef enum {
|
||||
///
|
||||
// Default behavior.
|
||||
///
|
||||
JSON_WRITER_DEFAULT = 0,
|
||||
|
||||
///
|
||||
// This option instructs the writer that if a Binary value is encountered,
|
||||
// the value (and key if within a dictionary) will be omitted from the
|
||||
// output, and success will be returned. Otherwise, if a binary value is
|
||||
// encountered, failure will be returned.
|
||||
///
|
||||
JSON_WRITER_OMIT_BINARY_VALUES = 1 << 0,
|
||||
|
||||
///
|
||||
// This option instructs the writer to write doubles that have no fractional
|
||||
// part as a normal integer (i.e., without using exponential notation
|
||||
// or appending a '.0') as long as the value is within the range of a
|
||||
// 64-bit int.
|
||||
///
|
||||
JSON_WRITER_OMIT_DOUBLE_TYPE_PRESERVATION = 1 << 1,
|
||||
|
||||
///
|
||||
// Return a slightly nicer formatted json string (pads with whitespace to
|
||||
// help with readability).
|
||||
///
|
||||
JSON_WRITER_PRETTY_PRINT = 1 << 2,
|
||||
} cef_json_writer_options_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "include/cef_parser.h"
|
||||
#include "libcef/common/values_impl.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int GetJSONReaderOptions(cef_json_parser_options_t options) {
|
||||
int op = base::JSON_PARSE_RFC;
|
||||
if (options & JSON_PARSER_ALLOW_TRAILING_COMMAS)
|
||||
op |= base::JSON_ALLOW_TRAILING_COMMAS;
|
||||
return op;
|
||||
}
|
||||
|
||||
int GetJSONWriterOptions(cef_json_writer_options_t options) {
|
||||
int op = 0;
|
||||
if (op & JSON_WRITER_OMIT_BINARY_VALUES)
|
||||
op |= base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES;
|
||||
if (op & JSON_WRITER_OMIT_DOUBLE_TYPE_PRESERVATION)
|
||||
op |= base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION;
|
||||
if (op & JSON_WRITER_PRETTY_PRINT)
|
||||
op |= base::JSONWriter::OPTIONS_PRETTY_PRINT;
|
||||
return op;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
const std::string& json = json_string.ToString();
|
||||
base::Value* parse_result =
|
||||
base::JSONReader::Read(json, GetJSONReaderOptions(options));
|
||||
if (parse_result)
|
||||
return new CefValueImpl(parse_result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string,
|
||||
cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out,
|
||||
CefString& error_msg_out) {
|
||||
const std::string& json = json_string.ToString();
|
||||
|
||||
int error_code;
|
||||
std::string error_msg;
|
||||
base::Value* parse_result = base::JSONReader::ReadAndReturnError(
|
||||
json, GetJSONReaderOptions(options), &error_code, &error_msg);
|
||||
if (parse_result)
|
||||
return new CefValueImpl(parse_result);
|
||||
|
||||
error_code_out = static_cast<cef_json_parser_error_t>(error_code);
|
||||
error_msg_out = error_msg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options) {
|
||||
if (!node.get() || !node->IsValid())
|
||||
return CefString();
|
||||
|
||||
CefValueImpl* impl = static_cast<CefValueImpl*>(node.get());
|
||||
CefValueImpl::ScopedLockedValue scoped_value(impl);
|
||||
|
||||
std::string json_string;
|
||||
if (base::JSONWriter::WriteWithOptions(scoped_value.value(),
|
||||
GetJSONWriterOptions(options),
|
||||
&json_string)) {
|
||||
return json_string;
|
||||
}
|
||||
return CefString();
|
||||
}
|
|
@ -71,6 +71,9 @@ class CefValueController
|
|||
// Returns true if the controller is locked on the current thread.
|
||||
virtual bool locked() =0;
|
||||
|
||||
// Assert that the lock has been acquired.
|
||||
virtual void AssertLockAcquired() =0;
|
||||
|
||||
// Verify that the current thread is correct for accessing the controller.
|
||||
inline bool VerifyThread() {
|
||||
if (!thread_safe() && !on_correct_thread()) {
|
||||
|
@ -149,6 +152,9 @@ class CefValueControllerThreadSafe : public CefValueController {
|
|||
bool locked() override {
|
||||
return (locked_thread_id_ == base::PlatformThread::CurrentId());
|
||||
}
|
||||
void AssertLockAcquired() override {
|
||||
lock_.AssertAcquired();
|
||||
}
|
||||
|
||||
private:
|
||||
base::Lock lock_;
|
||||
|
@ -171,6 +177,9 @@ class CefValueControllerNonThreadSafe : public CefValueController {
|
|||
void lock() override {}
|
||||
void unlock() override {}
|
||||
bool locked() override { return on_correct_thread(); }
|
||||
void AssertLockAcquired() override {
|
||||
DCHECK(locked());
|
||||
}
|
||||
|
||||
private:
|
||||
base::PlatformThreadId thread_id_;
|
||||
|
|
|
@ -363,6 +363,55 @@ void CefValueImpl::SetValueInternal(base::Value* value) {
|
|||
}
|
||||
}
|
||||
|
||||
CefValueController* CefValueImpl::GetValueController() const {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
if (binary_value_) {
|
||||
return static_cast<CefBinaryValueImpl*>(binary_value_.get())->controller();
|
||||
} else if (dictionary_value_) {
|
||||
return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get())->
|
||||
controller();
|
||||
} else if (list_value_) {
|
||||
return static_cast<CefListValueImpl*>(list_value_.get())->controller();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CefValueImpl::AcquireLock() {
|
||||
lock_.Acquire();
|
||||
|
||||
CefValueController* controller = GetValueController();
|
||||
if (controller)
|
||||
controller->lock();
|
||||
}
|
||||
|
||||
void CefValueImpl::ReleaseLock() {
|
||||
CefValueController* controller = GetValueController();
|
||||
if (controller) {
|
||||
controller->AssertLockAcquired();
|
||||
controller->unlock();
|
||||
}
|
||||
|
||||
lock_.Release();
|
||||
}
|
||||
|
||||
base::Value* CefValueImpl::GetValueUnsafe() const {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
if (binary_value_) {
|
||||
return static_cast<CefBinaryValueImpl*>(binary_value_.get())->
|
||||
GetValueUnsafe();
|
||||
} else if (dictionary_value_) {
|
||||
return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get())->
|
||||
GetValueUnsafe();
|
||||
} else if (list_value_) {
|
||||
return static_cast<CefListValueImpl*>(list_value_.get())->GetValueUnsafe();
|
||||
}
|
||||
|
||||
return value_.get();
|
||||
}
|
||||
|
||||
|
||||
// CefBinaryValueImpl implementation.
|
||||
|
||||
|
@ -441,6 +490,13 @@ bool CefBinaryValueImpl::IsEqualValue(const base::BinaryValue* that) {
|
|||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::BinaryValue* CefBinaryValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::BinaryValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefBinaryValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
@ -572,6 +628,13 @@ bool CefDictionaryValueImpl::IsEqualValue(const base::DictionaryValue* that) {
|
|||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::DictionaryValue* CefDictionaryValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::DictionaryValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefDictionaryValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
@ -979,6 +1042,13 @@ bool CefListValueImpl::IsEqualValue(const base::ListValue* that) {
|
|||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::ListValue* CefListValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::ListValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefListValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
|
|
@ -73,9 +73,41 @@ class CefValueImpl : public CefValue {
|
|||
bool SetDictionary(CefRefPtr<CefDictionaryValue> value) override;
|
||||
bool SetList(CefRefPtr<CefListValue> value) override;
|
||||
|
||||
// Ensures exclusive access to the underlying data for the life of this scoped
|
||||
// object.
|
||||
class ScopedLockedValue {
|
||||
public:
|
||||
explicit ScopedLockedValue(CefRefPtr<CefValueImpl> impl)
|
||||
: impl_(impl) {
|
||||
impl_->AcquireLock();
|
||||
}
|
||||
~ScopedLockedValue() {
|
||||
impl_->ReleaseLock();
|
||||
}
|
||||
|
||||
base::Value* value() const {
|
||||
return impl_->GetValueUnsafe();
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefValueImpl> impl_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedLockedValue);
|
||||
};
|
||||
|
||||
private:
|
||||
void SetValueInternal(base::Value* value);
|
||||
|
||||
// Returns the controller for the current value, if any.
|
||||
CefValueController* GetValueController() const;
|
||||
|
||||
// Explicitly lock/unlock this object and the underlying data.
|
||||
void AcquireLock();
|
||||
void ReleaseLock();
|
||||
|
||||
// Returns a reference to the underlying data. Access must be protected by
|
||||
// calling AcquireLock/ReleaseLock.
|
||||
base::Value* GetValueUnsafe() const;
|
||||
|
||||
// Access to all members must be protected by |lock_|.
|
||||
base::Lock lock_;
|
||||
|
||||
|
@ -127,6 +159,10 @@ class CefBinaryValueImpl
|
|||
bool IsSameValue(const base::BinaryValue* that);
|
||||
bool IsEqualValue(const base::BinaryValue* that);
|
||||
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::BinaryValue* GetValueUnsafe();
|
||||
|
||||
// CefBinaryValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
|
@ -181,6 +217,10 @@ class CefDictionaryValueImpl
|
|||
bool IsSameValue(const base::DictionaryValue* that);
|
||||
bool IsEqualValue(const base::DictionaryValue* that);
|
||||
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::DictionaryValue* GetValueUnsafe();
|
||||
|
||||
// CefDictionaryValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
|
@ -264,7 +304,11 @@ class CefListValueImpl
|
|||
bool IsSameValue(const base::ListValue* that);
|
||||
bool IsEqualValue(const base::ListValue* that);
|
||||
|
||||
/// CefListValue methods.
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::ListValue* GetValueUnsafe();
|
||||
|
||||
// CefListValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
bool IsReadOnly() override;
|
||||
|
|
|
@ -594,6 +594,81 @@ CEF_EXPORT int cef_parse_csscolor(const cef_string_t* string, int strict,
|
|||
return _retval;
|
||||
}
|
||||
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_json(const cef_string_t* json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(json_string);
|
||||
if (!json_string)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefValue> _retval = CefParseJSON(
|
||||
CefString(json_string),
|
||||
options);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_jsonand_return_error(
|
||||
const cef_string_t* json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t* error_code_out, cef_string_t* error_msg_out) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(json_string);
|
||||
if (!json_string)
|
||||
return NULL;
|
||||
// Verify param: error_code_out; type: simple_byref
|
||||
DCHECK(error_code_out);
|
||||
if (!error_code_out)
|
||||
return NULL;
|
||||
// Verify param: error_msg_out; type: string_byref
|
||||
DCHECK(error_msg_out);
|
||||
if (!error_msg_out)
|
||||
return NULL;
|
||||
|
||||
// Translate param: error_code_out; type: simple_byref
|
||||
cef_json_parser_error_t error_code_outVal =
|
||||
error_code_out?*error_code_out:JSON_NO_ERROR;
|
||||
// Translate param: error_msg_out; type: string_byref
|
||||
CefString error_msg_outStr(error_msg_out);
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefValue> _retval = CefParseJSONAndReturnError(
|
||||
CefString(json_string),
|
||||
options,
|
||||
error_code_outVal,
|
||||
error_msg_outStr);
|
||||
|
||||
// Restore param: error_code_out; type: simple_byref
|
||||
if (error_code_out)
|
||||
*error_code_out = error_code_outVal;
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT cef_string_userfree_t cef_write_json(struct _cef_value_t* node,
|
||||
cef_json_writer_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: node; type: refptr_same
|
||||
DCHECK(node);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefString _retval = CefWriteJSON(
|
||||
CefValueCppToC::Unwrap(node),
|
||||
options);
|
||||
|
||||
// Return type: string
|
||||
return _retval.DetachToUserFree();
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_get_path(cef_path_key_t key, cef_string_t* path) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
|
|
@ -549,6 +549,65 @@ CEF_GLOBAL bool CefParseCSSColor(const CefString& string, bool strict,
|
|||
return _retval?true:false;
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(!json_string.empty());
|
||||
if (json_string.empty())
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
cef_value_t* _retval = cef_parse_json(
|
||||
json_string.GetStruct(),
|
||||
options);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out, CefString& error_msg_out) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(!json_string.empty());
|
||||
if (json_string.empty())
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
cef_value_t* _retval = cef_parse_jsonand_return_error(
|
||||
json_string.GetStruct(),
|
||||
options,
|
||||
&error_code_out,
|
||||
error_msg_out.GetWritableStruct());
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: node; type: refptr_same
|
||||
DCHECK(node.get());
|
||||
if (!node.get())
|
||||
return CefString();
|
||||
|
||||
// Execute
|
||||
cef_string_userfree_t _retval = cef_write_json(
|
||||
CefValueCToCpp::Unwrap(node),
|
||||
options);
|
||||
|
||||
// Return type: string
|
||||
CefString _retvalStr;
|
||||
_retvalStr.AttachToUserFree(_retval);
|
||||
return _retvalStr;
|
||||
}
|
||||
|
||||
CEF_GLOBAL bool CefGetPath(PathKey key, CefString& path) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
|
|
@ -309,3 +309,134 @@ TEST(ParserTest, ParseCSSColor) {
|
|||
EXPECT_FALSE(CefParseCSSColor(value, false, color));
|
||||
EXPECT_EQ(0U, color);
|
||||
}
|
||||
|
||||
|
||||
TEST(ParserTest, ParseJSONInvalid) {
|
||||
const char data[] = "This is my test data";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_FALSE(value.get());
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONNull) {
|
||||
const char data[] = "{\"key1\":null}";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
|
||||
CefDictionaryValue::KeyList key_list;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list));
|
||||
EXPECT_EQ((size_t)1, key_list.size());
|
||||
EXPECT_EQ("key1", key_list[0].ToString());
|
||||
EXPECT_EQ(VTYPE_NULL, dict->GetType("key1"));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = data;
|
||||
EXPECT_EQ(expected_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, WriteJSONBinary) {
|
||||
const char data[] = "\00\01\02";
|
||||
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
|
||||
CefRefPtr<CefBinaryValue> binary = CefBinaryValue::Create(data, sizeof(data));
|
||||
dict->SetBinary("key1", binary);
|
||||
CefRefPtr<CefValue> node = CefValue::Create();
|
||||
node->SetDictionary(dict);
|
||||
CefString result = CefWriteJSON(node, JSON_WRITER_DEFAULT);
|
||||
CefString expect_result = "";
|
||||
// binary data will be omitted.
|
||||
EXPECT_EQ(expect_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONDictionary) {
|
||||
const char data[] = "{\"key1\":\"value1\",\"key2\":123,\"key3\":[1,2,3]}";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
|
||||
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
|
||||
CefDictionaryValue::KeyList key_list;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list));
|
||||
EXPECT_EQ((size_t)3, key_list.size());
|
||||
EXPECT_EQ("key1", key_list[0].ToString());
|
||||
EXPECT_EQ("key2", key_list[1].ToString());
|
||||
EXPECT_EQ("key3", key_list[2].ToString());
|
||||
EXPECT_EQ(VTYPE_STRING, dict->GetType("key1"));
|
||||
EXPECT_EQ(dict->GetString("key1"), "value1");
|
||||
EXPECT_EQ(VTYPE_INT, dict->GetType("key2"));
|
||||
EXPECT_EQ(123, dict->GetInt("key2"));
|
||||
EXPECT_EQ(VTYPE_LIST, dict->GetType("key3"));
|
||||
CefRefPtr<CefListValue> key3 = dict->GetList("key3");
|
||||
EXPECT_TRUE(NULL != key3);
|
||||
EXPECT_TRUE(key3->IsValid());
|
||||
EXPECT_EQ((size_t)3, key3->GetSize());
|
||||
EXPECT_EQ(1, key3->GetInt(0));
|
||||
EXPECT_EQ(2, key3->GetInt(1));
|
||||
EXPECT_EQ(3, key3->GetInt(2));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = data;
|
||||
EXPECT_EQ(expected_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONList) {
|
||||
const char data[] = "[\"value1\", 123, {\"key3\": [1, 2, 3]}]";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_LIST);
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
CefRefPtr<CefListValue> list = value->GetList();
|
||||
EXPECT_TRUE(NULL != list);
|
||||
EXPECT_TRUE(list->IsValid());
|
||||
EXPECT_EQ((size_t)3, list->GetSize());
|
||||
|
||||
EXPECT_EQ(VTYPE_STRING, list->GetType(0));
|
||||
EXPECT_EQ(list->GetString(0), "value1");
|
||||
EXPECT_EQ(VTYPE_INT, list->GetType(1));
|
||||
EXPECT_EQ(123, list->GetInt(1));
|
||||
EXPECT_EQ(VTYPE_DICTIONARY, list->GetType(2));
|
||||
CefRefPtr<CefDictionaryValue> dict = list->GetDictionary(2);
|
||||
CefDictionaryValue::KeyList key_list2;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list2));
|
||||
EXPECT_EQ((size_t)1, key_list2.size());
|
||||
CefRefPtr<CefListValue> list2 = dict->GetList("key3");
|
||||
EXPECT_EQ((size_t)3, list2->GetSize());
|
||||
EXPECT_EQ(1, list2->GetInt(0));
|
||||
EXPECT_EQ(2, list2->GetInt(1));
|
||||
EXPECT_EQ(3, list2->GetInt(2));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = "[\"value1\",123,{\"key3\":[1,2,3]}]";
|
||||
EXPECT_EQ(expected_result.ToString(), result.ToString());
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONAndReturnErrorInvalid) {
|
||||
const char data[] = "This is my test data";
|
||||
cef_json_parser_error_t error_code;
|
||||
CefString error_msg;
|
||||
CefRefPtr<CefValue> value = CefParseJSONAndReturnError(data,
|
||||
JSON_PARSER_RFC, error_code, error_msg);
|
||||
CefString expect_error_msg = "Line: 1, column: 1, Unexpected token.";
|
||||
EXPECT_FALSE(value.get());
|
||||
EXPECT_EQ(JSON_UNEXPECTED_TOKEN, error_code);
|
||||
EXPECT_EQ(expect_error_msg, error_msg);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONAndReturnErrorTrailingComma) {
|
||||
const char data[] = "{\"key1\":123,}";
|
||||
cef_json_parser_error_t error_code;
|
||||
CefString error_msg;
|
||||
CefRefPtr<CefValue> value = CefParseJSONAndReturnError(data,
|
||||
JSON_PARSER_RFC, error_code, error_msg);
|
||||
CefString expect_error_msg =
|
||||
"Line: 1, column: 13, Trailing comma not allowed.";
|
||||
EXPECT_FALSE(value.get());
|
||||
EXPECT_EQ(JSON_TRAILING_COMMA, error_code);
|
||||
EXPECT_EQ(expect_error_msg, error_msg);
|
||||
}
|
||||
|
|
|
@ -396,6 +396,7 @@ _simpletypes = {
|
|||
'char': ['char', '0'],
|
||||
'char* const': ['char* const', 'NULL'],
|
||||
'cef_color_t': ['cef_color_t', '0'],
|
||||
'cef_json_parser_error_t': ['cef_json_parser_error_t', 'JSON_NO_ERROR'],
|
||||
'CefCursorHandle' : ['cef_cursor_handle_t', 'kNullCursorHandle'],
|
||||
'CefEventHandle' : ['cef_event_handle_t', 'kNullEventHandle'],
|
||||
'CefWindowHandle' : ['cef_window_handle_t', 'kNullWindowHandle'],
|
||||
|
|
Loading…
Reference in New Issue