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" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "chrome/utility/media_galleries/iapps_xml_utils.h" | 13 #include "chrome/utility/media_galleries/iapps_xml_utils.h" |
14 #include "third_party/libxml/chromium/libxml_utils.h" | 14 #include "third_party/libxml/chromium/libxml_utils.h" |
15 | 15 |
16 namespace iphoto { | 16 namespace iphoto { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 struct PhotoInfo { | 20 struct PhotoInfo { |
21 uint64 id; | 21 uint64 id; |
22 std::string guid; | |
23 base::FilePath location; | 22 base::FilePath location; |
24 std::string type; | 23 base::FilePath original_location; |
25 }; | 24 }; |
26 | 25 |
27 struct AlbumInfo { | 26 struct AlbumInfo { |
28 std::set<uint64> photo_ids; | 27 std::set<uint64> photo_ids; |
29 std::string name; | 28 std::string name; |
30 uint64 id; | 29 uint64 id; |
31 }; | 30 }; |
32 | 31 |
33 // Walk through a dictionary filling in |result| with photo information. Return | 32 // Walk through a dictionary filling in |result| with photo information. Return |
34 // true if at least the id and location were found. | 33 // true if at least the id and location were found. |
35 // In either case, the cursor is advanced out of the dictionary. | 34 // In either case, the cursor is advanced out of the dictionary. |
36 bool GetPhotoInfoFromDict(XmlReader* reader, PhotoInfo* result) { | 35 bool GetPhotoInfoFromDict(XmlReader* reader, PhotoInfo* result) { |
37 DCHECK(result); | 36 DCHECK(result); |
38 if (reader->NodeName() != "dict") | 37 if (reader->NodeName() != "dict") |
39 return false; | 38 return false; |
40 | 39 |
41 int dict_content_depth = reader->Depth() + 1; | 40 int dict_content_depth = reader->Depth() + 1; |
42 // Advance past the dict node and into the body of the dictionary. | 41 // Advance past the dict node and into the body of the dictionary. |
43 if (!reader->Read()) | 42 if (!reader->Read()) |
44 return false; | 43 return false; |
45 | 44 |
46 bool found_guid = false; | |
47 bool found_location = false; | 45 bool found_location = false; |
48 bool found_type = false; | 46 while (reader->Depth() >= dict_content_depth) { |
49 while (reader->Depth() >= dict_content_depth && | |
50 !(found_guid && found_location && found_type)) { | |
vandebo (ex-Chrome)
2013/11/01 18:50:33
If you like, add this logic back in - if both loca
| |
51 if (!iapps::SeekToNodeAtCurrentDepth(reader, "key")) | 47 if (!iapps::SeekToNodeAtCurrentDepth(reader, "key")) |
52 break; | 48 break; |
53 std::string found_key; | 49 std::string found_key; |
54 if (!reader->ReadElementContent(&found_key)) | 50 if (!reader->ReadElementContent(&found_key)) |
55 break; | 51 break; |
56 DCHECK_EQ(dict_content_depth, reader->Depth()); | 52 DCHECK_EQ(dict_content_depth, reader->Depth()); |
57 | 53 |
58 if (found_key == "GUID") { | 54 if (found_key == "ImagePath") { |
59 if (found_guid) | |
60 break; | |
61 if (!iapps::ReadString(reader, &result->guid)) | |
62 break; | |
63 found_guid = true; | |
64 } else if (found_key == "MediaType") { | |
65 if (found_type) | |
66 break; | |
67 if (!iapps::ReadString(reader, &result->type)) | |
68 break; | |
69 found_type = true; | |
70 } else if (found_key == "ImagePath") { | |
71 if (found_location) | 55 if (found_location) |
72 break; | 56 break; |
73 std::string value; | 57 std::string value; |
74 if (!iapps::ReadString(reader, &value)) | 58 if (!iapps::ReadString(reader, &value)) |
75 break; | 59 break; |
76 result->location = base::FilePath(value); | 60 result->location = base::FilePath(value); |
77 found_location = true; | 61 found_location = true; |
62 } else if (found_key == "OriginalPath") { | |
63 std::string value; | |
64 if (!iapps::ReadString(reader, &value)) | |
65 break; | |
66 result->original_location = base::FilePath(value); | |
78 } else { | 67 } else { |
79 if (!iapps::SkipToNextElement(reader)) | 68 if (!iapps::SkipToNextElement(reader)) |
80 break; | 69 break; |
81 if (!reader->Next()) | 70 if (!reader->Next()) |
82 break; | 71 break; |
83 } | 72 } |
84 } | 73 } |
85 | 74 |
86 // Seek to the end of the dictionary | 75 // Seek to the end of the dictionary |
87 while (reader->Depth() >= dict_content_depth) | 76 while (reader->Depth() >= dict_content_depth) |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 break; | 211 break; |
223 } | 212 } |
224 | 213 |
225 PhotoInfo photo_info; | 214 PhotoInfo photo_info; |
226 photo_info.id = id; | 215 photo_info.id = id; |
227 if (!GetPhotoInfoFromDict(reader, &photo_info)) { | 216 if (!GetPhotoInfoFromDict(reader, &photo_info)) { |
228 errors = true; | 217 errors = true; |
229 break; | 218 break; |
230 } | 219 } |
231 | 220 |
232 parser::Photo photo(photo_info.id, photo_info.location); | 221 parser::Photo photo(photo_info.id, photo_info.location, |
222 photo_info.original_location); | |
233 all_photos->insert(photo); | 223 all_photos->insert(photo); |
234 } | 224 } |
235 | 225 |
236 return !errors; | 226 return !errors; |
237 } | 227 } |
238 | 228 |
239 } // namespace | 229 } // namespace |
240 | 230 |
241 IPhotoLibraryParser::IPhotoLibraryParser() {} | 231 IPhotoLibraryParser::IPhotoLibraryParser() {} |
242 IPhotoLibraryParser::~IPhotoLibraryParser() {} | 232 IPhotoLibraryParser::~IPhotoLibraryParser() {} |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "array") || | 269 if (!iapps::SeekToNodeAtCurrentDepth(&reader, "array") || |
280 !reader.Read()) { | 270 !reader.Read()) { |
281 continue; | 271 continue; |
282 } | 272 } |
283 | 273 |
284 while (iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) { | 274 while (iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) { |
285 AlbumInfo album_info; | 275 AlbumInfo album_info; |
286 if (GetAlbumInfoFromDict(&reader, &album_info)) { | 276 if (GetAlbumInfoFromDict(&reader, &album_info)) { |
287 parser::Album album; | 277 parser::Album album; |
288 album = album_info.photo_ids; | 278 album = album_info.photo_ids; |
289 // Strip / from album name. | 279 // Strip / from album name and dedupe any collisions. |
290 std::string name; | 280 std::string name; |
291 ReplaceChars(album_info.name, "//", " ", &name); | 281 ReplaceChars(album_info.name, "//", " ", &name); |
292 library_.albums[name] = album; | 282 if (!ContainsKey(library_.albums, name)) { |
283 library_.albums[name] = album; | |
284 } else { | |
285 library_.albums[name+"("+base::Uint64ToString(album_info.id)+")"] = | |
286 album; | |
287 } | |
293 } | 288 } |
294 } | 289 } |
295 } else if (found_key == "Master Image List") { | 290 } else if (found_key == "Master Image List") { |
296 if (found_photos) | 291 if (found_photos) |
297 continue; | 292 continue; |
298 found_photos = true; | 293 found_photos = true; |
299 if (!ParseAllPhotos(&reader, &library_.all_photos)) | 294 if (!ParseAllPhotos(&reader, &library_.all_photos)) |
300 return false; | 295 return false; |
301 } | 296 } |
302 } | 297 } |
303 | 298 |
304 return true; | 299 return true; |
305 } | 300 } |
306 | 301 |
307 } // namespace iphoto | 302 } // namespace iphoto |
OLD | NEW |