X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmUtil.cxx;h=8433ad06ce08115ff2ec04b62d288bcb6c384da7;hb=02163588f1fa2bb0af4b45455b6f9d08ec64f7b3;hp=cbaa71b6de46ff00220bba5c3cf7cd53727c3022;hpb=d6e77ac1b3e594f70ce73df711ad6ec6969f6791;p=gdcm.git diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index cbaa71b6..8433ad06 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 20:02:46 $ - Version: $Revision: 1.116 $ + Date: $Date: 2005/01/28 09:37:29 $ + Version: $Revision: 1.126 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -19,13 +19,14 @@ #include "gdcmUtil.h" #include "gdcmDebug.h" #include +#include // For GetCurrentDate, GetCurrentTime #include #include #include -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) #include #else #include @@ -89,6 +90,9 @@ namespace gdcm { +const std::string Util::GDCM_UID = "1.2.826.0.1.3680043.2.1143"; +std::string Util::RootUID = GDCM_UID; + /** * \brief Provide a better 'c++' approach for sprintf * For example c code is: @@ -284,23 +288,23 @@ std::string Util::GetCurrentDateTime() { char tmp[40]; long milliseconds; - time_t *timep; + time_t timep; // We need implementation specific functions to obtain millisecond precision #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) struct timeb tb; ::ftime(&tb); - timep = &tb.time; + timep = tb.time; milliseconds = tb.millitm; #else struct timeval tv; gettimeofday (&tv, NULL); - timep = &tv.tv_sec; + 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); + 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); @@ -328,13 +332,13 @@ std::string Util::DicomString(const char *s, size_t l) /** * \brief Create a /DICOM/ string: - * It should a of even lenght (no odd length ever) + * 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. * This function is similar to DicomString(const char*), - * except it doesn't take a lenght. + * except it doesn't take a length. * It only pad with a null character if length is odd */ std::string Util::DicomString(const char *s) @@ -351,8 +355,8 @@ std::string Util::DicomString(const char *s) /** * \brief Safely compare two Dicom String: - * - Both string should be of even lenght - * - We allow padding of even lenght string by either a null + * - Both string should be of even length + * - We allow padding of even length string by either a null * character of a space */ bool Util::DicomStringEqual(const std::string &s1, const char *s2) @@ -367,8 +371,6 @@ bool Util::DicomStringEqual(const std::string &s1, const char *s2) return s1_even == s2_even; } - - /** * \brief tells us if the processor we are working with is BigEndian or not */ @@ -667,6 +669,23 @@ int GetMacAddrSys ( unsigned char *addr ) #endif //__sun } +/** + * Mini function to return the last digit from a number express in base 256 + * pre condition data contain an array of 6 unsigned char + * post condition carry contain the last digit + */ +inline int getlastdigit(unsigned char *data) +{ + int extended, carry = 0; + for(int i=0;i<6;i++) + { + extended = (carry << 8) + data[i]; + data[i] = extended / 10; + carry = extended % 10; + } + return carry; +} + /** * \brief Encode the mac address on a fixed lenght string of 15 characters. * we save space this way. @@ -678,15 +697,27 @@ std::string Util::GetMACAddress() // 3 OS: Win32, SunOS and 'real' POSIX // http://groups-beta.google.com/group/comp.unix.solaris/msg/ad36929d783d63be // http://bdn.borland.com/article/0,1410,26040,00.html - union dual { uint64_t n; unsigned char addr[6]; }; - - // zero-initialize the whole thing first: - dual d = { 0 }; - int stat = GetMacAddrSys(d.addr); + unsigned char addr[6]; + + int stat = GetMacAddrSys(addr); if (stat == 0) { - // fill with zero to fit on 15 bytes. - return Format("%015llu", d.n); + // We need to convert a 6 digit number from base 256 to base 10, using integer + // would requires a 48bits one. To avoid this we have to reimplement the div + modulo + // with string only + bool zero = false; + int res; + std::string sres; + while(!zero) + { + res = getlastdigit(addr); + sres += ('0' + res); + zero = (addr[0] == 0) && (addr[1] == 0) && (addr[2] == 0) && (addr[3] == 0) && (addr[4] == 0) && (addr[5] == 0); + } + // Since we push back the proper number is reversed: + std::reverse(sres.begin(),sres.end()); + + return sres; } else { @@ -756,25 +787,57 @@ std::string Util::GetIPAddress() return str; } +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(); +#else + //default implementation + return 0; +#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 + +} + /** * \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 prefix = root; + std::string prefix; std::string append; if( root.empty() ) { - // No root was specified use "GDCM" then - // echo "gdcm" | od -b - // 0000000 147 144 143 155 012 - prefix = "147.144.143.155"; // special easter egg + // gdcm UID prefix, as supplied by http://www.medicalconnections.co.uk + prefix = RootUID; } - // else + else + { + prefix = root; + } + // A root was specified use it to forge our new UID: append += "."; append += Util::GetMACAddress(); @@ -797,32 +860,17 @@ std::string Util::CreateUniqueUID(const std::string &root) return prefix + append; } -unsigned int Util::GetCurrentThreadID() +void Util::SetRootUID(const std::string &root) { -// 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 + if( root.empty() ) + RootUID = GDCM_UID; + else + RootUID = root; } -unsigned int Util::GetCurrentProcessID() +const std::string &Util::GetRootUID() { -#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 RootUID; } /**