Program: gdcm
Module: $RCSfile: gdcmUtil.cxx,v $
Language: C++
- Date: $Date: 2004/11/14 00:53:10 $
- Version: $Revision: 1.62 $
+ Date: $Date: 2004/11/16 10:37:54 $
+ Version: $Revision: 1.66 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include <stdarg.h> //only included in implementation file
#include <stdio.h> //only included in implementation file
+#if defined _MSC_VER || defined(__BORLANDC__)
+ #include <winsock.h> // for gethostname & gethostbyname
+ #undef GetCurrentTime
+#else
+ #include <unistd.h> // for gethostname
+ #include <netdb.h> // for gethostbyname
+#endif
+
namespace gdcm
{
-
/**
* \ingroup Globals
* \brief Provide a better 'c++' approach for sprintf
/**
* \ingroup Globals
* \brief Add a SEPARATOR to the end of the name is necessary
- * @param name file/directory name to normalize
+ * @param pathname file/directory name to normalize
*/
std::string Util::NormalizePath(std::string const & pathname)
{
}
}
+/**
+ * \ingroup Util
+ * \brief Get the current date of the system in a dicom string
+ */
+std::string Util::GetCurrentDate()
+{
+ char tmp[512];
+ time_t tloc;
+ time (&tloc);
+ strftime(tmp,512,"%Y%m%d", localtime(&tloc) );
+ return tmp;
+}
+
+/**
+ * \ingroup Util
+ * \brief Get the current time of the system in a dicom string
+ */
+std::string Util::GetCurrentTime()
+{
+ char tmp[512];
+ time_t tloc;
+ time (&tloc);
+ strftime(tmp,512,"%H%M%S", localtime(&tloc) );
+ return tmp;
+}
+
+/**
+ * \brief Create a /DICOM/ string:
+ * It should a of even length (no odd length ever)
+ * It can contain as many (if you are reading this from your
+ * editor the following character is is backslash followed by zero
+ * that needed to be escaped with an extra backslash for doxygen) \\0
+ * as you want.
+ */
+std::string Util::DicomString(const char* s, size_t l)
+{
+ std::string r(s, s+l);
+ assert( !(r.size() % 2) ); // == basically 'l' is even
+ return r;
+}
+
/**
* \ingroup Util
* \brief Create a /DICOM/ string:
* It should a of even lenght (no odd length ever)
- * It can contains as many \0 as you want.
+ * It can contain as many (if you are reading this from your
+ * editor the following character is is backslash followed by zero
+ * that needed to be escaped with an extra backslash for doxygen) \\0
+ * as you want.
* This function is similar to DicomString(const char*),
* except it doesn't take a lenght.
* It only pad with a null character if length is odd
/**
* \ingroup Util
- * \brief Get the current date of the system in a dicom string
+ * \brief Safely compare two Dicom String:
+ * - Both string should be of even lenght
+ * - We allow padding of even lenght string by either a null
+ * character of a space
*/
-std::string Util::GetCurrentDate()
+bool Util::DicomStringEqual(const std::string& s1, const char *s2)
{
- char tmp[512];
- time_t tloc;
- time (&tloc);
- strftime(tmp,512,"%Y%m%d", localtime(&tloc) );
- return tmp;
+ // s2 is the string from the DICOM reference: 'MONOCHROME1'
+ std::string s1_even = s1; //Never change input parameter
+ std::string s2_even = DicomString( s2 );
+ if( s1_even[s1_even.size()-1] == ' ')
+ {
+ s1_even[s1_even.size()-1] = '\0'; //replace space character by null
+ }
+ return s1_even == s2_even;
}
/**
* \ingroup Util
- * \brief Get the current time of the system in a dicom string
+ * \brief Return the IP adress of the machine writting the DICOM image
*/
-std::string Util::GetCurrentTime()
+std::string Util::GetIPAddress()
{
- char tmp[512];
- time_t tloc;
- time (&tloc);
- strftime(tmp,512,"%H%M%S", localtime(&tloc) );
- return tmp;
+ // 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 Create a /DICOM/ string:
- * It should a of even length (no odd length ever)
- * It can contains as many \0 as you want.
+ * \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::DicomString(const char* s, size_t l)
+std::string Util::CreateUniqueUID(const std::string& root)
{
- std::string r(s, s+l);
- assert( !(r.size() % 2) );
- return r;
+ // 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>