Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6077)

Unified Diff: chrome/utility/media_galleries/iphoto_library_parser.cc

Issue 436293002: Created helper class for parsing Apple style XML dictionaries. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Converted IPhotoLibraryParser Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698