Browse Source

Fixed memory allocation issues with ctkVersion.

Sascha Zelzer 14 years ago
parent
commit
6a3c772d21

+ 38 - 8
Libs/PluginFramework/ctkVersion.cpp

@@ -30,23 +30,30 @@
 const QString ctkVersion::SEPARATOR = ".";
 const QRegExp ctkVersion::RegExp = QRegExp("[a-zA-Z0-9_\\-]*");
 
-const ctkVersion& ctkVersion::emptyVersion()
+ctkVersion ctkVersion::emptyVersion()
 {
-  static ctkVersion emptyV;
+  static ctkVersion emptyV(false);
   return emptyV;
 }
 
+ctkVersion ctkVersion::undefinedVersion()
+{
+  static ctkVersion undefinedV(true);
+  return undefinedV;
+}
+
 ctkVersion& ctkVersion::operator=(const ctkVersion& v)
 {
   majorVersion = v.majorVersion;
   minorVersion = v.minorVersion;
   microVersion = v.microVersion;
   qualifier = v.qualifier;
+  undefined = v.undefined;
   return *this;
 }
 
-ctkVersion::ctkVersion()
-  : majorVersion(0), minorVersion(0), microVersion(0), qualifier("")
+ctkVersion::ctkVersion(bool undefined)
+  : majorVersion(0), minorVersion(0), microVersion(0), qualifier(""), undefined(undefined)
 {
 
 }
@@ -56,22 +63,26 @@ void ctkVersion::validate()
 {
   if (!RegExp.exactMatch(qualifier))
     throw std::invalid_argument(std::string("invalid qualifier: ") + qualifier.toStdString());
+
+  undefined = false;
 }
 
 ctkVersion::ctkVersion(unsigned int majorVersion, unsigned int minorVersion, unsigned int microVersion)
-  : majorVersion(majorVersion), minorVersion(minorVersion), microVersion(microVersion), qualifier("")
+  : majorVersion(majorVersion), minorVersion(minorVersion), microVersion(microVersion), qualifier(""),
+    undefined(false)
 {
 
 }
 
 ctkVersion::ctkVersion(unsigned int majorVersion, unsigned int minorVersion, unsigned int microVersion, const QString& qualifier)
-   : majorVersion(majorVersion), minorVersion(minorVersion), microVersion(microVersion), qualifier(qualifier)
+   : majorVersion(majorVersion), minorVersion(minorVersion), microVersion(microVersion), qualifier(qualifier),
+     undefined(true)
 {
   this->validate();
 }
 
 ctkVersion::ctkVersion(const QString& version)
-  : majorVersion(0), minorVersion(0), microVersion(0)
+  : majorVersion(0), minorVersion(0), microVersion(0), undefined(true)
 {
   unsigned int maj = 0;
   unsigned int min = 0;
@@ -115,7 +126,8 @@ ctkVersion::ctkVersion(const QString& version)
 
 ctkVersion::ctkVersion(const ctkVersion& version)
 : majorVersion(version.majorVersion), minorVersion(version.minorVersion),
-  microVersion(version.microVersion), qualifier(version.qualifier)
+  microVersion(version.microVersion), qualifier(version.qualifier),
+  undefined(version.undefined)
 {
 
 }
@@ -136,28 +148,39 @@ ctkVersion ctkVersion::parseVersion(const QString& version)
   return ctkVersion(version2);
 }
 
+bool ctkVersion::isUndefined() const
+{
+  return undefined;
+}
+
 unsigned int ctkVersion::getMajor() const
 {
+  if (undefined) throw std::logic_error("Version undefined");
   return majorVersion;
 }
 
 unsigned int ctkVersion::getMinor() const
 {
+  if (undefined) throw std::logic_error("Version undefined");
   return minorVersion;
 }
 
 unsigned int ctkVersion::getMicro() const
 {
+  if (undefined) throw std::logic_error("Version undefined");
   return microVersion;
 }
 
 QString ctkVersion::getQualifier() const
 {
+  if (undefined) throw std::logic_error("Version undefined");
   return qualifier;
 }
 
 QString ctkVersion::toString() const
 {
+  if (undefined) return "undefined";
+
   QString result;
   result += QString::number(majorVersion) + SEPARATOR + QString::number(minorVersion) + SEPARATOR + QString::number(microVersion);
   if (!qualifier.isEmpty())
@@ -174,6 +197,10 @@ bool ctkVersion::operator==(const ctkVersion& other) const
     return true;
   }
 
+  if (other.undefined && this->undefined) return true;
+  if (this->undefined) throw std::logic_error("Version undefined");
+  if (other.undefined) return false;
+
   return (majorVersion == other.majorVersion) && (minorVersion == other.minorVersion) && (microVersion
       == other.microVersion) && qualifier == other.qualifier;
 }
@@ -185,6 +212,9 @@ int ctkVersion::compare(const ctkVersion& other) const
     return 0;
   }
 
+  if (this->undefined || other.undefined)
+    throw std::logic_error("Cannot compare undefined version");
+
   if (majorVersion < other.majorVersion)
   {
     return -1;

+ 18 - 2
Libs/PluginFramework/ctkVersion.h

@@ -62,6 +62,8 @@
     static const QString SEPARATOR; //  = "."
     static const QRegExp RegExp;
 
+    bool undefined;
+
 
     /**
      * Called by the ctkVersion constructors to validate the version components.
@@ -72,14 +74,20 @@
 
     ctkVersion& operator=(const ctkVersion& v);
 
-    ctkVersion();
+    ctkVersion(bool undefined = false);
 
   public:
 
     /**
      * The empty version "0.0.0".
      */
-    static const ctkVersion& emptyVersion();
+    static ctkVersion emptyVersion();
+
+    /**
+     * Creates an undefined version identifier, representing either
+     * infinity or minus infinity.
+     */
+    static ctkVersion undefinedVersion();
 
     /**
      * Creates a version identifier from the specified numerical components.
@@ -150,6 +158,14 @@
     static ctkVersion parseVersion(const QString& version);
 
     /**
+     * Returns the undefined state of this version identifier.
+     *
+     * @return <code>true</code> if this version identifier is undefined,
+     *         <code>false</code> otherwise.
+     */
+    bool isUndefined() const;
+
+    /**
      * Returns the majorVersion component of this version identifier.
      *
      * @return The majorVersion component.

+ 20 - 22
Libs/PluginFramework/ctkVersionRange.cpp

@@ -24,7 +24,7 @@
 #include <stdexcept>
 
 
-  const ctkVersionRange& ctkVersionRange::defaultVersionRange()
+  ctkVersionRange ctkVersionRange::defaultVersionRange()
   {
     static ctkVersionRange defaultVR;
     return defaultVR;
@@ -43,8 +43,8 @@
 
       if (comma > 0 && (cp || cb))
       {
-        low = new ctkVersion(vr.mid(1, comma-1).trimmed());
-        high = new ctkVersion(vr.mid(comma+1, vr.length()-comma-2).trimmed());
+        low = ctkVersion(vr.mid(1, comma-1).trimmed());
+        high = ctkVersion(vr.mid(comma+1, vr.length()-comma-2).trimmed());
         lowIncluded = ob;
         highIncluded = cb;
       }
@@ -55,8 +55,8 @@
     }
     else
     {
-      low = new ctkVersion(vr);
-      high = 0;
+      low = ctkVersion(vr);
+      high = ctkVersion();
       lowIncluded = true;
       highIncluded = false;
     }
@@ -64,16 +64,14 @@
 
   ctkVersionRange::ctkVersionRange()
   {
-    low = new ctkVersion(ctkVersion::emptyVersion());
-    high = 0;
+    low = ctkVersion(ctkVersion::emptyVersion());
+    high = ctkVersion();
     lowIncluded = true;
     highIncluded = false;
   }
 
   ctkVersionRange::~ctkVersionRange()
   {
-    delete low;
-    delete high;
   }
 
   bool ctkVersionRange::isSpecified() const
@@ -87,15 +85,15 @@
     {
       return true;
     }
-    int c = low->compare(ver);
+    int c = low.compare(ver);
 
     if (c < 0 || (c == 0 && lowIncluded))
     {
-      if (!high)
+      if (high.isUndefined())
       {
         return true;
       }
-      c = high->compare(ver);
+      c = high.compare(ver);
       return c > 0 || (c == 0 && highIncluded);
     }
     return false;
@@ -106,15 +104,15 @@
     if (*this == range) {
       return true;
     }
-    int c = low->compare(*range.low);
+    int c = low.compare(range.low);
 
     if (c < 0 || (c == 0 && lowIncluded == range.lowIncluded))
     {
-      if (!high)
+      if (high.isUndefined())
       {
         return true;
       }
-      c = high->compare(*range.high);
+      c = high.compare(range.high);
       return c > 0 || (c == 0 && highIncluded == range.highIncluded);
     }
     return false;
@@ -122,12 +120,12 @@
 
   int ctkVersionRange::compare(const ctkVersionRange& obj) const
   {
-    return low->compare(*obj.low);
+    return low.compare(obj.low);
   }
 
   QString ctkVersionRange::toString() const
   {
-    if (high)
+    if (!high.isUndefined())
     {
       QString res;
       if (lowIncluded)
@@ -138,7 +136,7 @@
       {
         res += '(';
       }
-      res += low->toString() + "," + high->toString();
+      res += low.toString() + "," + high.toString();
       if (highIncluded)
       {
         res += ']';
@@ -151,17 +149,17 @@
     }
     else
     {
-      return low->toString();
+      return low.toString();
     }
   }
 
   bool ctkVersionRange::operator==(const ctkVersionRange& r) const
   {
-    if (*low == *(r.low))
+    if (low == r.low)
     {
-      if (high)
+      if (!high.isUndefined())
       {
-        return (*high == *(r.high))  &&
+        return (high == r.high)  &&
           (lowIncluded == r.lowIncluded) &&
           (highIncluded == r.highIncluded);
       }

+ 3 - 3
Libs/PluginFramework/ctkVersionRange_p.h

@@ -33,8 +33,8 @@
 
   private:
 
-    ctkVersion* low;
-    ctkVersion* high;
+    ctkVersion low;
+    ctkVersion high;
     bool lowIncluded;
     bool highIncluded;
 
@@ -43,7 +43,7 @@
     /**
      * The empty version range "[0.0.0,inf)".
      */
-    static const ctkVersionRange& defaultVersionRange();
+    static ctkVersionRange defaultVersionRange();
 
     /**
      * Construct a ctkVersionRange object.