~noskcaj/ubuntu/trusty/libextractor/merge

« back to all changes in this revision

Viewing changes to src/plugins/exiv2/value.hpp

  • 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    value.hpp
23
 
  @brief   Value interface and concrete subclasses
24
 
  @version $Rev: 560 $
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 <iostream>
42
 
#include <sstream>
43
 
#include <memory>
44
 
#include <string.h>
45
 
 
46
 
// *****************************************************************************
47
 
// namespace extensions
48
 
namespace Exiv2 {
49
 
 
50
 
// *****************************************************************************
51
 
// class definitions
52
 
 
53
 
    /*!
54
 
      @brief Common interface for all types of values used with metadata.
55
 
 
56
 
      The interface provides a uniform way to access values independent from
57
 
      their actual C++ type for simple tasks like reading the values from a
58
 
      string or data buffer.  For other tasks, like modifying values you may
59
 
      need to downcast it to the actual subclass of %Value so that you can
60
 
      access the subclass specific interface.
61
 
     */
62
 
    class Value {
63
 
    public:
64
 
        //! Shortcut for a %Value auto pointer.
65
 
        typedef std::auto_ptr<Value> AutoPtr;
66
 
 
67
 
        //! @name Creators
68
 
        //@{
69
 
        //! Constructor, taking a type id to initialize the base class with
70
 
        explicit Value(TypeId typeId)
71
 
            : type_(typeId) {}
72
 
        //! Copy constructor
73
 
        Value(const Value& rhs)
74
 
            : type_(rhs.type_) {}
75
 
        //! Virtual destructor.
76
 
        virtual ~Value() {}
77
 
        //@}
78
 
 
79
 
        //! @name Manipulators
80
 
        //@{
81
 
        /*!
82
 
          @brief Read the value from a character buffer.
83
 
 
84
 
          @param buf Pointer to the data buffer to read from
85
 
          @param len Number of bytes in the data buffer
86
 
          @param byteOrder Applicable byte order (little or big endian).
87
 
         */
88
 
        virtual void read(const byte* buf, long len, ByteOrder byteOrder) =0;
89
 
        /*!
90
 
          @brief Set the value from a string buffer. The format of the string
91
 
                 corresponds to that of the write() method, i.e., a string
92
 
                 obtained through the write() method can be read by this
93
 
                 function.
94
 
 
95
 
          @param buf The string to read from.
96
 
         */
97
 
        virtual void 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) { return -1; }
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 the value as a string. Implemented in terms of
119
 
                 write(std::ostream& os) const of the concrete class.
120
 
         */
121
 
        std::string toString() const;
122
 
        /*!
123
 
          @brief Return an auto-pointer to a copy of itself (deep copy).
124
 
                 The caller owns this copy and the auto-pointer ensures that
125
 
                 it will be deleted.
126
 
         */
127
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
128
 
        /*!
129
 
          @brief Write value to a data buffer.
130
 
 
131
 
          The user must ensure that the buffer has enough memory. Otherwise
132
 
          the call results in undefined behaviour.
133
 
 
134
 
          @param buf Data buffer to write to.
135
 
          @param byteOrder Applicable byte order (little or big endian).
136
 
          @return Number of bytes written.
137
 
        */
138
 
        virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
139
 
        //! Return the number of components of the value
140
 
        virtual long count() const =0;
141
 
        //! Return the size of the value in bytes
142
 
        virtual long size() const =0;
143
 
        /*!
144
 
          @brief Write the value to an output stream. You do not usually have
145
 
                 to use this function; it is used for the implementation of
146
 
                 the output operator for %Value,
147
 
                 operator<<(std::ostream &os, const Value &value).
148
 
        */
149
 
        virtual std::ostream& write(std::ostream& os) const =0;
150
 
        /*!
151
 
          @brief Convert the n-th component of the value to a long. The
152
 
                 behaviour of this method may be undefined if there is no
153
 
                 n-th component.
154
 
 
155
 
          @return The converted value.
156
 
         */
157
 
        virtual long toLong(long n =0) const =0;
158
 
        /*!
159
 
          @brief Convert the n-th component of the value to a float. The
160
 
                 behaviour of this method may be undefined if there is no
161
 
                 n-th component.
162
 
 
163
 
          @return The converted value.
164
 
         */
165
 
        virtual float toFloat(long n =0) const =0;
166
 
        /*!
167
 
          @brief Convert the n-th component of the value to a Rational. The
168
 
                 behaviour of this method may be undefined if there is no
169
 
                 n-th component.
170
 
 
171
 
          @return The converted value.
172
 
         */
173
 
        virtual Rational toRational(long n =0) const =0;
174
 
        //! Return the size of the data area, 0 if there is none.
175
 
        virtual long sizeDataArea() const { return 0; }
176
 
        /*!
177
 
          @brief Return a copy of the data area if the value has one. The
178
 
                 caller owns this copy and DataBuf ensures that it will be
179
 
                 deleted.
180
 
 
181
 
          Values may have a data area, which can contain additional
182
 
          information besides the actual value. This method is used to access
183
 
          such a data area.
184
 
 
185
 
          @return A DataBuf containing a copy of the data area or an empty
186
 
                  DataBuf if the value does not have a data area assigned.
187
 
         */
188
 
        virtual DataBuf dataArea() const { return DataBuf(0, 0); };
189
 
        //@}
190
 
 
191
 
        /*!
192
 
          @brief A (simple) factory to create a Value type.
193
 
 
194
 
          The following Value subclasses are created depending on typeId:<BR><BR>
195
 
          <TABLE>
196
 
          <TR><TD class="indexkey"><B>typeId</B></TD><TD class="indexvalue"><B>%Value subclass</B></TD></TR>
197
 
          <TR><TD class="indexkey">invalidTypeId</TD><TD class="indexvalue">%DataValue(invalidTypeId)</TD></TR>
198
 
          <TR><TD class="indexkey">unsignedByte</TD><TD class="indexvalue">%DataValue(unsignedByte)</TD></TR>
199
 
          <TR><TD class="indexkey">asciiString</TD><TD class="indexvalue">%AsciiValue</TD></TR>
200
 
          <TR><TD class="indexkey">string</TD><TD class="indexvalue">%StringValue</TD></TR>
201
 
          <TR><TD class="indexkey">unsignedShort</TD><TD class="indexvalue">%ValueType &lt; uint16_t &gt;</TD></TR>
202
 
          <TR><TD class="indexkey">unsignedLong</TD><TD class="indexvalue">%ValueType &lt; uint32_t &gt;</TD></TR>
203
 
          <TR><TD class="indexkey">unsignedRational</TD><TD class="indexvalue">%ValueType &lt; URational &gt;</TD></TR>
204
 
          <TR><TD class="indexkey">invalid6</TD><TD class="indexvalue">%DataValue(invalid6)</TD></TR>
205
 
          <TR><TD class="indexkey">undefined</TD><TD class="indexvalue">%DataValue</TD></TR>
206
 
          <TR><TD class="indexkey">signedShort</TD><TD class="indexvalue">%ValueType &lt; int16_t &gt;</TD></TR>
207
 
          <TR><TD class="indexkey">signedLong</TD><TD class="indexvalue">%ValueType &lt; int32_t &gt;</TD></TR>
208
 
          <TR><TD class="indexkey">signedRational</TD><TD class="indexvalue">%ValueType &lt; Rational &gt;</TD></TR>
209
 
          <TR><TD class="indexkey">date</TD><TD class="indexvalue">%DateValue</TD></TR>
210
 
          <TR><TD class="indexkey">time</TD><TD class="indexvalue">%TimeValue</TD></TR>
211
 
          <TR><TD class="indexkey">comment</TD><TD class="indexvalue">%CommentValue</TD></TR>
212
 
          <TR><TD class="indexkey"><EM>default:</EM></TD><TD class="indexvalue">%DataValue(typeId)</TD></TR>
213
 
          </TABLE>
214
 
 
215
 
          @param typeId Type of the value.
216
 
          @return Auto-pointer to the newly created Value. The caller owns this
217
 
                  copy and the auto-pointer ensures that it will be deleted.
218
 
         */
219
 
        static AutoPtr create(TypeId typeId);
220
 
 
221
 
    protected:
222
 
        /*!
223
 
          @brief Assignment operator. Protected so that it can only be used
224
 
                 by subclasses but not directly.
225
 
         */
226
 
        Value& operator=(const Value& rhs);
227
 
 
228
 
    private:
229
 
        //! Internal virtual copy constructor.
230
 
        virtual Value* clone_() const =0;
231
 
        // DATA
232
 
        TypeId type_;                           //!< Type of the data
233
 
 
234
 
    }; // class Value
235
 
 
236
 
    //! Output operator for Value types
237
 
    inline std::ostream& operator<<(std::ostream& os, const Value& value)
238
 
    {
239
 
        return value.write(os);
240
 
    }
241
 
 
242
 
    //! %Value for an undefined data type.
243
 
    class DataValue : public Value {
244
 
    public:
245
 
        //! Shortcut for a %DataValue auto pointer.
246
 
        typedef std::auto_ptr<DataValue> AutoPtr;
247
 
 
248
 
        //! @name Creators
249
 
        //@{
250
 
        //! Default constructor.
251
 
        DataValue(TypeId typeId =undefined) : Value(typeId) {}
252
 
        //! Constructor
253
 
        DataValue(const byte* buf,
254
 
                  long len, ByteOrder byteOrder =invalidByteOrder,
255
 
                  TypeId typeId =undefined)
256
 
            : Value(typeId) { read(buf, len, byteOrder); }
257
 
        //! Virtual destructor.
258
 
        virtual ~DataValue() {}
259
 
        //@}
260
 
 
261
 
        //! @name Manipulators
262
 
        //@{
263
 
        //! Assignment operator.
264
 
        DataValue& operator=(const DataValue& rhs);
265
 
        /*!
266
 
          @brief Read the value from a character buffer.
267
 
 
268
 
          @note The byte order is required by the interface but not
269
 
                used by this method, so just use the default.
270
 
 
271
 
          @param buf Pointer to the data buffer to read from
272
 
          @param len Number of bytes in the data buffer
273
 
          @param byteOrder Byte order. Not needed.
274
 
         */
275
 
        virtual void read(const byte* buf,
276
 
                          long len,
277
 
                          ByteOrder byteOrder =invalidByteOrder);
278
 
        //! Set the data from a string of integer values (e.g., "0 1 2 3")
279
 
        virtual void read(const std::string& buf);
280
 
        //@}
281
 
 
282
 
        //! @name Accessors
283
 
        //@{
284
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
285
 
        /*!
286
 
          @brief Write value to a character data buffer.
287
 
 
288
 
          @note The byte order is required by the interface but not used by this
289
 
                method, so just use the default.
290
 
 
291
 
          The user must ensure that the buffer has enough memory. Otherwise
292
 
          the call results in undefined behaviour.
293
 
 
294
 
          @param buf Data buffer to write to.
295
 
          @param byteOrder Byte order. Not needed.
296
 
          @return Number of characters written.
297
 
        */
298
 
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
299
 
        virtual long count() const { return size(); }
300
 
        virtual long size() const;
301
 
        virtual std::ostream& write(std::ostream& os) const;
302
 
        virtual long toLong(long n =0) const { return value_[n]; }
303
 
        virtual float toFloat(long n =0) const { return value_[n]; }
304
 
        virtual Rational toRational(long n =0) const
305
 
            { return Rational(value_[n], 1); }
306
 
        //@}
307
 
 
308
 
    private:
309
 
        //! Internal virtual copy constructor.
310
 
        virtual DataValue* clone_() const;
311
 
        // DATA
312
 
        std::vector<byte> value_;
313
 
 
314
 
    }; // class DataValue
315
 
 
316
 
    /*!
317
 
      @brief Abstract base class for a string based %Value type.
318
 
 
319
 
      Uses a std::string to store the value and implements defaults for
320
 
      most operations.
321
 
     */
322
 
    class StringValueBase : public Value {
323
 
    public:
324
 
        //! Shortcut for a %StringValueBase auto pointer.
325
 
        typedef std::auto_ptr<StringValueBase> AutoPtr;
326
 
 
327
 
        //! @name Creators
328
 
        //@{
329
 
        //! Constructor for subclasses
330
 
        StringValueBase(TypeId typeId)
331
 
            : Value(typeId) {}
332
 
        //! Constructor for subclasses
333
 
        StringValueBase(TypeId typeId, const std::string& buf)
334
 
            : Value(typeId) { read(buf); }
335
 
        //! Copy constructor
336
 
        StringValueBase(const StringValueBase& rhs)
337
 
            : Value(rhs), value_(rhs.value_) {}
338
 
 
339
 
        //! Virtual destructor.
340
 
        virtual ~StringValueBase() {}
341
 
        //@}
342
 
 
343
 
        //! @name Manipulators
344
 
        //@{
345
 
        //! Assignment operator.
346
 
        StringValueBase& operator=(const StringValueBase& rhs);
347
 
        //! Read the value from buf. This default implementation uses buf as it is.
348
 
        virtual void read(const std::string& buf);
349
 
        /*!
350
 
          @brief Read the value from a character buffer.
351
 
 
352
 
          @note The byte order is required by the interface but not used by this
353
 
                method, so just use the default.
354
 
 
355
 
          @param buf Pointer to the data buffer to read from
356
 
          @param len Number of bytes in the data buffer
357
 
          @param byteOrder Byte order. Not needed.
358
 
         */
359
 
        virtual void read(const byte* buf,
360
 
                          long len,
361
 
                          ByteOrder byteOrder =invalidByteOrder);
362
 
        //@}
363
 
 
364
 
        //! @name Accessors
365
 
        //@{
366
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
367
 
        /*!
368
 
          @brief Write value to a character data buffer.
369
 
 
370
 
          The user must ensure that the buffer has enough memory. Otherwise
371
 
          the call results in undefined behaviour.
372
 
 
373
 
          @note The byte order is required by the interface but not used by this
374
 
                method, so just use the default.
375
 
 
376
 
          @param buf Data buffer to write to.
377
 
          @param byteOrder Byte order. Not used.
378
 
          @return Number of characters written.
379
 
        */
380
 
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
381
 
        virtual long count() const { return size(); }
382
 
        virtual long size() const;
383
 
        virtual long toLong(long n =0) const { return value_[n]; }
384
 
        virtual float toFloat(long n =0) const { return value_[n]; }
385
 
        virtual Rational toRational(long n =0) const
386
 
            { return Rational(value_[n], 1); }
387
 
        virtual std::ostream& write(std::ostream& os) const;
388
 
        //@}
389
 
 
390
 
    protected:
391
 
        //! Internal virtual copy constructor.
392
 
        virtual StringValueBase* clone_() const =0;
393
 
        // DATA
394
 
        std::string value_;                     //!< Stores the string value.
395
 
 
396
 
    }; // class StringValueBase
397
 
 
398
 
    /*!
399
 
      @brief %Value for string type.
400
 
 
401
 
      This can be a plain Ascii string or a multipe byte encoded string. It is
402
 
      left to caller to decode and encode the string to and from readable
403
 
      text if that is required.
404
 
    */
405
 
    class StringValue : public StringValueBase {
406
 
    public:
407
 
        //! Shortcut for a %StringValue auto pointer.
408
 
        typedef std::auto_ptr<StringValue> AutoPtr;
409
 
 
410
 
        //! @name Creators
411
 
        //@{
412
 
        //! Default constructor.
413
 
        StringValue()
414
 
            : StringValueBase(string) {}
415
 
        //! Constructor
416
 
        StringValue(const std::string& buf)
417
 
            : StringValueBase(string, buf) {}
418
 
        //! Copy constructor
419
 
        StringValue(const StringValue& rhs)
420
 
            : StringValueBase(rhs) {}
421
 
        //! Virtual destructor.
422
 
        virtual ~StringValue() {}
423
 
        //@}
424
 
 
425
 
        //! @name Manipulators
426
 
        //@{
427
 
        StringValue& operator=(const StringValue& rhs);
428
 
        //@}
429
 
 
430
 
        //! @name Accessors
431
 
        //@{
432
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
433
 
        //@}
434
 
 
435
 
    private:
436
 
        //! Internal virtual copy constructor.
437
 
        virtual StringValue* clone_() const;
438
 
 
439
 
    }; // class StringValue
440
 
 
441
 
    /*!
442
 
      @brief %Value for an Ascii string type.
443
 
 
444
 
      This class is for null terminated single byte Ascii strings.
445
 
      This class also ensures that the string is null terminated.
446
 
     */
447
 
    class AsciiValue : public StringValueBase {
448
 
    public:
449
 
        //! Shortcut for a %AsciiValue auto pointer.
450
 
        typedef std::auto_ptr<AsciiValue> AutoPtr;
451
 
 
452
 
        //! @name Creators
453
 
        //@{
454
 
        //! Default constructor.
455
 
        AsciiValue()
456
 
            : StringValueBase(asciiString) {}
457
 
        //! Constructor
458
 
        AsciiValue(const std::string &buf)
459
 
            : StringValueBase(asciiString, buf) {}
460
 
        //! Copy constructor
461
 
        AsciiValue(const AsciiValue& rhs)
462
 
            : StringValueBase(rhs) {}
463
 
        //! Virtual destructor.
464
 
        virtual ~AsciiValue() {}
465
 
        //@}
466
 
 
467
 
        //! @name Manipulators
468
 
        //@{
469
 
        //! Assignment operator
470
 
        AsciiValue& operator=(const AsciiValue& rhs);
471
 
        /*!
472
 
          @brief Set the value to that of the string buf. Overrides base class
473
 
                 to append a terminating '\\0' character if buf doesn't end
474
 
                 with '\\0'.
475
 
         */
476
 
        virtual void read(const std::string& buf);
477
 
        //@}
478
 
 
479
 
        //! @name Accessors
480
 
        //@{
481
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
482
 
        /*!
483
 
          @brief Write the value to an output stream. Any trailing '\\0'
484
 
                 characters of the ASCII value are stripped and not written to
485
 
                 the output stream.
486
 
        */
487
 
        virtual std::ostream& write(std::ostream& os) const;
488
 
        //@}
489
 
 
490
 
    private:
491
 
        //! Internal virtual copy constructor.
492
 
        virtual AsciiValue* clone_() const;
493
 
 
494
 
    }; // class AsciiValue
495
 
 
496
 
    /*!
497
 
      @brief %Value for an Exif comment.
498
 
 
499
 
      This can be a plain Ascii string or a multipe byte encoded string. The
500
 
      comment is expected to be encoded in the character set indicated (default
501
 
      undefined), but this is not checked. It is left to caller to decode and
502
 
      encode the string to and from readable text if that is required.
503
 
    */
504
 
    class CommentValue : public StringValueBase {
505
 
    public:
506
 
        //! Character set identifiers for the character sets defined by %Exif
507
 
        enum CharsetId { ascii, jis, unicode, undefined,
508
 
                         invalidCharsetId, lastCharsetId };
509
 
        //! Information pertaining to the defined character sets
510
 
        struct CharsetTable {
511
 
            //! Constructor
512
 
            CharsetTable(CharsetId charsetId,
513
 
                         const char* name,
514
 
                         const char* code);
515
 
            CharsetId charsetId_;                   //!< Charset id
516
 
            const char* name_;                      //!< Name of the charset
517
 
            const char* code_;                      //!< Code of the charset
518
 
        }; // struct CharsetTable
519
 
        //! Charset information lookup functions. Implemented as a static class.
520
 
        class CharsetInfo {
521
 
            //! Prevent construction: not implemented.
522
 
            CharsetInfo() {}
523
 
            //! Prevent copy-construction: not implemented.
524
 
            CharsetInfo(const CharsetInfo&);
525
 
            //! Prevent assignment: not implemented.
526
 
            CharsetInfo& operator=(const CharsetInfo&);
527
 
 
528
 
        public:
529
 
            //! Return the name for a charset id
530
 
            static const char* name(CharsetId charsetId);
531
 
            //! Return the code for a charset id
532
 
            static const char* code(CharsetId charsetId);
533
 
            //! Return the charset id for a name
534
 
            static CharsetId charsetIdByName(const std::string& name);
535
 
            //! Return the charset id for a code
536
 
            static CharsetId charsetIdByCode(const std::string& code);
537
 
 
538
 
        private:
539
 
            static const CharsetTable charsetTable_[];
540
 
        }; // class CharsetInfo
541
 
 
542
 
        //! Shortcut for a %CommentValue auto pointer.
543
 
        typedef std::auto_ptr<CommentValue> AutoPtr;
544
 
 
545
 
        //! @name Creators
546
 
        //@{
547
 
        //! Default constructor.
548
 
        CommentValue()
549
 
            : StringValueBase(Exiv2::undefined) {}
550
 
        //! Constructor, uses read(const std::string& comment)
551
 
        CommentValue(const std::string& comment);
552
 
        //! Copy constructor
553
 
        CommentValue(const CommentValue& rhs)
554
 
            : StringValueBase(rhs) {}
555
 
        //! Virtual destructor.
556
 
        virtual ~CommentValue() {}
557
 
        //@}
558
 
 
559
 
        //! @name Manipulators
560
 
        //@{
561
 
        //! Assignment operator.
562
 
        CommentValue& operator=(const CommentValue& rhs);
563
 
        /*!
564
 
          @brief Read the value from a comment
565
 
 
566
 
          The format of \em comment is:
567
 
          <BR>
568
 
          <CODE>[charset=["]Ascii|Jis|Unicode|Undefined["] ]comment</CODE>
569
 
          <BR>
570
 
          The default charset is Undefined.
571
 
 
572
 
          @throw Error if an invalid character set is encountered
573
 
        */
574
 
        void read(const std::string& comment);
575
 
        //@}
576
 
 
577
 
        //! @name Accessors
578
 
        //@{
579
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
580
 
        /*!
581
 
          @brief Write the comment in a format which can be read by
582
 
          read(const std::string& comment).
583
 
         */
584
 
        std::ostream& write(std::ostream& os) const;
585
 
        //! Return the comment (without a charset="..." prefix)
586
 
        std::string comment() const;
587
 
        //! Return the charset id of the comment
588
 
        CharsetId charsetId() const;
589
 
        //@}
590
 
 
591
 
    private:
592
 
        //! Internal virtual copy constructor.
593
 
        virtual CommentValue* clone_() const;
594
 
 
595
 
    }; // class CommentValue
596
 
 
597
 
    /*!
598
 
      @brief %Value for simple ISO 8601 dates
599
 
 
600
 
      This class is limited to parsing simple date strings in the ISO 8601
601
 
      format CCYYMMDD (century, year, month, day).
602
 
     */
603
 
    class DateValue : public Value {
604
 
    public:
605
 
        //! Shortcut for a %DateValue auto pointer.
606
 
        typedef std::auto_ptr<DateValue> AutoPtr;
607
 
 
608
 
        //! @name Creators
609
 
        //@{
610
 
        //! Default constructor.
611
 
        DateValue() : Value(date) { memset(&date_, 0, sizeof(date_)); }
612
 
        //! Constructor
613
 
        DateValue(int year, int month, int day);
614
 
        //! Virtual destructor.
615
 
        virtual ~DateValue() {}
616
 
        //@}
617
 
 
618
 
        //! Simple Date helper structure
619
 
        struct Date
620
 
        {
621
 
            int year;                           //!< Year
622
 
            int month;                          //!< Month
623
 
            int day;                            //!< Day
624
 
        };
625
 
 
626
 
        //! @name Manipulators
627
 
        //@{
628
 
        //! Assignment operator.
629
 
        DateValue& operator=(const DateValue& rhs);
630
 
        /*!
631
 
          @brief Read the value from a character buffer.
632
 
 
633
 
          @note The byte order is required by the interface but not used by this
634
 
                method, so just use the default.
635
 
 
636
 
          @param buf Pointer to the data buffer to read from
637
 
          @param len Number of bytes in the data buffer
638
 
          @param byteOrder Byte order. Not needed.
639
 
 
640
 
          @throw Error in case of an unsupported date format
641
 
         */
642
 
        virtual void read(const byte* buf,
643
 
                          long len,
644
 
                          ByteOrder byteOrder =invalidByteOrder);
645
 
        /*!
646
 
          @brief Set the value to that of the string buf.
647
 
 
648
 
          @param buf String containing the date
649
 
 
650
 
          @throw Error in case of an unsupported date format
651
 
         */
652
 
        virtual void read(const std::string& buf);
653
 
        //! Set the date
654
 
        void setDate(const Date& src);
655
 
        //@}
656
 
 
657
 
        //! @name Accessors
658
 
        //@{
659
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
660
 
        /*!
661
 
          @brief Write value to a character data buffer.
662
 
 
663
 
          The user must ensure that the buffer has enough memory. Otherwise
664
 
          the call results in undefined behaviour.
665
 
 
666
 
          @note The byte order is required by the interface but not used by this
667
 
                method, so just use the default.
668
 
 
669
 
          @param buf Data buffer to write to.
670
 
          @param byteOrder Byte order. Not used.
671
 
          @return Number of characters written.
672
 
        */
673
 
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
674
 
        //! Return date struct containing date information
675
 
        virtual const Date& getDate() const { return date_; }
676
 
        virtual long count() const { return size(); }
677
 
        virtual long size() const;
678
 
        /*!
679
 
          @brief Write the value to an output stream. .
680
 
        */
681
 
        virtual std::ostream& write(std::ostream& os) const;
682
 
        virtual long toLong(long n =0) const;
683
 
        virtual float toFloat(long n =0) const
684
 
            { return static_cast<float>(toLong(n)); }
685
 
        virtual Rational toRational(long n =0) const
686
 
            { return Rational(toLong(n), 1); }
687
 
        //@}
688
 
 
689
 
    private:
690
 
        //! Internal virtual copy constructor.
691
 
        virtual DateValue* clone_() const;
692
 
        // DATA
693
 
        Date date_;
694
 
 
695
 
    }; // class DateValue
696
 
 
697
 
    /*!
698
 
     @brief %Value for simple ISO 8601 times.
699
 
 
700
 
     This class is limited to handling simple time strings in the ISO 8601
701
 
     format HHMMSS�HHMM where HHMMSS refers to local hour, minute and
702
 
     seconds and �HHMM refers to hours and minutes ahead or behind
703
 
     Universal Coordinated Time.
704
 
     */
705
 
    class TimeValue : public Value {
706
 
    public:
707
 
        //! Shortcut for a %TimeValue auto pointer.
708
 
        typedef std::auto_ptr<TimeValue> AutoPtr;
709
 
 
710
 
        //! @name Creators
711
 
        //@{
712
 
        //! Default constructor.
713
 
        TimeValue() : Value(time) { memset(&time_, 0, sizeof(time_)); }
714
 
        //! Constructor
715
 
        TimeValue(int hour, int minute, int second =0,
716
 
                  int tzHour =0, int tzMinute =0);
717
 
 
718
 
        //! Virtual destructor.
719
 
        virtual ~TimeValue() {}
720
 
        //@}
721
 
 
722
 
        //! Simple Time helper structure
723
 
        struct Time
724
 
        {
725
 
            int hour;                           //!< Hour
726
 
            int minute;                         //!< Minute
727
 
            int second;                         //!< Second
728
 
            int tzHour;                         //!< Hours ahead or behind UTC
729
 
            int tzMinute;                       //!< Minutes ahead or behind UTC
730
 
        };
731
 
 
732
 
        //! @name Manipulators
733
 
        //@{
734
 
        //! Assignment operator.
735
 
        TimeValue& operator=(const TimeValue& rhs);
736
 
        /*!
737
 
          @brief Read the value from a character buffer.
738
 
 
739
 
          @note The byte order is required by the interface but not used by this
740
 
                method, so just use the default.
741
 
 
742
 
          @param buf Pointer to the data buffer to read from
743
 
          @param len Number of bytes in the data buffer
744
 
          @param byteOrder Byte order. Not needed.
745
 
 
746
 
          @throw Error in case of an unsupported time format
747
 
         */
748
 
        virtual void read(const byte* buf,
749
 
                          long len,
750
 
                          ByteOrder byteOrder =invalidByteOrder);
751
 
        /*!
752
 
          @brief Set the value to that of the string buf.
753
 
 
754
 
          @param buf String containing the time.
755
 
 
756
 
          @throw Error in case of an unsupported time format
757
 
         */
758
 
        virtual void read(const std::string& buf);
759
 
        //! Set the time
760
 
        void setTime(const Time& src);
761
 
        //@}
762
 
 
763
 
        //! @name Accessors
764
 
        //@{
765
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
766
 
        /*!
767
 
          @brief Write value to a character data buffer.
768
 
 
769
 
          The user must ensure that the buffer has enough memory. Otherwise
770
 
          the call results in undefined behaviour.
771
 
 
772
 
          @note The byte order is required by the interface but not used by this
773
 
                method, so just use the default.
774
 
 
775
 
          @param buf Data buffer to write to.
776
 
          @param byteOrder Byte order. Not used.
777
 
          @return Number of characters written.
778
 
        */
779
 
        virtual long copy(byte* buf, ByteOrder byteOrder =invalidByteOrder) const;
780
 
        //! Return time struct containing time information
781
 
        virtual const Time& getTime() const { return time_; }
782
 
        virtual long count() const { return size(); }
783
 
        virtual long size() const;
784
 
        /*!
785
 
          @brief Write the value to an output stream. .
786
 
        */
787
 
        virtual std::ostream& write(std::ostream& os) const;
788
 
        virtual long toLong(long n =0) const;
789
 
        virtual float toFloat(long n =0) const
790
 
            { return static_cast<float>(toLong(n)); }
791
 
        virtual Rational toRational(long n =0) const
792
 
            { return Rational(toLong(n), 1); }
793
 
        //@}
794
 
 
795
 
    private:
796
 
        //! Internal virtual copy constructor.
797
 
        virtual TimeValue* clone_() const;
798
 
        // DATA
799
 
        Time time_;
800
 
 
801
 
    }; // class TimeValue
802
 
    //! Template to determine the TypeId for a type T
803
 
    template<typename T> TypeId getType();
804
 
 
805
 
    //! Specialization for an unsigned short
806
 
    template<> inline TypeId getType<uint16_t>() { return unsignedShort; }
807
 
    //! Specialization for an unsigned long
808
 
    template<> inline TypeId getType<uint32_t>() { return unsignedLong; }
809
 
    //! Specialization for an unsigned rational
810
 
    template<> inline TypeId getType<URational>() { return unsignedRational; }
811
 
    //! Specialization for a signed short
812
 
    template<> inline TypeId getType<int16_t>() { return signedShort; }
813
 
    //! Specialization for a signed long
814
 
    template<> inline TypeId getType<int32_t>() { return signedLong; }
815
 
    //! Specialization for a signed rational
816
 
    template<> inline TypeId getType<Rational>() { return signedRational; }
817
 
 
818
 
    // No default implementation: let the compiler/linker complain
819
 
//    template<typename T> inline TypeId getType() { return invalid; }
820
 
 
821
 
    /*!
822
 
      @brief Template for a %Value of a basic type. This is used for unsigned
823
 
             and signed short, long and rationals.
824
 
     */
825
 
    template<typename T>
826
 
    class ValueType : public Value {
827
 
    public:
828
 
        //! Shortcut for a %ValueType\<T\> auto pointer.
829
 
        typedef std::auto_ptr<ValueType<T> > AutoPtr;
830
 
 
831
 
        //! @name Creators
832
 
        //@{
833
 
        //! Default constructor.
834
 
        ValueType() : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0) {}
835
 
        //! Constructor
836
 
        ValueType(const byte* buf, long len, ByteOrder byteOrder);
837
 
        //! Constructor
838
 
        ValueType(const T& val, ByteOrder byteOrder =littleEndian);
839
 
        //! Copy constructor
840
 
        ValueType(const ValueType<T>& rhs);
841
 
        //! Virtual destructor.
842
 
        virtual ~ValueType();
843
 
        //@}
844
 
 
845
 
        //! @name Manipulators
846
 
        //@{
847
 
        //! Assignment operator.
848
 
        ValueType<T>& operator=(const ValueType<T>& rhs);
849
 
        virtual void read(const byte* buf, long len, ByteOrder byteOrder);
850
 
        /*!
851
 
          @brief Set the data from a string of values of type T (e.g.,
852
 
                 "0 1 2 3" or "1/2 1/3 1/4" depending on what T is).
853
 
                 Generally, the accepted input format is the same as that
854
 
                 produced by the write() method.
855
 
         */
856
 
        virtual void read(const std::string& buf);
857
 
        /*!
858
 
          @brief Set the data area. This method copies (clones) the buffer
859
 
                 pointed to by buf.
860
 
         */
861
 
        virtual int setDataArea(const byte* buf, long len);
862
 
        //@}
863
 
 
864
 
        //! @name Accessors
865
 
        //@{
866
 
        AutoPtr clone() const { return AutoPtr(clone_()); }
867
 
        virtual long copy(byte* buf, ByteOrder byteOrder) const;
868
 
        virtual long count() const { return static_cast<long>(value_.size()); }
869
 
        virtual long size() const;
870
 
        virtual std::ostream& write(std::ostream& os) const;
871
 
        virtual long toLong(long n =0) const;
872
 
        virtual float toFloat(long n =0) const;
873
 
        virtual Rational toRational(long n =0) const;
874
 
        //! Return the size of the data area.
875
 
        virtual long sizeDataArea() const { return sizeDataArea_; }
876
 
        /*!
877
 
          @brief Return a copy of the data area in a DataBuf. The caller owns
878
 
                 this copy and DataBuf ensures that it will be deleted.
879
 
         */
880
 
        virtual DataBuf dataArea() const;
881
 
        //@}
882
 
 
883
 
        //! Container for values
884
 
        typedef std::vector<T> ValueList;
885
 
        //! Iterator type defined for convenience.
886
 
        typedef typename std::vector<T>::iterator iterator;
887
 
        //! Const iterator type defined for convenience.
888
 
        typedef typename std::vector<T>::const_iterator const_iterator;
889
 
 
890
 
        // DATA
891
 
        /*!
892
 
          @brief The container for all values. In your application, if you know
893
 
                 what subclass of Value you're dealing with (and possibly the T)
894
 
                 then you can access this STL container through the usual
895
 
                 standard library functions.
896
 
         */
897
 
        ValueList value_;
898
 
 
899
 
    private:
900
 
        //! Internal virtual copy constructor.
901
 
        virtual ValueType<T>* clone_() const;
902
 
 
903
 
        // DATA
904
 
        //! Pointer to the buffer, 0 if none has been allocated
905
 
        byte* pDataArea_;
906
 
        //! The current size of the buffer
907
 
        long sizeDataArea_;
908
 
    }; // class ValueType
909
 
 
910
 
    //! Unsigned short value type
911
 
    typedef ValueType<uint16_t> UShortValue;
912
 
    //! Unsigned long value type
913
 
    typedef ValueType<uint32_t> ULongValue;
914
 
    //! Unsigned rational value type
915
 
    typedef ValueType<URational> URationalValue;
916
 
    //! Signed short value type
917
 
    typedef ValueType<int16_t> ShortValue;
918
 
    //! Signed long value type
919
 
    typedef ValueType<int32_t> LongValue;
920
 
    //! Signed rational value type
921
 
    typedef ValueType<Rational> RationalValue;
922
 
 
923
 
// *****************************************************************************
924
 
// template and inline definitions
925
 
 
926
 
    /*!
927
 
      @brief Read a value of type T from the data buffer.
928
 
 
929
 
      We need this template function for the ValueType template classes.
930
 
      There are only specializations of this function available; no default
931
 
      implementation is provided.
932
 
 
933
 
      @param buf Pointer to the data buffer to read from.
934
 
      @param byteOrder Applicable byte order (little or big endian).
935
 
      @return A value of type T.
936
 
     */
937
 
    template<typename T> T getValue(const byte* buf, ByteOrder byteOrder);
938
 
    // Specialization for a 2 byte unsigned short value.
939
 
    template<>
940
 
    inline uint16_t getValue(const byte* buf, ByteOrder byteOrder)
941
 
    {
942
 
        return getUShort(buf, byteOrder);
943
 
    }
944
 
    // Specialization for a 4 byte unsigned long value.
945
 
    template<>
946
 
    inline uint32_t getValue(const byte* buf, ByteOrder byteOrder)
947
 
    {
948
 
        return getULong(buf, byteOrder);
949
 
    }
950
 
    // Specialization for an 8 byte unsigned rational value.
951
 
    template<>
952
 
    inline URational getValue(const byte* buf, ByteOrder byteOrder)
953
 
    {
954
 
        return getURational(buf, byteOrder);
955
 
    }
956
 
    // Specialization for a 2 byte signed short value.
957
 
    template<>
958
 
    inline int16_t getValue(const byte* buf, ByteOrder byteOrder)
959
 
    {
960
 
        return getShort(buf, byteOrder);
961
 
    }
962
 
    // Specialization for a 4 byte signed long value.
963
 
    template<>
964
 
    inline int32_t getValue(const byte* buf, ByteOrder byteOrder)
965
 
    {
966
 
        return getLong(buf, byteOrder);
967
 
    }
968
 
    // Specialization for an 8 byte signed rational value.
969
 
    template<>
970
 
    inline Rational getValue(const byte* buf, ByteOrder byteOrder)
971
 
    {
972
 
        return getRational(buf, byteOrder);
973
 
    }
974
 
 
975
 
    /*!
976
 
      @brief Convert a value of type T to data, write the data to the data buffer.
977
 
 
978
 
      We need this template function for the ValueType template classes.
979
 
      There are only specializations of this function available; no default
980
 
      implementation is provided.
981
 
 
982
 
      @param buf Pointer to the data buffer to write to.
983
 
      @param t Value to be converted.
984
 
      @param byteOrder Applicable byte order (little or big endian).
985
 
      @return The number of bytes written to the buffer.
986
 
     */
987
 
    template<typename T> long toData(byte* buf, T t, ByteOrder byteOrder);
988
 
    /*!
989
 
      @brief Specialization to write an unsigned short to the data buffer.
990
 
             Return the number of bytes written.
991
 
     */
992
 
    template<>
993
 
    inline long toData(byte* buf, uint16_t t, ByteOrder byteOrder)
994
 
    {
995
 
        return us2Data(buf, t, byteOrder);
996
 
    }
997
 
    /*!
998
 
      @brief Specialization to write an unsigned long to the data buffer.
999
 
             Return the number of bytes written.
1000
 
     */
1001
 
    template<>
1002
 
    inline long toData(byte* buf, uint32_t t, ByteOrder byteOrder)
1003
 
    {
1004
 
        return ul2Data(buf, t, byteOrder);
1005
 
    }
1006
 
    /*!
1007
 
      @brief Specialization to write an unsigned rational to the data buffer.
1008
 
             Return the number of bytes written.
1009
 
     */
1010
 
    template<>
1011
 
    inline long toData(byte* buf, URational t, ByteOrder byteOrder)
1012
 
    {
1013
 
        return ur2Data(buf, t, byteOrder);
1014
 
    }
1015
 
    /*!
1016
 
      @brief Specialization to write a signed short to the data buffer.
1017
 
             Return the number of bytes written.
1018
 
     */
1019
 
    template<>
1020
 
    inline long toData(byte* buf, int16_t t, ByteOrder byteOrder)
1021
 
    {
1022
 
        return s2Data(buf, t, byteOrder);
1023
 
    }
1024
 
    /*!
1025
 
      @brief Specialization to write a signed long to the data buffer.
1026
 
             Return the number of bytes written.
1027
 
     */
1028
 
    template<>
1029
 
    inline long toData(byte* buf, int32_t t, ByteOrder byteOrder)
1030
 
    {
1031
 
        return l2Data(buf, t, byteOrder);
1032
 
    }
1033
 
    /*!
1034
 
      @brief Specialization to write a signed rational to the data buffer.
1035
 
             Return the number of bytes written.
1036
 
     */
1037
 
    template<>
1038
 
    inline long toData(byte* buf, Rational t, ByteOrder byteOrder)
1039
 
    {
1040
 
        return r2Data(buf, t, byteOrder);
1041
 
    }
1042
 
 
1043
 
    template<typename T>
1044
 
    ValueType<T>::ValueType(const byte* buf, long len, ByteOrder byteOrder)
1045
 
        : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
1046
 
    {
1047
 
        read(buf, len, byteOrder);
1048
 
    }
1049
 
 
1050
 
    template<typename T>
1051
 
    ValueType<T>::ValueType(const T& val, ByteOrder byteOrder)
1052
 
        : Value(getType<T>()), pDataArea_(0), sizeDataArea_(0)
1053
 
    {
1054
 
        read(reinterpret_cast<const byte*>(&val),
1055
 
             TypeInfo::typeSize(typeId()),
1056
 
             byteOrder);
1057
 
    }
1058
 
 
1059
 
    template<typename T>
1060
 
    ValueType<T>::ValueType(const ValueType<T>& rhs)
1061
 
        : Value(rhs), value_(rhs.value_), pDataArea_(0), sizeDataArea_(0)
1062
 
    {
1063
 
        if (rhs.sizeDataArea_ > 0) {
1064
 
            pDataArea_ = new byte[rhs.sizeDataArea_];
1065
 
            memcpy(pDataArea_, rhs.pDataArea_, rhs.sizeDataArea_);
1066
 
            sizeDataArea_ = rhs.sizeDataArea_;
1067
 
        }
1068
 
    }
1069
 
 
1070
 
    template<typename T>
1071
 
    ValueType<T>::~ValueType()
1072
 
    {
1073
 
        delete[] pDataArea_;
1074
 
    }
1075
 
 
1076
 
    template<typename T>
1077
 
    ValueType<T>& ValueType<T>::operator=(const ValueType<T>& rhs)
1078
 
    {
1079
 
        if (this == &rhs) return *this;
1080
 
        Value::operator=(rhs);
1081
 
        value_ = rhs.value_;
1082
 
 
1083
 
        byte* tmp = 0;
1084
 
        if (rhs.sizeDataArea_ > 0) {
1085
 
            tmp = new byte[rhs.sizeDataArea_];
1086
 
            memcpy(tmp, rhs.pDataArea_, rhs.sizeDataArea_);
1087
 
        }
1088
 
        delete[] pDataArea_;
1089
 
        pDataArea_ = tmp;
1090
 
        sizeDataArea_ = rhs.sizeDataArea_;
1091
 
 
1092
 
        return *this;
1093
 
    }
1094
 
 
1095
 
    template<typename T>
1096
 
    void ValueType<T>::read(const byte* buf, long len, ByteOrder byteOrder)
1097
 
    {
1098
 
        value_.clear();
1099
 
        for (long i = 0; i < len; i += TypeInfo::typeSize(typeId())) {
1100
 
            value_.push_back(getValue<T>(buf + i, byteOrder));
1101
 
        }
1102
 
    }
1103
 
 
1104
 
    template<typename T>
1105
 
    void ValueType<T>::read(const std::string& buf)
1106
 
    {
1107
 
        std::istringstream is(buf);
1108
 
        T tmp;
1109
 
        value_.clear();
1110
 
        while (is >> tmp) {
1111
 
            value_.push_back(tmp);
1112
 
        }
1113
 
    }
1114
 
 
1115
 
    template<typename T>
1116
 
    long ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const
1117
 
    {
1118
 
        long offset = 0;
1119
 
        typename ValueList::const_iterator end = value_.end();
1120
 
        for (typename ValueList::const_iterator i = value_.begin(); i != end; ++i) {
1121
 
            offset += toData(buf + offset, *i, byteOrder);
1122
 
        }
1123
 
        return offset;
1124
 
    }
1125
 
 
1126
 
    template<typename T>
1127
 
    long ValueType<T>::size() const
1128
 
    {
1129
 
        return static_cast<long>(TypeInfo::typeSize(typeId()) * value_.size());
1130
 
    }
1131
 
 
1132
 
    template<typename T>
1133
 
    ValueType<T>* ValueType<T>::clone_() const
1134
 
    {
1135
 
        return new ValueType<T>(*this);
1136
 
    }
1137
 
 
1138
 
    template<typename T>
1139
 
    std::ostream& ValueType<T>::write(std::ostream& os) const
1140
 
    {
1141
 
        typename ValueList::const_iterator end = value_.end();
1142
 
        typename ValueList::const_iterator i = value_.begin();
1143
 
        while (i != end) {
1144
 
            os << *i;
1145
 
            if (++i != end) os << " ";
1146
 
        }
1147
 
        return os;
1148
 
    }
1149
 
    // Default implementation
1150
 
    template<typename T>
1151
 
    inline long ValueType<T>::toLong(long n) const
1152
 
    {
1153
 
        return value_[n];
1154
 
    }
1155
 
    // Specialization for rational
1156
 
    template<>
1157
 
    inline long ValueType<Rational>::toLong(long n) const
1158
 
    {
1159
 
        return value_[n].first / value_[n].second;
1160
 
    }
1161
 
    // Specialization for unsigned rational
1162
 
    template<>
1163
 
    inline long ValueType<URational>::toLong(long n) const
1164
 
    {
1165
 
        return value_[n].first / value_[n].second;
1166
 
    }
1167
 
    // Default implementation
1168
 
    template<typename T>
1169
 
    inline float ValueType<T>::toFloat(long n) const
1170
 
    {
1171
 
        return static_cast<float>(value_[n]);
1172
 
    }
1173
 
    // Specialization for rational
1174
 
    template<>
1175
 
    inline float ValueType<Rational>::toFloat(long n) const
1176
 
    {
1177
 
        return static_cast<float>(value_[n].first) / value_[n].second;
1178
 
    }
1179
 
    // Specialization for unsigned rational
1180
 
    template<>
1181
 
    inline float ValueType<URational>::toFloat(long n) const
1182
 
    {
1183
 
        return static_cast<float>(value_[n].first) / value_[n].second;
1184
 
    }
1185
 
    // Default implementation
1186
 
    template<typename T>
1187
 
    inline Rational ValueType<T>::toRational(long n) const
1188
 
    {
1189
 
        return Rational(value_[n], 1);
1190
 
    }
1191
 
    // Specialization for rational
1192
 
    template<>
1193
 
    inline Rational ValueType<Rational>::toRational(long n) const
1194
 
    {
1195
 
        return Rational(value_[n].first, value_[n].second);
1196
 
    }
1197
 
    // Specialization for unsigned rational
1198
 
    template<>
1199
 
    inline Rational ValueType<URational>::toRational(long n) const
1200
 
    {
1201
 
        return Rational(value_[n].first, value_[n].second);
1202
 
    }
1203
 
 
1204
 
    template<typename T>
1205
 
    inline DataBuf ValueType<T>::dataArea() const
1206
 
    {
1207
 
        return DataBuf(pDataArea_, sizeDataArea_);
1208
 
    }
1209
 
 
1210
 
    template<typename T>
1211
 
    inline int ValueType<T>::setDataArea(const byte* buf, long len)
1212
 
    {
1213
 
        byte* tmp = 0;
1214
 
        if (len > 0) {
1215
 
            tmp = new byte[len];
1216
 
            memcpy(tmp, buf, len);
1217
 
        }
1218
 
        delete[] pDataArea_;
1219
 
        pDataArea_ = tmp;
1220
 
        sizeDataArea_ = len;
1221
 
        return 0;
1222
 
    }
1223
 
 
1224
 
}                                       // namespace Exiv2
1225
 
 
1226
 
#endif                                  // #ifndef VALUE_HPP_