OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/libxml_utils.h" | 5 #include "libxml_utils.h" |
6 | |
7 #include "base/compiler_specific.h" | |
8 #include "base/file_path.h" | |
9 #include "base/logging.h" | |
10 #include "base/stringprintf.h" | |
11 #include "base/utf_string_conversions.h" | |
12 | 6 |
13 #include "libxml/xmlreader.h" | 7 #include "libxml/xmlreader.h" |
14 | 8 |
15 std::string XmlStringToStdString(const xmlChar* xmlstring) { | 9 std::string XmlStringToStdString(const xmlChar* xmlstring) { |
16 // xmlChar*s are UTF-8, so this cast is safe. | 10 // xmlChar*s are UTF-8, so this cast is safe. |
17 if (xmlstring) | 11 if (xmlstring) |
18 return std::string(reinterpret_cast<const char*>(xmlstring)); | 12 return std::string(reinterpret_cast<const char*>(xmlstring)); |
19 else | 13 else |
20 return ""; | 14 return ""; |
21 } | 15 } |
22 | 16 |
23 XmlReader::XmlReader() | 17 XmlReader::XmlReader() : reader_(NULL) { |
24 : reader_(NULL), | |
25 ALLOW_THIS_IN_INITIALIZER_LIST( | |
26 error_func_(this, &XmlReader::GenericErrorCallback)) { | |
27 } | 18 } |
28 | 19 |
29 XmlReader::~XmlReader() { | 20 XmlReader::~XmlReader() { |
30 if (reader_) | 21 if (reader_) |
31 xmlFreeTextReader(reader_); | 22 xmlFreeTextReader(reader_); |
32 } | 23 } |
33 | 24 |
34 // static | |
35 void XmlReader::GenericErrorCallback(void* context, const char* msg, ...) { | |
36 va_list args; | |
37 va_start(args, msg); | |
38 | |
39 XmlReader* reader = static_cast<XmlReader*>(context); | |
40 reader->errors_.append(base::StringPrintV(msg, args)); | |
41 va_end(args); | |
42 } | |
43 | |
44 bool XmlReader::Load(const std::string& input) { | 25 bool XmlReader::Load(const std::string& input) { |
45 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors | 26 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors |
46 XML_PARSE_NONET; // forbid network access | 27 XML_PARSE_NONET; // forbid network access |
47 // TODO(evanm): Verify it's OK to pass NULL for the URL and encoding. | 28 // TODO(evanm): Verify it's OK to pass NULL for the URL and encoding. |
48 // The libxml code allows for these, but it's unclear what effect is has. | 29 // The libxml code allows for these, but it's unclear what effect is has. |
49 reader_ = xmlReaderForMemory(input.data(), static_cast<int>(input.size()), | 30 reader_ = xmlReaderForMemory(input.data(), static_cast<int>(input.size()), |
50 NULL, NULL, kParseOptions); | 31 NULL, NULL, kParseOptions); |
51 return reader_ != NULL; | 32 return reader_ != NULL; |
52 } | 33 } |
53 | 34 |
54 bool XmlReader::LoadFile(const FilePath& file_path) { | 35 bool XmlReader::LoadFile(const std::string& file_path) { |
55 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors | 36 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors |
56 XML_PARSE_NONET; // forbid network access | 37 XML_PARSE_NONET; // forbid network access |
57 reader_ = xmlReaderForFile( | 38 reader_ = xmlReaderForFile(file_path.c_str(), NULL, kParseOptions); |
58 #if defined(OS_WIN) | |
59 // libxml takes UTF-8 paths on Windows; search the source for | |
60 // xmlWrapOpenUtf8 to see it converting UTF-8 back to wide | |
61 // characters. | |
62 WideToUTF8(file_path.value()).c_str(), | |
63 #else | |
64 file_path.value().c_str(), | |
65 #endif | |
66 NULL, kParseOptions); | |
67 return reader_ != NULL; | 39 return reader_ != NULL; |
68 } | 40 } |
69 | 41 |
70 bool XmlReader::NodeAttribute(const char* name, std::string* out) { | 42 bool XmlReader::NodeAttribute(const char* name, std::string* out) { |
71 xmlChar* value = xmlTextReaderGetAttribute(reader_, BAD_CAST name); | 43 xmlChar* value = xmlTextReaderGetAttribute(reader_, BAD_CAST name); |
72 if (!value) | 44 if (!value) |
73 return false; | 45 return false; |
74 *out = XmlStringToStdString(value); | 46 *out = XmlStringToStdString(value); |
75 xmlFree(value); | 47 xmlFree(value); |
76 return true; | 48 return true; |
77 } | 49 } |
78 | 50 |
79 bool XmlReader::ReadElementContent(std::string* content) { | 51 bool XmlReader::ReadElementContent(std::string* content) { |
80 DCHECK(NodeType() == XML_READER_TYPE_ELEMENT); | |
81 const int start_depth = Depth(); | 52 const int start_depth = Depth(); |
82 | 53 |
83 if (xmlTextReaderIsEmptyElement(reader_)) { | 54 if (xmlTextReaderIsEmptyElement(reader_)) { |
84 // Empty tag. We succesfully read the content, but it's | 55 // Empty tag. We succesfully read the content, but it's |
85 // empty. | 56 // empty. |
86 *content = ""; | 57 *content = ""; |
87 // Advance past this empty tag. | 58 // Advance past this empty tag. |
88 if (!Read()) | 59 if (!Read()) |
89 return false; | 60 return false; |
90 return true; | 61 return true; |
91 } | 62 } |
92 | 63 |
93 // Advance past opening element tag. | 64 // Advance past opening element tag. |
94 if (!Read()) | 65 if (!Read()) |
95 return false; | 66 return false; |
96 | 67 |
97 // Read the content. We read up until we hit a closing tag at the | 68 // Read the content. We read up until we hit a closing tag at the |
98 // same level as our starting point. | 69 // same level as our starting point. |
99 while (NodeType() != XML_READER_TYPE_END_ELEMENT || Depth() != start_depth) { | 70 while (NodeType() != XML_READER_TYPE_END_ELEMENT || Depth() != start_depth) { |
100 *content += XmlStringToStdString(xmlTextReaderConstValue(reader_)); | 71 *content += XmlStringToStdString(xmlTextReaderConstValue(reader_)); |
101 if (!Read()) | 72 if (!Read()) |
102 return false; | 73 return false; |
103 } | 74 } |
104 | 75 |
105 // Advance past ending element tag. | 76 // Advance past ending element tag. |
106 DCHECK_EQ(NodeType(), XML_READER_TYPE_END_ELEMENT); | |
107 if (!Read()) | 77 if (!Read()) |
108 return false; | 78 return false; |
109 | 79 |
110 return true; | 80 return true; |
111 } | 81 } |
112 | 82 |
113 bool XmlReader::SkipToElement() { | 83 bool XmlReader::SkipToElement() { |
114 do { | 84 do { |
115 switch (NodeType()) { | 85 switch (NodeType()) { |
116 case XML_READER_TYPE_ELEMENT: | 86 case XML_READER_TYPE_ELEMENT: |
(...skipping 27 matching lines...) Expand all Loading... |
144 writer_ = xmlNewTextWriterMemory(buffer_, 0); | 114 writer_ = xmlNewTextWriterMemory(buffer_, 0); |
145 xmlTextWriterSetIndent(writer_, 1); | 115 xmlTextWriterSetIndent(writer_, 1); |
146 xmlTextWriterStartDocument(writer_, NULL, NULL, NULL); | 116 xmlTextWriterStartDocument(writer_, NULL, NULL, NULL); |
147 } | 117 } |
148 | 118 |
149 void XmlWriter::StopWriting() { | 119 void XmlWriter::StopWriting() { |
150 xmlTextWriterEndDocument(writer_); | 120 xmlTextWriterEndDocument(writer_); |
151 xmlFreeTextWriter(writer_); | 121 xmlFreeTextWriter(writer_); |
152 writer_ = NULL; | 122 writer_ = NULL; |
153 } | 123 } |
OLD | NEW |