Index: chrome/utility/media_galleries/iphoto_library_parser.cc |
diff --git a/chrome/utility/media_galleries/iphoto_library_parser.cc b/chrome/utility/media_galleries/iphoto_library_parser.cc |
index cd52a6b647765eeae60c47af4600d830c25ba357..c8b74d88b2ecd38e80ab0729e704585858eeecb8 100644 |
--- a/chrome/utility/media_galleries/iphoto_library_parser.cc |
+++ b/chrome/utility/media_galleries/iphoto_library_parser.cc |
@@ -29,55 +29,35 @@ struct AlbumInfo { |
uint64 id; |
}; |
-// Walk through a dictionary filling in |result| with photo information. Return |
-// true if at least the id and location were found. |
-// In either case, the cursor is advanced out of the dictionary. |
-bool GetPhotoInfoFromDict(XmlReader* reader, PhotoInfo* result) { |
- DCHECK(result); |
- if (reader->NodeName() != "dict") |
- return false; |
+class PhotosXmlDictReader : public iapps::XmlDictReader { |
+ public: |
+ PhotosXmlDictReader(XmlReader* reader, PhotoInfo* photo_info) |
+ : iapps::XmlDictReader(reader), photo_info_(photo_info) {} |
- int dict_content_depth = reader->Depth() + 1; |
- // Advance past the dict node and into the body of the dictionary. |
- if (!reader->Read()) |
- return false; |
- |
- bool found_location = false; |
- while (reader->Depth() >= dict_content_depth) { |
- if (!iapps::SeekToNodeAtCurrentDepth(reader, "key")) |
- break; |
- std::string found_key; |
- if (!reader->ReadElementContent(&found_key)) |
- break; |
- DCHECK_EQ(dict_content_depth, reader->Depth()); |
- |
- if (found_key == "ImagePath") { |
- if (found_location) |
- break; |
+ virtual bool HandleKeyImpl(const std::string& key) OVERRIDE { |
+ if (key == "ImagePath") { |
std::string value; |
- if (!iapps::ReadString(reader, &value)) |
- break; |
- result->location = base::FilePath(value); |
- found_location = true; |
- } else if (found_key == "OriginalPath") { |
+ if (!iapps::ReadString(reader_, &value)) |
+ return false; |
+ photo_info_->location = base::FilePath(value); |
+ } else if (key == "OriginalPath") { |
std::string value; |
- if (!iapps::ReadString(reader, &value)) |
- break; |
- result->original_location = base::FilePath(value); |
- } else { |
- if (!iapps::SkipToNextElement(reader)) |
- break; |
- if (!reader->Next()) |
- break; |
+ if (!iapps::ReadString(reader_, &value)) |
+ return false; |
+ photo_info_->original_location = base::FilePath(value); |
+ } else if (!SkipToNext()) { |
+ return false; |
} |
+ return true; |
} |
- // Seek to the end of the dictionary |
- while (reader->Depth() >= dict_content_depth) |
- reader->Next(); |
+ virtual bool FinishedOk() OVERRIDE { |
+ return Found("ImagePath"); |
+ } |
- return found_location; |
-} |
+ private: |
+ PhotoInfo* photo_info_; |
+}; |
// Contents of the album 'KeyList' key are |
// <array> |
@@ -110,62 +90,40 @@ bool ReadStringArray(XmlReader* reader, std::set<uint64>* photo_ids) { |
return true; |
} |
-bool GetAlbumInfoFromDict(XmlReader* reader, AlbumInfo* result) { |
- DCHECK(result); |
- if (reader->NodeName() != "dict") |
- return false; |
+class AlbumXmlDictReader : public iapps::XmlDictReader { |
+ public: |
+ AlbumXmlDictReader(XmlReader* reader, AlbumInfo* album_info) |
+ : iapps::XmlDictReader(reader), album_info_(album_info) {} |
- int dict_content_depth = reader->Depth() + 1; |
- // Advance past the dict node and into the body of the dictionary. |
- if (!reader->Read()) |
- return false; |
+ virtual bool ShouldLoop() OVERRIDE { |
+ return !(Found("AlbumId") && Found("AlbumName") && Found("KeyList")); |
+ } |
- bool found_id = false; |
- bool found_name = false; |
- bool found_contents = false; |
- while (reader->Depth() >= dict_content_depth && |
- !(found_id && found_name && found_contents)) { |
- if (!iapps::SeekToNodeAtCurrentDepth(reader, "key")) |
- break; |
- std::string found_key; |
- if (!reader->ReadElementContent(&found_key)) |
- break; |
- DCHECK_EQ(dict_content_depth, reader->Depth()); |
- |
- if (found_key == "AlbumId") { |
- if (found_id) |
- break; |
- if (!iapps::ReadInteger(reader, &result->id)) |
- break; |
- found_id = true; |
- } else if (found_key == "AlbumName") { |
- if (found_name) |
- break; |
- if (!iapps::ReadString(reader, &result->name)) |
- break; |
- found_name = true; |
- } else if (found_key == "KeyList") { |
- if (found_contents) |
- break; |
- if (!iapps::SeekToNodeAtCurrentDepth(reader, "array")) |
- break; |
- if (!ReadStringArray(reader, &result->photo_ids)) |
- break; |
- found_contents = true; |
- } else { |
- if (!iapps::SkipToNextElement(reader)) |
- break; |
- if (!reader->Next()) |
- break; |
+ virtual bool HandleKeyImpl(const std::string& key) OVERRIDE { |
+ if (key == "AlbumId") { |
+ if (!iapps::ReadInteger(reader_, &album_info_->id)) |
+ return false; |
+ } else if (key == "AlbumName") { |
+ if (!iapps::ReadString(reader_, &album_info_->name)) |
+ return false; |
+ } else if (key == "KeyList") { |
+ if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array")) |
+ return false; |
+ if (!ReadStringArray(reader_, &album_info_->photo_ids)) |
+ return false; |
+ } else if (!SkipToNext()) { |
+ return false; |
} |
+ return true; |
} |
- // Seek to the end of the dictionary |
- while (reader->Depth() >= dict_content_depth) |
- reader->Next(); |
+ virtual bool FinishedOk() OVERRIDE { |
+ return !ShouldLoop(); |
+ } |
- return found_id && found_name && found_contents; |
-} |
+ private: |
+ AlbumInfo* album_info_; |
+}; |
// Inside the master image list, we expect photos to be arranged as |
// <dict> |
@@ -213,7 +171,11 @@ bool ParseAllPhotos(XmlReader* reader, |
PhotoInfo photo_info; |
photo_info.id = id; |
- if (!GetPhotoInfoFromDict(reader, &photo_info)) { |
+ // Walk through a dictionary filling in |result| with photo information. |
+ // Return true if at least the location was found. |
+ // In either case, the cursor is advanced out of the dictionary. |
+ PhotosXmlDictReader dict_reader(reader, &photo_info); |
+ if (!dict_reader.Read()) { |
errors = true; |
break; |
} |
@@ -231,72 +193,82 @@ bool ParseAllPhotos(XmlReader* reader, |
IPhotoLibraryParser::IPhotoLibraryParser() {} |
IPhotoLibraryParser::~IPhotoLibraryParser() {} |
-bool IPhotoLibraryParser::Parse(const std::string& library_xml) { |
- XmlReader reader; |
- if (!reader.Load(library_xml)) |
- return false; |
+class IPhotoLibraryXmlDictReader : public iapps::XmlDictReader { |
+ public: |
+ IPhotoLibraryXmlDictReader(XmlReader* reader, parser::Library* library) |
+ : iapps::XmlDictReader(reader), library_(library), ok_(true) {} |
- // Find the plist node and then search within that tag. |
- if (!iapps::SeekToNodeAtCurrentDepth(&reader, "plist")) |
- return false; |
- if (!reader.Read()) |
- return false; |
- |
- if (!iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) |
- return false; |
- |
- int dict_content_depth = reader.Depth() + 1; |
- // Advance past the dict node and into the body of the dictionary. |
- if (!reader.Read()) |
- return false; |
- |
- bool found_photos = false; |
- bool found_albums = false; |
- while (reader.Depth() >= dict_content_depth && |
- !(found_photos && found_albums)) { |
- if (!iapps::SeekToNodeAtCurrentDepth(&reader, "key")) |
- break; |
- std::string found_key; |
- if (!reader.ReadElementContent(&found_key)) |
- break; |
- DCHECK_EQ(dict_content_depth, reader.Depth()); |
+ virtual bool ShouldLoop() OVERRIDE { |
+ return !(Found("List of Albums") && Found("Master Image List")); |
+ } |
- if (found_key == "List of Albums") { |
- if (found_albums) |
- continue; |
- found_albums = true; |
+ virtual bool HandleKeyImpl(const std::string& key) OVERRIDE { |
+ if (key == "List of Albums") { |
Lei Zhang
2014/08/05 19:38:24
nit: no empty lines at the beginning of a block.
Kevin Bailey
2014/08/05 21:52:06
Done.
|
- if (!iapps::SeekToNodeAtCurrentDepth(&reader, "array") || |
- !reader.Read()) { |
- continue; |
+ if (!iapps::SeekToNodeAtCurrentDepth(reader_, "array") || |
+ !reader_->Read()) { |
+ return true; |
} |
- |
- while (iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) { |
+ while (iapps::SeekToNodeAtCurrentDepth(reader_, "dict")) { |
AlbumInfo album_info; |
- if (GetAlbumInfoFromDict(&reader, &album_info)) { |
+ AlbumXmlDictReader dict_reader(reader_, &album_info); |
+ if (dict_reader.Read()) { |
parser::Album album; |
album = album_info.photo_ids; |
// Strip / from album name and dedupe any collisions. |
std::string name; |
base::ReplaceChars(album_info.name, "//", " ", &name); |
- if (!ContainsKey(library_.albums, name)) { |
- library_.albums[name] = album; |
+ if (!ContainsKey(library_->albums, name)) { |
Lei Zhang
2014/08/05 19:38:24
This block can be shortened to:
if (ContainsKey(l
Kevin Bailey
2014/08/05 21:52:05
Done.
|
+ library_->albums[name] = album; |
} else { |
- library_.albums[name+"("+base::Uint64ToString(album_info.id)+")"] = |
+ library_->albums[name+"("+base::Uint64ToString(album_info.id)+")"] = |
album; |
} |
} |
} |
- } else if (found_key == "Master Image List") { |
- if (found_photos) |
- continue; |
- found_photos = true; |
- if (!ParseAllPhotos(&reader, &library_.all_photos)) |
+ } else if (key == "Master Image List") { |
+ if (!ParseAllPhotos(reader_, &library_->all_photos)) { |
+ ok_ = false; |
return false; |
+ } |
} |
+ return true; |
} |
- return true; |
+ virtual bool FinishedOk() OVERRIDE { |
+ return ok_; |
+ } |
+ |
+ // The IPhotoLibrary allows duplicate "List of Albums" and |
+ // "Master Image List" keys (although that seems odd.) |
+ virtual bool AllowRepeats() OVERRIDE { |
+ return true; |
+ } |
+ |
+ private: |
+ parser::Library* library_; |
Lei Zhang
2014/08/05 19:38:24
nit: blank line after
Kevin Bailey
2014/08/05 21:52:06
Done.
|
+ // The base class bails when we request, and then calls |FinishedOk()| |
+ // to decide what to return. We need to remember that we bailed because |
+ // of an error. That's what |ok_| does. |
+ bool ok_; |
+}; |
+ |
+bool IPhotoLibraryParser::Parse(const std::string& library_xml) { |
+ XmlReader reader; |
+ if (!reader.Load(library_xml)) |
+ return false; |
+ |
+ // Find the plist node and then search within that tag. |
+ if (!iapps::SeekToNodeAtCurrentDepth(&reader, "plist")) |
+ return false; |
+ if (!reader.Read()) |
+ return false; |
+ |
+ if (!iapps::SeekToNodeAtCurrentDepth(&reader, "dict")) |
+ return false; |
+ |
+ IPhotoLibraryXmlDictReader dict_reader(&reader, &library_); |
+ return dict_reader.Read(); |
} |
} // namespace iphoto |