[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:36:39 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=6034d99

The following commit has been merged in the master branch:
commit 6034d999507936bd0f4d9281a13027d3e756e5a7
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Tue Sep 21 16:06:50 2004 +0000

    Added support for unknown Iptc keys
---
 src/datasets.cpp | 97 ++++++++++++++++++++++++++------------------------------
 src/datasets.hpp | 42 ++++++++----------------
 src/iptc.cpp     | 47 ++++++++++++++++++++++-----
 src/iptc.hpp     | 29 ++++++++++-------
 src/iptctest.cpp | 26 ++++++---------
 src/key-test.cpp | 41 +++++++++++++++++++++++-
 6 files changed, 164 insertions(+), 118 deletions(-)

diff --git a/src/datasets.cpp b/src/datasets.cpp
index fd7c22c..f8d0e32 100644
--- a/src/datasets.cpp
+++ b/src/datasets.cpp
@@ -20,13 +20,13 @@
  */
 /*
   File:      datasets.cpp
-  Version:   $Name:  $ $Revision: 1.5 $
+  Version:   $Name:  $ $Revision: 1.6 $
   Author(s): Brad Schick (brad) <schick at robotbattle.com>
   History:   24-Jul-04, brad: created
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.5 $ $RCSfile: datasets.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.6 $ $RCSfile: datasets.cpp,v $");
 
 // *****************************************************************************
 // included header files
@@ -37,6 +37,10 @@ EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.5 $ $RCSfile: datasets.cpp,v $");
 
 #include <iostream>
 #include <iomanip>
+#include <sstream>
+
+// Todo: remove circular dependency
+#include "iptc.hpp"                             // for DataSet operator<<
 
 // *****************************************************************************
 // class member definitions
@@ -162,8 +166,6 @@ namespace Exiv2 {
         0
     };
 
-    const char* IptcDataSets::familyName_ = "Iptc";
-
     int IptcDataSets::dataSetIdx(uint16_t number, uint16_t recordId)
     {
         if( recordId != envelope && recordId != application2 ) return -1;
@@ -195,11 +197,15 @@ namespace Exiv2 {
         return records_[recordId][idx].type_;
     }
 
-    const char* IptcDataSets::dataSetName(uint16_t number, uint16_t recordId)
+    std::string IptcDataSets::dataSetName(uint16_t number, uint16_t recordId)
     {
         int idx = dataSetIdx(number, recordId);
-        if (idx == -1) throw Error("No dataSet for record Id");
-        return records_[recordId][idx].name_;
+        if (idx != -1) return records_[recordId][idx].name_;
+
+        std::ostringstream os;
+        os << "0x" << std::setw(4) << std::setfill('0') << std::right
+           << std::hex << number;
+        return os.str();
     }
 
     const char* IptcDataSets::dataSetDesc(uint16_t number, uint16_t recordId)
@@ -223,12 +229,33 @@ namespace Exiv2 {
         return records_[recordId][idx].repeatable_;
     }
 
-    const char* IptcDataSets::recordName(uint16_t recordId)
+    uint16_t IptcDataSets::dataSet(const std::string& dataSetName, 
+                                   uint16_t recordId)
     {
-        if( recordId != envelope && recordId != application2 ) {
-            throw Error("Unknown record");
+        uint16_t dataSet;
+        int idx = dataSetIdx(dataSetName, recordId);
+        if (idx != -1) {
+            // dataSetIdx checks the range of recordId
+            dataSet = records_[recordId][idx].number_;
         }
-        return recordInfo_[recordId].name_;
+        else {
+            // Todo: Check format of tagName
+            std::istringstream is(dataSetName);
+            is >> std::hex >> dataSet;
+        }
+        return dataSet;
+    }
+
+    std::string IptcDataSets::recordName(uint16_t recordId)
+    {
+        if (recordId == envelope || recordId == application2) {
+            return recordInfo_[recordId].name_;            
+        }
+
+        std::ostringstream os;
+        os << "0x" << std::setw(4) << std::setfill('0') << std::right
+           << std::hex << recordId;
+        return os.str();
     }
 
     const char* IptcDataSets::recordDesc(uint16_t recordId)
@@ -245,49 +272,14 @@ namespace Exiv2 {
         for (i = application2; i > 0; --i) {
             if (recordInfo_[i].name_ == recordName) break;
         }
+        if (i == 0) {
+            // Todo: Check format of recordName
+            std::istringstream is(recordName);
+            is >> std::hex >> i;
+        }
         return i;
     }
 
-    std::string IptcDataSets::makeKey(const DataSet& dataSet)
-    {
-        return std::string(familyName())
-            + "." + std::string(recordName(dataSet.recordId_)) 
-            + "." + dataSet.name_;
-    }
-
-    std::string IptcDataSets::makeKey(uint16_t number, uint16_t recordId)
-    {
-        return std::string(familyName())
-            + "." + std::string(recordName(recordId)) 
-            + "." + std::string(dataSetName(number, recordId));
-    }
-
-    // This 'database lookup' function returns a match if it exists
-    std::pair<uint16_t, uint16_t> IptcDataSets::decomposeKey(const std::string& key)
-    {
-        // Get the type, record name and dataSet name parts of the key
-        std::string::size_type pos1 = key.find('.');
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string type = key.substr(0, pos1);
-        if (type != "Iptc") throw Error("Invalid key");
-        std::string::size_type pos0 = pos1 + 1;
-        pos1 = key.find('.', pos0);
-        if (pos1 == std::string::npos) throw Error("Invalid key");
-        std::string recordName = key.substr(pos0, pos1 - pos0);
-        if (recordName == "") throw Error("Invalid key");
-        std::string dataSetName = key.substr(pos1 + 1);
-        if (dataSetName == "") throw Error("Invalid key");
-
-        // Use the parts of the key to find dataSet and recordInfo
-        uint16_t recId = recordId(recordName);
-        if (recId == invalidRecord) return std::make_pair((uint16_t)0xffff, invalidRecord);
-
-        int idx = dataSetIdx(dataSetName, recId);
-        if (idx == -1 ) return std::make_pair((uint16_t)0xffff, invalidRecord);
-
-        return std::make_pair(records_[recId][idx].number_, recId);
-    } // IptcDataSets::decomposeKey
-
     void IptcDataSets::dataSetList(std::ostream& os)
     {
         const int count = sizeof(records_)/sizeof(records_[0]);
@@ -304,6 +296,7 @@ namespace Exiv2 {
 
     std::ostream& operator<<(std::ostream& os, const DataSet& dataSet) 
     {
+        IptcKey iptcKey(dataSet.number_, dataSet.recordId_);
         return os << dataSet.name_ << ", "
                   << std::dec << dataSet.number_ << ", "
                   << "0x" << std::setw(4) << std::setfill('0') 
@@ -313,7 +306,7 @@ namespace Exiv2 {
                   << dataSet.repeatable_ << ", "
                   << std::dec << dataSet.minbytes_ << ", "
                   << dataSet.maxbytes_ << ", "
-                  << IptcDataSets::makeKey(dataSet) << ", "
+                  << iptcKey.key() << ", "
                   << dataSet.desc_;
     }
 
diff --git a/src/datasets.hpp b/src/datasets.hpp
index 0cd136b..199b3e8 100644
--- a/src/datasets.hpp
+++ b/src/datasets.hpp
@@ -21,7 +21,7 @@
 /*!
   @file    datasets.hpp
   @brief   Iptc dataSet and type information
-  @version $Name:  $ $Revision: 1.4 $
+  @version $Name:  $ $Revision: 1.5 $
   @author  Brad Schick (brad) <schick at robotbattle.com>
   @date    24-Jul-04, brad: created
  */
@@ -173,9 +173,6 @@ namespace Exiv2 {
         //@}
 
     private:
-        static const char* familyName_;
-
-    private:
         //! Prevent construction: not implemented.
         IptcDataSets() {}
         //! Prevent copy-construction: not implemented.
@@ -184,17 +181,15 @@ namespace Exiv2 {
         IptcDataSets& operator=(const IptcDataSets& rhs);
 
     public:
-        //! Return an identifier for Iptc datasets
-        static const char* familyName() { return familyName_; }
         /*!
           @brief Return the name of the dataset.
           @param number The dataset number
           @param recordId The Iptc record Id 
-          @return The name of the dataset
-          @throw Error ("No dataset for recordId") if there is no dataset info
-                 for the given record id in the lookup tables.
+          @return The name of the dataset or a string containing the hexadecimal
+                  value of the dataset in the form "0x01ff", if this is an unknown 
+                  dataset.
          */
-        static const char* dataSetName(uint16_t number, uint16_t recordId);
+        static std::string dataSetName(uint16_t number, uint16_t recordId);
         /*!
           @brief Return the description of the dataset.
           @param number The dataset number
@@ -227,8 +222,14 @@ namespace Exiv2 {
         static uint16_t dataSet(const std::string& dataSetName, uint16_t recordId);
         //! Return the type for dataSet number and Record id
         static TypeId dataSetType(uint16_t number, uint16_t recordId);
-        //! Return the name of the Record
-        static const char* recordName(uint16_t recordId);
+        /*!
+          @brief Return the name of the Record
+          @param recordId The record id
+          @return The name of the record or a string containing the hexadecimal
+                  value of the record in the form "0x01ff", if this is an
+                  unknown record.
+         */
+        static std::string recordName(uint16_t recordId);
         /*!
            @brief Return the description of a record
            @param recordId Record Id number
@@ -243,23 +244,6 @@ namespace Exiv2 {
            @throw Error("Unknown record");
          */
         static uint16_t recordId(const std::string& recordName);
-        /*!
-          @brief Return the key for the dataSet number and record id. The key is
-                 of the form '<b>Iptc</b>.recordName.dataSetName'.
-         */
-        static std::string makeKey(uint16_t number, uint16_t recordId);
-        /*!
-          @brief Return the key for the dataSet. The key is of the form
-                 '<b>Iptc</b>.recordName.dataSetName'.
-         */
-        static std::string makeKey(const DataSet& dataSet);
-        /*!
-          @brief Return dataSet and record id pair for the key.
-          @return A pair consisting of the dataSet number and record id.
-          @throw Error ("Invalid key") if the key cannot be parsed into
-                 record name and dataSet name parts.
-         */
-        static std::pair<uint16_t, uint16_t> decomposeKey(const std::string& key);
         //! Print a list of all dataSets to output stream
         static void dataSetList(std::ostream& os);
 
diff --git a/src/iptc.cpp b/src/iptc.cpp
index 5c6d70d..78ce451 100644
--- a/src/iptc.cpp
+++ b/src/iptc.cpp
@@ -20,13 +20,13 @@
  */
 /*
   File:      iptc.cpp
-  Version:   $Name:  $ $Revision: 1.4 $
+  Version:   $Name:  $ $Revision: 1.5 $
   Author(s): Brad Schick (brad) <schick at robotbattle.com>
   History:   31-July-04, brad: created
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.4 $ $RCSfile: iptc.cpp,v $");
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.5 $ $RCSfile: iptc.cpp,v $");
 
 // Define DEBUG_MAKERNOTE to output debug information to std::cerr
 #undef DEBUG_MAKERNOTE
@@ -48,6 +48,8 @@ EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.4 $ $RCSfile: iptc.cpp,v $");
 // class member definitions
 namespace Exiv2 {
 
+    const char* IptcKey::familyName_ = "Iptc";
+
     IptcKey::IptcKey(const std::string& key)
         : key_(key)
     {
@@ -55,8 +57,9 @@ namespace Exiv2 {
     }
 
     IptcKey::IptcKey(uint16_t tag, uint16_t record)
-        : tag_(tag), record_(record), key_(IptcDataSets::makeKey(tag, record))
+        : tag_(tag), record_(record)
     {
+        makeKey();
     }
 
     IptcKey::IptcKey(const IptcKey& rhs)
@@ -81,11 +84,39 @@ namespace Exiv2 {
 
     void IptcKey::decomposeKey()
     {
-        std::pair<uint16_t, uint16_t> p = IptcDataSets::decomposeKey(key_);
-        if (p.first == 0xffff) throw Error("Invalid key");
-        if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key");
-        tag_ = p.first;
-        record_ = p.second;
+        // Get the family name, record name and dataSet name parts of the key
+        std::string::size_type pos1 = key_.find('.');
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string familyName = key_.substr(0, pos1);
+        if (familyName != std::string(familyName_)) {
+            throw Error("Invalid key");
+        }
+        std::string::size_type pos0 = pos1 + 1;
+        pos1 = key_.find('.', pos0);
+        if (pos1 == std::string::npos) throw Error("Invalid key");
+        std::string recordName = key_.substr(pos0, pos1 - pos0);
+        if (recordName == "") throw Error("Invalid key");
+        std::string dataSetName = key_.substr(pos1 + 1);
+        if (dataSetName == "") throw Error("Invalid key");
+
+        // Use the parts of the key to find dataSet and recordId
+        uint16_t recId = IptcDataSets::recordId(recordName);
+        uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
+
+        // Possibly translate hex name parts (0xabcd) to real names 
+        recordName = IptcDataSets::recordName(recId);
+        dataSetName = IptcDataSets::dataSetName(dataSet, recId);
+
+        tag_ = dataSet;
+        record_ = recId;
+        key_ = familyName + "." + recordName + "." + dataSetName;
+    } // IptcKey::decomposeKey
+
+    void IptcKey::makeKey()
+    {
+        key_ = std::string(familyName_)
+            + "." + IptcDataSets::recordName(record_)
+            + "." + IptcDataSets::dataSetName(tag_, record_);
     }
 
     Iptcdatum::Iptcdatum(const IptcKey& key, 
diff --git a/src/iptc.hpp b/src/iptc.hpp
index 36253d2..d613c1a 100644
--- a/src/iptc.hpp
+++ b/src/iptc.hpp
@@ -21,7 +21,7 @@
 /*!
   @file    iptc.hpp
   @brief   Encoding and decoding of Iptc data
-  @version $Name:  $ $Revision: 1.5 $
+  @version $Name:  $ $Revision: 1.6 $
   @author  Brad Schick (brad) 
            <a href="mailto:schick at robotbattle.com">schick at robotbattle.com</a>
   @date    31-Jul-04, brad: created
@@ -83,8 +83,7 @@ namespace Exiv2 {
         //! @name Accessors
         //@{
         virtual std::string key() const { return key_; }
-        virtual const char* familyName() const 
-            { return IptcDataSets::familyName(); }
+        virtual const char* familyName() const { return familyName_; }
         /*!
           @brief Return the name of the group (the second part of the key).
                  For Iptc keys, the group name is the record name.
@@ -96,7 +95,7 @@ namespace Exiv2 {
         virtual IptcKey* clone() const;
 
         //! Return the name of the record
-        const char* recordName() const
+        std::string recordName() const
             { return IptcDataSets::recordName(record_); }
         //! Return the record id
         uint16_t record() const { return record_; }
@@ -106,20 +105,26 @@ namespace Exiv2 {
         //! @name Manipulators
         //@{
         /*!
-          @brief Parse and convert the key string into dataset and record id. 
-                 Updates tag_ and record_ if the string can be decomposed,
-                 or throws Error ("Invalid key").
+          @brief Set the key corresponding to the dataset and record id. 
+                 The key is of the form '<b>Iptc</b>.recordName.dataSetName'.
+         */
+        void makeKey();
+        /*!
+          @brief Parse and convert the key string into dataset and record id.
+                 Updates data members if the string can be decomposed, or throws
+                 Error ("Invalid key").
 
-          @throw Error ("Invalid key") if the key cannot be parsed into
-                 family name, group name and tag name parts.
+          @throw Error ("Invalid key") if the key cannot be decomposed.
          */
         void decomposeKey();
         //@}
 
     private:
         // DATA
-        uint16_t tag_;                   //!< Tag value
-        uint16_t record_;                //!< Record value 
+        static const char* familyName_;
+
+        uint16_t tag_;                 //!< Tag value
+        uint16_t record_;              //!< Record value 
         std::string key_;              //!< Key
 
     }; // class IptcKey
@@ -195,7 +200,7 @@ namespace Exiv2 {
            @return record name
            @throw Error("Unknown record");
          */
-        const char* recordName() const
+        std::string recordName() const
             { return pKey_ == 0 ? "" : pKey_->recordName(); }
         /*!
            @brief Return the record id 
diff --git a/src/iptctest.cpp b/src/iptctest.cpp
index 648c705..5f849d0 100644
--- a/src/iptctest.cpp
+++ b/src/iptctest.cpp
@@ -4,7 +4,7 @@
              This is not designed to be a robust application.
 
   File     : iptctest.cpp
-  Version  : $Name:  $ $Revision: 1.3 $
+  Version  : $Name:  $ $Revision: 1.4 $
   Author(s): Brad Schick (brad) <schick at robotbattle.com>
   History  : 01-Aug-04, brad: created
  */
@@ -105,20 +105,18 @@ void processAdd(const std::string& line, int num)
     }
 
     std::string key(line.substr(keyStart, keyEnd-keyStart));
-    std::pair<uint16_t, uint16_t> p = IptcDataSets::decomposeKey(key);
-    if (p.first == 0xffff) throw Error("Invalid key " + key);
-    if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key " + key);
+    IptcKey iptcKey(key);
 
     std::string data(line.substr(dataStart));
     // if data starts and ends with quotes, remove them
     if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
         data = data.substr(1, data.size()-2);
     }
-    TypeId type = IptcDataSets::dataSetType(p.first, p.second);
+    TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
     Value *val = Value::create(type);
     val->read(data);
 
-    int rc = g_iptcData.add(IptcKey(key), val);
+    int rc = g_iptcData.add(iptcKey, val);
     if (rc) {
         std::string error = IptcData::strError(rc, "Input file");
         throw Error(error);
@@ -137,11 +135,9 @@ void processRemove(const std::string& line, int num)
     }
 
     const std::string key( line.substr(keyStart) );
-    std::pair<uint16_t, uint16_t> p = IptcDataSets::decomposeKey(key);
-    if (p.first == 0xffff) throw Error("Invalid key" + key);
-    if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key" + key);
+    IptcKey iptcKey(key);
 
-    IptcData::iterator iter = g_iptcData.findId(p.first, p.second);
+    IptcData::iterator iter = g_iptcData.findId(iptcKey.tag(), iptcKey.record());
     if (iter != g_iptcData.end()) {
         g_iptcData.erase(iter);
     }
@@ -162,25 +158,23 @@ void processModify(const std::string& line, int num)
     }
 
     std::string key(line.substr(keyStart, keyEnd-keyStart));
-    std::pair<uint16_t, uint16_t> p = IptcDataSets::decomposeKey(key);
-    if (p.first == 0xffff) throw Error("Invalid key" + key);
-    if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key" + key);
+    IptcKey iptcKey(key);
 
     std::string data(line.substr(dataStart));
     // if data starts and ends with quotes, remove them
     if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
         data = data.substr(1, data.size()-2);
     }
-    TypeId type = IptcDataSets::dataSetType(p.first, p.second);
+    TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
     Value *val = Value::create(type);
     val->read(data);
 
-    IptcData::iterator iter = g_iptcData.findId(p.first, p.second);
+    IptcData::iterator iter = g_iptcData.findId(iptcKey.tag(), iptcKey.record());
     if (iter != g_iptcData.end()) {
         iter->setValue(val);
     }
     else {
-        int rc = g_iptcData.add(IptcKey(key), val);
+        int rc = g_iptcData.add(iptcKey, val);
         if (rc) {
             std::string error = IptcData::strError(rc, "Input file");
             throw Error(error);
diff --git a/src/key-test.cpp b/src/key-test.cpp
index 03d531b..0908914 100644
--- a/src/key-test.cpp
+++ b/src/key-test.cpp
@@ -3,7 +3,7 @@
   Abstract : Key unit tests 
 
   File     : key-test.cpp
-  Version  : $Name:  $ $Revision: 1.3 $
+  Version  : $Name:  $ $Revision: 1.4 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History  : 24-Aug-04, ahu: created
 
@@ -11,6 +11,7 @@
 // *****************************************************************************
 // included header files
 #include "exif.hpp"
+#include "iptc.hpp"
 #include <iostream>
 #include <string>
 
@@ -229,6 +230,44 @@ int main()
 
     // -----
 
+    IptcKey ik1("Iptc.Envelope.0x0005");
+    tc += 1;
+    if (ik1.key() != "Iptc.Envelope.Destination") {
+        std::cout << "Testcase failed (converted Iptc key)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ik1.tagName() != "Destination") {
+        std::cout << "Testcase failed (converted tagName)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ik1.recordName() != "Envelope") {
+        std::cout << "Testcase failed (converted recordName)" << std::endl;
+        rc += 1; 
+    }
+
+    // -----
+
+    IptcKey ik2(0xabcd, 0x1234);
+    tc += 1;
+    if (ik2.key() != "Iptc.0x1234.0xabcd") {
+        std::cout << "Testcase failed (unknown Iptc key)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ik2.tagName() != "0xabcd") {
+        std::cout << "Testcase failed (converted tagName)" << std::endl;
+        rc += 1; 
+    }
+    tc += 1;
+    if (ik2.recordName() != "0x1234") {
+        std::cout << "Testcase failed (converted recordName)" << std::endl;
+        rc += 1; 
+    }
+
+    // -----
+
     if (rc == 0) {
         std::cout << "All " << tc << " testcases passed." << std::endl;
     }

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list