Expose XML parsing support (issue #28).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@119 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
4c0ccb6768
commit
18bc093786
11
cef.gyp
11
cef.gyp
|
@ -98,6 +98,7 @@
|
|||
'tests/unittests/test_handler.h',
|
||||
'tests/unittests/test_suite.h',
|
||||
'tests/unittests/v8_unittest.cc',
|
||||
'tests/unittests/xml_reader_unittest.cc',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
|
@ -157,6 +158,7 @@
|
|||
'../third_party/icu/icu.gyp:icuuc',
|
||||
'../third_party/libjpeg/libjpeg.gyp:libjpeg',
|
||||
'../third_party/libpng/libpng.gyp:libpng',
|
||||
'../third_party/libxml/libxml.gyp:libxml',
|
||||
'../third_party/libxslt/libxslt.gyp:libxslt',
|
||||
'../third_party/mesa/mesa.gyp:osmesa',
|
||||
'../third_party/modp_b64/modp_b64.gyp:modp_b64',
|
||||
|
@ -216,6 +218,8 @@
|
|||
'libcef_dll/cpptoc/stream_writer_cpptoc.h',
|
||||
'libcef_dll/cpptoc/v8value_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/v8value_cpptoc.h',
|
||||
'libcef_dll/cpptoc/xml_reader_cpptoc.cc',
|
||||
'libcef_dll/cpptoc/xml_reader_cpptoc.h',
|
||||
'libcef_dll/ctocpp/ctocpp.h',
|
||||
'libcef_dll/ctocpp/download_handler_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/download_handler_ctocpp.h',
|
||||
|
@ -274,6 +278,7 @@
|
|||
'..',
|
||||
],
|
||||
'sources': [
|
||||
'include/cef_wrapper.h',
|
||||
'libcef_dll/cef_logging.h',
|
||||
'libcef_dll/cpptoc/cpptoc.h',
|
||||
'libcef_dll/cpptoc/download_handler_cpptoc.cc',
|
||||
|
@ -309,8 +314,11 @@
|
|||
'libcef_dll/cpptoc/task_cpptoc.h',
|
||||
'libcef_dll/ctocpp/v8value_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/v8value_ctocpp.h',
|
||||
'libcef_dll/ctocpp/xml_reader_ctocpp.cc',
|
||||
'libcef_dll/ctocpp/xml_reader_ctocpp.h',
|
||||
'libcef_dll/transfer_util.cpp',
|
||||
'libcef_dll/transfer_util.h',
|
||||
'libcef_dll/wrapper/cef_xml_object.cc',
|
||||
'libcef_dll/wrapper/libcef_dll_wrapper.cc',
|
||||
],
|
||||
},
|
||||
|
@ -344,6 +352,7 @@
|
|||
'../third_party/icu/icu.gyp:icuuc',
|
||||
'../third_party/libjpeg/libjpeg.gyp:libjpeg',
|
||||
'../third_party/libpng/libpng.gyp:libpng',
|
||||
'../third_party/libxml/libxml.gyp:libxml',
|
||||
'../third_party/libxslt/libxslt.gyp:libxslt',
|
||||
'../third_party/mesa/mesa.gyp:osmesa',
|
||||
'../third_party/modp_b64/modp_b64.gyp:modp_b64',
|
||||
|
@ -423,6 +432,8 @@
|
|||
'libcef/v8_impl.h',
|
||||
'libcef/webview_host.h',
|
||||
'libcef/webwidget_host.h',
|
||||
'libcef/xml_reader_impl.cc',
|
||||
'libcef/xml_reader_impl.h',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
|
|
182
include/cef.h
182
include/cef.h
|
@ -265,6 +265,24 @@ public:
|
|||
void Lock() { m_critsec.Lock(); }
|
||||
void Unlock() { m_critsec.Unlock(); }
|
||||
|
||||
// A helper class that acquires the lock for the given CefThreadSafeBase while
|
||||
// the CefAutoLock is in scope.
|
||||
class AutoLock
|
||||
{
|
||||
public:
|
||||
AutoLock(CefThreadSafeBase* base) : base_(base)
|
||||
{
|
||||
base_->Lock();
|
||||
}
|
||||
~AutoLock()
|
||||
{
|
||||
base_->Unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
CefThreadSafeBase* base_;
|
||||
};
|
||||
|
||||
protected:
|
||||
long m_dwRef;
|
||||
CefCriticalSection m_critsec;
|
||||
|
@ -1005,7 +1023,7 @@ public:
|
|||
class CefStreamWriter : public CefBase
|
||||
{
|
||||
public:
|
||||
// Create a new CefStreamWriter object.
|
||||
// Create a new CefStreamWriter object.
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefStreamWriter> CreateForFile(const std::wstring& fileName);
|
||||
/*--cef()--*/
|
||||
|
@ -1232,4 +1250,166 @@ public:
|
|||
virtual void Complete() =0;
|
||||
};
|
||||
|
||||
|
||||
// Class that supports the reading of XML data via the libxml streaming API.
|
||||
/*--cef(source=library)--*/
|
||||
class CefXmlReader : public CefBase
|
||||
{
|
||||
public:
|
||||
typedef cef_xml_encoding_type_t EncodingType;
|
||||
typedef cef_xml_node_type_t NodeType;
|
||||
|
||||
// Create a new CefXmlReader object. The returned object's methods can only
|
||||
// be called from the thread that created the object.
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefXmlReader> Create(CefRefPtr<CefStreamReader> stream,
|
||||
EncodingType encodingType,
|
||||
const std::wstring& URI);
|
||||
|
||||
// Moves the cursor to the next element node in the document. This method
|
||||
// must be called at least once to set the current cursor position. Returns
|
||||
// true if the cursor position was set successfully.
|
||||
/*--cef()--*/
|
||||
virtual bool MoveToNextElement() =0;
|
||||
|
||||
// Close the document. This must be called directly to ensure that cleanup
|
||||
// occurs on the correct thread.
|
||||
/*--cef()--*/
|
||||
virtual bool Close() =0;
|
||||
|
||||
// Returns true if an error has been reported by the XML parser.
|
||||
/*--cef()--*/
|
||||
virtual bool HasError() =0;
|
||||
|
||||
// Returns the error string.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetError() =0;
|
||||
|
||||
|
||||
// The below methods retrieve data for the node at the current cursor
|
||||
// position.
|
||||
|
||||
// Returns the node type.
|
||||
/*--cef()--*/
|
||||
virtual NodeType GetType() =0;
|
||||
|
||||
// Returns the node depth. Depth starts at 0 for the root node.
|
||||
/*--cef()--*/
|
||||
virtual int GetDepth() =0;
|
||||
|
||||
// Returns the local name. See
|
||||
// http://www.w3.org/TR/REC-xml-names/#NT-LocalPart for additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetLocalName() =0;
|
||||
|
||||
// Returns the namespace prefix. See http://www.w3.org/TR/REC-xml-names/ for
|
||||
// additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetPrefix() =0;
|
||||
|
||||
// Returns the qualified name, equal to (Prefix:)LocalName. See
|
||||
// http://www.w3.org/TR/REC-xml-names/#ns-qualnames for additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetQualifiedName() =0;
|
||||
|
||||
// Returns the URI defining the namespace associated with the node. See
|
||||
// http://www.w3.org/TR/REC-xml-names/ for additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetNamespaceURI() =0;
|
||||
|
||||
// Returns the base URI of the node. See http://www.w3.org/TR/xmlbase/ for
|
||||
// additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetBaseURI() =0;
|
||||
|
||||
// Returns the xml:lang scope within which the node resides. See
|
||||
// http://www.w3.org/TR/REC-xml/#sec-lang-tag for additional details.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetXmlLang() =0;
|
||||
|
||||
// Returns true if the node represents an empty element. <a/> is considered
|
||||
// empty but <a></a> is not.
|
||||
/*--cef()--*/
|
||||
virtual bool IsEmptyElement() =0;
|
||||
|
||||
// Returns true if the node has a text value.
|
||||
/*--cef()--*/
|
||||
virtual bool HasValue() =0;
|
||||
|
||||
// Returns the text value.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetValue() =0;
|
||||
|
||||
// Returns true if the node has attributes.
|
||||
/*--cef()--*/
|
||||
virtual bool HasAttributes() =0;
|
||||
|
||||
// Returns the number of attributes.
|
||||
/*--cef()--*/
|
||||
virtual size_t GetAttributeCount() =0;
|
||||
|
||||
// Returns the value of the attribute at the specified 0-based index.
|
||||
/*--cef(capi_name=get_attribute_byindex)--*/
|
||||
virtual std::wstring GetAttribute(int index) =0;
|
||||
|
||||
// Returns the value of the attribute with the specified qualified name.
|
||||
/*--cef(capi_name=get_attribute_byqname)--*/
|
||||
virtual std::wstring GetAttribute(const std::wstring& qualifiedName) =0;
|
||||
|
||||
// Returns the value of the attribute with the specified local name and
|
||||
// namespace URI.
|
||||
/*--cef(capi_name=get_attribute_bylname)--*/
|
||||
virtual std::wstring GetAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI) =0;
|
||||
|
||||
// Returns an XML representation of the current node's children.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetInnerXml() =0;
|
||||
|
||||
// Returns an XML representation of the current node including its children.
|
||||
/*--cef()--*/
|
||||
virtual std::wstring GetOuterXml() =0;
|
||||
|
||||
// Returns the line number for the current node.
|
||||
/*--cef()--*/
|
||||
virtual int GetLineNumber() =0;
|
||||
|
||||
|
||||
// Attribute nodes are not traversed by default. The below methods can be
|
||||
// used to move the cursor to an attribute node. MoveToCarryingElement() can
|
||||
// be called afterwards to return the cursor to the carrying element. The
|
||||
// depth of an attribute node will be 1 + the depth of the carrying element.
|
||||
|
||||
// Moves the cursor to the attribute at the specified 0-based index. Returns
|
||||
// true if the cursor position was set successfully.
|
||||
/*--cef(capi_name=move_to_attribute_byindex)--*/
|
||||
virtual bool MoveToAttribute(int index) =0;
|
||||
|
||||
// Moves the cursor to the attribute with the specified qualified name.
|
||||
// Returns true if the cursor position was set successfully.
|
||||
/*--cef(capi_name=move_to_attribute_byqname)--*/
|
||||
virtual bool MoveToAttribute(const std::wstring& qualifiedName) =0;
|
||||
|
||||
// Moves the cursor to the attribute with the specified local name and
|
||||
// namespace URI. Returns true if the cursor position was set successfully.
|
||||
/*--cef(capi_name=move_to_attribute_bylname)--*/
|
||||
virtual bool MoveToAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI) =0;
|
||||
|
||||
// Moves the cursor to the first attribute in the current element. Returns
|
||||
// true if the cursor position was set successfully.
|
||||
/*--cef()--*/
|
||||
virtual bool MoveToFirstAttribute() =0;
|
||||
|
||||
// Moves the cursor to the next attribute in the current element. Returns
|
||||
// true if the cursor position was set successfully.
|
||||
/*--cef()--*/
|
||||
virtual bool MoveToNextAttribute() =0;
|
||||
|
||||
// Moves the cursor back to the carrying element. Returns true if the cursor
|
||||
// position was set successfully.
|
||||
/*--cef()--*/
|
||||
virtual bool MoveToCarryingElement() =0;
|
||||
};
|
||||
|
||||
#endif // _CEF_H
|
||||
|
|
|
@ -1004,6 +1004,159 @@ typedef struct _cef_download_handler_t
|
|||
} cef_download_handler_t;
|
||||
|
||||
|
||||
// Structure that supports the reading of XML data via the libxml streaming API.
|
||||
typedef struct _cef_xml_reader_t
|
||||
{
|
||||
// Base structure.
|
||||
cef_base_t base;
|
||||
|
||||
// Moves the cursor to the next element node in the document. This function
|
||||
// must be called at least once to set the current cursor position. Returns
|
||||
// true (1) if the cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_next_element)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Close the document. This must be called directly to ensure that cleanup
|
||||
// occurs on the correct thread.
|
||||
int (CEF_CALLBACK *close)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns true (1) if an error has been reported by the XML parser.
|
||||
int (CEF_CALLBACK *has_error)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the error string.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_error)(struct _cef_xml_reader_t* self);
|
||||
|
||||
|
||||
// The below functions retrieve data for the node at the current cursor
|
||||
// position.
|
||||
|
||||
// Returns the node type.
|
||||
enum cef_xml_node_type_t (CEF_CALLBACK *get_type)(
|
||||
struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the node depth. Depth starts at 0 for the root node.
|
||||
int (CEF_CALLBACK *get_depth)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the local name. See http://www.w3.org/TR/REC-xml-names/#NT-
|
||||
// LocalPart for additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_local_name)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the namespace prefix. See http://www.w3.org/TR/REC-xml-names/ for
|
||||
// additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_prefix)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the qualified name, equal to (Prefix:)LocalName. See
|
||||
// http://www.w3.org/TR/REC-xml-names/#ns-qualnames for additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_qualified_name)(
|
||||
struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the URI defining the namespace associated with the node. See
|
||||
// http://www.w3.org/TR/REC-xml-names/ for additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_namespace_uri)(
|
||||
struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the base URI of the node. See http://www.w3.org/TR/xmlbase/ for
|
||||
// additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_base_uri)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the xml:lang scope within which the node resides. See
|
||||
// http://www.w3.org/TR/REC-xml/#sec-lang-tag for additional details.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_xml_lang)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns true (1) if the node represents an NULL element. <a/> is considered
|
||||
// NULL but <a></a> is not.
|
||||
int (CEF_CALLBACK *is_empty_element)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns true (1) if the node has a text value.
|
||||
int (CEF_CALLBACK *has_value)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the text value.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_value)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns true (1) if the node has attributes.
|
||||
int (CEF_CALLBACK *has_attributes)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the number of attributes.
|
||||
size_t (CEF_CALLBACK *get_attribute_count)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the value of the attribute at the specified 0-based index.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_attribute_byindex)(
|
||||
struct _cef_xml_reader_t* self, int index);
|
||||
|
||||
// Returns the value of the attribute with the specified qualified name.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_attribute_byqname)(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* qualifiedName);
|
||||
|
||||
// Returns the value of the attribute with the specified local name and
|
||||
// namespace URI.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_attribute_bylname)(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* localName,
|
||||
const wchar_t* namespaceURI);
|
||||
|
||||
// Returns an XML representation of the current node's children.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_inner_xml)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns an XML representation of the current node including its children.
|
||||
// The resulting string must be freed by calling cef_string_free().
|
||||
cef_string_t (CEF_CALLBACK *get_outer_xml)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Returns the line number for the current node.
|
||||
int (CEF_CALLBACK *get_line_number)(struct _cef_xml_reader_t* self);
|
||||
|
||||
|
||||
// Attribute nodes are not traversed by default. The below functions can be
|
||||
// used to move the cursor to an attribute node. move_to_carrying_element()
|
||||
// can be called afterwards to return the cursor to the carrying element. The
|
||||
// depth of an attribute node will be 1 + the depth of the carrying element.
|
||||
|
||||
// Moves the cursor to the attribute at the specified 0-based index. Returns
|
||||
// true (1) if the cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_attribute_byindex)(struct _cef_xml_reader_t* self,
|
||||
int index);
|
||||
|
||||
// Moves the cursor to the attribute with the specified qualified name.
|
||||
// Returns true (1) if the cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_attribute_byqname)(struct _cef_xml_reader_t* self,
|
||||
const wchar_t* qualifiedName);
|
||||
|
||||
// Moves the cursor to the attribute with the specified local name and
|
||||
// namespace URI. Returns true (1) if the cursor position was set
|
||||
// successfully.
|
||||
int (CEF_CALLBACK *move_to_attribute_bylname)(struct _cef_xml_reader_t* self,
|
||||
const wchar_t* localName, const wchar_t* namespaceURI);
|
||||
|
||||
// Moves the cursor to the first attribute in the current element. Returns
|
||||
// true (1) if the cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_first_attribute)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Moves the cursor to the next attribute in the current element. Returns true
|
||||
// (1) if the cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_next_attribute)(struct _cef_xml_reader_t* self);
|
||||
|
||||
// Moves the cursor back to the carrying element. Returns true (1) if the
|
||||
// cursor position was set successfully.
|
||||
int (CEF_CALLBACK *move_to_carrying_element)(struct _cef_xml_reader_t* self);
|
||||
|
||||
} cef_xml_reader_t;
|
||||
|
||||
|
||||
// Create a new cef_xml_reader_t object. The returned object's functions can
|
||||
// only be called from the thread that created the object.
|
||||
CEF_EXPORT cef_xml_reader_t* cef_xml_reader_create(cef_stream_reader_t* stream,
|
||||
enum cef_xml_encoding_type_t encodingType, const wchar_t* URI);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -301,6 +301,35 @@ typedef struct _cef_print_options_t
|
|||
struct cef_print_margins paper_margins;
|
||||
} cef_print_options_t;
|
||||
|
||||
// Supported XML encoding types. The parser supports ASCII, ISO-8859-1, and
|
||||
// UTF16 (LE and BE) by default. All other types must be translated to UTF8
|
||||
// before being passed to the parser. If a BOM is detected and the correct
|
||||
// decoder is available then that decoder will be used automatically.
|
||||
enum cef_xml_encoding_type_t
|
||||
{
|
||||
XML_ENCODING_NONE = 0,
|
||||
XML_ENCODING_UTF8,
|
||||
XML_ENCODING_UTF16LE,
|
||||
XML_ENCODING_UTF16BE,
|
||||
XML_ENCODING_ASCII,
|
||||
};
|
||||
|
||||
// XML node types.
|
||||
enum cef_xml_node_type_t
|
||||
{
|
||||
XML_NODE_UNSUPPORTED = 0,
|
||||
XML_NODE_PROCESSING_INSTRUCTION,
|
||||
XML_NODE_DOCUMENT_TYPE,
|
||||
XML_NODE_ELEMENT_START,
|
||||
XML_NODE_ELEMENT_END,
|
||||
XML_NODE_ATTRIBUTE,
|
||||
XML_NODE_TEXT,
|
||||
XML_NODE_CDATA,
|
||||
XML_NODE_ENTITY_REFERENCE,
|
||||
XML_NODE_WHITESPACE,
|
||||
XML_NODE_COMMENT,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) 2010 Marshall A. Greenblatt. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// The contents of this file are only available to applications that link
|
||||
// against the libcef_dll_wrapper target.
|
||||
//
|
||||
|
||||
#ifndef _CEF_WRAPPER_H
|
||||
#define _CEF_WRAPPER_H
|
||||
|
||||
#include "cef.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
// Thread safe class for representing XML data as a structured object. This
|
||||
// class should not be used with large XML documents because all data will be
|
||||
// resident in memory at the same time. This implementation supports a
|
||||
// restricted set of XML features:
|
||||
// (1) Processing instructions, whitespace and comments are ignored.
|
||||
// (2) Elements and attributes must always be referenced using the fully
|
||||
// qualified name (ie, namespace:localname).
|
||||
// (3) Empty elements (<a/>) and elements with zero-length values (<a></a>)
|
||||
// are considered the same.
|
||||
// (4) Element nodes are considered part of a value if:
|
||||
// (a) The element node follows a non-element node at the same depth
|
||||
// (see 5), or
|
||||
// (b) The element node does not have a namespace and the parent node does.
|
||||
// (5) Mixed node types at the same depth are combined into a single element
|
||||
// value as follows:
|
||||
// (a) All node values are concatenated to form a single string value.
|
||||
// (b) Entity reference nodes are resolved to the corresponding entity
|
||||
// value.
|
||||
// (c) Element nodes are represented by their outer XML string.
|
||||
class CefXmlObject : public CefThreadSafeBase<CefBase>
|
||||
{
|
||||
public:
|
||||
typedef std::vector<CefRefPtr<CefXmlObject> > ObjectVector;
|
||||
typedef std::map<std::wstring, std::wstring > AttributeMap;
|
||||
|
||||
// Create a new object with the specified name. An object name must always be
|
||||
// at least one character long.
|
||||
CefXmlObject(const std::wstring& name);
|
||||
virtual ~CefXmlObject();
|
||||
|
||||
// Load the contents of the specified XML stream into this object. The
|
||||
// existing children and attributes, if any, will first be cleared.
|
||||
bool Load(CefRefPtr<CefStreamReader> stream,
|
||||
CefXmlReader::EncodingType encodingType,
|
||||
const std::wstring& URI, std::wstring* loadError);
|
||||
|
||||
// Set the name, children and attributes of this object to a duplicate of the
|
||||
// specified object's contents. The existing children and attributes, if any,
|
||||
// will first be cleared.
|
||||
void Set(CefRefPtr<CefXmlObject> object);
|
||||
|
||||
// Append a duplicate of the children and attributes of the specified object
|
||||
// to this object. If |overwriteAttributes| is true then any attributes in
|
||||
// this object that also exist in the specified object will be overwritten
|
||||
// with the new values. The name of this object is not changed.
|
||||
void Append(CefRefPtr<CefXmlObject> object, bool overwriteAttributes);
|
||||
|
||||
// Return a new object with the same name, children and attributes as this
|
||||
// object. The parent of the new object will be NULL.
|
||||
CefRefPtr<CefXmlObject> Duplicate();
|
||||
|
||||
// Clears this object's children and attributes. The name and parenting of
|
||||
// this object are not changed.
|
||||
void Clear();
|
||||
|
||||
// Access the object's name. An object name must always be at least one
|
||||
// character long.
|
||||
std::wstring GetName();
|
||||
bool SetName(const std::wstring& name);
|
||||
|
||||
// Access the object's parent. The parent can be NULL if this object has not
|
||||
// been added as the child on another object.
|
||||
bool HasParent();
|
||||
CefRefPtr<CefXmlObject> GetParent();
|
||||
|
||||
// Access the object's value. An object cannot have a value if it also has
|
||||
// children. Attempting to set the value while children exist will fail.
|
||||
bool HasValue();
|
||||
std::wstring GetValue();
|
||||
bool SetValue(const std::wstring& value);
|
||||
|
||||
// Access the object's attributes. Attributes must have unique names.
|
||||
bool HasAttributes();
|
||||
size_t GetAttributeCount();
|
||||
bool HasAttribute(const std::wstring& name);
|
||||
std::wstring GetAttributeValue(const std::wstring& name);
|
||||
bool SetAttributeValue(const std::wstring& name, const std::wstring& value);
|
||||
size_t GetAttributes(AttributeMap& attributes);
|
||||
void ClearAttributes();
|
||||
|
||||
// Access the object's children. Each object can only have one parent so
|
||||
// attempting to add an object that already has a parent will fail. Removing a
|
||||
// child will set the child's parent to NULL. Adding a child will set the
|
||||
// child's parent to this object. This object's value, if any, will be cleared
|
||||
// if a child is added.
|
||||
bool HasChildren();
|
||||
size_t GetChildCount();
|
||||
bool HasChild(CefRefPtr<CefXmlObject> child);
|
||||
bool AddChild(CefRefPtr<CefXmlObject> child);
|
||||
bool RemoveChild(CefRefPtr<CefXmlObject> child);
|
||||
size_t GetChildren(ObjectVector& children);
|
||||
void ClearChildren();
|
||||
|
||||
// Find the first child with the specified name.
|
||||
CefRefPtr<CefXmlObject> FindChild(const std::wstring& name);
|
||||
|
||||
// Find all children with the specified name.
|
||||
size_t FindChildren(const std::wstring& name, ObjectVector& children);
|
||||
|
||||
private:
|
||||
void SetParent(CefXmlObject* parent);
|
||||
|
||||
std::wstring name_;
|
||||
CefXmlObject* parent_;
|
||||
std::wstring value_;
|
||||
AttributeMap attributes_;
|
||||
ObjectVector children_;
|
||||
};
|
||||
|
||||
#endif // _CEF_WRAPPER_H
|
|
@ -0,0 +1,506 @@
|
|||
// Copyright (c) 20010 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 "xml_reader_impl.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/utf_string_conversions.h"
|
||||
|
||||
// Static functions
|
||||
|
||||
//static
|
||||
CefRefPtr<CefXmlReader> CefXmlReader::Create(CefRefPtr<CefStreamReader> stream,
|
||||
EncodingType encodingType,
|
||||
const std::wstring& URI)
|
||||
{
|
||||
CefRefPtr<CefXmlReaderImpl> impl(new CefXmlReaderImpl());
|
||||
if (!impl->Initialize(stream, encodingType, URI))
|
||||
return NULL;
|
||||
return impl.get();
|
||||
}
|
||||
|
||||
|
||||
// CefXmlReaderImpl
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* xmlInputReadCallback:
|
||||
* @context: an Input context
|
||||
* @buffer: the buffer to store data read
|
||||
* @len: the length of the buffer in bytes
|
||||
*
|
||||
* Callback used in the I/O Input API to read the resource
|
||||
*
|
||||
* Returns the number of bytes read or -1 in case of error
|
||||
*/
|
||||
int XMLCALL xml_read_callback(void * context, char * buffer, int len)
|
||||
{
|
||||
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(context));
|
||||
return reader->Read(buffer, 1, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlInputCloseCallback:
|
||||
* @context: an Input context
|
||||
*
|
||||
* Callback used in the I/O Input API to close the resource
|
||||
*
|
||||
* Returns 0 or -1 in case of error
|
||||
*/
|
||||
int XMLCALL xml_close_callback(void * context)
|
||||
{
|
||||
CefRefPtr<CefStreamReader> reader(static_cast<CefStreamReader*>(context));
|
||||
|
||||
// Release the reference added by CefXmlReaderImpl::Initialize().
|
||||
reader->Release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlTextReaderErrorFunc:
|
||||
* @arg: the user argument
|
||||
* @msg: the message
|
||||
* @severity: the severity of the error
|
||||
* @locator: a locator indicating where the error occured
|
||||
*
|
||||
* Signature of an error callback from a reader parser
|
||||
*/
|
||||
void XMLCALL xml_error_callback(void *arg, const char *msg,
|
||||
xmlParserSeverities severity, xmlTextReaderLocatorPtr locator)
|
||||
{
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
std::wstring error_str;
|
||||
UTF8ToWide(msg, strlen(msg), &error_str);
|
||||
|
||||
if (!error_str.empty() && error_str[error_str.length()-1] == '\n')
|
||||
error_str.resize(error_str.length()-1);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << error_str << L", line " << xmlTextReaderLocatorLineNumber(locator);
|
||||
|
||||
LOG(INFO) << ss.str();
|
||||
|
||||
CefRefPtr<CefXmlReaderImpl> impl(static_cast<CefXmlReaderImpl*>(arg));
|
||||
impl->AppendError(ss.str());
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlStructuredErrorFunc:
|
||||
* @userData: user provided data for the error callback
|
||||
* @error: the error being raised.
|
||||
*
|
||||
* Signature of the function to use when there is an error and
|
||||
* the module handles the new error reporting mechanism.
|
||||
*/
|
||||
void XMLCALL xml_structured_error_callback(void *userData, xmlErrorPtr error)
|
||||
{
|
||||
if (!error->message)
|
||||
return;
|
||||
|
||||
std::wstring error_str;
|
||||
UTF8ToWide(error->message, strlen(error->message), &error_str);
|
||||
|
||||
if (!error_str.empty() && error_str[error_str.length()-1] == '\n')
|
||||
error_str.resize(error_str.length()-1);
|
||||
|
||||
std::wstringstream ss;
|
||||
ss << error_str << L", line " << error->line;
|
||||
|
||||
LOG(INFO) << ss.str();
|
||||
|
||||
CefRefPtr<CefXmlReaderImpl> impl(static_cast<CefXmlReaderImpl*>(userData));
|
||||
impl->AppendError(ss.str());
|
||||
}
|
||||
|
||||
std::wstring xmlCharToWString(const xmlChar* xmlStr, bool free)
|
||||
{
|
||||
if (!xmlStr)
|
||||
return std::wstring();
|
||||
|
||||
const char* str = reinterpret_cast<const char*>(xmlStr);
|
||||
std::wstring wstr;
|
||||
UTF8ToWide(str, strlen(str), &wstr);
|
||||
|
||||
if (free)
|
||||
xmlFree(const_cast<xmlChar*>(xmlStr));
|
||||
|
||||
return wstr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefXmlReaderImpl::CefXmlReaderImpl()
|
||||
: supported_thread_id_(PlatformThread::CurrentId()), reader_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CefXmlReaderImpl::~CefXmlReaderImpl()
|
||||
{
|
||||
if (reader_ != NULL) {
|
||||
if (!VerifyContext()) {
|
||||
// Close() is supposed to be called directly. We'll try to free the reader
|
||||
// now on the wrong thread but there's no guarantee this call won't crash.
|
||||
xmlFreeTextReader(reader_);
|
||||
} else {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::Initialize(CefRefPtr<CefStreamReader> stream,
|
||||
EncodingType encodingType,
|
||||
const std::wstring& URI)
|
||||
{
|
||||
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
|
||||
switch (encodingType) {
|
||||
case XML_ENCODING_UTF8:
|
||||
enc = XML_CHAR_ENCODING_UTF8;
|
||||
break;
|
||||
case XML_ENCODING_UTF16LE:
|
||||
enc = XML_CHAR_ENCODING_UTF16LE;
|
||||
break;
|
||||
case XML_ENCODING_UTF16BE:
|
||||
enc = XML_CHAR_ENCODING_UTF16BE;
|
||||
break;
|
||||
case XML_ENCODING_ASCII:
|
||||
enc = XML_CHAR_ENCODING_ASCII;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the input buffer.
|
||||
xmlParserInputBufferPtr input_buffer = xmlAllocParserInputBuffer(enc);
|
||||
if (!input_buffer)
|
||||
return false;
|
||||
|
||||
// Add a reference that will be released by xml_close_callback().
|
||||
stream->AddRef();
|
||||
|
||||
input_buffer->context = stream.get();
|
||||
input_buffer->readcallback = xml_read_callback;
|
||||
input_buffer->closecallback = xml_close_callback;
|
||||
|
||||
// Create the text reader.
|
||||
reader_ = xmlNewTextReader(input_buffer, WideToUTF8(URI).c_str());
|
||||
if (!reader_) {
|
||||
// Free the input buffer.
|
||||
xmlFreeParserInputBuffer(input_buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register the error callbacks.
|
||||
xmlTextReaderSetErrorHandler(reader_, xml_error_callback, this);
|
||||
xmlTextReaderSetStructuredErrorHandler(reader_,
|
||||
xml_structured_error_callback, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToNextElement()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderRead(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::Close()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
// The input buffer will be freed automatically.
|
||||
xmlFreeTextReader(reader_);
|
||||
reader_ = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::HasError()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return !error_buf_.str().empty();
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetError()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return error_buf_.str();
|
||||
}
|
||||
|
||||
CefXmlReader::NodeType CefXmlReaderImpl::GetType()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return XML_NODE_UNSUPPORTED;
|
||||
|
||||
switch (xmlTextReaderNodeType(reader_)) {
|
||||
case XML_READER_TYPE_ELEMENT:
|
||||
return XML_NODE_ELEMENT_START;
|
||||
case XML_READER_TYPE_END_ELEMENT:
|
||||
return XML_NODE_ELEMENT_END;
|
||||
case XML_READER_TYPE_ATTRIBUTE:
|
||||
return XML_NODE_ATTRIBUTE;
|
||||
case XML_READER_TYPE_TEXT:
|
||||
return XML_NODE_TEXT;
|
||||
case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
|
||||
case XML_READER_TYPE_WHITESPACE:
|
||||
return XML_NODE_WHITESPACE;
|
||||
case XML_READER_TYPE_CDATA:
|
||||
return XML_NODE_CDATA;
|
||||
case XML_READER_TYPE_ENTITY_REFERENCE:
|
||||
return XML_NODE_ENTITY_REFERENCE;
|
||||
case XML_READER_TYPE_PROCESSING_INSTRUCTION:
|
||||
return XML_NODE_PROCESSING_INSTRUCTION;
|
||||
case XML_READER_TYPE_COMMENT:
|
||||
return XML_NODE_COMMENT;
|
||||
case XML_READER_TYPE_DOCUMENT_TYPE:
|
||||
return XML_NODE_DOCUMENT_TYPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return XML_NODE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int CefXmlReaderImpl::GetDepth()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return -1;
|
||||
|
||||
return xmlTextReaderDepth(reader_);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetLocalName()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstLocalName(reader_), false);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetPrefix()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstPrefix(reader_), false);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetQualifiedName()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstName(reader_), false);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetNamespaceURI()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstNamespaceUri(reader_), false);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetBaseURI()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstBaseUri(reader_), false);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetXmlLang()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderConstXmlLang(reader_), false);
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::IsEmptyElement()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderIsEmptyElement(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::HasValue()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
if (xmlTextReaderNodeType(reader_) == XML_READER_TYPE_ENTITY_REFERENCE) {
|
||||
// Provide special handling to return entity reference values.
|
||||
return true;
|
||||
} else {
|
||||
return xmlTextReaderHasValue(reader_) == 1 ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetValue()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
if (xmlTextReaderNodeType(reader_) == XML_READER_TYPE_ENTITY_REFERENCE) {
|
||||
// Provide special handling to return entity reference values.
|
||||
xmlNodePtr node = xmlTextReaderCurrentNode(reader_);
|
||||
if (node->content != NULL)
|
||||
return xmlCharToWString(node->content, false);
|
||||
return NULL;
|
||||
} else {
|
||||
return xmlCharToWString(xmlTextReaderConstValue(reader_), false);
|
||||
}
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::HasAttributes()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderHasAttributes(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
size_t CefXmlReaderImpl::GetAttributeCount()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return 0;
|
||||
|
||||
return xmlTextReaderAttributeCount(reader_);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetAttribute(int index)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderGetAttributeNo(reader_, index), true);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetAttribute(const std::wstring& qualifiedName)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
std::string qualifiedNameStr = WideToUTF8(qualifiedName);
|
||||
return xmlCharToWString(xmlTextReaderGetAttribute(reader_,
|
||||
BAD_CAST qualifiedNameStr.c_str()), true);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
std::string localNameStr = WideToUTF8(localName);
|
||||
std::string namespaceURIStr = WideToUTF8(namespaceURI);
|
||||
return xmlCharToWString(xmlTextReaderGetAttributeNs(reader_,
|
||||
BAD_CAST localNameStr.c_str(), BAD_CAST namespaceURIStr.c_str()), true);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetInnerXml()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderReadInnerXml(reader_), true);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderImpl::GetOuterXml()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return std::wstring();
|
||||
|
||||
return xmlCharToWString(xmlTextReaderReadOuterXml(reader_), true);
|
||||
}
|
||||
|
||||
int CefXmlReaderImpl::GetLineNumber()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return -1;
|
||||
|
||||
return xmlTextReaderGetParserLineNumber(reader_);
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToAttribute(int index)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderMoveToAttributeNo(reader_, index) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToAttribute(const std::wstring& qualifiedName)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
std::string qualifiedNameStr = WideToUTF8(qualifiedName);
|
||||
return xmlTextReaderMoveToAttribute(reader_,
|
||||
BAD_CAST qualifiedNameStr.c_str()) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI)
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
std::string localNameStr = WideToUTF8(localName);
|
||||
std::string namespaceURIStr = WideToUTF8(namespaceURI);
|
||||
return xmlTextReaderMoveToAttributeNs(reader_,
|
||||
BAD_CAST localNameStr.c_str(), BAD_CAST namespaceURIStr.c_str()) == 1 ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToFirstAttribute()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderMoveToFirstAttribute(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToNextAttribute()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderMoveToNextAttribute(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::MoveToCarryingElement()
|
||||
{
|
||||
if (!VerifyContext())
|
||||
return false;
|
||||
|
||||
return xmlTextReaderMoveToElement(reader_) == 1 ? true : false;
|
||||
}
|
||||
|
||||
void CefXmlReaderImpl::AppendError(const std::wstring& error_str)
|
||||
{
|
||||
if (!error_buf_.str().empty())
|
||||
error_buf_ << L"\n";
|
||||
error_buf_ << error_str;
|
||||
}
|
||||
|
||||
bool CefXmlReaderImpl::VerifyContext()
|
||||
{
|
||||
if (PlatformThread::CurrentId() != supported_thread_id_) {
|
||||
// This object should only be accessed from the thread that created it.
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
return (reader_ != NULL);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 20010 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.
|
||||
|
||||
#ifndef _XML_READER_IMPL_H
|
||||
#define _XML_READER_IMPL_H
|
||||
|
||||
#include "../include/cef.h"
|
||||
#include "base/platform_thread.h"
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <sstream>
|
||||
|
||||
// Implementation of CefXmlReader
|
||||
class CefXmlReaderImpl : public CefThreadSafeBase<CefXmlReader>
|
||||
{
|
||||
public:
|
||||
CefXmlReaderImpl();
|
||||
~CefXmlReaderImpl();
|
||||
|
||||
// Initialize the reader context.
|
||||
bool Initialize(CefRefPtr<CefStreamReader> stream,
|
||||
EncodingType encodingType, const std::wstring& URI);
|
||||
|
||||
virtual bool MoveToNextElement();
|
||||
virtual bool Close();
|
||||
virtual bool HasError();
|
||||
virtual std::wstring GetError();
|
||||
virtual NodeType GetType();
|
||||
virtual int GetDepth();
|
||||
virtual std::wstring GetLocalName();
|
||||
virtual std::wstring GetPrefix();
|
||||
virtual std::wstring GetQualifiedName();
|
||||
virtual std::wstring GetNamespaceURI();
|
||||
virtual std::wstring GetBaseURI();
|
||||
virtual std::wstring GetXmlLang();
|
||||
virtual bool IsEmptyElement();
|
||||
virtual bool HasValue();
|
||||
virtual std::wstring GetValue();
|
||||
virtual bool HasAttributes();
|
||||
virtual size_t GetAttributeCount();
|
||||
virtual std::wstring GetAttribute(int index);
|
||||
virtual std::wstring GetAttribute(const std::wstring& qualifiedName);
|
||||
virtual std::wstring GetAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI);
|
||||
virtual std::wstring GetInnerXml();
|
||||
virtual std::wstring GetOuterXml();
|
||||
virtual int GetLineNumber();
|
||||
virtual bool MoveToAttribute(int index);
|
||||
virtual bool MoveToAttribute(const std::wstring& qualifiedName);
|
||||
virtual bool MoveToAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI);
|
||||
virtual bool MoveToFirstAttribute();
|
||||
virtual bool MoveToNextAttribute();
|
||||
virtual bool MoveToCarryingElement();
|
||||
|
||||
// Add another line to the error string.
|
||||
void AppendError(const std::wstring& error_str);
|
||||
|
||||
// Verify that the reader exists and is being accessed from the correct
|
||||
// thread.
|
||||
bool VerifyContext();
|
||||
|
||||
protected:
|
||||
PlatformThreadId supported_thread_id_;
|
||||
xmlTextReaderPtr reader_;
|
||||
std::wstringstream error_buf_;
|
||||
};
|
||||
|
||||
#endif // _XML_READER_IMPL_H
|
|
@ -0,0 +1,409 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// A portion of this file was generated by the CEF translator tool. When
|
||||
// making changes by hand only do so within the body of existing function
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/stream_reader_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/xml_reader_cpptoc.h"
|
||||
|
||||
|
||||
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
CEF_EXPORT cef_xml_reader_t* cef_xml_reader_create(cef_stream_reader_t* stream,
|
||||
enum cef_xml_encoding_type_t encodingType, const wchar_t* URI)
|
||||
{
|
||||
std::wstring encodingTypeStr;
|
||||
if(encodingType)
|
||||
encodingTypeStr = encodingType;
|
||||
CefRefPtr<CefXmlReader> impl = CefXmlReader::Create(
|
||||
CefStreamReaderCppToC::Unwrap(stream), encodingType, encodingTypeStr);
|
||||
if(impl.get())
|
||||
return CefXmlReaderCppToC::Wrap(impl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_next_element(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToNextElement();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_close(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->Close();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_has_error(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->HasError();
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_error(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetError();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
enum cef_xml_node_type_t CEF_CALLBACK xml_reader_get_type(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return XML_NODE_UNSUPPORTED;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->GetType();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_get_depth(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return -1;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->GetDepth();
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_local_name(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetLocalName();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_prefix(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetPrefix();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_qualified_name(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetQualifiedName();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_namespace_uri(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetNamespaceURI();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_base_uri(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetBaseURI();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_xml_lang(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetXmlLang();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_is_empty_element(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->IsEmptyElement();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_has_value(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->HasValue();
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_value(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetValue();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_has_attributes(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->HasAttributes();
|
||||
}
|
||||
|
||||
size_t CEF_CALLBACK xml_reader_get_attribute_count(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->GetAttributeCount();
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_attribute_byindex(
|
||||
struct _cef_xml_reader_t* self, int index)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetAttribute(index);
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_attribute_byqname(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* qualifiedName)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(qualifiedName);
|
||||
if(!self || !qualifiedName)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetAttribute(
|
||||
qualifiedName);
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_attribute_bylname(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* localName,
|
||||
const wchar_t* namespaceURI)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(localName);
|
||||
DCHECK(namespaceURI);
|
||||
if(!self || !localName || !namespaceURI)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetAttribute(
|
||||
localName, namespaceURI);
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_inner_xml(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetInnerXml();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cef_string_t CEF_CALLBACK xml_reader_get_outer_xml(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return NULL;
|
||||
|
||||
std::wstring retStr = CefXmlReaderCppToC::Get(self)->GetOuterXml();
|
||||
if(!retStr.empty())
|
||||
return cef_string_alloc(retStr.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_get_line_number(struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->GetLineNumber();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_attribute_byindex(
|
||||
struct _cef_xml_reader_t* self, int index)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToAttribute(index);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_attribute_byqname(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* qualifiedName)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(qualifiedName);
|
||||
if(!self || !qualifiedName)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToAttribute(qualifiedName);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_attribute_bylname(
|
||||
struct _cef_xml_reader_t* self, const wchar_t* localName,
|
||||
const wchar_t* namespaceURI)
|
||||
{
|
||||
DCHECK(self);
|
||||
DCHECK(localName);
|
||||
DCHECK(namespaceURI);
|
||||
if(!self || !localName || !namespaceURI)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToAttribute(localName,
|
||||
namespaceURI);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_first_attribute(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToFirstAttribute();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_next_attribute(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToNextAttribute();
|
||||
}
|
||||
|
||||
int CEF_CALLBACK xml_reader_move_to_carrying_element(
|
||||
struct _cef_xml_reader_t* self)
|
||||
{
|
||||
DCHECK(self);
|
||||
if(!self)
|
||||
return 0;
|
||||
|
||||
return CefXmlReaderCppToC::Get(self)->MoveToCarryingElement();
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefXmlReaderCppToC::CefXmlReaderCppToC(CefXmlReader* cls)
|
||||
: CefCppToC<CefXmlReaderCppToC, CefXmlReader, cef_xml_reader_t>(cls)
|
||||
{
|
||||
struct_.struct_.move_to_next_element = xml_reader_move_to_next_element;
|
||||
struct_.struct_.close = xml_reader_close;
|
||||
struct_.struct_.has_error = xml_reader_has_error;
|
||||
struct_.struct_.get_error = xml_reader_get_error;
|
||||
struct_.struct_.get_type = xml_reader_get_type;
|
||||
struct_.struct_.get_depth = xml_reader_get_depth;
|
||||
struct_.struct_.get_local_name = xml_reader_get_local_name;
|
||||
struct_.struct_.get_prefix = xml_reader_get_prefix;
|
||||
struct_.struct_.get_qualified_name = xml_reader_get_qualified_name;
|
||||
struct_.struct_.get_namespace_uri = xml_reader_get_namespace_uri;
|
||||
struct_.struct_.get_base_uri = xml_reader_get_base_uri;
|
||||
struct_.struct_.get_xml_lang = xml_reader_get_xml_lang;
|
||||
struct_.struct_.is_empty_element = xml_reader_is_empty_element;
|
||||
struct_.struct_.has_value = xml_reader_has_value;
|
||||
struct_.struct_.get_value = xml_reader_get_value;
|
||||
struct_.struct_.has_attributes = xml_reader_has_attributes;
|
||||
struct_.struct_.get_attribute_count = xml_reader_get_attribute_count;
|
||||
struct_.struct_.get_attribute_byindex = xml_reader_get_attribute_byindex;
|
||||
struct_.struct_.get_attribute_byqname = xml_reader_get_attribute_byqname;
|
||||
struct_.struct_.get_attribute_bylname = xml_reader_get_attribute_bylname;
|
||||
struct_.struct_.get_inner_xml = xml_reader_get_inner_xml;
|
||||
struct_.struct_.get_outer_xml = xml_reader_get_outer_xml;
|
||||
struct_.struct_.get_line_number = xml_reader_get_line_number;
|
||||
struct_.struct_.move_to_attribute_byindex =
|
||||
xml_reader_move_to_attribute_byindex;
|
||||
struct_.struct_.move_to_attribute_byqname =
|
||||
xml_reader_move_to_attribute_byqname;
|
||||
struct_.struct_.move_to_attribute_bylname =
|
||||
xml_reader_move_to_attribute_bylname;
|
||||
struct_.struct_.move_to_first_attribute = xml_reader_move_to_first_attribute;
|
||||
struct_.struct_.move_to_next_attribute = xml_reader_move_to_next_attribute;
|
||||
struct_.struct_.move_to_carrying_element =
|
||||
xml_reader_move_to_carrying_element;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
long CefCppToC<CefXmlReaderCppToC, CefXmlReader, cef_xml_reader_t>::DebugObjCt =
|
||||
0;
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool and should not edited
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
#ifndef _XMLREADER_CPPTOC_H
|
||||
#define _XMLREADER_CPPTOC_H
|
||||
|
||||
#ifndef BUILDING_CEF_SHARED
|
||||
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||
#else // BUILDING_CEF_SHARED
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "include/cef_capi.h"
|
||||
#include "libcef_dll/cpptoc/cpptoc.h"
|
||||
|
||||
// Wrap a C++ class with a C structure.
|
||||
// This class may be instantiated and accessed DLL-side only.
|
||||
class CefXmlReaderCppToC
|
||||
: public CefCppToC<CefXmlReaderCppToC, CefXmlReader, cef_xml_reader_t>
|
||||
{
|
||||
public:
|
||||
CefXmlReaderCppToC(CefXmlReader* cls);
|
||||
virtual ~CefXmlReaderCppToC() {}
|
||||
};
|
||||
|
||||
#endif // BUILDING_CEF_SHARED
|
||||
#endif // _XMLREADER_CPPTOC_H
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// A portion of this file was generated by the CEF translator tool. When
|
||||
// making changes by hand only do so within the body of existing static and
|
||||
// virtual method implementations. See the translator.README.txt file in the
|
||||
// tools directory for more information.
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/stream_reader_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/xml_reader_ctocpp.h"
|
||||
|
||||
|
||||
// STATIC METHODS - Body may be edited by hand.
|
||||
|
||||
CefRefPtr<CefXmlReader> CefXmlReader::Create(CefRefPtr<CefStreamReader> stream,
|
||||
EncodingType encodingType, const std::wstring& URI)
|
||||
{
|
||||
cef_xml_reader_t* impl = cef_xml_reader_create(
|
||||
CefStreamReaderCToCpp::Unwrap(stream), encodingType, URI.c_str());
|
||||
if(impl)
|
||||
return CefXmlReaderCToCpp::Wrap(impl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToNextElement()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_next_element))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_next_element(struct_) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::Close()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, close))
|
||||
return false;
|
||||
|
||||
return struct_->close(struct_) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::HasError()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, has_error))
|
||||
return false;
|
||||
|
||||
return struct_->has_error(struct_) ? true : false;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetError()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_error))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_error(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
CefXmlReader::NodeType CefXmlReaderCToCpp::GetType()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, get_type))
|
||||
return XML_NODE_UNSUPPORTED;
|
||||
|
||||
return struct_->get_type(struct_);
|
||||
}
|
||||
|
||||
int CefXmlReaderCToCpp::GetDepth()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, get_depth))
|
||||
return -1;
|
||||
|
||||
return struct_->get_depth(struct_);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetLocalName()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_local_name))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_local_name(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetPrefix()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_prefix))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_prefix(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetQualifiedName()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_qualified_name))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_qualified_name(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetNamespaceURI()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_namespace_uri))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_namespace_uri(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetBaseURI()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_base_uri))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_base_uri(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetXmlLang()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_xml_lang))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_xml_lang(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::IsEmptyElement()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, is_empty_element))
|
||||
return false;
|
||||
|
||||
return struct_->is_empty_element(struct_) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::HasValue()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, has_value))
|
||||
return false;
|
||||
|
||||
return struct_->has_value(struct_) ? true : false;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetValue()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_value))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_value(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::HasAttributes()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, has_attributes))
|
||||
return false;
|
||||
|
||||
return struct_->has_attributes(struct_) ? true : false;
|
||||
}
|
||||
|
||||
size_t CefXmlReaderCToCpp::GetAttributeCount()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, get_attribute_count))
|
||||
return 0;
|
||||
|
||||
return struct_->get_attribute_count(struct_);
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetAttribute(int index)
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_attribute_byindex))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_attribute_byindex(struct_, index);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetAttribute(const std::wstring& qualifiedName)
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_attribute_byqname))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_attribute_byqname(struct_,
|
||||
qualifiedName.c_str());
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI)
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_attribute_bylname))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_attribute_bylname(struct_,
|
||||
localName.c_str(), namespaceURI.c_str());
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetInnerXml()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_inner_xml))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_inner_xml(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring CefXmlReaderCToCpp::GetOuterXml()
|
||||
{
|
||||
std::wstring str;
|
||||
if(CEF_MEMBER_MISSING(struct_, get_outer_xml))
|
||||
return str;
|
||||
|
||||
cef_string_t cef_str = struct_->get_outer_xml(struct_);
|
||||
if(cef_str) {
|
||||
str = cef_str;
|
||||
cef_string_free(cef_str);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int CefXmlReaderCToCpp::GetLineNumber()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, get_line_number))
|
||||
return false;
|
||||
|
||||
return struct_->get_line_number(struct_);
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToAttribute(int index)
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_attribute_byindex))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_attribute_byindex(struct_, index) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToAttribute(const std::wstring& qualifiedName)
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_attribute_byqname))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_attribute_byqname(struct_, qualifiedName.c_str()) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI)
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_attribute_bylname))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_attribute_bylname(struct_, localName.c_str(),
|
||||
namespaceURI.c_str()) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToFirstAttribute()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_first_attribute))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_first_attribute(struct_) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToNextAttribute()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_next_attribute))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_next_attribute(struct_) ? true : false;
|
||||
}
|
||||
|
||||
bool CefXmlReaderCToCpp::MoveToCarryingElement()
|
||||
{
|
||||
if(CEF_MEMBER_MISSING(struct_, move_to_carrying_element))
|
||||
return false;
|
||||
|
||||
return struct_->move_to_carrying_element(struct_) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
long CefCToCpp<CefXmlReaderCToCpp, CefXmlReader, cef_xml_reader_t>::DebugObjCt =
|
||||
0;
|
||||
#endif
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
// This file was generated by the CEF translator tool and should not edited
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
|
||||
#ifndef _XMLREADER_CTOCPP_H
|
||||
#define _XMLREADER_CTOCPP_H
|
||||
|
||||
#ifndef USING_CEF_SHARED
|
||||
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
|
||||
#else // USING_CEF_SHARED
|
||||
|
||||
#include "include/cef.h"
|
||||
#include "include/cef_capi.h"
|
||||
#include "libcef_dll/ctocpp/ctocpp.h"
|
||||
|
||||
// Wrap a C structure with a C++ class.
|
||||
// This class may be instantiated and accessed wrapper-side only.
|
||||
class CefXmlReaderCToCpp
|
||||
: public CefCToCpp<CefXmlReaderCToCpp, CefXmlReader, cef_xml_reader_t>
|
||||
{
|
||||
public:
|
||||
CefXmlReaderCToCpp(cef_xml_reader_t* str)
|
||||
: CefCToCpp<CefXmlReaderCToCpp, CefXmlReader, cef_xml_reader_t>(str) {}
|
||||
virtual ~CefXmlReaderCToCpp() {}
|
||||
|
||||
// CefXmlReader methods
|
||||
virtual bool MoveToNextElement();
|
||||
virtual bool Close();
|
||||
virtual bool HasError();
|
||||
virtual std::wstring GetError();
|
||||
virtual NodeType GetType();
|
||||
virtual int GetDepth();
|
||||
virtual std::wstring GetLocalName();
|
||||
virtual std::wstring GetPrefix();
|
||||
virtual std::wstring GetQualifiedName();
|
||||
virtual std::wstring GetNamespaceURI();
|
||||
virtual std::wstring GetBaseURI();
|
||||
virtual std::wstring GetXmlLang();
|
||||
virtual bool IsEmptyElement();
|
||||
virtual bool HasValue();
|
||||
virtual std::wstring GetValue();
|
||||
virtual bool HasAttributes();
|
||||
virtual size_t GetAttributeCount();
|
||||
virtual std::wstring GetAttribute(int index);
|
||||
virtual std::wstring GetAttribute(const std::wstring& qualifiedName);
|
||||
virtual std::wstring GetAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI);
|
||||
virtual std::wstring GetInnerXml();
|
||||
virtual std::wstring GetOuterXml();
|
||||
virtual int GetLineNumber();
|
||||
virtual bool MoveToAttribute(int index);
|
||||
virtual bool MoveToAttribute(const std::wstring& qualifiedName);
|
||||
virtual bool MoveToAttribute(const std::wstring& localName,
|
||||
const std::wstring& namespaceURI);
|
||||
virtual bool MoveToFirstAttribute();
|
||||
virtual bool MoveToNextAttribute();
|
||||
virtual bool MoveToCarryingElement();
|
||||
};
|
||||
|
||||
#endif // USING_CEF_SHARED
|
||||
#endif // _XMLREADER_CTOCPP_H
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
#include "cpptoc/stream_reader_cpptoc.h"
|
||||
#include "cpptoc/stream_writer_cpptoc.h"
|
||||
#include "cpptoc/v8value_cpptoc.h"
|
||||
#include "cpptoc/xml_reader_cpptoc.h"
|
||||
#include "ctocpp/download_handler_ctocpp.h"
|
||||
#include "ctocpp/handler_ctocpp.h"
|
||||
#include "ctocpp/read_handler_ctocpp.h"
|
||||
|
@ -47,6 +48,7 @@ CEF_EXPORT void cef_shutdown()
|
|||
DCHECK(CefStreamReaderCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefStreamWriterCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefV8ValueCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefXmlReaderCppToC::DebugObjCt == 0);
|
||||
DCHECK(CefDownloadHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefHandlerCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefReadHandlerCToCpp::DebugObjCt == 0);
|
||||
|
|
|
@ -0,0 +1,488 @@
|
|||
// Copyright (c) 2010 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_wrapper.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class CefXmlObjectLoader
|
||||
{
|
||||
public:
|
||||
CefXmlObjectLoader(CefRefPtr<CefXmlObject> root_object)
|
||||
: root_object_(root_object)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(CefRefPtr<CefStreamReader> stream,
|
||||
CefXmlReader::EncodingType encodingType,
|
||||
const std::wstring& URI)
|
||||
{
|
||||
CefRefPtr<CefXmlReader> reader(
|
||||
CefXmlReader::Create(stream, encodingType, URI));
|
||||
if (!reader.get())
|
||||
return false;
|
||||
|
||||
bool ret = reader->MoveToNextElement();
|
||||
if (ret) {
|
||||
CefRefPtr<CefXmlObject> cur_object(root_object_), new_object;
|
||||
CefXmlObject::ObjectVector queue;
|
||||
int cur_depth, value_depth = -1;
|
||||
CefXmlReader::NodeType cur_type;
|
||||
std::wstringstream cur_value;
|
||||
bool last_has_ns = false;
|
||||
|
||||
queue.push_back(root_object_);
|
||||
|
||||
do {
|
||||
cur_depth = reader->GetDepth();
|
||||
if (value_depth >= 0 && cur_depth > value_depth) {
|
||||
// The current node has already been parsed as part of a value.
|
||||
continue;
|
||||
}
|
||||
|
||||
cur_type = reader->GetType();
|
||||
if (cur_type == XML_NODE_ELEMENT_START) {
|
||||
if (cur_depth == value_depth) {
|
||||
// Add to the current value.
|
||||
cur_value << reader->GetOuterXml();
|
||||
continue;
|
||||
} else if(last_has_ns && reader->GetPrefix().empty()) {
|
||||
if (!cur_object->HasChildren()) {
|
||||
// Start a new value because the last element has a namespace and
|
||||
// this element does not.
|
||||
value_depth = cur_depth;
|
||||
cur_value << reader->GetOuterXml();
|
||||
} else {
|
||||
// Value following a child element is not allowed.
|
||||
std::wstringstream ss;
|
||||
ss << L"Value following child element, line " <<
|
||||
reader->GetLineNumber();
|
||||
load_error_ = ss.str();
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Start a new element.
|
||||
new_object = new CefXmlObject(reader->GetQualifiedName());
|
||||
cur_object->AddChild(new_object);
|
||||
last_has_ns = !reader->GetPrefix().empty();
|
||||
|
||||
if (!reader->IsEmptyElement()) {
|
||||
// The new element potentially has a value and/or children, so
|
||||
// set the current object and add the object to the queue.
|
||||
cur_object = new_object;
|
||||
queue.push_back(cur_object);
|
||||
}
|
||||
|
||||
if (reader->HasAttributes() && reader->MoveToFirstAttribute()) {
|
||||
// Read all object attributes.
|
||||
do {
|
||||
new_object->SetAttributeValue(reader->GetQualifiedName(),
|
||||
reader->GetValue());
|
||||
} while(reader->MoveToNextAttribute());
|
||||
reader->MoveToCarryingElement();
|
||||
}
|
||||
}
|
||||
} else if(cur_type == XML_NODE_ELEMENT_END) {
|
||||
if (cur_depth == value_depth) {
|
||||
// Ending an element that is already in the value.
|
||||
continue;
|
||||
} else if (cur_depth < value_depth) {
|
||||
// Done with parsing the value portion of the current element.
|
||||
cur_object->SetValue(cur_value.str());
|
||||
cur_value.str(L"");
|
||||
value_depth = -1;
|
||||
}
|
||||
|
||||
// Pop the current element from the queue.
|
||||
queue.pop_back();
|
||||
|
||||
if (queue.empty() ||
|
||||
cur_object->GetName() != reader->GetQualifiedName()) {
|
||||
// Open tag without close tag or close tag without open tag should
|
||||
// never occur (the parser catches this error).
|
||||
NOTREACHED();
|
||||
std::wstringstream ss;
|
||||
ss << L"Mismatched end tag for " << cur_object->GetName() <<
|
||||
L", line " << reader->GetLineNumber();
|
||||
load_error_ = ss.str();
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the current object to the previous object in the queue.
|
||||
cur_object = queue.back().get();
|
||||
} else if(cur_type == XML_NODE_TEXT || cur_type == XML_NODE_CDATA ||
|
||||
cur_type == XML_NODE_ENTITY_REFERENCE) {
|
||||
if (cur_depth == value_depth) {
|
||||
// Add to the current value.
|
||||
cur_value << reader->GetValue();
|
||||
} else if (!cur_object->HasChildren()) {
|
||||
// Start a new value.
|
||||
value_depth = cur_depth;
|
||||
cur_value << reader->GetValue();
|
||||
} else {
|
||||
// Value following a child element is not allowed.
|
||||
std::wstringstream ss;
|
||||
ss << L"Value following child element, line " <<
|
||||
reader->GetLineNumber();
|
||||
load_error_ = ss.str();
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(reader->MoveToNextElement());
|
||||
}
|
||||
|
||||
if (reader->HasError()) {
|
||||
load_error_ = reader->GetError();
|
||||
return false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::wstring GetLoadError() { return load_error_; }
|
||||
|
||||
private:
|
||||
std::wstring load_error_;
|
||||
CefRefPtr<CefXmlObject> root_object_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefXmlObject::CefXmlObject(const std::wstring& name)
|
||||
: name_(name), parent_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CefXmlObject::~CefXmlObject()
|
||||
{
|
||||
}
|
||||
|
||||
bool CefXmlObject::Load(CefRefPtr<CefStreamReader> stream,
|
||||
CefXmlReader::EncodingType encodingType,
|
||||
const std::wstring& URI, std::wstring* loadError)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
Clear();
|
||||
|
||||
CefXmlObjectLoader loader(this);
|
||||
if (!loader.Load(stream, encodingType, URI)) {
|
||||
if (loadError)
|
||||
*loadError = loader.GetLoadError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefXmlObject::Set(CefRefPtr<CefXmlObject> object)
|
||||
{
|
||||
DCHECK(object.get());
|
||||
|
||||
AutoLock lock_scope1(this);
|
||||
AutoLock lock_scope2(object);
|
||||
|
||||
Clear();
|
||||
name_ = object->GetName();
|
||||
Append(object, true);
|
||||
}
|
||||
|
||||
void CefXmlObject::Append(CefRefPtr<CefXmlObject> object,
|
||||
bool overwriteAttributes)
|
||||
{
|
||||
DCHECK(object.get());
|
||||
|
||||
AutoLock lock_scope1(this);
|
||||
AutoLock lock_scope2(object);
|
||||
|
||||
if (object->HasChildren()) {
|
||||
ObjectVector children;
|
||||
object->GetChildren(children);
|
||||
ObjectVector::const_iterator it = children.begin();
|
||||
for (; it != children.end(); ++it)
|
||||
AddChild((*it)->Duplicate());
|
||||
}
|
||||
|
||||
if (object->HasAttributes()) {
|
||||
AttributeMap attributes;
|
||||
object->GetAttributes(attributes);
|
||||
AttributeMap::const_iterator it = attributes.begin();
|
||||
for (; it != attributes.end(); ++it) {
|
||||
if (overwriteAttributes || !HasAttribute(it->first))
|
||||
SetAttributeValue(it->first, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefXmlObject> CefXmlObject::Duplicate()
|
||||
{
|
||||
CefRefPtr<CefXmlObject> new_obj;
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
new_obj = new CefXmlObject(name_);
|
||||
new_obj->Append(this, true);
|
||||
}
|
||||
return new_obj;
|
||||
}
|
||||
|
||||
void CefXmlObject::Clear()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
ClearChildren();
|
||||
ClearAttributes();
|
||||
}
|
||||
|
||||
std::wstring CefXmlObject::GetName()
|
||||
{
|
||||
std::wstring name;
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
name = name_;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
bool CefXmlObject::SetName(const std::wstring& name)
|
||||
{
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
name_ = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasParent()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return (parent_ != NULL);
|
||||
}
|
||||
|
||||
CefRefPtr<CefXmlObject> CefXmlObject::GetParent()
|
||||
{
|
||||
CefRefPtr<CefXmlObject> parent;
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
parent = parent_;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasValue()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return !value_.empty();
|
||||
}
|
||||
|
||||
std::wstring CefXmlObject::GetValue()
|
||||
{
|
||||
std::wstring value;
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
value = value_;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool CefXmlObject::SetValue(const std::wstring& value)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
DCHECK(children_.empty());
|
||||
if (!children_.empty())
|
||||
return false;
|
||||
value_ = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasAttributes()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return !attributes_.empty();
|
||||
}
|
||||
|
||||
size_t CefXmlObject::GetAttributeCount()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return attributes_.size();
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasAttribute(const std::wstring& name)
|
||||
{
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
AttributeMap::const_iterator it = attributes_.find(name);
|
||||
return (it != attributes_.end());
|
||||
}
|
||||
|
||||
std::wstring CefXmlObject::GetAttributeValue(const std::wstring& name)
|
||||
{
|
||||
DCHECK(!name.empty());
|
||||
std::wstring value;
|
||||
if (!name.empty()) {
|
||||
AutoLock lock_scope(this);
|
||||
AttributeMap::const_iterator it = attributes_.find(name);
|
||||
if (it != attributes_.end())
|
||||
value = it->second;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool CefXmlObject::SetAttributeValue(const std::wstring& name,
|
||||
const std::wstring& value)
|
||||
{
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
AttributeMap::iterator it = attributes_.find(name);
|
||||
if (it != attributes_.end()) {
|
||||
it->second = value;
|
||||
} else {
|
||||
attributes_.insert(
|
||||
std::make_pair<std::wstring,std::wstring>(name, value));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t CefXmlObject::GetAttributes(AttributeMap& attributes)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
attributes = attributes_;
|
||||
return attributes_.size();
|
||||
}
|
||||
|
||||
void CefXmlObject::ClearAttributes()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
attributes_.clear();
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasChildren()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return !children_.empty();
|
||||
}
|
||||
|
||||
size_t CefXmlObject::GetChildCount()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
return children_.size();
|
||||
}
|
||||
|
||||
bool CefXmlObject::HasChild(CefRefPtr<CefXmlObject> child)
|
||||
{
|
||||
DCHECK(child.get());
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
ObjectVector::const_iterator it = children_.begin();
|
||||
for (; it != children_.end(); ++it) {
|
||||
if ((*it).get() == child.get())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefXmlObject::AddChild(CefRefPtr<CefXmlObject> child)
|
||||
{
|
||||
DCHECK(child.get());
|
||||
if (!child.get())
|
||||
return false;
|
||||
|
||||
AutoLock lock_scope1(child);
|
||||
|
||||
DCHECK(child->GetParent() == NULL);
|
||||
if (child->GetParent() != NULL)
|
||||
return false;
|
||||
|
||||
AutoLock lock_scope2(this);
|
||||
|
||||
children_.push_back(child);
|
||||
child->SetParent(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefXmlObject::RemoveChild(CefRefPtr<CefXmlObject> child)
|
||||
{
|
||||
DCHECK(child.get());
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
ObjectVector::iterator it = children_.begin();
|
||||
for (; it != children_.end(); ++it) {
|
||||
if ((*it).get() == child.get()) {
|
||||
children_.erase(it);
|
||||
child->SetParent(NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t CefXmlObject::GetChildren(ObjectVector& children)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
children = children_;
|
||||
return children_.size();
|
||||
}
|
||||
|
||||
void CefXmlObject::ClearChildren()
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
ObjectVector::iterator it = children_.begin();
|
||||
for (; it != children_.end(); ++it)
|
||||
(*it)->SetParent(NULL);
|
||||
children_.clear();
|
||||
}
|
||||
|
||||
CefRefPtr<CefXmlObject> CefXmlObject::FindChild(const std::wstring& name)
|
||||
{
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return NULL;
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
ObjectVector::const_iterator it = children_.begin();
|
||||
for (; it != children_.end(); ++it) {
|
||||
if((*it)->GetName() == name)
|
||||
return (*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t CefXmlObject::FindChildren(const std::wstring& name,
|
||||
ObjectVector& children)
|
||||
{
|
||||
DCHECK(!name.empty());
|
||||
if (name.empty())
|
||||
return 0;
|
||||
|
||||
size_t ct = 0;
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
ObjectVector::const_iterator it = children_.begin();
|
||||
for (; it != children_.end(); ++it) {
|
||||
if((*it)->GetName() == name) {
|
||||
children.push_back(*it);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
void CefXmlObject::SetParent(CefXmlObject* parent)
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
if (parent) {
|
||||
DCHECK(parent_ == NULL);
|
||||
parent_ = parent;
|
||||
} else {
|
||||
DCHECK(parent_ != NULL);
|
||||
parent_ = NULL;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
||||
// Copyright (c) 2010 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.
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include "libcef_dll/ctocpp/stream_reader_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/stream_writer_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/v8value_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/xml_reader_ctocpp.h"
|
||||
|
||||
|
||||
bool CefInitialize(bool multi_threaded_message_loop,
|
||||
|
@ -50,6 +51,7 @@ void CefShutdown()
|
|||
DCHECK(CefStreamReaderCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefStreamWriterCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefV8ValueCToCpp::DebugObjCt == 0);
|
||||
DCHECK(CefXmlReaderCToCpp::DebugObjCt == 0);
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,644 @@
|
|||
// Copyright (c) 2010 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.h"
|
||||
#include "include/cef_wrapper.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
char g_test_xml[] =
|
||||
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
|
||||
"<?my_instruction my_value?>\n"
|
||||
"<!DOCTYPE my_document SYSTEM \"example.dtd\" [\n"
|
||||
" <!ENTITY EA \"EA Value\">\n"
|
||||
" <!ENTITY EB \"EB Value\">\n"
|
||||
"]>\n"
|
||||
"<ns:obj xmlns:ns=\"http://www.example.org/ns\">\n"
|
||||
" <ns:objA>value A</ns:objA>\n"
|
||||
" <!-- my comment -->\n"
|
||||
" <ns:objB>\n"
|
||||
" <ns:objB_1>value B1</ns:objB_1>\n"
|
||||
" <ns:objB_2><![CDATA[some <br/> data]]></ns:objB_2>\n"
|
||||
" <ns:objB_3>&EB;</ns:objB_3>\n"
|
||||
" <ns:objB_4><b>this is</b> mixed content &EA;</ns:objB_4>\n"
|
||||
" </ns:objB>\n"
|
||||
" <ns:objC ns:attr1=\"value C1\" ns:attr2=\"value C2\"/><ns:objD></ns:objD>\n"
|
||||
"</ns:obj>\n";
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test XML reading
|
||||
TEST(XmlReaderTest, Read)
|
||||
{
|
||||
// Create the stream reader.
|
||||
CefRefPtr<CefStreamReader> stream(
|
||||
CefStreamReader::CreateForData(g_test_xml, sizeof(g_test_xml) - 1));
|
||||
ASSERT_TRUE(stream.get() != NULL);
|
||||
|
||||
// Create the XML reader.
|
||||
CefRefPtr<CefXmlReader> reader(
|
||||
CefXmlReader::Create(stream, XML_ENCODING_NONE,
|
||||
L"http://www.example.org/example.xml"));
|
||||
ASSERT_TRUE(reader.get() != NULL);
|
||||
|
||||
// Move to the processing instruction node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 0);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_PROCESSING_INSTRUCTION);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"my_instruction");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"my_instruction");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"my_value");
|
||||
|
||||
// Move to the DOCTYPE node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 0);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_DOCUMENT_TYPE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"my_document");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"my_document");
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to ns:obj element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 0);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"obj");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:obj");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetAttributeCount(), 1);
|
||||
ASSERT_EQ(reader->GetAttribute(0), L"http://www.example.org/ns");
|
||||
ASSERT_EQ(reader->GetAttribute(L"xmlns:ns"), L"http://www.example.org/ns");
|
||||
ASSERT_EQ(reader->GetAttribute(L"ns", L"http://www.w3.org/2000/xmlns/"),
|
||||
L"http://www.example.org/ns");
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objA element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objA");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objA");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the ns:objA value node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"#text");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"#text");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"value A");
|
||||
|
||||
// Move to the ns:objA element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objA");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objA");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the comment node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_COMMENT);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"#comment");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"#comment");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L" my comment ");
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB_1 element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_1");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_1");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the ns:objB_1 value node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"value B1");
|
||||
|
||||
// Move to the ns:objB_1 element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_1");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_1");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB_2 element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_2");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_2");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the ns:objB_2 value node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_CDATA);
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"some <br/> data");
|
||||
|
||||
// Move to the ns:objB_2 element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_2");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_2");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB_3 element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_3");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_3");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the EB entity reference node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ENTITY_REFERENCE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"EB");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"EB");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"EB Value");
|
||||
|
||||
// Move to the ns:objB_3 element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_3");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_3");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB_4 element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_4");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_4");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetInnerXml(), L"<b>this is</b> mixed content &EA;");
|
||||
ASSERT_EQ(reader->GetOuterXml(),
|
||||
L"<ns:objB_4 xmlns:ns=\"http://www.example.org/ns\">"
|
||||
L"<b>this is</b> mixed content &EA;</ns:objB_4>");
|
||||
|
||||
// Move to the <b> element node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"b");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"b");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the text node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 4);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"#text");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"#text");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"this is");
|
||||
|
||||
// Move to the </b> element node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"b");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"b");
|
||||
|
||||
// Move to the text node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_TEXT);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"#text");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"#text");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L" mixed content ");
|
||||
|
||||
// Move to the EA entity reference node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 3);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ENTITY_REFERENCE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"EA");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"EA");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetValue(), L"EA Value");
|
||||
|
||||
// Move to the ns:objB_4 element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB_4");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB_4");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objB element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objB");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objB");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to the ns:objC element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objC");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objC");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->IsEmptyElement());
|
||||
ASSERT_TRUE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
ASSERT_EQ(reader->GetAttributeCount(), 2);
|
||||
ASSERT_EQ(reader->GetAttribute(0), L"value C1");
|
||||
ASSERT_EQ(reader->GetAttribute(L"ns:attr1"), L"value C1");
|
||||
ASSERT_EQ(reader->GetAttribute(L"attr1", L"http://www.example.org/ns"),
|
||||
L"value C1");
|
||||
ASSERT_EQ(reader->GetAttribute(1), L"value C2");
|
||||
ASSERT_EQ(reader->GetAttribute(L"ns:attr2"), L"value C2");
|
||||
ASSERT_EQ(reader->GetAttribute(L"attr2", L"http://www.example.org/ns"),
|
||||
L"value C2");
|
||||
|
||||
// Move to the ns:attr1 attribute.
|
||||
ASSERT_TRUE(reader->MoveToFirstAttribute());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"attr1");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:attr1");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetValue(), L"value C1");
|
||||
|
||||
// Move to the ns:attr2 attribute.
|
||||
ASSERT_TRUE(reader->MoveToNextAttribute());
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"attr2");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:attr2");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetValue(), L"value C2");
|
||||
|
||||
// No more attributes.
|
||||
ASSERT_FALSE(reader->MoveToNextAttribute());
|
||||
|
||||
// Return to the ns:objC element start node.
|
||||
ASSERT_TRUE(reader->MoveToCarryingElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objC");
|
||||
|
||||
// Move to the ns:attr1 attribute.
|
||||
ASSERT_TRUE(reader->MoveToAttribute(0));
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"attr1");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:attr1");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetValue(), L"value C1");
|
||||
|
||||
// Return to the ns:objC element start node.
|
||||
ASSERT_TRUE(reader->MoveToCarryingElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objC");
|
||||
|
||||
// Move to the ns:attr2 attribute.
|
||||
ASSERT_TRUE(reader->MoveToAttribute(L"ns:attr2"));
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"attr2");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:attr2");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetValue(), L"value C2");
|
||||
|
||||
// Move to the ns:attr1 attribute without returning to the ns:objC element.
|
||||
ASSERT_TRUE(reader->MoveToAttribute(L"attr1", L"http://www.example.org/ns"));
|
||||
ASSERT_EQ(reader->GetDepth(), 2);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ATTRIBUTE);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"attr1");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:attr1");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_TRUE(reader->HasValue());
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetValue(), L"value C1");
|
||||
|
||||
// Move to the ns:objD element start node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_START);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objD");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objD");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the ns:objD element end node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 1);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"objD");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:objD");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_FALSE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
|
||||
// Move to the whitespace node without returning to the ns:objC element.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_WHITESPACE);
|
||||
|
||||
// Move to ns:obj element ending node.
|
||||
ASSERT_TRUE(reader->MoveToNextElement());
|
||||
ASSERT_EQ(reader->GetDepth(), 0);
|
||||
ASSERT_EQ(reader->GetType(), XML_NODE_ELEMENT_END);
|
||||
ASSERT_EQ(reader->GetLocalName(), L"obj");
|
||||
ASSERT_EQ(reader->GetPrefix(), L"ns");
|
||||
ASSERT_EQ(reader->GetQualifiedName(), L"ns:obj");
|
||||
ASSERT_EQ(reader->GetNamespaceURI(), L"http://www.example.org/ns");
|
||||
ASSERT_FALSE(reader->IsEmptyElement());
|
||||
ASSERT_TRUE(reader->HasAttributes());
|
||||
ASSERT_FALSE(reader->HasValue());
|
||||
// Strangely, the end node will report if the starting node has attributes
|
||||
// but will not provide access to them.
|
||||
ASSERT_TRUE(reader->HasAttributes());
|
||||
ASSERT_EQ(reader->GetAttributeCount(), 0);
|
||||
|
||||
// And we're done.
|
||||
ASSERT_FALSE(reader->MoveToNextElement());
|
||||
|
||||
ASSERT_TRUE(reader->Close());
|
||||
}
|
||||
|
||||
// Test XML read error handling.
|
||||
TEST(XmlReaderTest, ReadError)
|
||||
{
|
||||
char test_str[] =
|
||||
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
|
||||
"<!ATTRIBUTE foo bar>\n";
|
||||
|
||||
// Create the stream reader.
|
||||
CefRefPtr<CefStreamReader> stream(
|
||||
CefStreamReader::CreateForData(test_str, sizeof(test_str) - 1));
|
||||
ASSERT_TRUE(stream.get() != NULL);
|
||||
|
||||
// Create the XML reader.
|
||||
CefRefPtr<CefXmlReader> reader(
|
||||
CefXmlReader::Create(stream, XML_ENCODING_NONE,
|
||||
L"http://www.example.org/example.xml"));
|
||||
ASSERT_TRUE(reader.get() != NULL);
|
||||
|
||||
// Move to the processing instruction node and generate parser error.
|
||||
ASSERT_FALSE(reader->MoveToNextElement());
|
||||
ASSERT_TRUE(reader->HasError());
|
||||
}
|
||||
|
||||
// Test XmlObject load behavior.
|
||||
TEST(XmlReaderTest, ObjectLoad)
|
||||
{
|
||||
// Create the stream reader.
|
||||
CefRefPtr<CefStreamReader> stream(
|
||||
CefStreamReader::CreateForData(g_test_xml, sizeof(g_test_xml) - 1));
|
||||
ASSERT_TRUE(stream.get() != NULL);
|
||||
|
||||
// Create the XML reader.
|
||||
CefRefPtr<CefXmlObject> object(new CefXmlObject(L"object"));
|
||||
ASSERT_TRUE(object->Load(stream, XML_ENCODING_NONE,
|
||||
L"http://www.example.org/example.xml", NULL));
|
||||
|
||||
ASSERT_FALSE(object->HasAttributes());
|
||||
ASSERT_TRUE(object->HasChildren());
|
||||
ASSERT_EQ(object->GetChildCount(), 1);
|
||||
|
||||
CefRefPtr<CefXmlObject> obj(object->FindChild(L"ns:obj"));
|
||||
ASSERT_TRUE(obj.get());
|
||||
ASSERT_TRUE(obj->HasChildren());
|
||||
ASSERT_EQ(obj->GetChildCount(), 4);
|
||||
|
||||
CefRefPtr<CefXmlObject> obj_child(obj->FindChild(L"ns:objC"));
|
||||
ASSERT_TRUE(obj_child.get());
|
||||
ASSERT_EQ(obj_child->GetName(), L"ns:objC");
|
||||
ASSERT_FALSE(obj_child->HasChildren());
|
||||
ASSERT_FALSE(obj_child->HasValue());
|
||||
ASSERT_TRUE(obj_child->HasAttributes());
|
||||
|
||||
CefXmlObject::ObjectVector obj_children;
|
||||
ASSERT_EQ(obj->GetChildren(obj_children), 4);
|
||||
ASSERT_EQ(obj_children.size(), 4);
|
||||
|
||||
CefXmlObject::ObjectVector::const_iterator it = obj_children.begin();
|
||||
for (int ct = 0; it != obj_children.end(); ++it, ++ct) {
|
||||
obj_child = *it;
|
||||
ASSERT_TRUE(obj_child.get());
|
||||
if (ct == 0) {
|
||||
// ns:objA
|
||||
ASSERT_EQ(obj_child->GetName(), L"ns:objA");
|
||||
ASSERT_FALSE(obj_child->HasChildren());
|
||||
ASSERT_TRUE(obj_child->HasValue());
|
||||
ASSERT_FALSE(obj_child->HasAttributes());
|
||||
ASSERT_EQ(obj_child->GetValue(), L"value A");
|
||||
} else if (ct == 1) {
|
||||
// ns:objB
|
||||
ASSERT_EQ(obj_child->GetName(), L"ns:objB");
|
||||
ASSERT_TRUE(obj_child->HasChildren());
|
||||
ASSERT_FALSE(obj_child->HasValue());
|
||||
ASSERT_FALSE(obj_child->HasAttributes());
|
||||
ASSERT_EQ(obj_child->GetChildCount(), 4);
|
||||
obj_child = obj_child->FindChild(L"ns:objB_4");
|
||||
ASSERT_TRUE(obj_child.get());
|
||||
ASSERT_TRUE(obj_child->HasValue());
|
||||
ASSERT_EQ(obj_child->GetValue(),
|
||||
L"<b>this is</b> mixed content EA Value");
|
||||
} else if (ct == 2) {
|
||||
// ns:objC
|
||||
ASSERT_EQ(obj_child->GetName(), L"ns:objC");
|
||||
ASSERT_FALSE(obj_child->HasChildren());
|
||||
ASSERT_FALSE(obj_child->HasValue());
|
||||
ASSERT_TRUE(obj_child->HasAttributes());
|
||||
|
||||
CefXmlObject::AttributeMap attribs;
|
||||
ASSERT_EQ(obj_child->GetAttributes(attribs), 2);
|
||||
ASSERT_EQ(attribs.size(), 2);
|
||||
ASSERT_EQ(attribs[L"ns:attr1"], L"value C1");
|
||||
ASSERT_EQ(attribs[L"ns:attr2"], L"value C2");
|
||||
|
||||
ASSERT_EQ(obj_child->GetAttributeCount(), 2);
|
||||
ASSERT_TRUE(obj_child->HasAttribute(L"ns:attr1"));
|
||||
ASSERT_EQ(obj_child->GetAttributeValue(L"ns:attr1"), L"value C1");
|
||||
ASSERT_TRUE(obj_child->HasAttribute(L"ns:attr2"));
|
||||
ASSERT_EQ(obj_child->GetAttributeValue(L"ns:attr2"), L"value C2");
|
||||
} else if (ct == 3) {
|
||||
// ns:objD
|
||||
ASSERT_EQ(obj_child->GetName(), L"ns:objD");
|
||||
ASSERT_FALSE(obj_child->HasChildren());
|
||||
ASSERT_FALSE(obj_child->HasValue());
|
||||
ASSERT_FALSE(obj_child->HasAttributes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test XmlObject load error handling behavior.
|
||||
TEST(XmlReaderTest, ObjectLoadError)
|
||||
{
|
||||
// Test start/end tag mismatch error.
|
||||
{
|
||||
char error_xml[] = "<obj>\n<foo>\n</obj>\n</foo>";
|
||||
|
||||
// Create the stream reader.
|
||||
CefRefPtr<CefStreamReader> stream(
|
||||
CefStreamReader::CreateForData(error_xml, sizeof(error_xml) - 1));
|
||||
ASSERT_TRUE(stream.get() != NULL);
|
||||
|
||||
std::wstring error_str;
|
||||
|
||||
// Create the XML reader.
|
||||
CefRefPtr<CefXmlObject> object(new CefXmlObject(L"object"));
|
||||
ASSERT_FALSE(object->Load(stream, XML_ENCODING_NONE,
|
||||
L"http://www.example.org/example.xml", &error_str));
|
||||
ASSERT_EQ(error_str,
|
||||
L"Opening and ending tag mismatch: foo line 2 and obj, line 3");
|
||||
}
|
||||
|
||||
// Test value following child error.
|
||||
{
|
||||
char error_xml[] = "<obj>\n<foo>\n</foo>disallowed value\n</obj>";
|
||||
|
||||
// Create the stream reader.
|
||||
CefRefPtr<CefStreamReader> stream(
|
||||
CefStreamReader::CreateForData(error_xml, sizeof(error_xml) - 1));
|
||||
ASSERT_TRUE(stream.get() != NULL);
|
||||
|
||||
std::wstring error_str;
|
||||
|
||||
// Create the XML reader.
|
||||
CefRefPtr<CefXmlObject> object(new CefXmlObject(L"object"));
|
||||
ASSERT_FALSE(object->Load(stream, XML_ENCODING_NONE,
|
||||
L"http://www.example.org/example.xml", &error_str));
|
||||
ASSERT_EQ(error_str,
|
||||
L"Value following child element, line 4");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue