| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 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/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 } |
| 124 |
| OLD | NEW |