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 |
- |
|