# HG changeset patch
# User Sebastien Jodogne <s.jodogne@gmail.com>
# Date 1433942222 -7200
# Node ID 8e23f16a198d616e15ab3ad43c54891acdb67603
# Parent  037d5ffca74d8235587b64b87ba28e20ec8a5ae5
fix issues 35 and 37

diff -r 037d5ffca74d -r 8e23f16a198d NEWS
--- a/NEWS	Thu Jun 04 09:04:14 2015 +0200
+++ b/NEWS	Wed Jun 10 15:17:02 2015 +0200
@@ -1,6 +1,8 @@
 Pending changes in the mainline
 ===============================
 
+* Fix issue 35 (Characters in PatientID string are not protected for C-Find)
+* Fix issue 37 (Hyphens trigger range query even if datatype does not support ranges)
 
 
 Version 0.9.0 (2015/06/03)
diff -r 037d5ffca74d -r 8e23f16a198d OrthancServer/DicomFindQuery.cpp
--- a/OrthancServer/DicomFindQuery.cpp	Thu Jun 04 09:04:14 2015 +0200
+++ b/OrthancServer/DicomFindQuery.cpp	Wed Jun 10 15:17:02 2015 +0200
@@ -245,13 +245,30 @@
                                      const std::string& constraint,
                                      bool caseSensitivePN)
   {
-    bool sensitive = (FromDcmtkBridge::IsPNValueRepresentation(tag) ? caseSensitivePN : true);
+    ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag);
+
+    bool sensitive = true;
+    if (vr == ValueRepresentation_PatientName)
+    {
+      sensitive = caseSensitivePN;
+    }
 
     // http://www.itk.org/Wiki/DICOM_QueryRetrieve_Explained
     // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html  
 
-    if (constraint.find('-') != std::string::npos)
+    if ((vr == ValueRepresentation_Date ||
+         vr == ValueRepresentation_DateTime ||
+         vr == ValueRepresentation_Time) &&
+        constraint.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").
+       **/
       AssignConstraint(tag, new RangeConstraint(constraint));
     }
     else if (constraint.find('\\') != std::string::npos)
diff -r 037d5ffca74d -r 8e23f16a198d OrthancServer/FromDcmtkBridge.cpp
--- a/OrthancServer/FromDcmtkBridge.cpp	Thu Jun 04 09:04:14 2015 +0200
+++ b/OrthancServer/FromDcmtkBridge.cpp	Wed Jun 10 15:17:02 2015 +0200
@@ -746,10 +746,26 @@
   }
 
 
-  bool FromDcmtkBridge::IsPNValueRepresentation(const DicomTag& tag)
+  ValueRepresentation FromDcmtkBridge::GetValueRepresentation(const DicomTag& tag)
   {
     DcmTag t(tag.GetGroup(), tag.GetElement());
-    return t.getEVR() == EVR_PN;
+    switch (t.getEVR())
+    {
+      case EVR_PN:
+        return ValueRepresentation_PatientName;
+
+      case EVR_DA:
+        return ValueRepresentation_Date;
+
+      case EVR_DT:
+        return ValueRepresentation_DateTime;
+
+      case EVR_TM:
+        return ValueRepresentation_Time;
+
+      default:
+        return ValueRepresentation_Other;
+    }
   }
 
 }
diff -r 037d5ffca74d -r 8e23f16a198d OrthancServer/FromDcmtkBridge.h
--- a/OrthancServer/FromDcmtkBridge.h	Thu Jun 04 09:04:14 2015 +0200
+++ b/OrthancServer/FromDcmtkBridge.h	Wed Jun 10 15:17:02 2015 +0200
@@ -107,6 +107,6 @@
     static bool SaveToMemoryBuffer(std::string& buffer,
                                    DcmDataset& dataSet);
 
-    static bool IsPNValueRepresentation(const DicomTag& tag);
+    static ValueRepresentation GetValueRepresentation(const DicomTag& tag);
   };
 }
diff -r 037d5ffca74d -r 8e23f16a198d OrthancServer/ServerEnumerations.h
--- a/OrthancServer/ServerEnumerations.h	Thu Jun 04 09:04:14 2015 +0200
+++ b/OrthancServer/ServerEnumerations.h	Wed Jun 10 15:17:02 2015 +0200
@@ -90,6 +90,15 @@
     TransferSyntax_Rle
   };
 
+  enum ValueRepresentation
+  {
+    ValueRepresentation_Other,
+    ValueRepresentation_PatientName,
+    ValueRepresentation_Date,
+    ValueRepresentation_DateTime,
+    ValueRepresentation_Time
+  };
+
 
   /**
    * WARNING: Do not change the explicit values in the enumerations
diff -r 037d5ffca74d -r 8e23f16a198d UnitTestsSources/FromDcmtkTests.cpp
--- a/UnitTestsSources/FromDcmtkTests.cpp	Thu Jun 04 09:04:14 2015 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Wed Jun 10 15:17:02 2015 +0200
@@ -289,8 +289,16 @@
 }
 
 
-TEST(FromDcmtkBridge, VR)
+TEST(FromDcmtkBridge, ValueRepresentation)
 {
-  ASSERT_TRUE(FromDcmtkBridge::IsPNValueRepresentation(DICOM_TAG_PATIENT_NAME));
-  ASSERT_FALSE(FromDcmtkBridge::IsPNValueRepresentation(DICOM_TAG_PATIENT_ID));
+  ASSERT_EQ(ValueRepresentation_PatientName, 
+            FromDcmtkBridge::GetValueRepresentation(DICOM_TAG_PATIENT_NAME));
+  ASSERT_EQ(ValueRepresentation_Date, 
+            FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x0020) /* StudyDate */));
+  ASSERT_EQ(ValueRepresentation_Time, 
+            FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x0030) /* StudyTime */));
+  ASSERT_EQ(ValueRepresentation_DateTime, 
+            FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x002a) /* AcquisitionDateTime */));
+  ASSERT_EQ(ValueRepresentation_Other, 
+            FromDcmtkBridge::GetValueRepresentation(DICOM_TAG_PATIENT_ID));
 }