Project

General

Profile

Bug #898 ยป value.hpp

Robin Mills, 11 Apr 2013 07:09

 
1
// ***************************************************************** -*- C++ -*-
2
/*
3
 * Copyright (C) 2004-2012 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., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20
 */
21
/*!
22
  @file    value.hpp
23
  @brief   Value interface and concrete subclasses
24
  @version $Rev: 2907 $
25
  @author  Andreas Huggel (ahu)
26
           <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
27
  @date    09-Jan-04, ahu: created
28
           11-Feb-04, ahu: isolated as a component
29
           31-Jul-04, brad: added Time, Data and String values
30
 */
31
#ifndef VALUE_HPP_
32
#define VALUE_HPP_
33

    
34
// *****************************************************************************
35
// included header files
36
#include "types.hpp"
37

    
38
// + standard includes
39
#include <string>
40
#include <vector>
41
#include <map>
42
#include <iostream>
43
#include <iomanip>
44
#include <sstream>
45
#include <memory>
46
#include <cstring>
47

    
48
// *****************************************************************************
49
// namespace extensions
50
namespace Exiv2 {
51

    
52
// *****************************************************************************
53
// class definitions
54

    
55
    /*!
56
      @brief Common interface for all types of values used with metadata.
57

    
58
      The interface provides a uniform way to access values independent of
59
      their actual C++ type for simple tasks like reading the values from a
60
      string or data buffer.  For other tasks, like modifying values you may
61
      need to downcast it to a specific subclass to access its interface.
62
     */
63
    class EXIV2API Value {
64
    public:
65
        //! Shortcut for a %Value auto pointer.
66
        typedef std::auto_ptr<Value> AutoPtr;
67

    
68
        //! @name Creators
69
        //@{
70
        //! Constructor, taking a type id to initialize the base class with
71
        explicit Value(TypeId typeId);
72
        //! Virtual destructor.
73
        virtual ~Value();
74
        //@}
75
        //! @name Manipulators
76
        //@{
77
        /*!
78
          @brief Read the value from a character buffer.
79

    
80
          @param buf Pointer to the data buffer to read from
81
          @param len Number of bytes in the data buffer
82
          @param byteOrder Applicable byte order (little or big endian).
83

    
84
          @return 0 if successful.
85
         */
86
        virtual int read(const byte* buf, long len, ByteOrder byteOrder) =0;
87
        /*!
88
          @brief Set the value from a string buffer. The format of the string
89
                 corresponds to that of the write() method, i.e., a string
90
                 obtained through the write() method can be read by this
91
                 function.
92

    
93
          @param buf The string to read from.
94

    
95
          @return 0 if successful.
96
         */
97
        virtual int read(const std::string& buf) =0;
98
        /*!
99
          @brief Set the data area, if the value has one by copying (cloning)
100
                 the buffer pointed to by buf.
101

    
102
          Values may have a data area, which can contain additional
103
          information besides the actual value. This method is used to set such
104
          a data area.
105

    
106
          @param buf Pointer to the source data area
107
          @param len Size of the data area
108
          @return Return -1 if the value has no data area, else 0.
109
         */
110
        virtual int setDataArea(const byte* buf, long len);
111
        //@}
112

    
113
        //! @name Accessors
114
        //@{
115
        //! Return the type identifier (Exif data format type).
116
        TypeId typeId() const { return type_; }
117
        /*!
118
          @brief Return an auto-pointer to a copy of itself (deep copy).
119
                 The caller owns this copy and the auto-pointer ensures that
120
                 it will be deleted.
121
         */
122
        AutoPtr clone() const { return AutoPtr(clone_()); }
123
        /*!
124
          @brief Write value to a data buffer.
125

    
126
          The user must ensure that the buffer has enough memory. Otherwise
127
          the call results in undefined behaviour.
128

    
129
          @param buf Data buffer to write to.
130
          @param byteOrder Applicable byte order (little or big endian).
131
          @return Number of bytes written.
132
        */
133
        virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
134
        //! Return the number of components of the value
135
        virtual long count() const =0;
136
        //! Return the size of the value in bytes
137
        virtual long size() const =0;
138
        /*!
139
          @brief Write the value to an output stream. You do not usually have
140
                 to use this function; it is used for the implementation of
141
                 the output operator for %Value,
142
                 operator<<(std::ostream &os, const Value &value).
143
        */
144
        virtual std::ostream& write(std::ostream& os) const =0;
145
        /*!
146
          @brief Return the value as a string. Implemented in terms of
147
                 write(std::ostream& os) const of the concrete class.
148
         */
149
        std::string toString() const;
150
        /*!
151
          @brief Return the <EM>n</EM>-th component of the value as a string.
152
                 The default implementation returns toString(). The behaviour
153
                 of this method may be undefined if there is no <EM>n</EM>-th
154
                 component.
155
         */
156
        virtual std::string toString(long n) const;
157
        /*!
158
          @brief Convert the <EM>n</EM>-th component of the value to a long.
159
                 The behaviour of this method may be undefined if there is no
160
                 <EM>n</EM>-th component.
161

    
162
          @return The converted value.
163
         */
164
        virtual long toLong(long n =0) const =0;
165
        /*!
166
          @brief Convert the <EM>n</EM>-th component of the value to a float.
167
                 The behaviour of this method may be undefined if there is no
168
                 <EM>n</EM>-th component.
169

    
170
          @return The converted value.
171
         */
172
        virtual float toFloat(long n =0) const =0;
173
        /*!
174
          @brief Convert the <EM>n</EM>-th component of the value to a Rational.
175
                 The behaviour of this method may be undefined if there is no
176
                 <EM>n</EM>-th component.
177

    
178
          @return The converted value.
179
         */
180
        virtual Rational toRational(long n =0) const =0;
181
        //! Return the size of the data area, 0 if there is none.
182
        virtual long sizeDataArea() const;
183
        /*!
184
          @brief Return a copy of the data area if the value has one. The
185
                 caller owns this copy and DataBuf ensures that it will be
186
                 deleted.
187

    
188
          Values may have a data area, which can contain additional
189
          information besides the actual value. This method is used to access
190
          such a data area.
191

    
192
          @return A DataBuf containing a copy of the data area or an empty
193
                  DataBuf if the value does not have a data area assigned.
194
         */
195
        virtual DataBuf dataArea() const;
196
        /*!
197
          @brief Check the \em ok status indicator. After a to<Type> conversion,
198
                 this indicator shows whether the conversion was successful.
199
         */
200
        bool ok() const { return ok_; }
201
        //@}
202

    
203
        /*!
204
          @brief A (simple) factory to create a Value type.
205

    
206
          The following Value subclasses are created depending on typeId:<BR><BR>
207
          <TABLE>
208
          <TR><TD class="indexkey"><B>typeId</B></TD><TD class="indexvalue"><B>%Value subclass</B></TD></TR>
209
          <TR><TD class="indexkey">invalidTypeId</TD><TD class="indexvalue">%DataValue(invalidTypeId)</TD></TR>
210
          <TR><TD class="indexkey">unsignedByte</TD><TD class="indexvalue">%DataValue(unsignedByte)</TD></TR>
211
          <TR><TD class="indexkey">asciiString</TD><TD class="indexvalue">%AsciiValue</TD></TR>
212
          <TR><TD class="indexkey">string</TD><TD class="indexvalue">%StringValue</TD></TR>
213
          <TR><TD class="indexkey">unsignedShort</TD><TD class="indexvalue">%ValueType &lt; uint16_t &gt;</TD></TR>
214
          <TR><TD class="indexkey">unsignedLong</TD><TD class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
215
          <TR><TD class="indexkey">unsignedRational</TD><TD class="indexvalue">%ValueType &lt; URational &gt;</TD></TR>
216
          <TR><TD class="indexkey">invalid6</TD><TD class="indexvalue">%DataValue(invalid6)</TD></TR>
217
          <TR><TD class="indexkey">undefined</TD><TD class="indexvalue">%DataValue</TD></TR>
218
          <TR><TD class="indexkey">signedShort</TD><TD class="indexvalue">%ValueType &lt; int16_t &gt;</TD></TR>
219
          <TR><TD class="indexkey">signedLong</TD><TD class="indexvalue">%ValueType &lt; int32_t &gt;</TD></TR>
220
          <TR><TD class="indexkey">signedRational</TD><TD class="indexvalue">%ValueType &lt; Rational &gt;</TD></TR>
221
          <TR><TD class="indexkey">tiffFloat</TD><TD class="indexvalue">%ValueType &lt; float &gt;</TD></TR>
222
          <TR><TD class="indexkey">tiffDouble</TD><TD class="indexvalue">%ValueType &lt; double &gt;</TD></TR>
223
          <TR><TD class="indexkey">tiffIfd</TD><TD class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
224
          <TR><TD class="indexkey">date</TD><TD class="indexvalue">%DateValue</TD></TR>
225
          <TR><TD class="indexkey">time</TD><TD class="indexvalue">%TimeValue</TD></TR>
226
          <TR><TD class="indexkey">comment</TD><TD class="indexvalue">%CommentValue</TD></TR>
227
          <TR><TD class="indexkey">xmpText</TD><TD class="indexvalue">%XmpTextValue</TD></TR>
228
          <TR><TD class="indexkey">xmpBag</TD><TD class="indexvalue">%XmpArrayValue</TD></TR>
229
          <TR><TD class="indexkey">xmpSeq</TD><TD class="indexvalue">%XmpArrayValue</TD></TR>
230
          <TR><TD class="indexkey">xmpAlt</TD><TD class="indexvalue">%XmpArrayValue</TD></TR>
231
          <TR><TD class="indexkey">langAlt</TD><TD class="indexvalue">%LangAltValue</TD></TR>
232
          <TR><TD class="indexkey"><EM>default:</EM></TD><TD class="indexvalue">%DataValue(typeId)</TD></TR>
233
          </TABLE>
234

    
235
          @param typeId Type of the value.
236
          @return Auto-pointer to the newly created Value. The caller owns this
237
                  copy and the auto-pointer ensures that it will be deleted.
238
         */
239
        static AutoPtr create(TypeId typeId);
240

    
241
    protected:
242
        /*!
243
          @brief Assignment operator. Protected so that it can only be used
244
                 by subclasses but not directly.
245
         */
246
        Value& operator=(const Value& rhs);
247
        // DATA
248
        mutable bool ok_;                //!< Indicates the status of the previous to<Type> conversion
249

    
250
    private:
251
        //! Internal virtual copy constructor.
252
        virtual Value* clone_() const =0;
253
        // DATA
254
        TypeId type_;                    //!< Type of the data
255

    
256
    }; // class Value
257

    
258
    //! Output operator for Value types
259
    inline std::ostream& operator<<(std::ostream& os, const Value& value)
260
    {
261
        return value.write(os);
262
    }
263

    
264
    //! %Value for an undefined data type.
265
    class EXIV2API DataValue : public Value {
266
    public:
267
        //! Shortcut for a %DataValue auto pointer.
268
        typedef std::auto_ptr<DataValue> AutoPtr;
269

    
270
        //! @name Creators
271
        //@{
272
        //! Default constructor.
273
        explicit DataValue(TypeId typeId =undefined);
274
        //! Constructor
275
        DataValue(const byte* buf,
276
                  long len, ByteOrder byteOrder =invalidByteOrder,
277
                  TypeId typeId =undefined);
278
        //! Virtual destructor.
279
        virtual ~DataValue();
280
        //@}
281

    
282
        //! @name Manipulators
283
        //@{
284
        /*!
285
          @brief Read the value from a character buffer.
286

    
287
          @note The byte order is required by the interface but not
288
                used by this method, so just use the default.
289

    
290
          @param buf Pointer to the data buffer to read from
291
          @param len Number of bytes in the data buffer
292
          @param byteOrder Byte order. Not needed.
293

    
294
          @return 0 if successful.
295
         */
296
        virtual int read(const byte* buf,
297
                          long len,
298
                          ByteOrder byteOrder =invalidByteOrder);
299
        //! Set the data from a string of integer values (e.g., "0 1 2 3")
300
        virtual int read(const std::string& buf);
301
        //@}
302

    
303
        //! @name Accessors
304
        //@{
305
        AutoPtr clone() const { return AutoPtr(clone_()); }
306
        /*!
307
          @brief Write value to a character data buffer.
308

    
309
          @note The byte order is required by the interface but not used by this
310
                method, so just use the default.
311

    
312
          The user must ensure that the buffer has enough memory. Otherwise
313
          the call results in undefined behaviour.
314

    
315
          @param buf Data buffer to write to.
316
          @param byteOrder Byte order. Not needed.
317
          @return Number of characters written.
318
        */
319
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
320
        virtual long count() const;
321
        virtual long size() const;
322
        virtual std::ostream& write(std::ostream& os) const;
323
        /*!
324
          @brief Return the <EM>n</EM>-th component of the value as a string.
325
                 The behaviour of this method may be undefined if there is no
326
                 <EM>n</EM>-th component.
327
         */
328
        virtual std::string toString(long n) const;
329
        virtual long toLong(long n =0) const;
330
        virtual float toFloat(long n =0) const;
331
        virtual Rational toRational(long n =0) const;
332
        //@}
333

    
334
    private:
335
        //! Internal virtual copy constructor.
336
        EXV_DLLLOCAL virtual DataValue* clone_() const;
337

    
338
    public:
339
        //! Type used to store the data.
340
        typedef std::vector<byte> ValueType;
341
        // DATA
342
        ValueType value_;                       //!< Stores the data value
343

    
344
    }; // class DataValue
345

    
346
    /*!
347
      @brief Abstract base class for a string based %Value type.
348

    
349
      Uses a std::string to store the value and implements defaults for
350
      most operations.
351
     */
352
    class EXIV2API StringValueBase : public Value {
353
    public:
354
        //! Shortcut for a %StringValueBase auto pointer.
355
        typedef std::auto_ptr<StringValueBase> AutoPtr;
356

    
357
        //! @name Creators
358
        //@{
359
        //! Constructor for subclasses
360
        explicit StringValueBase(TypeId typeId);
361
        //! Constructor for subclasses
362
        StringValueBase(TypeId typeId, const std::string& buf);
363
        //! Copy constructor
364
        StringValueBase(const StringValueBase& rhs);
365
        //! Virtual destructor.
366
        virtual ~StringValueBase();
367
        //@}
368

    
369
        //! @name Manipulators
370
        //@{
371
        //! Read the value from buf. This default implementation uses buf as it is.
372
        virtual int read(const std::string& buf);
373
        /*!
374
          @brief Read the value from a character buffer.
375

    
376
          @note The byte order is required by the interface but not used by this
377
                method, so just use the default.
378

    
379
          @param buf Pointer to the data buffer to read from
380
          @param len Number of bytes in the data buffer
381
          @param byteOrder Byte order. Not needed.
382

    
383
          @return 0 if successful.
384
         */
385
        virtual int read(const byte* buf,
386
                         long len,
387
                         ByteOrder byteOrder =invalidByteOrder);
388
        //@}
389

    
390
        //! @name Accessors
391
        //@{
392
        AutoPtr clone() const { return AutoPtr(clone_()); }
393
        /*!
394
          @brief Write value to a character data buffer.
395

    
396
          The user must ensure that the buffer has enough memory. Otherwise
397
          the call results in undefined behaviour.
398

    
399
          @note The byte order is required by the interface but not used by this
400
                method, so just use the default.
401

    
402
          @param buf Data buffer to write to.
403
          @param byteOrder Byte order. Not used.
404
          @return Number of characters written.
405
        */
406
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
407
        virtual long count() const;
408
        virtual long size() const;
409
        virtual long toLong(long n =0) const;
410
        virtual float toFloat(long n =0) const;
411
        virtual Rational toRational(long n =0) const;
412
        virtual std::ostream& write(std::ostream& os) const;
413
        //@}
414

    
415
    protected:
416
        //! Assignment operator.
417
        StringValueBase& operator=(const StringValueBase& rhs);
418
        //! Internal virtual copy constructor.
419
        virtual StringValueBase* clone_() const =0;
420

    
421
    public:
422
        // DATA
423
        std::string value_;                     //!< Stores the string value.
424

    
425
    }; // class StringValueBase
426

    
427
    /*!
428
      @brief %Value for string type.
429

    
430
      This can be a plain Ascii string or a multipe byte encoded string. It is
431
      left to caller to decode and encode the string to and from readable
432
      text if that is required.
433
    */
434
    class EXIV2API StringValue : public StringValueBase {
435
    public:
436
        //! Shortcut for a %StringValue auto pointer.
437
        typedef std::auto_ptr<StringValue> AutoPtr;
438

    
439
        //! @name Creators
440
        //@{
441
        //! Default constructor.
442
        StringValue();
443
        //! Constructor
444
        explicit StringValue(const std::string& buf);
445
        //! Virtual destructor.
446
        virtual ~StringValue();
447
        //@}
448

    
449
        //! @name Accessors
450
        //@{
451
        AutoPtr clone() const { return AutoPtr(clone_()); }
452
        //@}
453

    
454
    private:
455
        //! Internal virtual copy constructor.
456
        EXV_DLLLOCAL virtual StringValue* clone_() const;
457

    
458
    }; // class StringValue
459

    
460
    /*!
461
      @brief %Value for an Ascii string type.
462

    
463
      This class is for null terminated single byte Ascii strings.
464
      This class also ensures that the string is null terminated.
465
     */
466
    class EXIV2API AsciiValue : public StringValueBase {
467
    public:
468
        //! Shortcut for a %AsciiValue auto pointer.
469
        typedef std::auto_ptr<AsciiValue> AutoPtr;
470

    
471
        //! @name Creators
472
        //@{
473
        //! Default constructor.
474
        AsciiValue();
475
        //! Constructor
476
        explicit AsciiValue(const std::string& buf);
477
        //! Virtual destructor.
478
        virtual ~AsciiValue();
479
        //@}
480

    
481
        //! @name Manipulators
482
        //@{
483
        using StringValueBase::read;
484
        /*!
485
          @brief Set the value to that of the string buf. Overrides base class
486
                 to append a terminating '\\0' character if buf doesn't end
487
                 with '\\0'.
488
         */
489
        virtual int read(const std::string& buf);
490
        //@}
491

    
492
        //! @name Accessors
493
        //@{
494
        AutoPtr clone() const { return AutoPtr(clone_()); }
495
        /*!
496
          @brief Write the value to an output stream. Any trailing '\\0'
497
                 characters of the ASCII value are stripped and not written to
498
                 the output stream.
499
        */
500
        virtual std::ostream& write(std::ostream& os) const;
501
        //@}
502

    
503
    private:
504
        //! Internal virtual copy constructor.
505
        EXV_DLLLOCAL virtual AsciiValue* clone_() const;
506

    
507
    }; // class AsciiValue
508

    
509
    /*!
510
      @brief %Value for an Exif comment.
511

    
512
      This can be a plain Ascii string or a multipe byte encoded string. The
513
      comment is expected to be encoded in the character set indicated (default
514
      undefined), but this is not checked. It is left to caller to decode and
515
      encode the string to and from readable text if that is required.
516
    */
517
    class EXIV2API CommentValue : public StringValueBase {
518
    public:
519
        //! Character set identifiers for the character sets defined by %Exif
520
        enum CharsetId { ascii, jis, unicode, undefined,
521
                         invalidCharsetId, lastCharsetId };
522
        //! Information pertaining to the defined character sets
523
        struct CharsetTable {
524
            //! Constructor
525
            CharsetTable(CharsetId charsetId,
526
                         const char* name,
527
                         const char* code);
528
            CharsetId charsetId_;                   //!< Charset id
529
            const char* name_;                      //!< Name of the charset
530
            const char* code_;                      //!< Code of the charset
531
        }; // struct CharsetTable
532
        //! Charset information lookup functions. Implemented as a static class.
533
        class EXIV2API CharsetInfo {
534
            //! Prevent construction: not implemented.
535
            CharsetInfo() {}
536
            //! Prevent copy-construction: not implemented.
537
            CharsetInfo(const CharsetInfo&);
538
            //! Prevent assignment: not implemented.
539
            CharsetInfo& operator=(const CharsetInfo&);
540

    
541
        public:
542
            //! Return the name for a charset id
543
            static const char* name(CharsetId charsetId);
544
            //! Return the code for a charset id
545
            static const char* code(CharsetId charsetId);
546
            //! Return the charset id for a name
547
            static CharsetId charsetIdByName(const std::string& name);
548
            //! Return the charset id for a code
549
            static CharsetId charsetIdByCode(const std::string& code);
550

    
551
        private:
552
            static const CharsetTable charsetTable_[];
553
        }; // class CharsetInfo
554

    
555
        //! Shortcut for a %CommentValue auto pointer.
556
        typedef std::auto_ptr<CommentValue> AutoPtr;
557

    
558
        //! @name Creators
559
        //@{
560
        //! Default constructor.
561
        CommentValue();
562
        //! Constructor, uses read(const std::string& comment)
563
        explicit CommentValue(const std::string& comment);
564
        //! Virtual destructor.
565
        virtual ~CommentValue();
566
        //@}
567

    
568
        //! @name Manipulators
569
        //@{
570
        /*!
571
          @brief Read the value from a comment
572

    
573
          The format of \em comment is:
574
          <BR>
575
          <CODE>[charset=["]Ascii|Jis|Unicode|Undefined["] ]comment</CODE>
576
          <BR>
577
          The default charset is Undefined.
578

    
579
          @return 0 if successful<BR>
580
                  1 if an invalid character set is encountered
581
        */
582
        int read(const std::string& comment);
583
        /*!
584
          @brief Read the comment from a byte buffer.
585
         */
586
        int read(const byte* buf, long len, ByteOrder byteOrder);
587
        //@}
588

    
589
        //! @name Accessors
590
        //@{
591
        AutoPtr clone() const { return AutoPtr(clone_()); }
592
        long copy(byte* buf, ByteOrder byteOrder) const;
593
        /*!
594
          @brief Write the comment in a format which can be read by
595
          read(const std::string& comment).
596
         */
597
        std::ostream& write(std::ostream& os) const;
598
        /*!
599
          @brief Return the comment (without a charset="..." prefix)
600

    
601
          The comment is decoded to UTF-8. For Exif UNICODE comments, the
602
          function makes an attempt to correctly determine the character
603
          encoding of the value. Alternatively, the optional \em encoding
604
          parameter can be used to specify it.
605

    
606
          @param encoding Optional argument to specify the character encoding
607
              that the comment is encoded in, as an iconv(3) name. Only used
608
              for Exif UNICODE comments.
609

    
610
          @return A string containing the comment converted to UTF-8.
611
         */
612
        std::string comment(const char* encoding =0) const;
613
        /*!
614
          @brief Determine the character encoding that was used to encode the
615
              UNICODE comment value as an iconv(3) name.
616

    
617
          If the comment \em c starts with a BOM, the BOM is interpreted and
618
          removed from the string.
619

    
620
          Todo: Implement rules to guess if the comment is UTF-8 encoded.
621
         */
622
        const char* detectCharset(std::string& c) const;
623
        //! Return the Exif charset id of the comment
624
        CharsetId charsetId() const;
625
        //@}
626

    
627
    private:
628
        //! Internal virtual copy constructor.
629
        EXV_DLLLOCAL virtual CommentValue* clone_() const;
630

    
631
    public:
632
        // DATA
633
        ByteOrder byteOrder_;      //!< Byte order of the comment string that was read
634

    
635
    }; // class CommentValue
636

    
637
    /*!
638
      @brief Base class for all Exiv2 values used to store XMP property values.
639
     */
640
    class EXIV2API XmpValue : public Value {
641
    public:
642
        //! Shortcut for a %XmpValue auto pointer.
643
        typedef std::auto_ptr<XmpValue> AutoPtr;
644

    
645
        //! XMP array types.
646
        enum XmpArrayType { xaNone, xaAlt, xaBag, xaSeq };
647
        //! XMP structure indicator.
648
        enum XmpStruct { xsNone, xsStruct };
649

    
650
        //! @name Creators
651
        //@{
652
        explicit XmpValue(TypeId typeId);
653
        //@}
654

    
655
        //! @name Accessors
656
        //@{
657
        //! Return XMP array type, indicates if an XMP value is an array.
658
        XmpArrayType xmpArrayType() const;
659
        //! Return XMP struct, indicates if an XMP value is a structure.
660
        XmpStruct xmpStruct() const;
661
        virtual long size() const;
662
        /*!
663
          @brief Write value to a character data buffer.
664

    
665
          The user must ensure that the buffer has enough memory. Otherwise
666
          the call results in undefined behaviour.
667

    
668
          @note The byte order is required by the interface but not used by this
669
                method, so just use the default.
670

    
671
          @param buf Data buffer to write to.
672
          @param byteOrder Byte order. Not used.
673
          @return Number of characters written.
674
        */
675
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
676
        //@}
677

    
678
        //! @name Manipulators
679
        //@{
680
        //! Set the XMP array type to indicate that an XMP value is an array.
681
        void setXmpArrayType(XmpArrayType xmpArrayType);
682
        //! Set the XMP struct type to indicate that an XMP value is a structure.
683
        void setXmpStruct(XmpStruct xmpStruct =xsStruct);
684
        /*!
685
          @brief Read the value from a character buffer.
686

    
687
          Uses read(const std::string& buf)
688

    
689
          @note The byte order is required by the interface but not used by this
690
                method, so just use the default.
691

    
692
          @param buf Pointer to the data buffer to read from
693
          @param len Number of bytes in the data buffer
694
          @param byteOrder Byte order. Not needed.
695

    
696
          @return 0 if successful.
697
         */
698
        virtual int read(const byte* buf,
699
                         long len,
700
                         ByteOrder byteOrder =invalidByteOrder);
701
        virtual int read(const std::string& buf) =0;
702
        //@}
703

    
704
        /*!
705
          @brief Return XMP array type for an array Value TypeId, xaNone if
706
                 \em typeId is not an XMP array value type.
707
         */
708
        static XmpArrayType xmpArrayType(TypeId typeId);
709

    
710
    protected:
711
        /*!
712
          @brief Assignment operator. Protected so that it can only be used
713
                 by subclasses but not directly.
714
         */
715
        XmpValue& operator=(const XmpValue& rhs);
716

    
717
    private:
718
        // DATA
719
        XmpArrayType xmpArrayType_;             //!< Type of XMP array
720
        XmpStruct    xmpStruct_;                //!< XMP structure indicator
721

    
722
    }; // class XmpValue
723

    
724
    /*!
725
      @brief %Value type suitable for simple XMP properties and
726
             XMP nodes of complex types which are not parsed into
727
             specific values.
728

    
729
      Uses a std::string to store the value.
730
     */
731
    class EXIV2API XmpTextValue : public XmpValue {
732
    public:
733
        //! Shortcut for a %XmpTextValue auto pointer.
734
        typedef std::auto_ptr<XmpTextValue> AutoPtr;
735

    
736
        //! @name Creators
737
        //@{
738
        //! Constructor.
739
        XmpTextValue();
740
        //! Constructor, reads the value from a string.
741
        explicit XmpTextValue(const std::string& buf);
742
        //@}
743

    
744
        //! @name Manipulators
745
        //@{
746
        using XmpValue::read;
747
        /*!
748
          @brief Read a simple property value from \em buf to set the value.
749

    
750
          Sets the value to the contents of \em buf. A optional keyword,
751
          \em type is supported to set the XMP value type. This is useful for
752
          complex value types for which Exiv2 does not have direct support.
753

    
754
          The format of \em buf is:
755
          <BR>
756
          <CODE>[type=["]Alt|Bag|Seq|Struct["] ]text</CODE>
757
          <BR>
758

    
759
          @return 0 if successful.
760
         */
761

    
762
        virtual int read(const std::string& buf);
763
        //@}
764

    
765
        //! @name Accessors
766
        //@{
767
        AutoPtr clone() const;
768
        long size() const;
769
        virtual long count() const;
770
        /*!
771
          @brief Convert the value to a long.
772
                 The optional parameter \em n is not used and is ignored.
773

    
774
          @return The converted value.
775
         */
776
        virtual long toLong(long n =0) const;
777
        /*!
778
          @brief Convert the value to a float.
779
                 The optional parameter \em n is not used and is ignored.
780

    
781
          @return The converted value.
782
         */
783
        virtual float toFloat(long n =0) const;
784
        /*!
785
          @brief Convert the value to a Rational.
786
                 The optional parameter \em n is not used and is ignored.
787

    
788
          @return The converted value.
789
         */
790
        virtual Rational toRational(long n =0) const;
791
        virtual std::ostream& write(std::ostream& os) const;
792
        //@}
793

    
794
    private:
795
        //! Internal virtual copy constructor.
796
        EXV_DLLLOCAL virtual XmpTextValue* clone_() const;
797

    
798
    public:
799
        // DATA
800
        std::string value_;                     //!< Stores the string values.
801

    
802
    }; // class XmpTextValue
803

    
804
    /*!
805
      @brief %Value type for simple arrays. Each item in the array is a simple
806
             value, without qualifiers. The array may be an ordered (\em seq),
807
             unordered (\em bag) or alternative array (\em alt). The array
808
             items must not contain qualifiers. For language alternatives use
809
             LangAltValue.
810

    
811
      Uses a vector of std::string to store the value(s).
812
     */
813
    class EXIV2API XmpArrayValue : public XmpValue {
814
    public:
815
        //! Shortcut for a %XmpArrayValue auto pointer.
816
        typedef std::auto_ptr<XmpArrayValue> AutoPtr;
817

    
818
        //! @name Creators
819
        //@{
820
        //! Constructor. \em typeId can be one of xmpBag, xmpSeq or xmpAlt.
821
        explicit XmpArrayValue(TypeId typeId =xmpBag);
822
        //@}
823

    
824
        //! @name Manipulators
825
        //@{
826
        using XmpValue::read;
827
        /*!
828
          @brief Read a simple property value from \em buf and append it
829
                 to the value.
830

    
831
          Appends \em buf to the value after the last existing array element.
832
          Subsequent calls will therefore populate multiple array elements in
833
          the order they are read.
834

    
835
          @return 0 if successful.
836
         */
837
        virtual int read(const std::string& buf);
838
        //@}
839

    
840
        //! @name Accessors
841
        //@{
842
        AutoPtr clone() const;
843
        virtual long count() const;
844
        /*!
845
          @brief Return the <EM>n</EM>-th component of the value as a string.
846
                 The behaviour of this method may be undefined if there is no
847
                 <EM>n</EM>-th component.
848
         */
849
        virtual std::string toString(long n) const;
850
        virtual long toLong(long n =0) const;
851
        virtual float toFloat(long n =0) const;
852
        virtual Rational toRational(long n =0) const;
853
        /*!
854
          @brief Write all elements of the value to \em os, separated by commas.
855

    
856
          @note The output of this method cannot directly be used as the parameter
857
                for read().
858
         */
859
        virtual std::ostream& write(std::ostream& os) const;
860
        //@}
861

    
862
    private:
863
        //! Internal virtual copy constructor.
864
        EXV_DLLLOCAL virtual XmpArrayValue* clone_() const;
865

    
866
    public:
867
        //! Type used to store XMP array elements.
868
        typedef std::vector<std::string> ValueType;
869
        // DATA
870
        std::vector<std::string> value_;        //!< Stores the string values.
871

    
872
    }; // class XmpArrayValue
873

    
874
    /*!
875
      @brief %Value type for XMP language alternative properties.
876

    
877
      A language alternative is an array consisting of simple text values,
878
      each of which has a language qualifier.
879
     */
880
    class EXIV2API LangAltValue : public XmpValue {
881
    public:
882
        //! Shortcut for a %LangAltValue auto pointer.
883
        typedef std::auto_ptr<LangAltValue> AutoPtr;
884

    
885
        //! @name Creators
886
        //@{
887
        //! Constructor.
888
        LangAltValue();
889
        //! Constructor, reads the value from a string.
890
        explicit LangAltValue(const std::string& buf);
891
        //@}
892

    
893
        //! @name Manipulators
894
        //@{
895
        using XmpValue::read;
896
        /*!
897
          @brief Read a simple property value from \em buf and append it
898
                 to the value.
899

    
900
          Appends \em buf to the value after the last existing array element.
901
          Subsequent calls will therefore populate multiple array elements in
902
          the order they are read.
903

    
904
          The format of \em buf is:
905
          <BR>
906
          <CODE>[lang=["]language code["] ]text</CODE>
907
          <BR>
908
          The XMP default language code <CODE>x-default</CODE> is used if
909
          \em buf doesn't start with the keyword <CODE>lang</CODE>.
910

    
911
          @return 0 if successful.
912
         */
913
        virtual int read(const std::string& buf);
914
        //@}
915

    
916
        //! @name Accessors
917
        //@{
918
        AutoPtr clone() const;
919
        virtual long count() const;
920
        /*!
921
          @brief Return the text value associated with the default language
922
                 qualifier \c x-default. The parameter \em n is not used, but
923
                 it is suggested that only 0 is passed in. Returns an empty
924
                 string and sets the ok-flag to \c false if there is no
925
                 default value.
926
         */
927
        virtual std::string toString(long n) const;
928
        /*!
929
          @brief Return the text value associated with the language qualifier
930
                 \em qualifier. Returns an empty string and sets the ok-flag
931
                 to \c false if there is no entry for the language qualifier.
932
         */
933
        std::string toString(const std::string& qualifier) const;
934
        virtual long toLong(long n =0) const;
935
        virtual float toFloat(long n =0) const;
936
        virtual Rational toRational(long n =0) const;
937
        /*!
938
          @brief Write all elements of the value to \em os, separated by commas.
939

    
940
          @note The output of this method cannot directly be used as the parameter
941
                for read().
942
         */
943
        virtual std::ostream& write(std::ostream& os) const;
944
        //@}
945

    
946
    private:
947
        //! Internal virtual copy constructor.
948
        EXV_DLLLOCAL virtual LangAltValue* clone_() const;
949

    
950
    public:
951
        //! Type used to store language alternative arrays.
952
        typedef std::map<std::string, std::string> ValueType;
953
        // DATA
954
        /*!
955
          @brief Map to store the language alternative values. The language
956
                 qualifier is used as the key for the map entries.
957
         */
958
        ValueType value_;
959

    
960
    }; // class LangAltValue
961

    
962
    /*!
963
      @brief %Value for simple ISO 8601 dates
964

    
965
      This class is limited to parsing simple date strings in the ISO 8601
966
      format CCYYMMDD (century, year, month, day).
967
     */
968
    class EXIV2API DateValue : public Value {
969
    public:
970
        //! Shortcut for a %DateValue auto pointer.
971
        typedef std::auto_ptr<DateValue> AutoPtr;
972

    
973
        //! @name Creators
974
        //@{
975
        //! Default constructor.
976
        DateValue();
977
        //! Constructor
978
        DateValue(int year, int month, int day);
979
        //! Virtual destructor.
980
        virtual ~DateValue();
981
        //@}
982

    
983
        //! Simple Date helper structure
984
        struct EXIV2API Date {
985
            Date() : year(0), month(0), day(0) {}
986
            int year;                           //!< Year
987
            int month;                          //!< Month
988
            int day;                            //!< Day
989
        };
990

    
991
        //! @name Manipulators
992
        //@{
993
        /*!
994
          @brief Read the value from a character buffer.
995

    
996
          @note The byte order is required by the interface but not used by this
997
                method, so just use the default.
998

    
999
          @param buf Pointer to the data buffer to read from
1000
          @param len Number of bytes in the data buffer
1001
          @param byteOrder Byte order. Not needed.
1002

    
1003
          @return 0 if successful<BR>
1004
                  1 in case of an unsupported date format
1005
         */
1006
        virtual int read(const byte* buf,
1007
                         long len,
1008
                         ByteOrder byteOrder =invalidByteOrder);
1009
        /*!
1010
          @brief Set the value to that of the string buf.
1011

    
1012
          @param buf String containing the date
1013

    
1014
          @return 0 if successful<BR>
1015
                  1 in case of an unsupported date format
1016
         */
1017
        virtual int read(const std::string& buf);
1018
        //! Set the date
1019
        void setDate(const Date& src);
1020
        //@}
1021

    
1022
        //! @name Accessors
1023
        //@{
1024
        AutoPtr clone() const { return AutoPtr(clone_()); }
1025
        /*!
1026
          @brief Write value to a character data buffer.
1027

    
1028
          The user must ensure that the buffer has enough memory. Otherwise
1029
          the call results in undefined behaviour.
1030

    
1031
          @note The byte order is required by the interface but not used by this
1032
                method, so just use the default.
1033

    
1034
          @param buf Data buffer to write to.
1035
          @param byteOrder Byte order. Not used.
1036
          @return Number of characters written.
1037
        */
1038
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
1039
        //! Return date struct containing date information
1040
        virtual const Date& getDate() const;
1041
        virtual long count() const;
1042
        virtual long size() const;
1043
        virtual std::ostream& write(std::ostream& os) const;
1044
        //! Return the value as a UNIX calender time converted to long.
1045
        virtual long toLong(long n =0) const;
1046
        //! Return the value as a UNIX calender time converted to float.
1047
        virtual float toFloat(long n =0) const;
1048
        //! Return the value as a UNIX calender time  converted to Rational.
1049
        virtual Rational toRational(long n =0) const;
1050
        //@}
1051

    
1052
    private:
1053
        //! Internal virtual copy constructor.
1054
        EXV_DLLLOCAL virtual DateValue* clone_() const;
1055

    
1056
        // DATA
1057
        Date date_;
1058

    
1059
    }; // class DateValue
1060

    
1061
    /*!
1062
     @brief %Value for simple ISO 8601 times.
1063

    
1064
     This class is limited to handling simple time strings in the ISO 8601
1065
     format HHMMSS?HHMM where HHMMSS refers to local hour, minute and
1066
     seconds and ?HHMM refers to hours and minutes ahead or behind
1067
     Universal Coordinated Time.
1068
     */
1069
    class EXIV2API TimeValue : public Value {
1070
    public:
1071
        //! Shortcut for a %TimeValue auto pointer.
1072
        typedef std::auto_ptr<TimeValue> AutoPtr;
1073

    
1074
        //! @name Creators
1075
        //@{
1076
        //! Default constructor.
1077
        TimeValue();
1078
        //! Constructor
1079
        TimeValue(int hour, int minute, int second =0,
1080
                  int tzHour =0, int tzMinute =0);
1081

    
1082
        //! Virtual destructor.
1083
        virtual ~TimeValue();
1084
        //@}
1085

    
1086
        //! Simple Time helper structure
1087
        struct Time
1088
        {
1089
            Time() : hour(0), minute(0), second(0), tzHour(0), tzMinute(0) {}
1090

    
1091
            int hour;                           //!< Hour
1092
            int minute;                         //!< Minute
1093
            int second;                         //!< Second
1094
            int tzHour;                         //!< Hours ahead or behind UTC
1095
            int tzMinute;                       //!< Minutes ahead or behind UTC
1096
        };
1097

    
1098
        //! @name Manipulators
1099
        //@{
1100
        /*!
1101
          @brief Read the value from a character buffer.
1102

    
1103
          @note The byte order is required by the interface but not used by this
1104
                method, so just use the default.
1105

    
1106
          @param buf Pointer to the data buffer to read from
1107
          @param len Number of bytes in the data buffer
1108
          @param byteOrder Byte order. Not needed.
1109

    
1110
          @return 0 if successful<BR>
1111
                  1 in case of an unsupported time format
1112
         */
1113
        virtual int read(const byte* buf,
1114
                         long len,
1115
                         ByteOrder byteOrder =invalidByteOrder);
1116
        /*!
1117
          @brief Set the value to that of the string buf.
1118

    
1119
          @param buf String containing the time.
1120

    
1121
          @return 0 if successful<BR>
1122
                  1 in case of an unsupported time format
1123
         */
1124
        virtual int read(const std::string& buf);
1125
        //! Set the time
1126
        void setTime(const Time& src);
1127
        //@}
1128

    
1129
        //! @name Accessors
1130
        //@{
1131
        AutoPtr clone() const { return AutoPtr(clone_()); }
1132
        /*!
1133
          @brief Write value to a character data buffer.
1134

    
1135
          The user must ensure that the buffer has enough memory. Otherwise
1136
          the call results in undefined behaviour.
1137

    
1138
          @note The byte order is required by the interface but not used by this
1139
                method, so just use the default.
1140

    
1141
          @param buf Data buffer to write to.
1142
          @param byteOrder Byte order. Not used.
1143
          @return Number of characters written.
1144
        */
1145
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
1146
        //! Return time struct containing time information
1147
        virtual const Time& getTime() const;
1148
        virtual long count() const;
1149
        virtual long size() const;
1150
        virtual std::ostream& write(std::ostream& os) const;
1151
        //! Returns number of seconds in the day in UTC.
1152
        virtual long toLong(long n =0) const;
1153
        //! Returns number of seconds in the day in UTC converted to float.
1154
        virtual float toFloat(long n =0) const;
1155
        //! Returns number of seconds in the day in UTC converted to Rational.
1156
        virtual Rational toRational(long n =0) const;
1157
        //@}
1158

    
1159
    private:
1160
        //! @name Manipulators
1161
        //@{
1162
        /*!
1163
          @brief Set time from \em buf if it conforms to \em format
1164
                 (3 input items).
1165

    
1166
          This function only sets the hour, minute and second parts of time_.
1167

    
1168
          @param buf    A 0 terminated C-string containing the time to parse.
1169
          @param format Format string for sscanf().
1170
          @return 0 if successful, else 1.
1171
         */
1172
        EXV_DLLLOCAL int scanTime3(const char* buf, const char* format);
1173
        /*!
1174
          @brief Set time from \em buf if it conforms to \em format
1175
                 (6 input items).
1176

    
1177
          This function sets all parts of time_.
1178

    
1179
          @param buf    A 0 terminated C-string containing the time to parse.
1180
          @param format Format string for sscanf().
1181
          @return 0 if successful, else 1.
1182
         */
1183
        EXV_DLLLOCAL int scanTime6(const char* buf, const char* format);
1184
        //@}
1185

    
1186
        //! @name Accessors
1187
        //@{
1188
        //! Internal virtual copy constructor.
1189
        EXV_DLLLOCAL virtual TimeValue* clone_() const;
1190
        //@}
1191

    
1192
        // DATA
1193
        Time time_;
1194

    
1195
    }; // class TimeValue
1196

    
1197
    //! Template to determine the TypeId for a type T
1198
    template<typename T> TypeId getType();
1199

    
1200
    //! Specialization for an unsigned short
1201
    template<> inline TypeId getType<uint16_t>() { return unsignedShort; }
1202
    //! Specialization for an unsigned long
1203
    template<> inline TypeId getType<uint32_t>() { return unsignedLong; }
1204
    //! Specialization for an unsigned rational
1205
    template<> inline TypeId getType<URational>() { return unsignedRational; }
1206
    //! Specialization for a signed short
1207
    template<> inline TypeId getType<int16_t>() { return signedShort; }
1208
    //! Specialization for a signed long
1209
    template<> inline TypeId getType<int32_t>() { return signedLong; }
1210
    //! Specialization for a signed rational
1211
    template<> inline TypeId getType<Rational>() { return signedRational; }
1212
    //! Specialization for a float
1213
    template<> inline TypeId getType<float>() { return tiffFloat; }
1214
    //! Specialization for a double
1215
    template<> inline TypeId getType<double>() { return tiffDouble; }
1216

    
1217
    // No default implementation: let the compiler/linker complain
1218
    // template<typename T> inline TypeId getType() { return invalid; }
1219

    
1220
    /*!
1221
      @brief Template for a %Value of a basic type. This is used for unsigned
1222
             and signed short, long and rationals.
1223
     */
1224
    template<typename T>
1225
    class ValueType : public Value {
1226
    public:
1227
        //! Shortcut for a %ValueType\<T\> auto pointer.
1228
        typedef std::auto_ptr<ValueType<T> > AutoPtr;
1229

    
1230
        //! @name Creators
1231
        //@{
1232
        //! Default Constructor.
1233
        ValueType();
1234
        //! Constructor.
1235
        // The default c'tor and this one can be combined, but that causes MSVC 7.1 to fall on its nose
1236
        explicit ValueType(TypeId typeId);
1237
        //! Constructor.
1238
        ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId =getType<T>());
1239
        //! Constructor.
1240
        explicit ValueType(const T& val, TypeId typeId =getType<T>());
1241
        //! Copy constructor
1242
        ValueType(const ValueType<T>& rhs);
1243
        //! Virtual destructor.
1244
        virtual ~ValueType();
1245
        //@}
1246

    
1247
        //! @name Manipulators
1248
        //@{
1249
        //! Assignment operator.
1250
        ValueType<T>& operator=(const ValueType<T>& rhs);
1251
        virtual int read(const byte* buf, long len, ByteOrder byteOrder);
1252
        /*!
1253
          @brief Set the data from a string of values of type T (e.g.,
1254
                 "0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
1255
                 Generally, the accepted input format is the same as that
1256
                 produced by the write() method.
1257
         */
1258
        virtual int read(const std::string& buf);
1259
        /*!
1260
          @brief Set the data area. This method copies (clones) the buffer
1261
                 pointed to by buf.
1262
         */
1263
        virtual int setDataArea(const byte* buf, long len);
1264
        //@}
1265

    
1266
        //! @name Accessors
1267
        //@{
1268
        AutoPtr clone() const { return AutoPtr(clone_()); }
1269
        virtual long copy(byte* buf, ByteOrder byteOrder) const;
1270
        virtual long count() const;
1271
        virtual long size() const;
1272
        virtual std::ostream& write(std::ostream& os) const;
1273
        /*!
1274
          @brief Return the <EM>n</EM>-th component of the value as a string.
1275
                 The behaviour of this method may be undefined if there is no
1276
                 <EM>n</EM>-th
1277
                 component.
1278
         */
1279
        virtual std::string toString(long n) const;
1280
        virtual long toLong(long n =0) const;
1281
        virtual float toFloat(long n =0) const;
1282
        virtual Rational toRational(long n =0) const;
1283
        //! Return the size of the data area.
1284
        virtual long sizeDataArea() const;
1285
        /*!
1286
          @brief Return a copy of the data area in a DataBuf. The caller owns
1287
                 this copy and DataBuf ensures that it will be deleted.
1288
         */
1289
        virtual DataBuf dataArea() const;
1290
        //@}
1291

    
1292
        //! Container for values
1293
        typedef std::vector<T> ValueList;
1294
        //! Iterator type defined for convenience.
1295
        typedef typename std::vector<T>::iterator iterator;
1296
        //! Const iterator type defined for convenience.
1297
        typedef typename std::vector<T>::const_iterator const_iterator;
1298

    
1299
        // DATA
1300
        /*!
1301
          @brief The container for all values. In your application, if you know
1302
                 what subclass of Value you're dealing with (and possibly the T)
1303
                 then you can access this STL container through the usual
1304
                 standard library functions.
1305
         */
1306
        ValueList value_;
1307

    
1308
    private:
1309
        //! Internal virtual copy constructor.
1310
        virtual ValueType<T>* clone_() const;
1311

    
1312
        // DATA
1313
        //! Pointer to the buffer, 0 if none has been allocated
1314
        byte* pDataArea_;
1315
        //! The current size of the buffer
1316
        long sizeDataArea_;
1317
    }; // class ValueType
1318

    
1319
    //! Unsigned short value type
1320
    typedef ValueType<uint16_t> UShortValue;
1321
    //! Unsigned long value type
1322
    typedef ValueType<uint32_t> ULongValue;
1323
    //! Unsigned rational value type
1324
    typedef ValueType<URational> URationalValue;
1325
    //! Signed short value type
1326
    typedef ValueType<int16_t> ShortValue;
1327
    //! Signed long value type
1328
    typedef ValueType<int32_t> LongValue;
1329
    //! Signed rational value type
1330
    typedef ValueType<Rational> RationalValue;
1331
    //! Float value type
1332
    typedef ValueType<float> FloatValue;
1333
    //! Double value type
1334
    typedef ValueType<double> DoubleValue;
1335

    
1336
// *****************************************************************************
1337
// free functions, template and inline definitions
1338

    
1339
    /*!
1340
      @brief Read a value of type T from the data buffer.
1341

    
1342
      We need this template function for the ValueType template classes.
1343
      There are only specializations of this function available; no default
1344
      implementation is provided.
1345

    
1346
      @param buf Pointer to the data buffer to read from.
1347
      @param byteOrder Applicable byte order (little or big endian).
1348
      @return A value of type T.
1349
     */
1350
    template<typename T> T getValue(const byte* buf, ByteOrder byteOrder);
1351
    // Specialization for a 2 byte unsigned short value.
1352
    template<>
1353
    inline uint16_t getValue(const byte* buf, ByteOrder byteOrder)
1354
    {
1355
        return getUShort(buf, byteOrder);
1356
    }
1357
    // Specialization for a 4 byte unsigned long value.
1358
    template<>
1359
    inline uint32_t getValue(const byte* buf, ByteOrder byteOrder)
1360
    {
1361
        return getULong(buf, byteOrder);
1362
    }
1363
    // Specialization for an 8 byte unsigned rational value.
1364
    template<>
1365
    inline URational getValue(const byte* buf, ByteOrder byteOrder)
1366
    {
1367
        return getURational(buf, byteOrder);
1368
    }
1369
    // Specialization for a 2 byte signed short value.
1370
    template<>
1371
    inline int16_t getValue(const byte* buf, ByteOrder byteOrder)
1372
    {
1373
        return getShort(buf, byteOrder);
1374
    }
1375
    // Specialization for a 4 byte signed long value.
1376
    template<>
1377
    inline int32_t getValue(const byte* buf, ByteOrder byteOrder)
1378
    {
1379
        return getLong(buf, byteOrder);
1380
    }
1381
    // Specialization for an 8 byte signed rational value.
1382
    template<>
1383
    inline Rational getValue(const byte* buf, ByteOrder byteOrder)
1384
    {
1385
        return getRational(buf, byteOrder);
1386
    }
1387
    // Specialization for a 4 byte float value.
1388
    template<>
1389
    inline float getValue(const byte* buf, ByteOrder byteOrder)
1390
    {
1391
        return getFloat(buf, byteOrder);
1392
    }
1393
    // Specialization for a 8 byte double value.
1394
    template<>
1395
    inline double getValue(const byte* buf, ByteOrder byteOrder)
1396
    {
1397
        return getDouble(buf, byteOrder);
1398
    }
1399

    
1400
    /*!
1401
      @brief Convert a value of type T to data, write the data to the data buffer.
1402

    
1403
      We need this template function for the ValueType template classes.
1404
      There are only specializations of this function available; no default
1405
      implementation is provided.
1406

    
1407
      @param buf Pointer to the data buffer to write to.
1408
      @param t Value to be converted.
1409
      @param byteOrder Applicable byte order (little or big endian).
1410
      @return The number of bytes written to the buffer.
1411
     */
1412
    template<typename T> long toData(byte* buf, T t, ByteOrder byteOrder);
1413
    /*!
1414
      @brief Specialization to write an unsigned short to the data buffer.
1415
             Return the number of bytes written.
1416
     */
1417
    template<>
1418
    inline long toData(byte* buf, uint16_t t, ByteOrder byteOrder)
1419
    {
1420
        return us2Data(buf, t, byteOrder);
1421
    }
1422
    /*!
1423
      @brief Specialization to write an unsigned long to the data buffer.
1424
             Return the number of bytes written.
1425
     */
1426
    template<>
1427
    inline long toData(byte* buf, uint32_t t, ByteOrder byteOrder)
1428
    {
1429
        return ul2Data(buf, t, byteOrder);
1430
    }
1431
    /*!
1432
      @brief Specialization to write an unsigned rational to the data buffer.
1433
             Return the number of bytes written.
1434
     */
1435
    template<>
1436
    inline long toData(byte* buf, URational t, ByteOrder byteOrder)
1437
    {
1438
        return ur2Data(buf, t, byteOrder);
1439
    }
1440
    /*!
1441
      @brief Specialization to write a signed short to the data buffer.
1442
             Return the number of bytes written.
1443
     */
1444
    template<>
1445
    inline long toData(byte* buf, int16_t t, ByteOrder byteOrder)
1446
    {
1447
        return s2Data(buf, t, byteOrder);
1448
    }
1449
    /*!
1450
      @brief Specialization to write a signed long to the data buffer.
1451
             Return the number of bytes written.
1452
     */
1453
    template<>
1454
    inline long toData(byte* buf, int32_t t, ByteOrder byteOrder)
1455
    {
1456
        return l2Data(buf, t, byteOrder);
1457
    }
1458
    /*!
1459
      @brief Specialization to write a signed rational to the data buffer.
1460
             Return the number of bytes written.
1461
     */
1462
    template<>
1463
    inline long toData(byte* buf, Rational t, ByteOrder byteOrder)
1464
    {
1465
        return r2Data(buf, t, byteOrder);
1466
    }
1467
    /*!
1468
      @brief Specialization to write a float to the data buffer.
1469
             Return the number of bytes written.
1470
     */
1471
    template<>
1472
    inline long toData(byte* buf, float t, ByteOrder byteOrder)
1473
    {
1474
        return f2Data(buf, t, byteOrder);
1475
    }
1476
    /*!
1477
      @brief Specialization to write a double to the data buffer.
1478
             Return the number of bytes written.
1479
     */
1480
    template<>
1481
    inline long toData(byte* buf, double t, ByteOrder byteOrder)
1482
    {
1483
        return d2Data(buf, t, byteOrder);
1484
    }
1485

    
1486
    template<typename T>
1487
    ValueType<T>::ValueType()
1488
        : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
1489
    {
1490
    }
1491

    
1492
    template<typename T>
1493
    ValueType<T>::ValueType(TypeId typeId)
1494
        : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1495
    {
1496
    }
1497

    
1498
    template<typename T>
1499
    ValueType<T>::ValueType(const byte* buf, long len, ByteOrder byteOrder, TypeId typeId)
1500
        : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1501
    {
1502
        read(buf, len, byteOrder);
1503
    }
1504

    
1505
    template<typename T>
1506
    ValueType<T>::ValueType(const T& val, TypeId typeId)
1507
        : Value(typeId), pDataArea_(0), sizeDataArea_(0)
1508
    {
1509
        value_.push_back(val);
1510
    }
1511

    
1512
    template<typename T>
1513
    ValueType<T>::ValueType(const ValueType<T>& rhs)
1514
        : Value(rhs), value_(rhs.value_), pDataArea_(0), sizeDataArea_(0)
1515
    {
1516
        if (rhs.sizeDataArea_ > 0) {
1517
            pDataArea_ = new byte[rhs.sizeDataArea_];
1518
            std::memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
1519
            sizeDataArea_ = rhs.sizeDataArea_;
1520
        }
1521
    }
1522

    
1523
    template<typename T>
1524
    ValueType<T>::~ValueType()
1525
    {
1526
        delete[] pDataArea_;
1527
    }
1528

    
1529
    template<typename T>
1530
    ValueType<T>& ValueType<T>::operator=(const ValueType<T>& rhs)
1531
    {
1532
        if (this == &rhs) return *this;
1533
        Value::operator=(rhs);
1534
        value_ = rhs.value_;
1535

    
1536
        byte* tmp = 0;
1537
        if (rhs.sizeDataArea_ > 0) {
1538
            tmp = new byte[rhs.sizeDataArea_];
1539
            std::memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
1540
        }
1541
        delete[] pDataArea_;
1542
        pDataArea_ = tmp;
1543
        sizeDataArea_ = rhs.sizeDataArea_;
1544

    
1545
        return *this;
1546
    }
1547

    
1548
    template<typename T>
1549
    int ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
1550
    {
1551
        value_.clear();
1552
        long ts = TypeInfo::typeSize(typeId());
1553
        if (len % ts != 0) len = (len / ts) * ts;
1554
        for (long i = 0; i < len; i += ts) {
1555
            value_.push_back(getValue<T>(buf + i, byteOrder));
1556
        }
1557
        return 0;
1558
    }
1559

    
1560
    template<typename T>
1561
    int ValueType<T>::read(const std::string& buf)
1562
    {
1563
        std::istringstream is(buf);
1564
        T tmp;
1565
        ValueList val;
1566
        while (!(is.eof())) {
1567
            is >> tmp;
1568
            if (is.fail()) return 1;
1569
            val.push_back(tmp);
1570
        }
1571
        value_.swap(val);
1572
        return 0;
1573
    }
1574

    
1575
    template<typename T>
1576
    long ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const
1577
    {
1578
        long offset = 0;
1579
        typename ValueList::const_iterator end = value_.end();
1580
        for (typename ValueList::const_iterator i = value_.begin(); i != end; ++i) {
1581
            offset += toData(buf + offset, *i, byteOrder);
1582
        }
1583
        return offset;
1584
    }
1585

    
1586
    template<typename T>
1587
    long ValueType<T>::count() const
1588
    {
1589
        return static_cast<long>(value_.size());
1590
    }
1591

    
1592
    template<typename T>
1593
    long ValueType<T>::size() const
1594
    {
1595
        return static_cast<long>(TypeInfo::typeSize(typeId()) * value_.size());
1596
    }
1597

    
1598
    template<typename T>
1599
    ValueType<T>* ValueType<T>::clone_() const
1600
    {
1601
        return new ValueType<T>(*this);
1602
    }
1603

    
1604
    template<typename T>
1605
    std::ostream& ValueType<T>::write(std::ostream& os) const
1606
    {
1607
        typename ValueList::const_iterator end = value_.end();
1608
        typename ValueList::const_iterator i = value_.begin();
1609
        while (i != end) {
1610
            os << std::setprecision(15) << *i;
1611
            if (++i != end) os << " ";
1612
        }
1613
        return os;
1614
    }
1615

    
1616
    template<typename T>
1617
    std::string ValueType<T>::toString(long n) const
1618
    {
1619
        ok_ = true;
1620
        return Exiv2::toString<T>(value_[n]);
1621
    }
1622

    
1623
    // Default implementation
1624
    template<typename T>
1625
    long ValueType<T>::toLong(long n) const
1626
    {
1627
        ok_ = true;
1628
        return static_cast<long>(value_[n]);
1629
    }
1630
    // Specialization for rational
1631
    template<>
1632
    inline long ValueType<Rational>::toLong(long n) const
1633
    {
1634
        ok_ = (value_[n].second != 0);
1635
        if (!ok_) return 0;
1636
        return value_[n].first / value_[n].second;
1637
    }
1638
    // Specialization for unsigned rational
1639
    template<>
1640
    inline long ValueType<URational>::toLong(long n) const
1641
    {
1642
        ok_ = (value_[n].second != 0);
1643
        if (!ok_) return 0;
1644
        return value_[n].first / value_[n].second;
1645
    }
1646
    // Default implementation
1647
    template<typename T>
1648
    float ValueType<T>::toFloat(long n) const
1649
    {
1650
        ok_ = true;
1651
        return static_cast<float>(value_[n]);
1652
    }
1653
    // Specialization for rational
1654
    template<>
1655
    inline float ValueType<Rational>::toFloat(long n) const
1656
    {
1657
        ok_ = (value_[n].second != 0);
1658
        if (!ok_) return 0.0f;
1659
        return static_cast<float>(value_[n].first) / value_[n].second;
1660
    }
1661
    // Specialization for unsigned rational
1662
    template<>
1663
    inline float ValueType<URational>::toFloat(long n) const
1664
    {
1665
        ok_ = (value_[n].second != 0);
1666
        if (!ok_) return 0.0f;
1667
        return static_cast<float>(value_[n].first) / value_[n].second;
1668
    }
1669
    // Default implementation
1670
    template<typename T>
1671
    Rational ValueType<T>::toRational(long n) const
1672
    {
1673
        ok_ = true;
1674
        return Rational(value_[n], 1);
1675
    }
1676
    // Specialization for rational
1677
    template<>
1678
    inline Rational ValueType<Rational>::toRational(long n) const
1679
    {
1680
        ok_ = true;
1681
        return Rational(value_[n].first, value_[n].second);
1682
    }
1683
    // Specialization for unsigned rational
1684
    template<>
1685
    inline Rational ValueType<URational>::toRational(long n) const
1686
    {
1687
        ok_ = true;
1688
        return Rational(value_[n].first, value_[n].second);
1689
    }
1690
    // Specialization for float.
1691
    template<>
1692
    inline Rational ValueType<float>::toRational(long n) const
1693
    {
1694
        ok_ = true;
1695
        // Warning: This is a very simple conversion, see floatToRationalCast()
1696
        return floatToRationalCast(value_[n]);
1697
    }
1698
    // Specialization for double.
1699
    template<>
1700
    inline Rational ValueType<double>::toRational(long n) const
1701
    {
1702
        ok_ = true;
1703
        // Warning: This is a very simple conversion, see floatToRationalCast()
1704
        return floatToRationalCast(static_cast<float>(value_[n]));
1705
    }
1706

    
1707
    template<typename T>
1708
    long ValueType<T>::sizeDataArea() const
1709
    {
1710
        return sizeDataArea_;
1711
    }
1712

    
1713
    template<typename T>
1714
    DataBuf ValueType<T>::dataArea() const
1715
    {
1716
        return DataBuf(pDataArea_, sizeDataArea_);
1717
    }
1718

    
1719
    template<typename T>
1720
    int ValueType<T>::setDataArea(const byte* buf, long len)
1721
    {
1722
        byte* tmp = 0;
1723
        if (len > 0) {
1724
            tmp = new byte[len];
1725
            std::memcpy(tmp, buf, len);
1726
        }
1727
        delete[] pDataArea_;
1728
        pDataArea_ = tmp;
1729
        sizeDataArea_ = len;
1730
        return 0;
1731
    }
1732
}                                       // namespace Exiv2
1733

    
1734
#endif                                  // #ifndef VALUE_HPP_
    (1-1/1)