From: malaterre Date: Fri, 21 Jan 2005 16:06:21 +0000 (+0000) Subject: ENH: Add two new methods: GetCurrentThreadID and ProcessID. This could be usefull... X-Git-Tag: Version1.0.bp~222 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;ds=inline;h=f5a3357d5243ea55d994eda5ff406edbdbe5077c;p=gdcm.git ENH: Add two new methods: GetCurrentThreadID and ProcessID. This could be usefull to generate the DICOM UID. Also reimplement GetCurrentDate / GetCurrentTime in only one call since we could be right at the edge of midnight and the two function call would not be consistent. Also this simplify the implementation of GetCurrentDateTime and add millisecond precision (yes we write DICOM quite fast) --- diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index 39d0ba7b..a989c3ad 100644 --- a/src/gdcmUtil.cxx +++ b/src/gdcmUtil.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.cxx,v $ Language: C++ - Date: $Date: 2005/01/21 11:40:56 $ - Version: $Revision: 1.113 $ + Date: $Date: 2005/01/21 16:06:21 $ + Version: $Revision: 1.114 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -25,6 +25,12 @@ #include #include +#ifdef _MSC_VER +#include +#else +#include +#endif + #include //only included in implementation file #include //only included in implementation file @@ -68,10 +74,19 @@ #include #endif #if defined(CMAKE_HAVE_NET_IF_ARP_H) && defined(__sun) - // This is absolutely necesseray on SunOS + // This is absolutely necessary on SunOS #include #endif +// For GetCurrentThreadID() +#ifdef __linux__ +#include +#include +#endif +#ifdef __sun +#include +#endif + namespace gdcm { /** @@ -261,6 +276,41 @@ std::string Util::GetCurrentTime() return tmp; } +/** + * \brief Get both the date and time at the same time to avoid problem + * around midnight where two call could be before and after midnight + */ +std::string Util::GetCurrentDateTime() +{ + char tmp[40]; + long milliseconds; + time_t *timep; + + // We need implementation specific functions to obtain millisecond precision +#ifdef _MSC_VER + struct timeb tb; + ::ftime(&tb); + timep = &tb.time; + milliseconds = tb.millitm; +#else + struct timeval tv; + gettimeofday (&tv, NULL); + timep = &tv.tv_sec; + // Compute milliseconds from microseconds. + milliseconds = tv.tv_usec / 1000; +#endif + // Obtain the time of day, and convert it to a tm struct. + struct tm *ptm = localtime (timep); + // Format the date and time, down to a single second. + strftime (tmp, sizeof (tmp), "%Y%m%d.%H%M%S", ptm); + + // Add milliseconds + std::string r = tmp; + r += Format("%03ld", milliseconds); + + return r; +} + /** * \brief Create a /DICOM/ string: * It should a of even length (no odd length ever) @@ -642,9 +692,9 @@ std::string Util::GetMACAddress() { for (int i=0; i<6; ++i) { - macaddr += Format("%2.2x", addr[i]); - //if(i) macaddr += "."; - //macaddr += Format("%i", (int)addr[i]); + //macaddr += Format("%2.2x", addr[i]); + if(i) macaddr += "."; + macaddr += Format("%i", (int)addr[i]); } return macaddr; } @@ -720,26 +770,68 @@ std::string Util::GetIPAddress() * \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) + * @param root is the DICOM prefix assigned by IOS group + * @param is a string you want to append to the UID. */ std::string Util::CreateUniqueUID(const std::string &root) { - std::string radical = root; - if( !root.size() ) + std::string prefix = root; + std::string append; + if( root.empty() ) { // No root was specified use "GDCM" then // echo "gdcm" | od -b // 0000000 147 144 143 155 012 - radical = "147.144.143.155"; // special easter egg + prefix = "147.144.143.155"; // special easter egg } // else // A root was specified use it to forge our new UID: - radical += Util::GetMACAddress(); - radical += "."; - radical += Util::GetCurrentDate(); - radical += "."; - radical += Util::GetCurrentTime(); + append += "."; + append += Util::GetMACAddress(); + append += "."; + //append += Util::GetCurrentDate(); + //append += "."; + //append += Util::GetCurrentTime(); + append += Util::GetCurrentDateTime(); + + // If append is too long we need to rehash it + if( (prefix + append).size() > 64 ) + { + gdcmErrorMacro( "Size of UID is too long." ); + // we need a hash function to truncate this number + // if only md5 was cross plateform + // MD5(append); + } + + return prefix + append; +} + +unsigned int Util::GetCurrentThreadID() +{ +// FIXME the implementation is far from complete +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) + return (unsigned int)GetCurrentThreadId(); +#endif +#ifdef __linux__ + return 0; + // Doesn't work on fedora, but is in the man page... + //return (unsigned int)gettid(); +#endif +#ifdef __sun + return (unsigned int)thr_self(); +#endif +} + +unsigned int Util::GetCurrentProcessID() +{ +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) + // NOTE: There is also a _getpid()... + return (unsigned int)GetCurrentProcessId(); +#else + // get process identification, POSIX + return (unsigned int)getpid(); +#endif - return radical; } /** diff --git a/src/gdcmUtil.h b/src/gdcmUtil.h index b2eba37b..129b14b2 100644 --- a/src/gdcmUtil.h +++ b/src/gdcmUtil.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.h,v $ Language: C++ - Date: $Date: 2005/01/11 15:15:38 $ - Version: $Revision: 1.49 $ + Date: $Date: 2005/01/21 16:06:21 $ + Version: $Revision: 1.50 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -50,6 +50,9 @@ public: static std::string GetName(std::string const &fullName); static std::string GetCurrentDate(); static std::string GetCurrentTime(); + static std::string GetCurrentDateTime(); + static unsigned int GetCurrentThreadID(); + static unsigned int GetCurrentProcessID(); static std::string DicomString(const char *s, size_t l); static std::string DicomString(const char *s);