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

Side by Side Diff: webkit/fileapi/media/picasa/pmp_column_reader.cc

Issue 14247034: Move Media Galleries FileAPI code out of webkit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cr-14352004
Patch Set: Add android ifdef. Created 7 years, 8 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 unified diff | Download patch
OLDNEW
(Empty)
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 "webkit/fileapi/media/picasa/pmp_column_reader.h"
6
7 #include <cstring>
8
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/threading/thread_restrictions.h"
13
14 namespace picasaimport {
15
16 namespace {
17
18 const size_t kPmpMaxFilesize = 50*1024*1024; // Maximum of 50 MB.
19
20 } // namespace
21
22 PmpColumnReader::PmpColumnReader()
23 : length_(0),
24 field_type_(PMP_TYPE_INVALID),
25 rows_(0) { }
26
27 PmpColumnReader::~PmpColumnReader() { }
28
29 bool PmpColumnReader::Init(const base::FilePath& filepath, uint32* rows_read) {
30 DCHECK(!data_.get());
31 base::ThreadRestrictions::AssertIOAllowed();
32
33 int64 length = 0; // Signed temporary.
34 if (!file_util::GetFileSize(filepath, &length))
35 return false;
36
37 length_ = length;
38
39 if (length_ < kPmpHeaderSize || length_ > kPmpMaxFilesize)
40 return false;
41
42 data_.reset(new uint8[length_]);
43
44 char* data_begin = reinterpret_cast<char*>(data_.get());
45
46 return file_util::ReadFile(filepath, data_begin, length_) &&
47 ParseData(rows_read);
48 }
49
50 bool PmpColumnReader::ReadString(const uint32 row, std::string* result) const {
51 DCHECK(data_.get() != NULL);
52 DCHECK_GT(length_, kPmpHeaderSize + row);
53
54 if (field_type_ != PMP_TYPE_STRING || row >= rows_)
55 return false;
56
57 *result = strings_[row];
58 return true;
59 }
60
61 bool PmpColumnReader::ReadUInt32(const uint32 row, uint32* result) const {
62 DCHECK(data_.get() != NULL);
63 DCHECK_GT(length_, kPmpHeaderSize + row * sizeof(uint32));
64
65 if (field_type_ != PMP_TYPE_UINT32 || row >= rows_)
66 return false;
67
68 *result = reinterpret_cast<uint32*>(data_.get() + kPmpHeaderSize)[row];
69 return true;
70 }
71
72 bool PmpColumnReader::ReadDouble64(const uint32 row, double* result) const {
73 DCHECK(data_.get() != NULL);
74 DCHECK_GT(length_, kPmpHeaderSize + row * sizeof(double));
75
76 if (field_type_ != PMP_TYPE_DOUBLE64 || row >= rows_)
77 return false;
78
79 *result = reinterpret_cast<double*>(data_.get() + kPmpHeaderSize)[row];
80 return true;
81 }
82
83 bool PmpColumnReader::ReadUInt8(const uint32 row, uint8* result) const {
84 DCHECK(data_.get() != NULL);
85 DCHECK_GT(length_, kPmpHeaderSize + row * sizeof(uint8));
86
87 if (field_type_ != PMP_TYPE_UINT8 || row >= rows_)
88 return false;
89
90 *result = reinterpret_cast<uint8*>(data_.get() + kPmpHeaderSize)[row];
91 return true;
92 }
93
94 bool PmpColumnReader::ReadUInt64(const uint32 row, uint64* result) const {
95 DCHECK(data_.get() != NULL);
96 DCHECK_GT(length_, kPmpHeaderSize + row * sizeof(uint64));
97
98 if (field_type_ != PMP_TYPE_UINT64 || row >= rows_)
99 return false;
100
101 *result = reinterpret_cast<uint64*>(data_.get() + kPmpHeaderSize)[row];
102 return true;
103 }
104
105 bool PmpColumnReader::ParseData(uint32* rows_read) {
106 DCHECK(data_.get() != NULL);
107 DCHECK_GE(length_, kPmpHeaderSize);
108
109 // Check all magic bytes.
110 if (memcmp(&kPmpMagic1, &data_[kPmpMagic1Offset], sizeof(kPmpMagic1)) != 0 ||
111 memcmp(&kPmpMagic2, &data_[kPmpMagic2Offset], sizeof(kPmpMagic2)) != 0 ||
112 memcmp(&kPmpMagic3, &data_[kPmpMagic3Offset], sizeof(kPmpMagic3)) != 0 ||
113 memcmp(&kPmpMagic4, &data_[kPmpMagic4Offset], sizeof(kPmpMagic4)) != 0) {
114 return false;
115 }
116
117 uint16 field_type_data =
118 *(reinterpret_cast<uint16*>(&data_[kPmpFieldType1Offset]));
119
120 // Verify if field type matches second declaration
121 if (field_type_data !=
122 *(reinterpret_cast<uint16*>(&data_[kPmpFieldType2Offset]))) {
123 return false;
124 }
125
126 field_type_ = static_cast<PmpFieldType>(field_type_data);
127
128 rows_ = *(reinterpret_cast<uint32*>(&data_[kPmpRowCountOffset]));
129
130 size_t body_length = length_ - kPmpHeaderSize;
131 size_t expected_body_length = 0;
132 switch (field_type_) {
133 case PMP_TYPE_STRING:
134 expected_body_length = IndexStrings();
135 break;
136 case PMP_TYPE_UINT32:
137 expected_body_length = rows_ * sizeof(uint32);
138 break;
139 case PMP_TYPE_DOUBLE64:
140 expected_body_length = rows_ * sizeof(double);
141 break;
142 case PMP_TYPE_UINT8:
143 expected_body_length = rows_ * sizeof(uint8);
144 break;
145 case PMP_TYPE_UINT64:
146 expected_body_length = rows_ * sizeof(uint64);
147 break;
148 default:
149 return false;
150 break;
151 }
152
153 if (body_length == expected_body_length && rows_read)
154 *rows_read = rows_;
155 return body_length == expected_body_length;
156 }
157
158 long PmpColumnReader::IndexStrings() {
159 DCHECK(data_.get() != NULL);
160 DCHECK_GE(length_, kPmpHeaderSize);
161
162 strings_.reserve(rows_);
163
164 size_t bytes_parsed = kPmpHeaderSize;
165 const uint8* data_cursor = data_.get() + kPmpHeaderSize;
166
167 while (strings_.size() < rows_) {
168 const uint8* string_end = static_cast<const uint8*>(
169 memchr(data_cursor, '\0', length_ - bytes_parsed));
170
171 // Fail if cannot find null termination. String runs on past file end.
172 if (string_end == NULL)
173 return -1;
174
175 // Length of string. (+1 to include the termination character).
176 ptrdiff_t length_in_bytes = string_end - data_cursor + 1;
177
178 strings_.push_back(reinterpret_cast<const char*>(data_cursor));
179 data_cursor += length_in_bytes;
180 bytes_parsed += length_in_bytes;
181 }
182
183 return bytes_parsed - kPmpHeaderSize;
184 }
185
186 } // namespace picasaimport
OLDNEW
« no previous file with comments | « webkit/fileapi/media/picasa/pmp_column_reader.h ('k') | webkit/fileapi/media/picasa/pmp_column_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698