[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