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

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

Issue 12704024: Simple PMP reader to parse Picasa's metadata (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More formatting/ style changes. Created 7 years, 9 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/files/file_path.h"
10 #include "base/logging.h"
11 #include "webkit/fileapi/media/picasa/pmp_constants.h"
12
13 namespace fileapi {
14
15 PmpColumnReader::PmpColumnReader(std::string column_name)
16 : column_name_(column_name),
17 data_(NULL),
18 length_(0),
19 rows_(0),
20 strings_(),
21 fieldsize_(0) { }
22
23 PmpColumnReader::~PmpColumnReader() { }
24
25 bool PmpColumnReader::ReadFromMemory(uint32* rows_read, const uint8* data,
26 const size_t len) {
27 if(len < kPmpHeaderSize || data == NULL) {
vandebo (ex-Chrome) 2013/03/27 00:06:19 nit: omit {}'s here.
tommycli 2013/03/27 19:34:30 Done.
28 return false;
29 }
30
31 length_ = len;
32 data_.reset(new uint8[length_]);
33 std::copy(data, data + length_, data_.get());
34
35 return ParseData(rows_read);
36 }
37
38 bool PmpColumnReader::ReadString(const uint32 row, std::string* target) const {
vandebo (ex-Chrome) 2013/03/27 00:06:19 const std::string*
tommycli 2013/03/27 19:34:30 I use operator= on it.
39 DCHECK(data_.get() != NULL);
40 DCHECK(length_ > kPmpHeaderSize);
41
42 if(row < rows_) {
vandebo (ex-Chrome) 2013/03/27 00:06:19 Check the field type?
tommycli 2013/03/27 19:34:30 Done.
43 *target = strings_[row];
44 return true;
45 } else {
46 return false;
47 }
48 }
49
50 bool PmpColumnReader::ReadUInt32(const uint32 row, uint32* target) const {
51 return ReadPrimitive<uint32>(row, target);
52 }
53
54 bool PmpColumnReader::ReadDouble64(const uint32 row, double* target) const {
55 return ReadPrimitive<double>(row, target);
56 }
57
58 bool PmpColumnReader::ReadUInt8(const uint32 row, uint8* target) const {
59 return ReadPrimitive<uint8>(row, target);
60 }
61
62 bool PmpColumnReader::ReadUInt64(const uint32 row, uint64* target) const {
63 return ReadPrimitive<uint64>(row, target);
64 }
65
66 template<class T>
67 bool PmpColumnReader::ReadPrimitive(uint32 row, T* target) const {
68 DCHECK(data_.get() != NULL);
69 DCHECK(length_ > kPmpHeaderSize);
70
71 if(sizeof(T) != fieldsize_) {
72 return false;
73 }
74
75 if(row < rows_) {
76 *target = *(reinterpret_cast<T*>(
77 data_.get() + kPmpHeaderSize + row*fieldsize_));
78 return true;
79 } else {
80 return false;
81 }
82 }
83
84 bool PmpColumnReader::ParseData(uint32* rows_read) {
85 DCHECK(data_.get() != NULL);
86 DCHECK(length_ >= kPmpHeaderSize);
87
88 // Check all magic bytes.
89 if (memcmp(kPmpMagicO0S4, data_.get(), 4) != 0||
90 memcmp(kPmpMagicO6S2, data_.get() + 6, 2) != 0 ||
91 memcmp(kPmpMagicO8S4, data_.get() + 8, 4) != 0 ||
92 memcmp(kPmpMagicO14S2, data_.get() + 14, 2) != 0) {
93 return false;
94 }
95
96 // Verify row field type matches.
97 if (data_[kPmpFieldTypeFirstOffset] != data_[kPmpFieldTypeSecondOffset]) {
98 return false;
99 }
100
101 // Read the field type and number of rows expected.
102 uint16 field_type = data_[kPmpFieldTypeFirstOffset];
103 rows_ = *(reinterpret_cast<uint32*>(&data_[kPmpRowCountOffset]));
104
105 bool parse_success = false;
106
107 switch (field_type) {
108 case kPmpFieldTypeString:
109 parse_success = IndexStrings();
110 break;
111 case kPmpFieldTypeUInt32:
112 parse_success = SetAndValidateFieldsize<uint32>();
113 break;
114 case kPmpFieldTypeDouble64:
115 parse_success = SetAndValidateFieldsize<double>();
116 break;
117 case kPmpFieldTypeUInt8:
118 parse_success = SetAndValidateFieldsize<uint8>();
119 break;
120 case kPmpFieldTypeUInt64:
121 parse_success = SetAndValidateFieldsize<uint64>();
122 break;
123 default:
124 parse_success = false;
125 break;
126 }
127
128 if(parse_success) {
129 // Set the number of rows read. Though it's not valid unless we return true.
130 if(rows_read != NULL) {
131 *rows_read = rows_;
132 }
133 return true;
134 }
135
136 return false;
137 }
138
139 bool PmpColumnReader::IndexStrings() {
140 DCHECK(data_.get() != NULL);
141 DCHECK(length_ >= kPmpHeaderSize);
142
143 strings_.clear();
144 strings_.reserve(rows_);
145
146 size_t bytes_parsed = kPmpHeaderSize;
147 const uint8* itr = data_.get() + kPmpHeaderSize;
148
149 while (strings_.size() < rows_) {
150 const uint8* ptr_to_str_end = static_cast<const uint8*>(
151 memchr(itr, '\0', length_ - bytes_parsed));
152
153 // Fail if cannot find null termination. String runs on past file end.
154 if(ptr_to_str_end == NULL) return false;
155
156 // Length of string. (+1 to include the termination character).
157 ptrdiff_t len_bytes = ptr_to_str_end - itr + 1;
158
159 strings_.push_back(reinterpret_cast<const char*>(itr));
160 itr += len_bytes;
161 bytes_parsed += len_bytes;
162 }
163
164 // This means the file has more bytes at the end we haven't parsed.
165 if(bytes_parsed != length_) return false;
vandebo (ex-Chrome) 2013/03/27 00:06:19 return false on next line.
tommycli 2013/03/27 19:34:30 Done.
166
167 return true;
168 }
169
170 template<class T>
171 bool PmpColumnReader::SetAndValidateFieldsize() {
172 unsigned long calculated_n_rows = (length_ - kPmpHeaderSize) / sizeof(T);
173
174 if(calculated_n_rows == rows_) {
175 fieldsize_ = sizeof(T);
176 return true;
177 }
178
179 return false;
180 }
181
182 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698