ccd61128e928729f1410466dcb6f8bd5fe99cd12
[platform/framework/web/crosswalk.git] / src / chrome / utility / media_galleries / picasa_album_table_reader.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/utility/media_galleries/picasa_album_table_reader.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/path_service.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/common/media_galleries/pmp_constants.h"
14 #include "chrome/utility/media_galleries/pmp_column_reader.h"
15
16 namespace picasa {
17
18 namespace {
19
20 // |variant_time| is specified as the number of days from Dec 30, 1899.
21 base::Time TimeFromMicrosoftVariantTime(double variant_time) {
22   base::TimeDelta variant_delta = base::TimeDelta::FromMicroseconds(
23       static_cast<int64>(variant_time * base::Time::kMicrosecondsPerDay));
24
25   return base::Time::FromLocalExploded(kPmpVariantTimeEpoch) + variant_delta;
26 }
27
28 }  // namespace
29
30 PicasaAlbumTableReader::PicasaAlbumTableReader(
31     const AlbumTableFiles& table_files)
32     : table_files_(table_files),
33       initialized_(false) {
34 }
35
36 PicasaAlbumTableReader::~PicasaAlbumTableReader() {
37   CloseAlbumTableFiles(&table_files_);
38 }
39
40 const std::vector<AlbumInfo>& PicasaAlbumTableReader::folders() const {
41   DCHECK(initialized_);
42   return folders_;
43 }
44
45 const std::vector<AlbumInfo>& PicasaAlbumTableReader::albums() const {
46   DCHECK(initialized_);
47   return albums_;
48 }
49
50 bool PicasaAlbumTableReader::Init() {
51   if (initialized_)
52     return true;
53
54   if (table_files_.indicator_file == base::kInvalidPlatformFileValue)
55     return false;
56
57   PmpColumnReader category_column, date_column, filename_column, name_column,
58                   token_column, uid_column;
59   if (!category_column.ReadFile(table_files_.category_file, PMP_TYPE_UINT32) ||
60       !date_column.ReadFile(table_files_.date_file, PMP_TYPE_DOUBLE64) ||
61       !filename_column.ReadFile(table_files_.filename_file, PMP_TYPE_STRING) ||
62       !name_column.ReadFile(table_files_.name_file, PMP_TYPE_STRING) ||
63       !token_column.ReadFile(table_files_.token_file, PMP_TYPE_STRING) ||
64       !uid_column.ReadFile(table_files_.uid_file, PMP_TYPE_STRING)) {
65     return false;
66   }
67
68   // In the PMP format, columns can be different lengths. The number of rows
69   // in the table is max of all the columns, and short columns are NULL padded.
70   uint32 row_count = 0;
71   row_count = std::max(row_count, category_column.rows_read());
72   row_count = std::max(row_count, date_column.rows_read());
73   row_count = std::max(row_count, filename_column.rows_read());
74   row_count = std::max(row_count, name_column.rows_read());
75   row_count = std::max(row_count, token_column.rows_read());
76   row_count = std::max(row_count, uid_column.rows_read());
77
78   for (uint32 i = 0; i < row_count; i++) {
79     uint32 category = kAlbumCategoryInvalid;
80     double date = 0;
81     std::string name;
82     std::string uid;
83     // PMP tables often contain 'garbage' rows of deleted or auto-generated
84     // album-like entities. We ignore those rows.
85     if (!category_column.ReadUInt32(i, &category) ||
86         !date_column.ReadDouble64(i, &date) ||
87         !name_column.ReadString(i, &name) || name.empty() ||
88         !uid_column.ReadString(i, &uid) || uid.empty()) {
89       continue;
90     }
91
92     base::Time timestamp = TimeFromMicrosoftVariantTime(date);
93
94     if (category == kAlbumCategoryAlbum) {
95       std::string token;
96       if (!token_column.ReadString(i, &token) || token.empty() ||
97           !StartsWithASCII(token, kAlbumTokenPrefix, false)) {
98         continue;
99       }
100
101       albums_.push_back(AlbumInfo(name, timestamp, uid, base::FilePath()));
102     } else if (category == kAlbumCategoryFolder) {
103       std::string filename;
104       if (!filename_column.ReadString(i, &filename) || filename.empty())
105         continue;
106
107       base::FilePath path =
108           base::FilePath(base::FilePath::FromUTF8Unsafe(filename));
109
110       folders_.push_back(AlbumInfo(name, timestamp, uid, path));
111     }
112   }
113
114   initialized_ = true;
115   return true;
116 }
117
118 }  // namespace picasa