~noskcaj/ubuntu/trusty/libextractor/merge

« back to all changes in this revision

Viewing changes to src/plugins/exiv2/datasets.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-17 20:27:32 UTC
  • mfrom: (1.10.4 upstream) (5.2.5 sid)
  • Revision ID: james.westby@ubuntu.com-20091117202732-ipm2h3gks5bdw2vx
Tags: 0.5.23+dfsg-3
* Building against libltdl7.
* Updating to standards version 3.8.3.
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Simplifying autotools handling in rules.
* Updating README.source.
* Moving maintainer homepage field from control to copyright.
* Dropping la files.
* Simplyfing debhelper install files.
* Bumping versioned build-depends on debhelper.
* Adding depends to dpkg install info.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ***************************************************************** -*- C++ -*-
2
 
/*
3
 
 * Copyright (C) 2004, 2005 Andreas Huggel <ahuggel@gmx.net>
4
 
 *
5
 
 * This program is part of the Exiv2 distribution.
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU General Public License
9
 
 * as published by the Free Software Foundation; either version 2
10
 
 * of the License, or (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
 
 */
21
 
/*
22
 
  File:      datasets.cpp
23
 
  Version:   $Rev: 560 $
24
 
  Author(s): Brad Schick (brad) <brad@robotbattle.com>
25
 
  History:   24-Jul-04, brad: created
26
 
 */
27
 
// *****************************************************************************
28
 
#include "rcsid.hpp"
29
 
EXIV2_RCSID("@(#) $Id: datasets.cpp 560 2005-04-17 11:51:32Z ahuggel $");
30
 
 
31
 
// *****************************************************************************
32
 
// included header files
33
 
#include "datasets.hpp"
34
 
#include "error.hpp"
35
 
#include "types.hpp"
36
 
#include "value.hpp"
37
 
#include "metadatum.hpp"
38
 
 
39
 
#include <iostream>
40
 
#include <iomanip>
41
 
#include <sstream>
42
 
 
43
 
// *****************************************************************************
44
 
// class member definitions
45
 
namespace Exiv2 {
46
 
 
47
 
    DataSet::DataSet(
48
 
        uint16_t number,
49
 
        const char* name,
50
 
        const char* desc,
51
 
        bool mandatory,
52
 
        bool repeatable,
53
 
        uint32_t minbytes,
54
 
        uint32_t maxbytes,
55
 
        TypeId type,
56
 
        uint16_t recordId,
57
 
        const char* photoshop
58
 
    )
59
 
        : number_(number), name_(name), desc_(desc), mandatory_(mandatory),
60
 
           repeatable_(repeatable), minbytes_(minbytes), maxbytes_(maxbytes),
61
 
           type_(type), recordId_(recordId), photoshop_(photoshop)
62
 
    {
63
 
    }
64
 
 
65
 
    RecordInfo::RecordInfo(
66
 
        uint16_t recordId,
67
 
        const char* name,
68
 
        const char* desc
69
 
    )
70
 
        : recordId_(recordId), name_(name), desc_(desc)
71
 
    {
72
 
    }
73
 
 
74
 
    const RecordInfo IptcDataSets::recordInfo_[] = {
75
 
        RecordInfo(IptcDataSets::invalidRecord, "(invalid)", "(invalid)"),
76
 
        RecordInfo(IptcDataSets::envelope, "Envelope", "IIM envelope record"),
77
 
        RecordInfo(IptcDataSets::application2, "Application2", "IIM application record 2"),
78
 
    };
79
 
 
80
 
    static const DataSet envelopeRecord[] = {
81
 
        DataSet(IptcDataSets::ModelVersion, "ModelVersion", "Version of IIM part 1", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
82
 
        DataSet(IptcDataSets::Destination, "Destination", "Routing information", false, true, 0, 1024, Exiv2::string, IptcDataSets::envelope, ""),
83
 
        DataSet(IptcDataSets::FileFormat, "FileFormat", "IIM appendix A file format", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
84
 
        DataSet(IptcDataSets::FileVersion, "FileVersion", "File format version", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
85
 
        DataSet(IptcDataSets::ServiceId, "ServiceId", "Identifies the provider and product", true, false, 0, 10, Exiv2::string, IptcDataSets::envelope, ""),
86
 
        DataSet(IptcDataSets::EnvelopeNumber, "EnvelopeNumber", "Combined unique identification", true, false, 8, 8, Exiv2::string, IptcDataSets::envelope, ""),
87
 
        DataSet(IptcDataSets::ProductId, "ProductId", "Identifies service subset", false, true, 0, 32, Exiv2::string, IptcDataSets::envelope, ""),
88
 
        DataSet(IptcDataSets::EnvelopePriority, "EnvelopePriority", "Envelope handling priority", false, false, 1, 1, Exiv2::string, IptcDataSets::envelope, ""),
89
 
        DataSet(IptcDataSets::DateSent, "DateSent", "Date material was sent", true, false, 8, 8, Exiv2::date, IptcDataSets::envelope, ""),
90
 
        DataSet(IptcDataSets::TimeSent, "TimeSent", "Time material was sent", false, false, 11, 11, Exiv2::time, IptcDataSets::envelope, ""),
91
 
        DataSet(IptcDataSets::CharacterSet, "CharacterSet", "Specifies character sets", false, false, 0, 32, Exiv2::undefined, IptcDataSets::envelope, ""),
92
 
        DataSet(IptcDataSets::UNO, "UNO", "Unique Name of Object", false, false, 14, 80, Exiv2::string, IptcDataSets::envelope, ""),
93
 
        DataSet(IptcDataSets::ARMId, "ARMId", "Abstract Relationship Method identifier", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
94
 
        DataSet(IptcDataSets::ARMVersion, "ARMVersion", "Abstract Relationship Method version", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::envelope, ""),
95
 
        DataSet(0xffff, "(Invalid)", "(Invalid)", false, false, 0, 0, Exiv2::unsignedShort, IptcDataSets::envelope, "")
96
 
    };
97
 
 
98
 
    static const DataSet application2Record[] = {
99
 
        DataSet(IptcDataSets::RecordVersion, "RecordVersion", "Version of IIM part 2", true, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
100
 
        DataSet(IptcDataSets::ObjectType, "ObjectType", "IIM appendix G object type", false, false, 3, 67, Exiv2::string, IptcDataSets::application2, ""),
101
 
        DataSet(IptcDataSets::ObjectAttribute, "ObjectAttribute", "IIM appendix G object attribute", false, true, 4, 68, Exiv2::string, IptcDataSets::application2, ""),
102
 
        DataSet(IptcDataSets::ObjectName, "ObjectName", "Shorthand reference of content", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, "Document title"),
103
 
        DataSet(IptcDataSets::EditStatus, "EditStatus", "Content status", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
104
 
        DataSet(IptcDataSets::EditorialUpdate, "EditorialUpdate", "Indicates the type of update", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
105
 
        DataSet(IptcDataSets::Urgency, "Urgency", "Editorial urgency of content", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, "Urgency"),
106
 
        DataSet(IptcDataSets::Subject, "Subject", "Structured definition of the subject", false, true, 13, 236, Exiv2::string, IptcDataSets::application2, ""),
107
 
        DataSet(IptcDataSets::Category, "Category", "Identifies the subject", false, false, 0, 3, Exiv2::string, IptcDataSets::application2, "Category"),
108
 
        DataSet(IptcDataSets::SuppCategory, "SuppCategory", "Refines the subject", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Supplemental Categories"),
109
 
        DataSet(IptcDataSets::FixtureId, "FixtureId", "Identifies content that recurs", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
110
 
        DataSet(IptcDataSets::Keywords, "Keywords", "Information retrieval words", false, true, 0, 64, Exiv2::string, IptcDataSets::application2, "Keywords"),
111
 
        DataSet(IptcDataSets::LocationCode, "LocationCode", "ISO country code for content", false, true, 3, 3, Exiv2::string, IptcDataSets::application2, ""),
112
 
        DataSet(IptcDataSets::LocationName, "LocationName", "Full country name for content", false, true, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
113
 
        DataSet(IptcDataSets::ReleaseDate, "ReleaseDate", "Earliest intended usable date", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
114
 
        DataSet(IptcDataSets::ReleaseTime, "ReleaseTime", "Earliest intended usable time", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
115
 
        DataSet(IptcDataSets::ExpirationDate, "ExpirationDate", "Latest intended usable date", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
116
 
        DataSet(IptcDataSets::ExpirationTime, "ExpirationTime", "Latest intended usable time", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
117
 
        DataSet(IptcDataSets::SpecialInstructions, "SpecialInstructions", "Editorial usage instructions", false, false, 0, 256, Exiv2::string, IptcDataSets::application2, "Instructions"),
118
 
        DataSet(IptcDataSets::ActionAdvised, "ActionAdvised", "Action provided to previous data", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
119
 
        DataSet(IptcDataSets::ReferenceService, "ReferenceService", "Service Identifier of a prior envelope", false, true, 0, 10, Exiv2::string, IptcDataSets::application2, ""),
120
 
        DataSet(IptcDataSets::ReferenceDate, "ReferenceDate", "Date of a prior envelope", false, true, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
121
 
        DataSet(IptcDataSets::ReferenceNumber, "ReferenceNumber", "Envelope Number of a prior envelope", false, true, 8, 8, Exiv2::string, IptcDataSets::application2, ""),
122
 
        DataSet(IptcDataSets::DateCreated, "DateCreated", "Creation date of intellectual content", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, "Date created"),
123
 
        DataSet(IptcDataSets::TimeCreated, "TimeCreated", "Creation time of intellectual content", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
124
 
        DataSet(IptcDataSets::DigitizationDate, "DigitizationDate", "Creation date of digital representation", false, false, 8, 8, Exiv2::date, IptcDataSets::application2, ""),
125
 
        DataSet(IptcDataSets::DigitizationTime, "DigitizationTime", "Creation time of digital representation", false, false, 11, 11, Exiv2::time, IptcDataSets::application2, ""),
126
 
        DataSet(IptcDataSets::Program, "Program", "Content creation program", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
127
 
        DataSet(IptcDataSets::ProgramVersion, "ProgramVersion", "Content creation program version", false, false, 0, 10, Exiv2::string, IptcDataSets::application2, ""),
128
 
        DataSet(IptcDataSets::ObjectCycle, "ObjectCycle", "Morning, evening, or both", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, ""),
129
 
        DataSet(IptcDataSets::Byline, "Byline", "Name of content creator", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Author"),
130
 
        DataSet(IptcDataSets::BylineTitle, "BylineTitle", "Title of content creator", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Authors Position"),
131
 
        DataSet(IptcDataSets::City, "City", "City of content origin", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "City"),
132
 
        DataSet(IptcDataSets::SubLocation, "SubLocation", "Location within city", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, ""),
133
 
        DataSet(IptcDataSets::ProvinceState, "ProvinceState", "Province/State of content origin", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "State/Province"),
134
 
        DataSet(IptcDataSets::CountryCode, "CountryCode", "ISO country code of content origin", false, false, 3, 3, Exiv2::string, IptcDataSets::application2, ""),
135
 
        DataSet(IptcDataSets::CountryName, "CountryName", "Full country name of content origin", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, "Country"),
136
 
        DataSet(IptcDataSets::TransmissionReference, "TransmissionReference", "Location of original transmission", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Transmission Reference"),
137
 
        DataSet(IptcDataSets::Headline, "Headline", "Content synopsis", false, false, 0, 256, Exiv2::string, IptcDataSets::application2, "Headline"),
138
 
        DataSet(IptcDataSets::Credit, "Credit", "Content provider", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Credit"),
139
 
        DataSet(IptcDataSets::Source, "Source", "Original owner of content", false, false, 0, 32, Exiv2::string, IptcDataSets::application2, "Source"),
140
 
        DataSet(IptcDataSets::Copyright, "Copyright", "Necessary copyright notice", false, false, 0, 128, Exiv2::string, IptcDataSets::application2, "Copyright notice"),
141
 
        DataSet(IptcDataSets::Contact, "Contact", "Person or organisation to contact", false, true, 0, 128, Exiv2::string, IptcDataSets::application2, ""),
142
 
        DataSet(IptcDataSets::Caption, "Caption", "Content description", false, false, 0, 2000, Exiv2::string, IptcDataSets::application2, "Description"),
143
 
        DataSet(IptcDataSets::Writer, "Writer", "Person responsible for caption", false, true, 0, 32, Exiv2::string, IptcDataSets::application2, "Description writer"),
144
 
        DataSet(IptcDataSets::RasterizedCaption, "RasterizedCaption", "Black and white caption image", false, false, 7360, 7360, Exiv2::undefined, IptcDataSets::application2, ""),
145
 
        DataSet(IptcDataSets::ImageType, "ImageType", "Color components in an image", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
146
 
        DataSet(IptcDataSets::ImageOrientation, "ImageOrientation", "Indicates the layout of an image", false, false, 1, 1, Exiv2::string, IptcDataSets::application2, ""),
147
 
        DataSet(IptcDataSets::Language, "Language", "ISO 639:1988 language code", false, false, 2, 3, Exiv2::string, IptcDataSets::application2, ""),
148
 
        DataSet(IptcDataSets::AudioType, "AudioType", "Information about audio content", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
149
 
        DataSet(IptcDataSets::AudioRate, "AudioRate", "Sampling rate of audio content", false, false, 6, 6, Exiv2::string, IptcDataSets::application2, ""),
150
 
        DataSet(IptcDataSets::AudioResolution, "AudioResolution", "Sampling resolution of audio content", false, false, 2, 2, Exiv2::string, IptcDataSets::application2, ""),
151
 
        DataSet(IptcDataSets::AudioDuration, "AudioDuration", "Duration of audio content", false, false, 6, 6, Exiv2::string, IptcDataSets::application2, ""),
152
 
        DataSet(IptcDataSets::AudioOutcue, "AudioOutcue", "Final words or sounds of audio content", false, false, 0, 64, Exiv2::string, IptcDataSets::application2, ""),
153
 
        DataSet(IptcDataSets::PreviewFormat, "PreviewFormat", "IIM appendix A file format of preview", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
154
 
        DataSet(IptcDataSets::PreviewVersion, "PreviewVersion", "File format version of preview", false, false, 2, 2, Exiv2::unsignedShort, IptcDataSets::application2, ""),
155
 
        DataSet(IptcDataSets::Preview, "Preview", "Binary preview data", false, false, 0, 256000, Exiv2::undefined, IptcDataSets::application2, ""),
156
 
        DataSet(0xffff, "(Invalid)", "(Invalid)", false, false, 0, 0, Exiv2::unsignedShort, IptcDataSets::application2, "")
157
 
    };
158
 
 
159
 
    static const DataSet unknownDataSet(0xffff, "Unknown dataset", "Unknown dataset", false, true, 0, 0xffffffff, Exiv2::string, IptcDataSets::invalidRecord, "Unknown dataset");
160
 
 
161
 
    // Dataset lookup lists.This is an array with pointers to one list per IIM4 Record.
162
 
    // The record id is used as the index into the array.
163
 
    const DataSet* IptcDataSets::records_[] = {
164
 
        0,
165
 
        envelopeRecord, application2Record,
166
 
        0
167
 
    };
168
 
 
169
 
    int IptcDataSets::dataSetIdx(uint16_t number, uint16_t recordId)
170
 
    {
171
 
        if( recordId != envelope && recordId != application2 ) return -1;
172
 
        const DataSet* dataSet = records_[recordId];
173
 
        if (dataSet == 0) return -1;
174
 
        int idx;
175
 
        for (idx = 0; dataSet[idx].number_ != number; ++idx) {
176
 
            if (dataSet[idx].number_ == 0xffff) return -1;
177
 
        }
178
 
        return idx;
179
 
    }
180
 
 
181
 
    int IptcDataSets::dataSetIdx(const std::string& dataSetName, uint16_t recordId)
182
 
    {
183
 
        if( recordId != envelope && recordId != application2 ) return -1;
184
 
        const DataSet* dataSet = records_[recordId];
185
 
        if (dataSet == 0) return -1;
186
 
        int idx;
187
 
        for (idx = 0; dataSet[idx].name_ != dataSetName; ++idx) {
188
 
            if (dataSet[idx].number_ == 0xffff) return -1;
189
 
        }
190
 
        return idx;
191
 
    }
192
 
 
193
 
    TypeId IptcDataSets::dataSetType(uint16_t number, uint16_t recordId)
194
 
    {
195
 
        int idx = dataSetIdx(number, recordId);
196
 
        if (idx == -1) return unknownDataSet.type_;
197
 
        return records_[recordId][idx].type_;
198
 
    }
199
 
 
200
 
    std::string IptcDataSets::dataSetName(uint16_t number, uint16_t recordId)
201
 
    {
202
 
        int idx = dataSetIdx(number, recordId);
203
 
        if (idx != -1) return records_[recordId][idx].name_;
204
 
 
205
 
        std::ostringstream os;
206
 
        os << "0x" << std::setw(4) << std::setfill('0') << std::right
207
 
           << std::hex << number;
208
 
        return os.str();
209
 
    }
210
 
 
211
 
    const char* IptcDataSets::dataSetDesc(uint16_t number, uint16_t recordId)
212
 
    {
213
 
        int idx = dataSetIdx(number, recordId);
214
 
        if (idx == -1) return unknownDataSet.desc_;
215
 
        return records_[recordId][idx].desc_;
216
 
    }
217
 
 
218
 
    const char* IptcDataSets::dataSetPsName(uint16_t number, uint16_t recordId)
219
 
    {
220
 
        int idx = dataSetIdx(number, recordId);
221
 
        if (idx == -1) return unknownDataSet.photoshop_;
222
 
        return records_[recordId][idx].photoshop_;
223
 
    }
224
 
 
225
 
    bool IptcDataSets::dataSetRepeatable(uint16_t number, uint16_t recordId)
226
 
    {
227
 
        int idx = dataSetIdx(number, recordId);
228
 
        if (idx == -1) return unknownDataSet.repeatable_;
229
 
        return records_[recordId][idx].repeatable_;
230
 
    }
231
 
 
232
 
    uint16_t IptcDataSets::dataSet(const std::string& dataSetName,
233
 
                                   uint16_t recordId)
234
 
    {
235
 
        uint16_t dataSet;
236
 
        int idx = dataSetIdx(dataSetName, recordId);
237
 
        if (idx != -1) {
238
 
            // dataSetIdx checks the range of recordId
239
 
            dataSet = records_[recordId][idx].number_;
240
 
        }
241
 
        else {
242
 
            if (!isHex(dataSetName, 4, "0x")) throw Error(4, dataSetName);
243
 
            std::istringstream is(dataSetName);
244
 
            is >> std::hex >> dataSet;
245
 
        }
246
 
        return dataSet;
247
 
    }
248
 
 
249
 
    std::string IptcDataSets::recordName(uint16_t recordId)
250
 
    {
251
 
        if (recordId == envelope || recordId == application2) {
252
 
            return recordInfo_[recordId].name_;
253
 
        }
254
 
 
255
 
        std::ostringstream os;
256
 
        os << "0x" << std::setw(4) << std::setfill('0') << std::right
257
 
           << std::hex << recordId;
258
 
        return os.str();
259
 
    }
260
 
 
261
 
    const char* IptcDataSets::recordDesc(uint16_t recordId)
262
 
    {
263
 
        if (recordId != envelope && recordId != application2) {
264
 
            return unknownDataSet.desc_;
265
 
        }
266
 
        return recordInfo_[recordId].desc_;
267
 
    }
268
 
 
269
 
    uint16_t IptcDataSets::recordId(const std::string& recordName)
270
 
    {
271
 
        uint16_t i;
272
 
        for (i = application2; i > 0; --i) {
273
 
            if (recordInfo_[i].name_ == recordName) break;
274
 
        }
275
 
        if (i == 0) {
276
 
            if (!isHex(recordName, 4, "0x")) throw Error(5, recordName);
277
 
            std::istringstream is(recordName);
278
 
            is >> std::hex >> i;
279
 
        }
280
 
        return i;
281
 
    }
282
 
 
283
 
    void IptcDataSets::dataSetList(std::ostream& os)
284
 
    {
285
 
        const int count = sizeof(records_)/sizeof(records_[0]);
286
 
        for (int i=0; i < count; ++i) {
287
 
            const DataSet *record = records_[i];
288
 
            for (int j=0; record != 0 && record[j].number_ != 0xffff; ++j) {
289
 
                os << record[j] << "\n";
290
 
            }
291
 
        }
292
 
    } // IptcDataSets::dataSetList
293
 
 
294
 
    const char* IptcKey::familyName_ = "Iptc";
295
 
 
296
 
    IptcKey::IptcKey(const std::string& key)
297
 
        : key_(key)
298
 
    {
299
 
        decomposeKey();
300
 
    }
301
 
 
302
 
    IptcKey::IptcKey(uint16_t tag, uint16_t record)
303
 
        : tag_(tag), record_(record)
304
 
    {
305
 
        makeKey();
306
 
    }
307
 
 
308
 
    IptcKey::IptcKey(const IptcKey& rhs)
309
 
        : tag_(rhs.tag_), record_(rhs.record_), key_(rhs.key_)
310
 
    {
311
 
    }
312
 
 
313
 
    IptcKey& IptcKey::operator=(const IptcKey& rhs)
314
 
    {
315
 
        if (this == &rhs) return *this;
316
 
        Key::operator=(rhs);
317
 
        tag_ = rhs.tag_;
318
 
        record_ = rhs.record_;
319
 
        key_ = rhs.key_;
320
 
        return *this;
321
 
    }
322
 
 
323
 
    IptcKey::AutoPtr IptcKey::clone() const
324
 
    {
325
 
        return AutoPtr(clone_());
326
 
    }
327
 
 
328
 
    IptcKey* IptcKey::clone_() const
329
 
    {
330
 
        return new IptcKey(*this);
331
 
    }
332
 
 
333
 
    void IptcKey::decomposeKey()
334
 
    {
335
 
        // Get the family name, record name and dataSet name parts of the key
336
 
        std::string::size_type pos1 = key_.find('.');
337
 
        if (pos1 == std::string::npos) throw Error(6, key_);
338
 
        std::string familyName = key_.substr(0, pos1);
339
 
        if (familyName != std::string(familyName_)) {
340
 
            throw Error(6, key_);
341
 
        }
342
 
        std::string::size_type pos0 = pos1 + 1;
343
 
        pos1 = key_.find('.', pos0);
344
 
        if (pos1 == std::string::npos) throw Error(6, key_);
345
 
        std::string recordName = key_.substr(pos0, pos1 - pos0);
346
 
        if (recordName == "") throw Error(6, key_);
347
 
        std::string dataSetName = key_.substr(pos1 + 1);
348
 
        if (dataSetName == "") throw Error(6, key_);
349
 
 
350
 
        // Use the parts of the key to find dataSet and recordId
351
 
        uint16_t recId = IptcDataSets::recordId(recordName);
352
 
        uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
353
 
 
354
 
        // Possibly translate hex name parts (0xabcd) to real names
355
 
        recordName = IptcDataSets::recordName(recId);
356
 
        dataSetName = IptcDataSets::dataSetName(dataSet, recId);
357
 
 
358
 
        tag_ = dataSet;
359
 
        record_ = recId;
360
 
        key_ = familyName + "." + recordName + "." + dataSetName;
361
 
    } // IptcKey::decomposeKey
362
 
 
363
 
    void IptcKey::makeKey()
364
 
    {
365
 
        key_ = std::string(familyName_)
366
 
            + "." + IptcDataSets::recordName(record_)
367
 
            + "." + IptcDataSets::dataSetName(tag_, record_);
368
 
    }
369
 
 
370
 
    // *************************************************************************
371
 
    // free functions
372
 
 
373
 
    std::ostream& operator<<(std::ostream& os, const DataSet& dataSet)
374
 
    {
375
 
        IptcKey iptcKey(dataSet.number_, dataSet.recordId_);
376
 
        return os << dataSet.name_ << ", "
377
 
                  << std::dec << dataSet.number_ << ", "
378
 
                  << "0x" << std::setw(4) << std::setfill('0')
379
 
                  << std::right << std::hex << dataSet.number_ << ", "
380
 
                  << IptcDataSets::recordName(dataSet.recordId_) << ", "
381
 
                  << std::boolalpha << dataSet.mandatory_ << ", "
382
 
                  << dataSet.repeatable_ << ", "
383
 
                  << std::dec << dataSet.minbytes_ << ", "
384
 
                  << dataSet.maxbytes_ << ", "
385
 
                  << iptcKey.key() << ", "
386
 
                  << TypeInfo::typeName(
387
 
                      IptcDataSets::dataSetType(dataSet.number_,
388
 
                                                dataSet.recordId_)) << ", "
389
 
                  << dataSet.desc_;
390
 
    }
391
 
 
392
 
}                                       // namespace Exiv2