| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/utility/media_galleries/picasa_album_table_reader.h" |
| |
| #include <algorithm> |
| #include <string> |
| |
| #include "base/path_service.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/common/media_galleries/pmp_constants.h" |
| #include "chrome/utility/media_galleries/pmp_column_reader.h" |
| |
| namespace picasa { |
| |
| namespace { |
| |
| // |variant_time| is specified as the number of days from Dec 30, 1899. |
| base::Time TimeFromMicrosoftVariantTime(double variant_time) { |
| base::TimeDelta variant_delta = base::TimeDelta::FromMicroseconds( |
| static_cast<int64>(variant_time * base::Time::kMicrosecondsPerDay)); |
| |
| return base::Time::FromLocalExploded(kPmpVariantTimeEpoch) + variant_delta; |
| } |
| |
| } // namespace |
| |
| PicasaAlbumTableReader::PicasaAlbumTableReader(AlbumTableFiles table_files) |
| : table_files_(table_files.Pass()), |
| initialized_(false) { |
| } |
| |
| PicasaAlbumTableReader::~PicasaAlbumTableReader() { |
| } |
| |
| const std::vector<AlbumInfo>& PicasaAlbumTableReader::folders() const { |
| DCHECK(initialized_); |
| return folders_; |
| } |
| |
| const std::vector<AlbumInfo>& PicasaAlbumTableReader::albums() const { |
| DCHECK(initialized_); |
| return albums_; |
| } |
| |
| bool PicasaAlbumTableReader::Init() { |
| if (initialized_) |
| return true; |
| |
| if (!table_files_.indicator_file.IsValid()) |
| return false; |
| |
| PmpColumnReader category_column, date_column, filename_column, name_column, |
| token_column, uid_column; |
| if (!category_column.ReadFile(&table_files_.category_file, PMP_TYPE_UINT32) || |
| !date_column.ReadFile(&table_files_.date_file, PMP_TYPE_DOUBLE64) || |
| !filename_column.ReadFile(&table_files_.filename_file, PMP_TYPE_STRING) || |
| !name_column.ReadFile(&table_files_.name_file, PMP_TYPE_STRING) || |
| !token_column.ReadFile(&table_files_.token_file, PMP_TYPE_STRING) || |
| !uid_column.ReadFile(&table_files_.uid_file, PMP_TYPE_STRING)) { |
| return false; |
| } |
| |
| // In the PMP format, columns can be different lengths. The number of rows |
| // in the table is max of all the columns, and short columns are NULL padded. |
| uint32 row_count = 0; |
| row_count = std::max(row_count, category_column.rows_read()); |
| row_count = std::max(row_count, date_column.rows_read()); |
| row_count = std::max(row_count, filename_column.rows_read()); |
| row_count = std::max(row_count, name_column.rows_read()); |
| row_count = std::max(row_count, token_column.rows_read()); |
| row_count = std::max(row_count, uid_column.rows_read()); |
| |
| for (uint32 i = 0; i < row_count; i++) { |
| uint32 category = kAlbumCategoryInvalid; |
| double date = 0; |
| std::string name; |
| std::string uid; |
| // PMP tables often contain 'garbage' rows of deleted or auto-generated |
| // album-like entities. We ignore those rows. |
| if (!category_column.ReadUInt32(i, &category) || |
| !date_column.ReadDouble64(i, &date) || |
| !name_column.ReadString(i, &name) || name.empty() || |
| !uid_column.ReadString(i, &uid) || uid.empty()) { |
| continue; |
| } |
| |
| base::Time timestamp = TimeFromMicrosoftVariantTime(date); |
| |
| if (category == kAlbumCategoryAlbum) { |
| std::string token; |
| if (!token_column.ReadString(i, &token) || token.empty() || |
| !StartsWithASCII(token, kAlbumTokenPrefix, false)) { |
| continue; |
| } |
| |
| albums_.push_back(AlbumInfo(name, timestamp, uid, base::FilePath())); |
| } else if (category == kAlbumCategoryFolder) { |
| std::string filename; |
| if (!filename_column.ReadString(i, &filename) || filename.empty()) |
| continue; |
| |
| base::FilePath path = |
| base::FilePath(base::FilePath::FromUTF8Unsafe(filename)); |
| |
| folders_.push_back(AlbumInfo(name, timestamp, uid, path)); |
| } |
| } |
| |
| initialized_ = true; |
| return true; |
| } |
| |
| } // namespace picasa |