Project

General

Profile

Patch #967 » 0004-iptc-convert-metadata-store-from-std-vector-to-std-m.patch

Michael Pratt, 05 Jul 2014 19:14

View differences:

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
- 
(6-6/7)