]> Creatis software - gdcm.git/commitdiff
ENH: Slightly bigger patch:
authormalaterre <malaterre>
Tue, 16 Nov 2004 02:54:34 +0000 (02:54 +0000)
committermalaterre <malaterre>
Tue, 16 Nov 2004 02:54:34 +0000 (02:54 +0000)
1. Getting toward full integration of JMR patch for writting dicom from scratch
2. Update Test to test part of this patch: CreateUniqueUID
3. File was not close properly in gdcmDict
4. Use of typedef is to be prefered when possible (gdcmDict.cxx)
5. Use of const ref instead of copy (speed issue)
6. Remove temporary (duplicate) string in TranslateToKey
7. Mark extremely dangerous code as such (gdcmDocument.cxx and AddEntry fallback case)
8. Do not repeat virtual in subclasses
9. Implemented in gdcm::Util two new function: GetIPAddress, and CreateUniqueUID

12 files changed:
ChangeLog
Testing/TestUtil.cxx
src/gdcmDict.cxx
src/gdcmDict.h
src/gdcmDictEntry.cxx
src/gdcmDocument.cxx
src/gdcmDocument.h
src/gdcmElementSet.cxx
src/gdcmFile.cxx
src/gdcmSeqEntry.h
src/gdcmUtil.cxx
src/gdcmUtil.h

index 39809c83e5598f50d1739ec313a1a65e538b9ddd..e4a4b8b718e35ba39b77be342b6f9284b7b01898 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-15 Mathieu Malaterre  <Mathieu.Malaterre@creatis.insa-lyon.fr>
+  * ENH: Slightly bigger patch:
+    1. Getting toward full integration of JMR patch for writting dicom from scratch
+    2. Update Test to test part of this patch: CreateUniqueUID
+    3. File was not close properly in gdcmDict
+    4. Use of typedef is to be prefered when possible (gdcmDict.cxx)
+    5. Use of const ref instead of copy (speed issue)
+    6. Remove temporary (duplicate) string in TranslateToKey
+    7. Mark extremely dangerous code as such (gdcmDocument.cxx and AddEntry fallback case)
+    8. Do not repeat virtual in subclasses
+    9. Implemented in gdcm::Util two new function: GetIPAddress, and CreateUniqueUID
+
 2004-11-15 Mathieu Malaterre  <Mathieu.Malaterre@creatis.insa-lyon.fr>
   * Apply first patch toward better string comparison when dealing with broken 
     DICOM files. Essentially the string could be padded with a space instead 
index fb9cb97c09203975999fb40d6060ce45e4a57137..8804c72023331645535fb37023808a19d5abd150 100644 (file)
@@ -5,6 +5,8 @@
 
 int TestUtil(int , char * [])
 {
+   std::cout << gdcm::Util::CreateUniqueUID("") << std::endl;
+   
    const char ref[] = "MONOCHROME1";
    std::string a = "MONOCHROME1";
    a += '\0';
index 051d44dee8bde4c8ed186df9554e2ed0cf0bc2d2..19b9363999d81d478884c554acff33f6c60dc107 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDict.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/11/03 18:08:56 $
-  Version:   $Revision: 1.51 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.52 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -63,10 +63,10 @@ Dict::Dict(std::string const & filename)
          const DictEntry newEntry(group, element, vr, fourth, name);
          AddNewEntry(newEntry);
       }
-      from.close();
 
       Filename = filename;
    }
+   from.close();
 }
 
 /**
@@ -159,12 +159,8 @@ bool Dict::AddNewEntry(DictEntry const & newEntry)
    } 
    else 
    {
-      KeyHt.insert( 
-         std::map<TagKey, DictEntry>::value_type
-            (newEntry.GetKey(), newEntry));
-      NameHt.insert(
-         std::map<TagName, DictEntry>::value_type
-            (newEntry.GetName(), newEntry ));
+      KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
+      NameHt.insert( TagNameHT::value_type(newEntry.GetName(), newEntry ));
       return true;
    }
 }
@@ -179,12 +175,8 @@ bool Dict::ReplaceEntry(DictEntry const & newEntry)
 {
    if ( RemoveEntry(newEntry.GetKey()) )
    {
-      KeyHt.insert( 
-         std::map<TagKey, DictEntry>::value_type
-            (newEntry.GetKey(), newEntry));
-      NameHt.insert(
-         std::map<TagName, DictEntry>::value_type
-            (newEntry.GetName(), newEntry ));
+       KeyHt.insert( TagKeyHT::value_type(newEntry.GetKey(), newEntry));
+       NameHt.insert( TagNameHT::value_type(newEntry.GetName(), newEntry ));
        return true;
    } 
    return false;
@@ -202,7 +194,7 @@ bool Dict::RemoveEntry (TagKey const & key)
    TagKeyHT::const_iterator it = KeyHt.find(key);
    if(it != KeyHt.end()) 
    {
-      const DictEntry & entryToDelete = it->second;
+      const DictEntry& entryToDelete = it->second;
       NameHt.erase(entryToDelete.GetName());
       KeyHt.erase(key);
 
index 2b90d10b3e737a5a9e2a33d7aa969dfc966c54d2..dd4910dc3451a8ea33fb6a52913d26c50e12717b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDict.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/27 22:31:12 $
-  Version:   $Revision: 1.22 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.23 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -30,10 +30,11 @@ namespace gdcm
 {
 
 //-----------------------------------------------------------------------------
-typedef std::map<TagKey, DictEntry> TagKeyHT;
+typedef std::map<TagKey, DictEntry>  TagKeyHT;
 typedef std::map<TagName, DictEntry> TagNameHT;
-typedef std::list<std::string>        EntryNamesList;
-typedef std::map<std::string, std::list<std::string> > EntryNamesByCatMap;
+typedef std::list<std::string>       EntryNamesList;
+typedef std::map<std::string, 
+            std::list<std::string> > EntryNamesByCatMap;
 //-----------------------------------------------------------------------------
 /*
  * \defgroup Dict
index 77590de3758fb5c0fdc399f947a7d2c6a73e9b36..bc0dddfd3dd246086632876d7c3db935d81b5aea 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDictEntry.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/18 02:35:35 $
-  Version:   $Revision: 1.28 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.29 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -61,9 +61,7 @@ DictEntry::DictEntry(uint16_t group, uint16_t element,
  */
 TagKey DictEntry::TranslateToKey(uint16_t group, uint16_t element)
 {
-   TagKey key = Util::Format("%04x|%04x", group , element);
-
-   return key;
+   return Util::Format("%04x|%04x", group, element);
 }
 
 //-----------------------------------------------------------------------------
index 879a334801386365886b843e93d5a8de6ecb645d..821b7027da0546aae3dbf59c3cd3228320ed2b99 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/11/15 16:12:30 $
-  Version:   $Revision: 1.123 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.124 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -1346,7 +1346,7 @@ void Document::ParseDES(DocEntrySet *set, long offset,
          {
          /////////////////////// ValEntry
             ValEntry* newValEntry =
-               new ValEntry( newDocEntry->GetDictEntry() );
+               new ValEntry( newDocEntry->GetDictEntry() ); //LEAK
             newValEntry->Copy( newDocEntry );
              
             // When "set" is a Document, then we are at the top of the
@@ -1365,7 +1365,11 @@ void Document::ParseDES(DocEntrySet *set, long offset,
                                    + newValEntry->GetKey() );
             }
              
-            set->AddEntry( newValEntry );
+            if( !set->AddEntry( newValEntry ) )
+            {
+              // If here expect big troubles
+              delete newValEntry; //otherwise mem leak
+            }
             LoadDocEntry( newValEntry );
             if (newValEntry->IsItemDelimitor())
             {
@@ -1406,7 +1410,11 @@ void Document::ParseDES(DocEntrySet *set, long offset,
                                    + newBinEntry->GetKey() );
             }
 
-            set->AddEntry( newBinEntry );
+            if( !set->AddEntry( newBinEntry ) )
+            {
+              //Expect big troubles if here
+              delete newBinEntry;
+            }
             LoadDocEntry( newBinEntry );
          }
 
@@ -1596,7 +1604,7 @@ void Document::LoadDocEntry(DocEntry* entry)
          s << " x(" << std::hex << entry->GetLength() << ")";
          binEntryPtr->SetValue(s.str());
       }
-       // Be carefull : a BinEntry IS_A ValEntry ... 
+      // Be carefull : a BinEntry IS_A ValEntry ... 
       else if (ValEntry* valEntryPtr = dynamic_cast< ValEntry* >(entry) )
       {
         // s << "gdcm::NotLoaded. (ValEntry)";
index 26cca8c810869e2505bd9dc560e20c6bb97f1dfe..8f9b84e945096189d4265ca8ff45ae54df26774b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.h,v $
   Language:  C++
-  Date:      $Date: 2004/11/15 16:12:30 $
-  Version:   $Revision: 1.58 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.59 $
  
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -261,7 +261,7 @@ private:
    void BuildFlatHashTableRecurse( TagDocEntryHT& builtHT,
                                    DocEntrySet* set );
 
-   void HandleBrokenEndian(uint16_t group, uint16_t elem);
+   void HandleBrokenEndian(uint16_t  group, uint16_t  elem);
 public:
 // Accessors:
    /// Accessor to \ref PrintLevel
index 47de1a189018dc053e0f5f5235258847bfbc0bcf..22f4ed98d1c9470fa4112804635526f5535893a1 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmElementSet.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/11/05 21:23:46 $
-  Version:   $Revision: 1.26 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.27 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -90,7 +90,9 @@ void ElementSet::Print(std::ostream& os)
   */ 
 void ElementSet::Write(std::ofstream* fp, FileType filetype)
 {
-   for (TagDocEntryHT::const_iterator i = TagHT.begin(); i != TagHT.end(); ++i)
+   for (TagDocEntryHT::const_iterator i = TagHT.begin(); 
+                                     i != TagHT.end(); 
+                                    ++i)
    {
       i->second->Write(fp, filetype);
    } 
@@ -107,9 +109,9 @@ void ElementSet::Write(std::ofstream* fp, FileType filetype)
  * \brief   add a new Dicom Element pointer to the H Table
  * @param   newEntry entry to add
  */
-bool ElementSet::AddEntry( DocEntry* newEntry)
+bool ElementSet::AddEntry(DocEntry* newEntry)
 {
-   TagKey key = newEntry->GetKey();
+   const TagKey& key = newEntry->GetKey();
 
    if( TagHT.count(key) == 1 )
    {
@@ -119,7 +121,7 @@ bool ElementSet::AddEntry( DocEntry* newEntry)
    } 
    else 
    {
-      TagHT[newEntry->GetKey()] = newEntry;
+      TagHT.insert(TagDocEntryHT::value_type(newEntry->GetKey(), newEntry));
       return true;
    }   
 }
@@ -128,9 +130,9 @@ bool ElementSet::AddEntry( DocEntry* newEntry)
  * \brief   Clear the hash table from given entry BUT keep the entry.
  * @param   entryToRemove Entry to remove.
  */
-bool ElementSet::RemoveEntryNoDestroy( DocEntry* entryToRemove)
+bool ElementSet::RemoveEntryNoDestroy(DocEntry* entryToRemove)
 {
-   TagKey key = entryToRemove->GetKey();
+   const TagKey& key = entryToRemove->GetKey();
    if( TagHT.count(key) == 1 )
    {
       TagHT.erase(key);
@@ -148,7 +150,7 @@ bool ElementSet::RemoveEntryNoDestroy( DocEntry* entryToRemove)
  */
 bool ElementSet::RemoveEntry( DocEntry* entryToRemove)
 {
-   TagKey key = entryToRemove->GetKey();
+   const TagKey& key = entryToRemove->GetKey();
    if( TagHT.count(key) == 1 )
    {
       TagHT.erase(key);
index 2faa65533b97252e4ae16041817351300ac834e9..b5de832e9f59741c52597ffb7aced3ab12230b10 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmFile.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/11/15 15:29:04 $
-  Version:   $Revision: 1.154 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.155 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -110,7 +110,6 @@ File::~File()
    {
       delete PixelConverter;
    }
-
 }
 
 /**
index e23657f9dc15afeccfff2a9f6c1a3d1f2b6caa38..5d0ca21b8febaa3fcabba6e399de32d706ada07d 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmSeqEntry.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/25 03:03:45 $
-  Version:   $Revision: 1.22 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.23 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -33,17 +33,17 @@ class GDCM_EXPORT SeqEntry : public DocEntry
 {
 public:
    SeqEntry( DictEntry* );
-   SeqEntry(DocEntry* d,  int depth);
+   SeqEntry( DocEntry* d, int depth );
    ~SeqEntry();
    
-   virtual void Print(std::ostream &os = std::cout); 
-   virtual void Write(std::ofstream *fp, FileType);
+   void Print(std::ostream &os = std::cout); 
+   void Write(std::ofstream *fp, FileType filetype);
 
    /// returns the SQITEM chained List for this SeQuence.
    ListSQItem const & GetSQItems() const { return Items; }
       
    /// Sets the delimitor mode
-   void SetDelimitorMode(bool dm) { DelimitorMode = dm;}
+   void SetDelimitorMode(bool dm) { DelimitorMode = dm; }
 
    /// Sets the Sequence Delimitation Item
    void SetSequenceDelimitationItem(DocEntry * e) { SeqTerm = e;}
index 30adaed290979a982ad03da1ca56290d6ff57374..b551067fad83ba2b2d15d34b399955c074554e6b 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmUtil.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/11/16 02:04:00 $
-  Version:   $Revision: 1.63 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.64 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -27,6 +27,9 @@
 #include <stdarg.h>  //only included in implementation file
 #include <stdio.h>   //only included in implementation file
 
+#include <unistd.h>  // for gethostname
+#include <netdb.h>   // for gethostbyname
+
 namespace gdcm 
 {
 
@@ -267,7 +270,7 @@ std::string Util::DicomString(const char* s)
 bool Util::DicomStringEqual(const std::string& s1, const char *s2)
 {
   // s2 is the string from the DICOM reference: 'MONOCHROME1'
-  std::string s1_even = s1; //Never directly change input parameter
+  std::string s1_even = s1; //Never change input parameter
   std::string s2_even = DicomString( s2 );
   if( s1_even[s1_even.size()-1] == ' ')
   {
@@ -276,6 +279,79 @@ bool Util::DicomStringEqual(const std::string& s1, const char *s2)
   return s1_even == s2_even;
 }
 
+/**
+ * \ingroup Util
+ * \brief   Return the IP adress of the machine writting the DICOM image
+ */
+std::string Util::GetIPAddress()
+{
+  // This is a rip from http://www.codeguru.com/Cpp/I-N/internet/network/article.php/c3445/
+#ifndef HOST_NAME_MAX
+  // SUSv2 guarantees that `Host names are limited to 255 bytes'.
+  // POSIX 1003.1-2001 guarantees that `Host names (not including the
+  // terminating NUL) are limited to HOST_NAME_MAX bytes'.
+#  define HOST_NAME_MAX 255
+  // In this case we should maybe check the string was not truncated.
+  // But I don't known how to check that...
+#endif //HOST_NAME_MAX
+
+  std::string str;
+  char szHostName[HOST_NAME_MAX+1];
+  int r = gethostname(szHostName, HOST_NAME_MAX);
+
+  if( r == 0 )
+  {
+    // Get host adresses
+    struct hostent * pHost = gethostbyname(szHostName);
+
+    for( int i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
+    {
+      for( int j = 0; j<pHost->h_length; j++ )
+      {
+        if( j > 0 ) str += ".";
+
+        str += Util::Format("%u", 
+            (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]);
+      }
+      // str now contains one local IP address 
+    }
+  }
+  // If an error occur r == -1
+  // Most of the time it will return 127.0.0.1...
+  return str;
+}
+
+/**
+ * \ingroup Util
+ * \brief Creates a new UID. As stipulate in the DICOM ref
+ *        each time a DICOM image is create it should have 
+ *        a unique identifier (URI)
+ */
+std::string Util::CreateUniqueUID(const std::string& root)
+{
+  // The code works as follow:
+  // echo "gdcm" | od -b
+  // 0000000 147 144 143 155 012
+  // Therefore we return
+  // radical + 147.144.143.155 + IP + time()
+  std::string radical = root;
+  if( !root.size() ) //anything better ?
+  {
+    radical = "0.0."; // Is this really usefull ?
+  }
+  // else
+  // A root was specified use it to forge our new UID:
+  radical += "147.144.143.155"; // gdcm
+  radical += ".";
+  radical += Util::GetIPAddress();
+  radical += ".";
+  radical += Util::GetCurrentDate();
+  radical += ".";
+  radical += Util::GetCurrentTime();
+
+  return radical;
+}
+
 template <class T>
 std::ostream& binary_write(std::ostream& os, const T& val)
 {
index 99cb255520818004e01cbbd0680fae3e59aaba40..bf8970157e28d472376924b80cf2adf3d5515d03 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmUtil.h,v $
   Language:  C++
-  Date:      $Date: 2004/11/16 02:04:00 $
-  Version:   $Revision: 1.43 $
+  Date:      $Date: 2004/11/16 02:54:35 $
+  Version:   $Revision: 1.44 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -54,6 +54,10 @@ public:
    static std::string DicomString(const char* s, size_t l);
    static std::string DicomString(const char* s);
    static bool        DicomStringEqual(const std::string& s1, const char *s2);
+   static std::string CreateUniqueUID(const std::string& root);
+
+private:
+   static std::string GetIPAddress(); //Do not expose this method
 };
 
    template <class T>