Patch #967 » 0004-iptc-convert-metadata-store-from-std-vector-to-std-m.patch
src/datasets.cpp | ||
---|---|---|
622 | 622 |
return *this; |
623 | 623 |
} |
624 | 624 | |
625 |
bool IptcKey::operator<(const IptcKey& b) const |
|
626 |
{ |
|
627 |
if (this->record() != b.record()) { |
|
628 |
return this->record() < b.record(); |
|
629 |
} |
|
630 | ||
631 |
return this->tag() < b.tag(); |
|
632 |
} |
|
633 | ||
625 | 634 |
std::string IptcKey::key() const |
626 | 635 |
{ |
627 | 636 |
return key_; |
src/datasets.hpp | ||
---|---|---|
308 | 308 |
@brief Assignment operator. |
309 | 309 |
*/ |
310 | 310 |
IptcKey& operator=(const IptcKey& rhs); |
311 |
/*! |
|
312 |
@brief Comparison operator. |
|
313 |
*/ |
|
314 |
bool operator<(const IptcKey& b) const; |
|
311 | 315 |
//@} |
312 | 316 | |
313 | 317 |
//! @name Accessors |
src/iptc.cpp | ||
---|---|---|
61 | 61 |
const Exiv2::byte* data, |
62 | 62 |
uint32_t sizeData |
63 | 63 |
); |
64 | ||
65 |
//! Unary predicate that matches an Iptcdatum with given record and dataset |
|
66 |
class FindIptcdatum { |
|
67 |
public: |
|
68 |
//! Constructor, initializes the object with the record and dataset id |
|
69 |
FindIptcdatum(uint16_t dataset, uint16_t record) |
|
70 |
: dataset_(dataset), record_(record) {} |
|
71 |
/*! |
|
72 |
@brief Returns true if the record and dataset id of the argument |
|
73 |
Iptcdatum is equal to that of the object. |
|
74 |
*/ |
|
75 |
bool operator()(const Exiv2::Iptcdatum& iptcdatum) const |
|
76 |
{ |
|
77 |
return dataset_ == iptcdatum.tag() && record_ == iptcdatum.record(); |
|
78 |
} |
|
79 | ||
80 |
private: |
|
81 |
// DATA |
|
82 |
uint16_t dataset_; |
|
83 |
uint16_t record_; |
|
84 | ||
85 |
}; // class FindIptcdatum |
|
86 | 64 |
} |
87 | 65 | |
88 | 66 |
// ***************************************************************************** |
... | ... | |
117 | 95 |
return os << value(); |
118 | 96 |
} |
119 | 97 | |
98 |
const IptcKey& Iptcdatum::iptcKey() const |
|
99 |
{ |
|
100 |
if (key_.get() == 0) throw Error(8); |
|
101 |
return *key_; |
|
102 |
} |
|
103 | ||
120 | 104 |
std::string Iptcdatum::key() const |
121 | 105 |
{ |
122 | 106 |
return key_.get() == 0 ? "" : key_->key(); |
... | ... | |
269 | 253 | |
270 | 254 |
Iptcdatum& IptcData::operator[](const std::string& key) |
271 | 255 |
{ |
272 |
IptcKey iptcKey(key); |
|
273 |
iterator pos = findKey(iptcKey); |
|
274 |
if (pos == end()) { |
|
275 |
add(Iptcdatum(iptcKey)); |
|
276 |
pos = findKey(iptcKey); |
|
256 |
IptcKey k = IptcKey(key); |
|
257 |
IptcMetadata::iterator it = iptcMetadata_.find(k); |
|
258 |
if (it != iptcMetadata_.end()) { |
|
259 |
return it->second; |
|
277 | 260 |
} |
278 |
return *pos; |
|
261 | ||
262 |
add(Iptcdatum(k)); |
|
263 |
return (*this)[key]; |
|
279 | 264 |
} |
280 | 265 | |
281 | 266 |
long IptcData::size() const |
... | ... | |
309 | 294 |
return 6; |
310 | 295 |
} |
311 | 296 |
// allow duplicates |
312 |
iptcMetadata_.push_back(iptcDatum);
|
|
297 |
iptcMetadata_.insert(std::make_pair(iptcDatum.iptcKey(), iptcDatum));
|
|
313 | 298 |
return 0; |
314 | 299 |
} |
315 | 300 | |
316 | 301 |
IptcData::const_iterator IptcData::findKey(const IptcKey& key) const |
317 | 302 |
{ |
318 |
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(), |
|
319 |
FindIptcdatum(key.tag(), key.record())); |
|
303 |
return iptcMetadata_.find(key); |
|
320 | 304 |
} |
321 | 305 | |
322 | 306 |
IptcData::iterator IptcData::findKey(const IptcKey& key) |
323 | 307 |
{ |
324 |
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(), |
|
325 |
FindIptcdatum(key.tag(), key.record())); |
|
308 |
return iptcMetadata_.find(key); |
|
326 | 309 |
} |
327 | 310 | |
328 | 311 |
IptcData::const_iterator IptcData::findId(uint16_t dataset, uint16_t record) const |
329 | 312 |
{ |
330 |
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
|
|
331 |
FindIptcdatum(dataset, record));
|
|
313 |
IptcKey key = IptcKey(dataset, record);
|
|
314 |
return findKey(key);
|
|
332 | 315 |
} |
333 | 316 | |
334 | 317 |
IptcData::iterator IptcData::findId(uint16_t dataset, uint16_t record) |
335 | 318 |
{ |
336 |
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
|
|
337 |
FindIptcdatum(dataset, record));
|
|
319 |
IptcKey key = IptcKey(dataset, record);
|
|
320 |
return findKey(key);
|
|
338 | 321 |
} |
339 | 322 | |
340 | 323 |
void IptcData::sortByKey() |
341 | 324 |
{ |
342 |
std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByKey);
|
|
325 |
// map is sorted by record, then tag
|
|
343 | 326 |
} |
344 | 327 | |
345 | 328 |
void IptcData::sortByTag() |
346 | 329 |
{ |
347 |
std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByTag);
|
|
330 |
// map is already sorted by record, then tag
|
|
348 | 331 |
} |
349 | 332 | |
350 | 333 |
IptcData::iterator IptcData::erase(IptcData::iterator pos) |
351 | 334 |
{ |
352 |
return iptcMetadata_.erase(pos); |
|
335 |
IptcData::iterator next = pos; |
|
336 |
next++; |
|
337 |
iptcMetadata_.erase(pos.it); |
|
338 |
return next; |
|
353 | 339 |
} |
354 | 340 | |
355 | 341 |
const char *IptcData::detectCharset() const |
... | ... | |
487 | 473 |
byte *pWrite = buf.pData_; |
488 | 474 | |
489 | 475 |
// Copy the iptc data sets and sort them by record but preserve the order of datasets |
490 |
IptcMetadata sortedIptcData;
|
|
476 |
std::vector<Iptcdatum> sortedIptcData;
|
|
491 | 477 |
std::copy(iptcData.begin(), iptcData.end(), std::back_inserter(sortedIptcData)); |
492 | 478 |
std::stable_sort(sortedIptcData.begin(), sortedIptcData.end(), cmpIptcdataByRecord); |
493 | 479 | |
494 |
IptcData::const_iterator iter = sortedIptcData.begin();
|
|
495 |
IptcData::const_iterator end = sortedIptcData.end();
|
|
480 |
std::vector<Iptcdatum>::const_iterator iter = sortedIptcData.begin();
|
|
481 |
std::vector<Iptcdatum>::const_iterator end = sortedIptcData.end();
|
|
496 | 482 |
for ( ; iter != end; ++iter) { |
497 | 483 |
// marker, record Id, dataset num |
498 | 484 |
*pWrite++ = marker_; |
src/iptc.hpp | ||
---|---|---|
122 | 122 |
multiple metadata with the same key. |
123 | 123 |
*/ |
124 | 124 |
std::string key() const; |
125 |
const IptcKey& iptcKey() const; |
|
125 | 126 |
/*! |
126 | 127 |
@brief Return the name of the record (deprecated) |
127 | 128 |
@return record name |
... | ... | |
164 | 165 |
}; // class Iptcdatum |
165 | 166 | |
166 | 167 |
//! Container type to hold all metadata |
167 |
typedef std::vector<Iptcdatum> IptcMetadata;
|
|
168 |
typedef std::multimap<IptcKey, Iptcdatum> IptcMetadata;
|
|
168 | 169 | |
169 | 170 |
/*! |
170 | 171 |
@brief A container for IPTC data. This is a top-level class of |
... | ... | |
180 | 181 |
class EXIV2API IptcData { |
181 | 182 |
public: |
182 | 183 |
//! IptcMetadata iterator type |
183 |
typedef IptcMetadata::iterator iterator;
|
|
184 |
typedef map_value_iterator<IptcMetadata, IptcMetadata::iterator> iterator;
|
|
184 | 185 |
//! IptcMetadata const iterator type |
185 |
typedef IptcMetadata::const_iterator const_iterator;
|
|
186 |
typedef map_value_iterator<IptcMetadata, IptcMetadata::const_iterator, const typename IptcMetadata::const_iterator::value_type::second_type> const_iterator;
|
|
186 | 187 | |
187 | 188 |
// Use the compiler generated constructors and assignment operator |
188 | 189 | |
... | ... | |
223 | 224 |
@brief Delete all Iptcdatum instances resulting in an empty container. |
224 | 225 |
*/ |
225 | 226 |
void clear() { iptcMetadata_.clear(); } |
226 |
//! Sort metadata by key |
|
227 |
/*! |
|
228 |
@deprecated Iptc metadata is always kept sorted by record, then tag. |
|
229 |
This method is a no-op. |
|
230 |
*/ |
|
227 | 231 |
void sortByKey(); |
228 |
//! Sort metadata by tag (aka dataset) |
|
232 |
/*! |
|
233 |
@deprecated Iptc metadata is always kept sorted by record, then tag. |
|
234 |
This method is a no-op. |
|
235 |
*/ |
|
229 | 236 |
void sortByTag(); |
230 | 237 |
//! Begin of the metadata |
231 | 238 |
iterator begin() { return iptcMetadata_.begin(); } |
232 |
- |