changeset 3071:2df061cf2fec db-changes

getting rid of IFindConstraint hierarchy
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 02 Jan 2019 11:26:27 +0100
parents 1bc4a1bb66e9
children 1b05fd072c57
files CMakeLists.txt OrthancServer/DicomInstanceOrigin.cpp OrthancServer/Search/DatabaseLookup.cpp OrthancServer/Search/DatabaseLookup.h OrthancServer/Search/DicomTagConstraint.cpp OrthancServer/Search/DicomTagConstraint.h OrthancServer/Search/HierarchicalMatcher.cpp OrthancServer/Search/HierarchicalMatcher.h OrthancServer/Search/IFindConstraint.cpp OrthancServer/Search/IFindConstraint.h OrthancServer/Search/ListConstraint.cpp OrthancServer/Search/ListConstraint.h OrthancServer/Search/RangeConstraint.cpp OrthancServer/Search/RangeConstraint.h OrthancServer/Search/ValueConstraint.cpp OrthancServer/Search/ValueConstraint.h OrthancServer/Search/WildcardConstraint.cpp OrthancServer/Search/WildcardConstraint.h
diffstat 18 files changed, 129 insertions(+), 882 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Jan 02 10:13:11 2019 +0100
+++ b/CMakeLists.txt	Wed Jan 02 11:26:27 2019 +0100
@@ -79,11 +79,6 @@
   OrthancServer/Search/DicomTagConstraint.cpp
   OrthancServer/Search/HierarchicalMatcher.cpp
   OrthancServer/Search/ISqlLookupFormatter.cpp
-  OrthancServer/Search/IFindConstraint.cpp
-  OrthancServer/Search/ListConstraint.cpp
-  OrthancServer/Search/RangeConstraint.cpp
-  OrthancServer/Search/ValueConstraint.cpp
-  OrthancServer/Search/WildcardConstraint.cpp
   OrthancServer/ServerContext.cpp
   OrthancServer/ServerEnumerations.cpp
   OrthancServer/ServerIndex.cpp
--- a/OrthancServer/DicomInstanceOrigin.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/DicomInstanceOrigin.cpp	Wed Jan 02 11:26:27 2019 +0100
@@ -37,7 +37,6 @@
 #include "../Core/OrthancException.h"
 #include "../Core/SerializationToolbox.h"
 
-
 namespace Orthanc
 {
   void DicomInstanceOrigin::Format(Json::Value& result) const
--- a/OrthancServer/Search/DatabaseLookup.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/DatabaseLookup.cpp	Wed Jan 02 11:26:27 2019 +0100
@@ -36,6 +36,7 @@
 
 #include "../ServerToolbox.h"
 #include "../../Core/DicomParsing/FromDcmtkBridge.h"
+#include "../../Core/DicomParsing/ToDcmtkBridge.h"
 
 namespace Orthanc
 {
@@ -91,6 +92,50 @@
   }
 
 
+  bool DatabaseLookup::IsMatch(DcmItem& item,
+                               Encoding encoding) const
+  {
+    for (size_t i = 0; i < constraints_.size(); i++)
+    {
+      assert(constraints_[i] != NULL);
+
+      DcmTagKey tag = ToDcmtkBridge::Convert(constraints_[i]->GetTag());
+
+      DcmElement* element = NULL;
+      if (!item.findAndGetElement(tag, element).good())
+      {
+        if (constraints_[i]->IsMandatory())
+        {
+          return false;
+        }
+        else
+        {
+          return true;
+        }
+      }
+
+      if (element == NULL)
+      {
+        return false;
+      }
+
+      std::set<DicomTag> ignoreTagLength;
+      std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement
+                                      (*element, DicomToJsonFlags_None, 
+                                       ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength));
+
+      if (value->IsNull() ||
+          value->IsBinary() ||
+          !constraints_[i]->IsMatch(value->GetContent()))
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+
   void DatabaseLookup::AddDicomConstraintInternal(const DicomTag& tag,
                                                   ValueRepresentation vr,
                                                   const std::string& dicomQuery,
--- a/OrthancServer/Search/DatabaseLookup.h	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/DatabaseLookup.h	Wed Jan 02 11:26:27 2019 +0100
@@ -35,6 +35,8 @@
 
 #include "DicomTagConstraint.h"
 
+class DcmItem;
+
 namespace Orthanc
 {
   class DatabaseLookup : public boost::noncopyable
@@ -70,6 +72,9 @@
 
     bool IsMatch(const DicomMap& value) const;
 
+    bool IsMatch(DcmItem& item,
+                 Encoding encoding) const;
+
     void AddDicomConstraint(const DicomTag& tag,
                             const std::string& dicomQuery,
                             bool caseSensitivePN,
--- a/OrthancServer/Search/DicomTagConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/DicomTagConstraint.cpp	Wed Jan 02 11:26:27 2019 +0100
@@ -294,4 +294,49 @@
       return IsMatch(tmp->GetContent());
     }
   }
+
+
+  std::string DicomTagConstraint::Format() const
+  {
+    switch (constraintType_)
+    {
+      case ConstraintType_Equal:
+        return tag_.Format() + " == " + GetValue();
+
+      case ConstraintType_SmallerOrEqual:
+        return tag_.Format() + " <= " + GetValue();
+
+      case ConstraintType_GreaterOrEqual:
+        return tag_.Format() + " >= " + GetValue();
+
+      case ConstraintType_Wildcard:
+        return tag_.Format() + " ~~ " + GetValue();
+
+      case ConstraintType_List:
+      {
+        std::string s = tag_.Format() + " IN [ ";
+
+        bool first = true;
+        for (std::set<std::string>::const_iterator
+               it = values_.begin(); it != values_.end(); ++it)
+        {
+          if (first)
+          {
+            first = false;
+          }
+          else
+          {
+            s += ", ";
+          }
+
+          s += *it;
+        }
+
+        return s + "]";
+      }
+
+      default:
+        throw OrthancException(ErrorCode_InternalError);
+    }
+  }
 }
--- a/OrthancServer/Search/DicomTagConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/DicomTagConstraint.h	Wed Jan 02 11:26:27 2019 +0100
@@ -110,5 +110,7 @@
     bool IsMatch(const std::string& value);
 
     bool IsMatch(const DicomMap& value);
+
+    std::string Format() const;
   };
 }
--- a/OrthancServer/Search/HierarchicalMatcher.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/HierarchicalMatcher.cpp	Wed Jan 02 11:26:27 2019 +0100
@@ -59,15 +59,6 @@
 
   HierarchicalMatcher::~HierarchicalMatcher()
   {
-    for (Constraints::iterator it = constraints_.begin();
-         it != constraints_.end(); ++it)
-    {
-      if (it->second != NULL)
-      {
-        delete it->second;
-      }
-    }
-
     for (Sequences::iterator it = sequences_.begin();
          it != sequences_.end(); ++it)
     {
@@ -98,15 +89,14 @@
         continue;
       }
 
-      ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag);
-
-      if (constraints_.find(tag) != constraints_.end() ||
+      if (flatTags_.find(tag) != flatTags_.end() ||
           sequences_.find(tag) != sequences_.end())
       {
+        // A constraint already exists on this tag
         throw OrthancException(ErrorCode_BadRequest);        
       }
 
-      if (vr == ValueRepresentation_Sequence)
+      if (FromDcmtkBridge::LookupValueRepresentation(tag) == ValueRepresentation_Sequence)
       {
         DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(*element);
 
@@ -132,6 +122,8 @@
                                         (*element, DicomToJsonFlags_None, 
                                          ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength));
 
+        flatTags_.insert(tag);
+        
         if (value->IsBinary())
         {
           if (!value->GetContent().empty())
@@ -140,26 +132,16 @@
                          << tag.Format() << ") with UN (unknown) value representation. "
                          << "It will be ignored.";
           }
-
-          constraints_[tag] = NULL;
         }
         else if (value->IsNull() ||
                  value->GetContent().empty())
         {
           // This is an universal matcher
-          constraints_[tag] = NULL;
         }
         else
         {
-          // DICOM specifies that searches must be case sensitive, except
-          // for tags with a PN value representation
-          bool sensitive = true;
-          if (vr == ValueRepresentation_PersonName)
-          {
-            sensitive = caseSensitivePN;
-          }
-
-          constraints_[tag] = IFindConstraint::ParseDicomConstraint(tag, value->GetContent(), sensitive);
+          flatConstraints_.AddDicomConstraint
+            (tag, value->GetContent(), caseSensitivePN, true /* mandatory */);
         }
       }
     }
@@ -169,19 +151,23 @@
   std::string HierarchicalMatcher::Format(const std::string& prefix) const
   {
     std::string s;
-    
-    for (Constraints::const_iterator it = constraints_.begin();
-         it != constraints_.end(); ++it)
+
+    std::set<DicomTag> tags;
+    for (size_t i = 0; i < flatConstraints_.GetConstraintsCount(); i++)
     {
-      s += prefix + it->first.Format() + " ";
+      const DicomTagConstraint& c = flatConstraints_.GetConstraint(i);
 
-      if (it->second == NULL)
+      s += c.Format() + "\n";
+      tags.insert(c.GetTag());
+    }
+    
+    // Loop over the universal constraints
+    for (std::set<DicomTag>::const_iterator it = flatTags_.begin();
+         it != flatTags_.end(); ++it)
+    {
+      if (tags.find(*it) == tags.end())
       {
-        s += "*\n";
-      }
-      else
-      {
-        s += it->second->Format() + "\n";
+        s += prefix + it->Format() + " == *\n";
       }
     }
 
@@ -214,34 +200,11 @@
   bool HierarchicalMatcher::MatchInternal(DcmItem& item,
                                           Encoding encoding) const
   {
-    for (Constraints::const_iterator it = constraints_.begin();
-         it != constraints_.end(); ++it)
+    if (!flatConstraints_.IsMatch(item, encoding))
     {
-      if (it->second != NULL)
-      {
-        DcmTagKey tag = ToDcmtkBridge::Convert(it->first);
-
-        DcmElement* element = NULL;
-        if (!item.findAndGetElement(tag, element).good() ||
-            element == NULL)
-        {
-          return false;
-        }
-
-        std::set<DicomTag> ignoreTagLength;
-        std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement
-                                        (*element, DicomToJsonFlags_None, 
-                                         ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength));
-
-        if (value->IsNull() ||
-            value->IsBinary() ||
-            !it->second->Match(value->GetContent()))
-        {
-          return false;
-        }
-      }
+      return false;
     }
-
+    
     for (Sequences::const_iterator it = sequences_.begin();
          it != sequences_.end(); ++it)
     {
@@ -283,16 +246,16 @@
   {
     std::auto_ptr<DcmDataset> target(new DcmDataset);
 
-    for (Constraints::const_iterator it = constraints_.begin();
-         it != constraints_.end(); ++it)
+    for (std::set<DicomTag>::const_iterator it = flatTags_.begin();
+         it != flatTags_.end(); ++it)
     {
-      DcmTagKey tag = ToDcmtkBridge::Convert(it->first);
+      DcmTagKey tag = ToDcmtkBridge::Convert(*it);
       
       DcmElement* element = NULL;
       if (source.findAndGetElement(tag, element).good() &&
           element != NULL)
       {
-        std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(it->first));
+        std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(*it));
         cloned->copyFrom(*element);
         target->insert(cloned.release());
       }
--- a/OrthancServer/Search/HierarchicalMatcher.h	Wed Jan 02 10:13:11 2019 +0100
+++ b/OrthancServer/Search/HierarchicalMatcher.h	Wed Jan 02 11:26:27 2019 +0100
@@ -33,7 +33,7 @@
 
 #pragma once
 
-#include "IFindConstraint.h"
+#include "DatabaseLookup.h"
 #include "../../Core/DicomParsing/ParsedDicomFile.h"
 
 class DcmItem;
@@ -43,11 +43,11 @@
   class HierarchicalMatcher : public boost::noncopyable
   {
   private:
-    typedef std::map<DicomTag, IFindConstraint*>      Constraints;
     typedef std::map<DicomTag, HierarchicalMatcher*>  Sequences;
 
-    Constraints  constraints_;
-    Sequences    sequences_;
+    std::set<DicomTag>  flatTags_;
+    DatabaseLookup      flatConstraints_;
+    Sequences           sequences_;
 
     void Setup(DcmItem& query,
                bool caseSensitivePN,
--- a/OrthancServer/Search/IFindConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersServer.h"
-#include "IFindConstraint.h"
-
-#include "ListConstraint.h"
-#include "RangeConstraint.h"
-#include "ValueConstraint.h"
-#include "WildcardConstraint.h"
-
-#include "../../Core/DicomParsing/FromDcmtkBridge.h"
-#include "../../Core/OrthancException.h"
-#include "../../Core/Toolbox.h"
-
-namespace Orthanc
-{
-  IFindConstraint* IFindConstraint::ParseDicomConstraint(const DicomTag& tag,
-                                                         const std::string& dicomQuery,
-                                                         bool caseSensitive)
-  {
-    ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag);
-
-    if (vr == ValueRepresentation_Sequence)
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-
-    if ((vr == ValueRepresentation_Date ||
-         vr == ValueRepresentation_DateTime ||
-         vr == ValueRepresentation_Time) &&
-        dicomQuery.find('-') != std::string::npos)
-    {
-      /**
-       * Range matching is only defined for TM, DA and DT value
-       * representations. This code fixes issues 35 and 37.
-       *
-       * Reference: "Range matching is not defined for types of
-       * Attributes other than dates and times", DICOM PS 3.4,
-       * C.2.2.2.5 ("Range Matching").
-       **/
-      size_t separator = dicomQuery.find('-');
-      std::string lower = dicomQuery.substr(0, separator);
-      std::string upper = dicomQuery.substr(separator + 1);
-      return new RangeConstraint(lower, upper, caseSensitive);
-    }
-    else if (dicomQuery.find('\\') != std::string::npos)
-    {
-      std::auto_ptr<ListConstraint> constraint(new ListConstraint(caseSensitive));
-
-      std::vector<std::string> items;
-      Toolbox::TokenizeString(items, dicomQuery, '\\');
-
-      for (size_t i = 0; i < items.size(); i++)
-      {
-        constraint->AddAllowedValue(items[i]);
-      }
-
-      return constraint.release();
-    }
-    else if (dicomQuery.find('*') != std::string::npos ||
-             dicomQuery.find('?') != std::string::npos)
-    {
-      return new WildcardConstraint(dicomQuery, caseSensitive);
-    }
-    else
-    {
-      /**
-       * Case-insensitive match for PN value representation (Patient
-       * Name). Case-senstive match for all the other value
-       * representations.
-       *
-       * Reference: DICOM PS 3.4
-       *   - C.2.2.2.1 ("Single Value Matching") 
-       *   - C.2.2.2.4 ("Wild Card Matching")
-       * http://medical.nema.org/Dicom/2011/11_04pu.pdf
-       *
-       * "Except for Attributes with a PN Value Representation, only
-       * entities with values which match exactly the value specified in the
-       * request shall match. This matching is case-sensitive, i.e.,
-       * sensitive to the exact encoding of the key attribute value in
-       * character sets where a letter may have multiple encodings (e.g.,
-       * based on its case, its position in a word, or whether it is
-       * accented)
-       * 
-       * For Attributes with a PN Value Representation (e.g., Patient Name
-       * (0010,0010)), an application may perform literal matching that is
-       * either case-sensitive, or that is insensitive to some or all
-       * aspects of case, position, accent, or other character encoding
-       * variants."
-       *
-       * (0008,0018) UI SOPInstanceUID     => Case-sensitive
-       * (0008,0050) SH AccessionNumber    => Case-sensitive
-       * (0010,0020) LO PatientID          => Case-sensitive
-       * (0020,000D) UI StudyInstanceUID   => Case-sensitive
-       * (0020,000E) UI SeriesInstanceUID  => Case-sensitive
-       **/
-
-      return new ValueConstraint(dicomQuery, caseSensitive);
-    }
-  }
-}
--- a/OrthancServer/Search/IFindConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Core/DicomFormat/DicomTag.h"
-
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class IFindConstraint : public boost::noncopyable
-  {
-  public:
-    virtual ~IFindConstraint()
-    {
-    }
-
-    virtual IFindConstraint* Clone() const = 0;
-
-    virtual bool Match(const std::string& value) const = 0;
-
-    virtual std::string Format() const = 0;
-
-    static IFindConstraint* ParseDicomConstraint(const DicomTag& tag,
-                                                 const std::string& dicomQuery,
-                                                 bool caseSensitive);
-  };
-}
--- a/OrthancServer/Search/ListConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersServer.h"
-#include "ListConstraint.h"
-
-#include "../../Core/Toolbox.h"
-
-namespace Orthanc
-{
-  void ListConstraint::AddAllowedValue(const std::string& value)
-  {
-    if (isCaseSensitive_)
-    {
-      allowedValues_.insert(value);
-    }
-    else
-    {
-      allowedValues_.insert(Toolbox::ToUpperCaseWithAccents(value));
-    }
-  }
-
-
-  bool ListConstraint::Match(const std::string& value) const
-  {
-    std::string s;
-    
-    if (isCaseSensitive_)
-    {
-      s = value;
-    }
-    else
-    {
-      s = Toolbox::ToUpperCaseWithAccents(value);
-    }
-
-    return allowedValues_.find(s) != allowedValues_.end();
-  }
-
-
-  std::string ListConstraint::Format() const
-  {
-    std::string s;
-
-    for (std::set<std::string>::const_iterator
-           it = allowedValues_.begin(); it != allowedValues_.end(); ++it)
-    {
-      if (!s.empty())
-      {
-        s += "\\";
-      }
-
-      s += *it;
-    }
-
-    return s;
-  }
-}
--- a/OrthancServer/Search/ListConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFindConstraint.h"
-
-#include <set>
-
-namespace Orthanc
-{
-  class ListConstraint : public IFindConstraint
-  {
-  private:
-    std::set<std::string>  allowedValues_;
-    bool                   isCaseSensitive_;
-
-    ListConstraint(const ListConstraint& other) : 
-      allowedValues_(other.allowedValues_),
-      isCaseSensitive_(other.isCaseSensitive_)
-    {
-    }
-
-  public:
-    ListConstraint(bool isCaseSensitive) : 
-      isCaseSensitive_(isCaseSensitive)
-    {
-    }
-
-    void AddAllowedValue(const std::string& value);
-
-    virtual IFindConstraint* Clone() const
-    {
-      return new ListConstraint(*this);
-    }
-
-    virtual bool Match(const std::string& value) const;
-
-    virtual std::string Format() const;
-  };
-}
--- a/OrthancServer/Search/RangeConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersServer.h"
-#include "RangeConstraint.h"
-
-#include "../../Core/Toolbox.h"
-
-namespace Orthanc
-{
-  RangeConstraint::RangeConstraint(const std::string& lower,
-                                   const std::string& upper,
-                                   bool isCaseSensitive) : 
-    isCaseSensitive_(isCaseSensitive)
-  {
-    if (isCaseSensitive_)
-    {
-      lower_ = lower;
-      upper_ = upper;
-    }
-    else
-    {
-      lower_ = Toolbox::ToUpperCaseWithAccents(lower);
-      upper_ = Toolbox::ToUpperCaseWithAccents(upper);
-    }
-  }
-
-
-  bool RangeConstraint::Match(const std::string& value) const
-  {
-    std::string v;
-
-    if (isCaseSensitive_)
-    {
-      v = value;
-    }
-    else
-    {
-      v = Toolbox::ToUpperCaseWithAccents(value);
-    }
-
-    if (lower_.size() == 0 && 
-        upper_.size() == 0)
-    {
-      return false;
-    }
-
-    if (lower_.size() == 0)
-    {
-      return v <= upper_;
-    }
-
-    if (upper_.size() == 0)
-    {
-      return v >= lower_;
-    }
-    
-    return (v >= lower_ && v <= upper_);
-  }
-}
--- a/OrthancServer/Search/RangeConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFindConstraint.h"
-
-namespace Orthanc
-{
-  class RangeConstraint : public IFindConstraint
-  {
-  private:
-    std::string  lower_;
-    std::string  upper_;
-    bool         isCaseSensitive_;
-
-    RangeConstraint(const RangeConstraint& other) : 
-      lower_(other.lower_),
-      upper_(other.upper_),
-      isCaseSensitive_(other.isCaseSensitive_)
-    {
-    }
-
-  public:
-    RangeConstraint(const std::string& lower,
-                    const std::string& upper,
-                    bool isCaseSensitive);
-
-    virtual IFindConstraint* Clone() const
-    {
-      return new RangeConstraint(*this);
-    }
-
-    virtual bool Match(const std::string& value) const;
-
-    virtual std::string Format() const
-    {
-      return lower_ + "-" + upper_;
-    }
-  };
-}
--- a/OrthancServer/Search/ValueConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersServer.h"
-#include "ValueConstraint.h"
-
-#include "../../Core/Toolbox.h"
-
-#include <stdio.h>
-
-namespace Orthanc
-{
-  ValueConstraint::ValueConstraint(const std::string& value,
-                                   bool isCaseSensitive) : 
-    isCaseSensitive_(isCaseSensitive)
-  {
-    if (isCaseSensitive)
-    {
-      value_ = value;
-    }
-    else
-    {
-      value_ = Toolbox::ToUpperCaseWithAccents(value);
-    }
-  }
-
-
-  bool ValueConstraint::Match(const std::string& value) const
-  {
-    if (isCaseSensitive_)
-    {
-      return value_ == value;
-    }
-    else
-    {
-      return value_ == Toolbox::ToUpperCaseWithAccents(value);
-    }
-  }
-}
--- a/OrthancServer/Search/ValueConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFindConstraint.h"
-
-namespace Orthanc
-{
-  class ValueConstraint : public IFindConstraint
-  {
-  private:
-    std::string  value_;
-    bool         isCaseSensitive_;
-
-    ValueConstraint(const ValueConstraint& other) : 
-      value_(other.value_),
-      isCaseSensitive_(other.isCaseSensitive_)
-    {
-    }
-
-  public:
-    ValueConstraint(const std::string& value,
-                    bool isCaseSensitive);
-
-    virtual IFindConstraint* Clone() const
-    {
-      return new ValueConstraint(*this);
-    }
-
-    virtual bool Match(const std::string& value) const;
-
-    virtual std::string Format() const
-    {
-      return value_;
-    }
-  };
-}
--- a/OrthancServer/Search/WildcardConstraint.cpp	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeadersServer.h"
-#include "WildcardConstraint.h"
-
-#include "../../Core/Toolbox.h"
-
-#include <boost/regex.hpp>
-
-namespace Orthanc
-{
-  struct WildcardConstraint::PImpl
-  {
-    boost::regex  pattern_;
-    std::string   wildcard_;
-    bool          isCaseSensitive_;
-
-    PImpl(const std::string& wildcard,
-          bool isCaseSensitive)
-    {
-      isCaseSensitive_ = isCaseSensitive;
-    
-      if (isCaseSensitive)
-      {
-        wildcard_ = wildcard;
-      }
-      else
-      {
-        wildcard_ = Toolbox::ToUpperCaseWithAccents(wildcard);
-      }
-
-      pattern_ = boost::regex(Toolbox::WildcardToRegularExpression(wildcard_));
-    }
-  };
-
-
-  WildcardConstraint::WildcardConstraint(const WildcardConstraint& other) :
-    pimpl_(new PImpl(*other.pimpl_))
-  {
-  }
-
-
-  WildcardConstraint::WildcardConstraint(const std::string& wildcard,
-                                         bool isCaseSensitive) :
-    pimpl_(new PImpl(wildcard, isCaseSensitive))
-  {
-  }
-
-  bool WildcardConstraint::Match(const std::string& value) const
-  {
-    if (pimpl_->isCaseSensitive_)
-    {
-      return boost::regex_match(value, pimpl_->pattern_);
-    }
-    else
-    {
-      return boost::regex_match(Toolbox::ToUpperCaseWithAccents(value), pimpl_->pattern_);
-    }
-  }
-
-  std::string WildcardConstraint::Format() const
-  {
-    return pimpl_->wildcard_;
-  }
-}
--- a/OrthancServer/Search/WildcardConstraint.h	Wed Jan 02 10:13:11 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2019 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IFindConstraint.h"
-
-#include <boost/shared_ptr.hpp>
-
-namespace Orthanc
-{
-  class WildcardConstraint : public IFindConstraint
-  {
-  private:
-    struct PImpl;
-    boost::shared_ptr<PImpl>  pimpl_;
-
-    WildcardConstraint(const WildcardConstraint& other);
-
-  public:
-    WildcardConstraint(const std::string& wildcard,
-                       bool isCaseSensitive);
-
-    virtual IFindConstraint* Clone() const
-    {
-      return new WildcardConstraint(*this);
-    }
-
-    virtual bool Match(const std::string& value) const;
-
-    virtual std::string Format() const;
-  };
-}