| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/utility/media_galleries/iphoto_library_parser.h" | 5 #include "chrome/utility/media_galleries/iphoto_library_parser.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 std::set<uint64> photo_ids; | 27 std::set<uint64> photo_ids; |
| 28 std::string name; | 28 std::string name; |
| 29 uint64 id; | 29 uint64 id; |
| 30 }; | 30 }; |
| 31 | 31 |
| 32 class PhotosXmlDictReader : public iapps::XmlDictReader { | 32 class PhotosXmlDictReader : public iapps::XmlDictReader { |
| 33 public: | 33 public: |
| 34 PhotosXmlDictReader(XmlReader* reader, PhotoInfo* photo_info) | 34 PhotosXmlDictReader(XmlReader* reader, PhotoInfo* photo_info) |
| 35 : iapps::XmlDictReader(reader), photo_info_(photo_info) {} | 35 : iapps::XmlDictReader(reader), photo_info_(photo_info) {} |
| 36 | 36 |
| 37 virtual bool HandleKeyImpl(const std::string& key) override { | 37 bool HandleKeyImpl(const std::string& key) override { |
| 38 if (key == "ImagePath") { | 38 if (key == "ImagePath") { |
| 39 std::string value; | 39 std::string value; |
| 40 if (!iapps::ReadString(reader_, &value)) | 40 if (!iapps::ReadString(reader_, &value)) |
| 41 return false; | 41 return false; |
| 42 photo_info_->location = base::FilePath(value); | 42 photo_info_->location = base::FilePath(value); |
| 43 } else if (key == "OriginalPath") { | 43 } else if (key == "OriginalPath") { |
| 44 std::string value; | 44 std::string value; |
| 45 if (!iapps::ReadString(reader_, &value)) | 45 if (!iapps::ReadString(reader_, &value)) |
| 46 return false; | 46 return false; |
| 47 photo_info_->original_location = base::FilePath(value); | 47 photo_info_->original_location = base::FilePath(value); |
| 48 } else if (!SkipToNext()) { | 48 } else if (!SkipToNext()) { |
| 49 return false; | 49 return false; |
| 50 } | 50 } |
| 51 return true; | 51 return true; |
| 52 } | 52 } |
| 53 | 53 |
| 54 virtual bool FinishedOk() override { | 54 bool FinishedOk() override { return Found("ImagePath"); } |
| 55 return Found("ImagePath"); | |
| 56 } | |
| 57 | 55 |
| 58 private: | 56 private: |
| 59 PhotoInfo* photo_info_; | 57 PhotoInfo* photo_info_; |
| 60 }; | 58 }; |
| 61 | 59 |
| 62 // Contents of the album 'KeyList' key are | 60 // Contents of the album 'KeyList' key are |
| 63 // <array> | 61 // <array> |
| 64 // <string>1</string> | 62 // <string>1</string> |
| 65 // <string>2</string> | 63 // <string>2</string> |
| 66 // <string>3</string> | 64 // <string>3</string> |
| (...skipping 21 matching lines...) Expand all Loading... |
| 88 } | 86 } |
| 89 | 87 |
| 90 return true; | 88 return true; |
| 91 } | 89 } |
| 92 | 90 |
| 93 class AlbumXmlDictReader : public iapps::XmlDictReader { | 91 class AlbumXmlDictReader : public iapps::XmlDictReader { |
| 94 public: | 92 public: |
| 95 AlbumXmlDictReader(XmlReader* reader, AlbumInfo* album_info) | 93 AlbumXmlDictReader(XmlReader* reader, AlbumInfo* album_info) |
| 96 : iapps::XmlDictReader(reader), album_info_(album_info) {} | 94 : iapps::XmlDictReader(reader), album_info_(album_info) {} |
| 97 | 95 |
| 98 virtual bool ShouldLoop() override { | 96 bool ShouldLoop() override { |
| 99 return !(Found("AlbumId") && Found("AlbumName") && Found("KeyList")); | 97 return !(Found("AlbumId") && Found("AlbumName") && Found("KeyList")); |
| 100 } | 98 } |
| 101 | 99 |
| 102 virtual bool HandleKeyImpl(const std::string& key) override { | 100 bool HandleKeyImpl(const std::string& key) override { |
| 103 if (key == "AlbumId") { | 101 if (key == "AlbumId") { |
| 104 if (!iapps::ReadInteger(reader_, &album_info_->id)) | 102 if (!iapps::ReadInteger(reader_, &album_info_->id)) |
| 105 return false; | 103 return false; |
| 106 } else if (key == "AlbumName") { | 104 } else if (key == "AlbumName") { |
| 107 if (!iapps::ReadString(reader_, &album_info_->name)) | 105 if (!iapps::ReadString(reader_, &album_info_->name)) |
| 108 return false; | 106 return false; |
| 109 } else if (key == "KeyList") { | 107 } else if (key == "KeyList") { |
| 110 if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array")) | 108 if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array")) |
| 111 return false; | 109 return false; |
| 112 if (!ReadStringArray(reader_, &album_info_->photo_ids)) | 110 if (!ReadStringArray(reader_, &album_info_->photo_ids)) |
| 113 return false; | 111 return false; |
| 114 } else if (!SkipToNext()) { | 112 } else if (!SkipToNext()) { |
| 115 return false; | 113 return false; |
| 116 } | 114 } |
| 117 return true; | 115 return true; |
| 118 } | 116 } |
| 119 | 117 |
| 120 virtual bool FinishedOk() override { | 118 bool FinishedOk() override { return !ShouldLoop(); } |
| 121 return !ShouldLoop(); | |
| 122 } | |
| 123 | 119 |
| 124 private: | 120 private: |
| 125 AlbumInfo* album_info_; | 121 AlbumInfo* album_info_; |
| 126 }; | 122 }; |
| 127 | 123 |
| 128 // Inside the master image list, we expect photos to be arranged as | 124 // Inside the master image list, we expect photos to be arranged as |
| 129 // <dict> | 125 // <dict> |
| 130 // <key>$PHOTO_ID</key> | 126 // <key>$PHOTO_ID</key> |
| 131 // <dict> | 127 // <dict> |
| 132 // $photo properties | 128 // $photo properties |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 } // namespace | 187 } // namespace |
| 192 | 188 |
| 193 IPhotoLibraryParser::IPhotoLibraryParser() {} | 189 IPhotoLibraryParser::IPhotoLibraryParser() {} |
| 194 IPhotoLibraryParser::~IPhotoLibraryParser() {} | 190 IPhotoLibraryParser::~IPhotoLibraryParser() {} |
| 195 | 191 |
| 196 class IPhotoLibraryXmlDictReader : public iapps::XmlDictReader { | 192 class IPhotoLibraryXmlDictReader : public iapps::XmlDictReader { |
| 197 public: | 193 public: |
| 198 IPhotoLibraryXmlDictReader(XmlReader* reader, parser::Library* library) | 194 IPhotoLibraryXmlDictReader(XmlReader* reader, parser::Library* library) |
| 199 : iapps::XmlDictReader(reader), library_(library), ok_(true) {} | 195 : iapps::XmlDictReader(reader), library_(library), ok_(true) {} |
| 200 | 196 |
| 201 virtual bool ShouldLoop() override { | 197 bool ShouldLoop() override { |
| 202 return !(Found("List of Albums") && Found("Master Image List")); | 198 return !(Found("List of Albums") && Found("Master Image List")); |
| 203 } | 199 } |
| 204 | 200 |
| 205 virtual bool HandleKeyImpl(const std::string& key) override { | 201 bool HandleKeyImpl(const std::string& key) override { |
| 206 if (key == "List of Albums") { | 202 if (key == "List of Albums") { |
| 207 if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array") || | 203 if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array") || |
| 208 !reader_->Read()) { | 204 !reader_->Read()) { |
| 209 return true; | 205 return true; |
| 210 } | 206 } |
| 211 while (iapps::SeekToNodeAtCurrentDepth(reader_, "dict")) { | 207 while (iapps::SeekToNodeAtCurrentDepth(reader_, "dict")) { |
| 212 AlbumInfo album_info; | 208 AlbumInfo album_info; |
| 213 AlbumXmlDictReader dict_reader(reader_, &album_info); | 209 AlbumXmlDictReader dict_reader(reader_, &album_info); |
| 214 if (dict_reader.Read()) { | 210 if (dict_reader.Read()) { |
| 215 parser::Album album; | 211 parser::Album album; |
| 216 album = album_info.photo_ids; | 212 album = album_info.photo_ids; |
| 217 // Strip / from album name and dedupe any collisions. | 213 // Strip / from album name and dedupe any collisions. |
| 218 std::string name; | 214 std::string name; |
| 219 base::ReplaceChars(album_info.name, "//", " ", &name); | 215 base::ReplaceChars(album_info.name, "//", " ", &name); |
| 220 if (ContainsKey(library_->albums, name)) | 216 if (ContainsKey(library_->albums, name)) |
| 221 name = name + "("+base::Uint64ToString(album_info.id)+")"; | 217 name = name + "("+base::Uint64ToString(album_info.id)+")"; |
| 222 library_->albums[name] = album; | 218 library_->albums[name] = album; |
| 223 } | 219 } |
| 224 } | 220 } |
| 225 } else if (key == "Master Image List") { | 221 } else if (key == "Master Image List") { |
| 226 if (!ParseAllPhotos(reader_, &library_->all_photos)) { | 222 if (!ParseAllPhotos(reader_, &library_->all_photos)) { |
| 227 ok_ = false; | 223 ok_ = false; |
| 228 return false; | 224 return false; |
| 229 } | 225 } |
| 230 } | 226 } |
| 231 return true; | 227 return true; |
| 232 } | 228 } |
| 233 | 229 |
| 234 virtual bool FinishedOk() override { | 230 bool FinishedOk() override { return ok_; } |
| 235 return ok_; | |
| 236 } | |
| 237 | 231 |
| 238 // The IPhotoLibrary allows duplicate "List of Albums" and | 232 // The IPhotoLibrary allows duplicate "List of Albums" and |
| 239 // "Master Image List" keys (although that seems odd.) | 233 // "Master Image List" keys (although that seems odd.) |
| 240 virtual bool AllowRepeats() override { | 234 bool AllowRepeats() override { return true; } |
| 241 return true; | |
| 242 } | |
| 243 | 235 |
| 244 private: | 236 private: |
| 245 parser::Library* library_; | 237 parser::Library* library_; |
| 246 | 238 |
| 247 // The base class bails when we request, and then calls |FinishedOk()| | 239 // The base class bails when we request, and then calls |FinishedOk()| |
| 248 // to decide what to return. We need to remember that we bailed because | 240 // to decide what to return. We need to remember that we bailed because |
| 249 // of an error. That's what |ok_| does. | 241 // of an error. That's what |ok_| does. |
| 250 bool ok_; | 242 bool ok_; |
| 251 }; | 243 }; |
| 252 | 244 |
| 253 bool IPhotoLibraryParser::Parse(const std::string& library_xml) { | 245 bool IPhotoLibraryParser::Parse(const std::string& library_xml) { |
| 254 XmlReader reader; | 246 XmlReader reader; |
| 255 if (!reader.Load(library_xml)) | 247 if (!reader.Load(library_xml)) |
| 256 return false; | 248 return false; |
| 257 | 249 |
| 258 // Find the plist node and then search within that tag. | 250 // Find the plist node and then search within that tag. |
| 259 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "plist")) | 251 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "plist")) |
| 260 return false; | 252 return false; |
| 261 if (!reader.Read()) | 253 if (!reader.Read()) |
| 262 return false; | 254 return false; |
| 263 | 255 |
| 264 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) | 256 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) |
| 265 return false; | 257 return false; |
| 266 | 258 |
| 267 IPhotoLibraryXmlDictReader dict_reader(&reader, &library_); | 259 IPhotoLibraryXmlDictReader dict_reader(&reader, &library_); |
| 268 return dict_reader.Read(); | 260 return dict_reader.Read(); |
| 269 } | 261 } |
| 270 | 262 |
| 271 } // namespace iphoto | 263 } // namespace iphoto |
| OLD | NEW |