1 // Copyright 2013 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/utility/media_galleries/iapps_xml_utils.h" 6 7 #include "base/logging.h" 8 #include "base/stl_util.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "third_party/libxml/chromium/libxml_utils.h" 11 12 namespace iapps { 13 14 bool SkipToNextElement(XmlReader* reader) { 15 if (!reader->SkipToElement()) { 16 // SkipToElement returns false if the current node is an end element, 17 // try to advance to the next element and then try again. 18 if (!reader->Read() || !reader->SkipToElement()) 19 return false; 20 } 21 return true; 22 } 23 24 bool SeekToNodeAtCurrentDepth(XmlReader* reader, const std::string& name) { 25 int depth = reader->Depth(); 26 do { 27 if (!SkipToNextElement(reader) || reader->Depth() < depth) 28 return false; 29 DCHECK_EQ(depth, reader->Depth()); 30 if (reader->NodeName() == name) 31 return true; 32 } while (reader->Next()); 33 34 return false; 35 } 36 37 bool SeekInDict(XmlReader* reader, const std::string& key) { 38 DCHECK_EQ("dict", reader->NodeName()); 39 40 int dict_content_depth = reader->Depth() + 1; 41 // Advance past the dict node and into the body of the dictionary. 42 if (!reader->Read()) 43 return false; 44 45 while (reader->Depth() >= dict_content_depth) { 46 if (!SeekToNodeAtCurrentDepth(reader, "key")) 47 return false; 48 std::string found_key; 49 if (!reader->ReadElementContent(&found_key)) 50 return false; 51 DCHECK_EQ(dict_content_depth, reader->Depth()); 52 if (found_key == key) 53 return true; 54 } 55 return false; 56 } 57 58 // Seek to the start of a tag and read the value into |result| if the node's 59 // name is |node_name|. 60 bool ReadSimpleValue(XmlReader* reader, const std::string& node_name, 61 std::string* result) { 62 if (!iapps::SkipToNextElement(reader)) 63 return false; 64 if (reader->NodeName() != node_name) 65 return false; 66 return reader->ReadElementContent(result); 67 } 68 69 bool ReadString(XmlReader* reader, std::string* result) { 70 return ReadSimpleValue(reader, "string", result); 71 } 72 73 bool ReadInteger(XmlReader* reader, uint64* result) { 74 std::string value; 75 if (!ReadSimpleValue(reader, "integer", &value)) 76 return false; 77 return base::StringToUint64(value, result); 78 } 79 80 std::string ReadPlatformFileAsString(const base::PlatformFile file) { 81 std::string result; 82 if (file == base::kInvalidPlatformFileValue) 83 return result; 84 85 // A "reasonable" artificial limit. 86 // TODO(vandebo): Add a UMA to figure out what common values are. 87 const int64 kMaxLibraryFileSize = 150 * 1024 * 1024; 88 base::PlatformFileInfo file_info; 89 if (!base::GetPlatformFileInfo(file, &file_info) || 90 file_info.size > kMaxLibraryFileSize) { 91 base::ClosePlatformFile(file); 92 return result; 93 } 94 95 result.resize(file_info.size); 96 int bytes_read = 97 base::ReadPlatformFile(file, 0, string_as_array(&result), file_info.size); 98 if (bytes_read != file_info.size) 99 result.clear(); 100 101 base::ClosePlatformFile(file); 102 return result; 103 } 104 105 } // namespace iapps 106