OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/common/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 | |
13 #include "libxml/xmlreader.h" | |
14 | |
15 std::string XmlStringToStdString(const xmlChar* xmlstring) { | |
16 // xmlChar*s are UTF-8, so this cast is safe. | |
17 if (xmlstring) | |
18 return std::string(reinterpret_cast<const char*>(xmlstring)); | |
19 else | |
20 return ""; | |
21 } | |
22 | |
23 XmlReader::XmlReader() | |
24 : reader_(NULL), | |
25 ALLOW_THIS_IN_INITIALIZER_LIST( | |
26 error_func_(this, &XmlReader::GenericErrorCallback)) { | |
27 } | |
28 | |
29 XmlReader::~XmlReader() { | |
30 if (reader_) | |
31 xmlFreeTextReader(reader_); | |
32 } | |
33 | |
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) { | |
45 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors | |
46 XML_PARSE_NONET; // forbid network access | |
47 // 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. | |
49 reader_ = xmlReaderForMemory(input.data(), static_cast<int>(input.size()), | |
50 NULL, NULL, kParseOptions); | |
51 return reader_ != NULL; | |
52 } | |
53 | |
54 bool XmlReader::LoadFile(const FilePath& file_path) { | |
55 const int kParseOptions = XML_PARSE_RECOVER | // recover on errors | |
56 XML_PARSE_NONET; // forbid network access | |
57 reader_ = xmlReaderForFile( | |
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; | |
68 } | |
69 | |
70 bool XmlReader::NodeAttribute(const char* name, std::string* out) { | |
71 xmlChar* value = xmlTextReaderGetAttribute(reader_, BAD_CAST name); | |
72 if (!value) | |
73 return false; | |
74 *out = XmlStringToStdString(value); | |
75 xmlFree(value); | |
76 return true; | |
77 } | |
78 | |
79 bool XmlReader::ReadElementContent(std::string* content) { | |
80 DCHECK(NodeType() == XML_READER_TYPE_ELEMENT); | |
81 const int start_depth = Depth(); | |
82 | |
83 if (xmlTextReaderIsEmptyElement(reader_)) { | |
84 // Empty tag. We succesfully read the content, but it's | |
85 // empty. | |
86 *content = ""; | |
87 // Advance past this empty tag. | |
88 if (!Read()) | |
89 return false; | |
90 return true; | |
91 } | |
92 | |
93 // Advance past opening element tag. | |
94 if (!Read()) | |
95 return false; | |
96 | |
97 // Read the content. We read up until we hit a closing tag at the | |
98 // same level as our starting point. | |
99 while (NodeType() != XML_READER_TYPE_END_ELEMENT || Depth() != start_depth) { | |
100 *content += XmlStringToStdString(xmlTextReaderConstValue(reader_)); | |
101 if (!Read()) | |
102 return false; | |
103 } | |
104 | |
105 // Advance past ending element tag. | |
106 DCHECK_EQ(NodeType(), XML_READER_TYPE_END_ELEMENT); | |
107 if (!Read()) | |
108 return false; | |
109 | |
110 return true; | |
111 } | |
112 | |
113 bool XmlReader::SkipToElement() { | |
114 do { | |
115 switch (NodeType()) { | |
116 case XML_READER_TYPE_ELEMENT: | |
117 return true; | |
118 case XML_READER_TYPE_END_ELEMENT: | |
119 return false; | |
120 default: | |
121 // Skip all other node types. | |
122 continue; | |
123 } | |
124 } while (Read()); | |
125 return false; | |
126 } | |
127 | |
128 | |
129 // XmlWriter functions | |
130 | |
131 XmlWriter::XmlWriter() | |
132 : writer_(NULL), | |
133 buffer_(NULL) {} | |
134 | |
135 XmlWriter::~XmlWriter() { | |
136 if (writer_) | |
137 xmlFreeTextWriter(writer_); | |
138 if (buffer_) | |
139 xmlBufferFree(buffer_); | |
140 } | |
141 | |
142 void XmlWriter::StartWriting() { | |
143 buffer_ = xmlBufferCreate(); | |
144 writer_ = xmlNewTextWriterMemory(buffer_, 0); | |
145 xmlTextWriterSetIndent(writer_, 1); | |
146 xmlTextWriterStartDocument(writer_, NULL, NULL, NULL); | |
147 } | |
148 | |
149 void XmlWriter::StopWriting() { | |
150 xmlTextWriterEndDocument(writer_); | |
151 xmlFreeTextWriter(writer_); | |
152 writer_ = NULL; | |
153 } | |
OLD | NEW |