[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:06 UTC 2017


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

The following commit has been merged in the master branch:
commit 9a030e375d616a1c331038a0299d92728fb88ef9
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Fri Mar 5 07:56:48 2004 +0000

    Added wildcard support to MakerNoteFactory
---
 src/makernote.cpp | 156 ++++++++++++++++++++++++++++++++++++++++++++++++------
 src/makernote.hpp |  58 +++++++++++++++-----
 2 files changed, 184 insertions(+), 30 deletions(-)

diff --git a/src/makernote.cpp b/src/makernote.cpp
index a44cf73..592db73 100644
--- a/src/makernote.cpp
+++ b/src/makernote.cpp
@@ -20,7 +20,7 @@
  */
 /*
   File:      makernote.cpp
-  Version:   $Name:  $ $Revision: 1.1 $
+  Version:   $Name:  $ $Revision: 1.2 $
   Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
   History:   18-Feb-04, ahu: created
   Credits:   Canon MakerNote implemented according to the specification
@@ -29,7 +29,7 @@
  */
 // *****************************************************************************
 #include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.1 $ $RCSfile: makernote.cpp,v $")
+EXIV2_RCSID("@(#) $Name:  $ $Revision: 1.2 $ $RCSfile: makernote.cpp,v $")
 
 // *****************************************************************************
 // included header files
@@ -54,7 +54,7 @@ namespace Exif {
     {
         return std::string(ExifTags::ifdItem(makerIfd))
             + "." + sectionName(tag) + "." + tagName(tag);
-    }
+    } // MakerNote::makeKey
 
     uint16 MakerNote::decomposeKey(const std::string& key) const
     {
@@ -76,7 +76,7 @@ namespace Exif {
         if (sectionName != this->sectionName(tag)) return 0xffff;
 
         return tag;
-    }
+    } // MakerNote::decomposeKey
 
     std::string MakerNote::tagName(uint16 tag) const
     {
@@ -96,7 +96,7 @@ namespace Exif {
             tagName = os.str();
         }
         return tagName;
-    }
+    } // MakerNote::tagName
 
     uint16 MakerNote::tag(const std::string& tagName) const
     {
@@ -114,7 +114,7 @@ namespace Exif {
             is >> std::hex >> tag;
         }
         return tag;
-    }
+    } // MakerNote::tag
 
     MakerNoteFactory* MakerNoteFactory::instance_ = 0;
 
@@ -130,32 +130,154 @@ namespace Exif {
                                              const std::string& model, 
                                              MakerNote* makerNote)
     {
-        std::string key = make + "+" + model;
-        Registry::iterator i = registry_.find(key);
-        if (i != registry_.end()) {
-            delete i->second;
+        // Todo: use case insensitive make and model comparisons
+
+        // find or create a registry entry for make
+        ModelRegistry* modelRegistry = 0;
+        Registry::const_iterator end1 = registry_.end();
+        Registry::const_iterator pos1;
+        for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
+            if (pos1->first == make) break;
+        }
+        if (pos1 != end1) {
+            modelRegistry = pos1->second;
+        }
+        else {
+            modelRegistry = new ModelRegistry;
+            registry_.push_back(std::make_pair(make, modelRegistry));
+        }
+        // find or create a registry entry for model
+        ModelRegistry::iterator end2 = modelRegistry->end();
+        ModelRegistry::iterator pos2;
+        for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) {
+            if (pos2->first == model) break;
+        }
+        if (pos2 != end2) {
+            delete pos2->second;
+            pos2->second = makerNote;
+        }
+        else {
+            modelRegistry->push_back(std::make_pair(model, makerNote));
         }
-        registry_[key] = makerNote;
     } // MakerNoteFactory::registerMakerNote
 
     MakerNoteFactory::MakerNoteFactory()
     {
         // Register a prototype of each known MakerNote
-        registerMakerNote("Canon", "Canon PowerShot S40", new CanonMakerNote);
+        registerMakerNote("Canon", "*", new CanonMakerNote);
     } // MakerNoteFactory c'tor
 
     MakerNote* MakerNoteFactory::create(const std::string& make, 
                                         const std::string& model) const
     {
+        // loop through each make of the registry to find the best matching make
+        int matchCount = -1;
+        ModelRegistry* modelRegistry = 0;
+        Registry::const_iterator end1 = registry_.end();
+        Registry::const_iterator pos1;
+        for (pos1 = registry_.begin(); pos1 != end1; ++pos1) {
+            std::pair<bool, int> rc = match(pos1->first, make);
+            if (rc.first && rc.second > matchCount) {
+                matchCount = rc.second;
+                modelRegistry = pos1->second;
+            }
+        }
+        if (modelRegistry == 0) return 0;
+
+        // loop through each model of the model registry to find the best match
+        matchCount = -1;
         MakerNote* makerNote = 0;
-        std::string key = make + "+" + model;
-        Registry::const_iterator i = registry_.find(key);
-        if (i != registry_.end() && i->second != 0) {
-            makerNote = i->second->clone();
+        ModelRegistry::const_iterator end2 = modelRegistry->end();
+        ModelRegistry::const_iterator pos2;
+        for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) {
+            std::pair<bool, int> rc = match(pos2->first, model);
+            if (rc.first && rc.second > matchCount) {
+                matchCount = rc.second;
+                makerNote = pos2->second;
+            }
         }
-        return makerNote;
+        if (makerNote == 0) return 0;
+
+        return makerNote->clone();
     } // MakerNoteFactory::create
 
+    std::pair<bool, int> MakerNoteFactory::match(const std::string& regEntry,
+                                                 const std::string& key)
+    {
+        // Todo: make the comparisons case insensitive
+
+        std::string uKey = key;
+        std::string uReg = regEntry;
+
+        int count = 0;                          // number of matching characters
+        std::string::size_type ei = 0;          // index in the registry entry
+        std::string::size_type ki = 0;          // index in the key
+
+        while (ei != std::string::npos) {
+
+            std::string::size_type pos = uReg.find('*', ei);
+            if (pos != ei) {
+                std::string ss = pos == std::string::npos ?
+                    uReg.substr(ei) : uReg.substr(ei, pos - ei);
+
+                if (ki == std::string::npos) {
+                    return std::make_pair(false, 0);
+                }
+
+                bool found = false;
+                // Find the substr ss in the key starting from index ki. 
+                // Take care of the special cases
+                //   + where the substr must match the key from beg to end,
+                //   + from beg,
+                //   + to end 
+                //   + and where it can be anywhere in the key.
+                // If found, ki is adjusted to the position in the key after ss.
+                if (ei == 0 && pos == std::string::npos) { // ei == 0 => ki == 0
+                    if (0 == uKey.compare(ss)) {
+                        found = true;
+                        ki = std::string::npos;
+                    }
+                }
+                else if (ei == 0) { // ei == 0 => ki == 0
+                    if (0 == uKey.compare(0, ss.size(), ss)) {
+                        found = true;
+                        ki = ss.size();
+                    }
+                }
+                else if (pos == std::string::npos) {
+                    if (   ss.size() <= uKey.size() 
+                        && ki <= uKey.size() - ss.size()) {
+                        if (0 == uKey.compare(
+                                uKey.size() - ss.size(), ss.size(), ss)) {
+                            found = true;
+                            ki = std::string::npos;
+                        }
+                    }
+                }
+                else {
+                    std::string::size_type idx = uKey.find(ss, ki); 
+                    if (idx != std::string::npos) {
+                        found = true;
+                        ki = idx + ss.size();
+                    }
+                }
+
+                if (found) {
+                    count += ss.size();
+                }
+                else {
+                    return std::make_pair(false, 0);
+                }
+            } // if the substr is not empty
+
+            ei = pos == std::string::npos ? std::string::npos : pos + 1;
+
+        } // while ei doesn't point to the end of the registry entry
+                                     
+        return std::make_pair(true, count);
+        
+    } // MakerNoteFactory::match
+
     int IfdMakerNote::read(const char* buf,
                            long len, 
                            ByteOrder byteOrder, 
diff --git a/src/makernote.hpp b/src/makernote.hpp
index 37097c8..94efec6 100644
--- a/src/makernote.hpp
+++ b/src/makernote.hpp
@@ -21,7 +21,7 @@
 /*!
   @file    makernote.hpp
   @brief   
-  @version $Name:  $ $Revision: 1.1 $
+  @version $Name:  $ $Revision: 1.2 $
   @author  Andreas Huggel (ahu)
            <a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
   @date    18-Feb-04, ahu: created
@@ -37,7 +37,8 @@
 // + standard includes
 #include <string>
 #include <iosfwd>
-#include <map>
+#include <utility>
+#include <vector>
 
 // *****************************************************************************
 // namespace extensions
@@ -151,9 +152,6 @@ namespace Exif {
       Creates an instance of the %MakerNote for one camera model. The factory is
       implemented as a singleton, which can be accessed only through the static
       member function instance().
-
-      Todo: Implement more intelligent registry that allows wildcards in the 
-            make and model strings to register classes
     */
     class MakerNoteFactory {
     public:
@@ -169,6 +167,20 @@ namespace Exif {
                  instance. Return 0 if no %MakerNote is defined for the camera
                  model.
 
+          The method searches the make-model tree for a make and model
+          combination in the registry that matches the search key. The search is
+          case insensitive (Todo: implement case-insensitive comparisons) and
+          wildcards in the registry entries are supported. First the best
+          matching make is searched, then the best matching model for this make
+          is searched. If there is no matching make or no matching model within
+          the models registered for the best matching make, then no maker note
+          is created and the function returns 0. If a match is found, the
+          function returns a pointer to a clone of the registered prototype. The
+          maker note pointed to is owned by the caller of the function, i.e.,
+          the caller is responsible to delete the returned make note when it is
+          no longer needed.
+          The best match is the match with the most matching characters.
+
           @param make Camera manufacturer. (Typically the string from the %Exif
                  make tag.)
           @param model Camera model. (Typically the string from the %Exif
@@ -180,12 +192,17 @@ namespace Exif {
                           const std::string& model) const;
 
         /*!
-          @brief Register a %MakerNote prototype for a camera model.
-
-          The %MakerNote factory creates new %MakerNotes for a camera by cloning
-          the associated prototype. Additional %MakerNotes can be registered.
-          If called for a camera model for which a %MakerNote is already
-          registered, the corresponding prototype is replaced.
+          @brief Register a %MakerNote prototype for a camera make and model.
+
+          Registers a %MakerNote for a given make and model combination with the
+          factory. Both the make and model strings may contain wildcards ('*',
+          e.g., "Canon*").  The method adds a new makerNote pointer to the
+          registry with the make and model strings provided. It takes ownership
+          of the object pointed to by the maker note pointer provided. If the
+          make already exists, then a new branch for the model is added to the
+          registry. If the model also already exists, then the new makerNote
+          pointer replaces the old one and the maker note pointed to by the old
+          pointer is deleted.
 
           @param make Camera manufacturer. (Typically the string from the %Exif
                  make tag.)
@@ -197,6 +214,19 @@ namespace Exif {
         void registerMakerNote(const std::string& make, 
                                const std::string& model, 
                                MakerNote* makerNote);
+        /*!
+          @brief Match a registry entry with a key (used for make and model).
+
+          The matching algorithm is case insensitive and wildcards ('*') in the
+          registry entry are supported. The best match is the match with the
+          most matching characters.
+
+          @return A pair of which the first component indicates whether or not
+                  the key matches and the second component contains the number
+                  of matching characters.
+         */
+        static std::pair<bool, int> match(const std::string& regEntry, 
+                                          const std::string& key);
 
     private:
         //! Prevent construction other than through instance().
@@ -206,8 +236,10 @@ namespace Exif {
 
         //! Pointer to the one and only instance of this class.
         static MakerNoteFactory* instance_;
-        //! Type used to store %MakerNote prototype classes
-        typedef std::map<std::string, MakerNote*> Registry;
+        //! Type used to store model labels and %MakerNote prototype classes
+        typedef std::vector<std::pair<std::string, MakerNote*> > ModelRegistry;
+        //! Type used to store a list of make labels and model registries
+        typedef std::vector<std::pair<std::string, ModelRegistry*> > Registry;
         //! List of makernote types and corresponding prototypes.
         Registry registry_;
 

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list