+#include "gdcmDebug.h"
+#include <iostream>
+
+// For GetCurrentDate, GetCurrentTime
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdarg.h> //only included in implementation file
+#include <stdio.h> //only included in implementation file
+
+#if defined(_MSC_VER)
+ #include <winsock.h> // for gethostname & gethostbyname
+ #undef GetCurrentTime
+#else
+#ifndef __BORLANDC__
+ #include <unistd.h> // for gethostname
+ #include <netdb.h> // for gethostbyname
+#endif
+#endif
+
+namespace gdcm
+{
+/**
+ * \ingroup Globals
+ * \brief Provide a better 'c++' approach for sprintf
+ * For example c code is:
+ * sprintf(trash, "%04x|%04x", group , elem);
+ *
+ * c++ code is
+ * std::ostringstream buf;
+ * buf << std::right << std::setw(4) << std::setfill('0') << std::hex
+ * << group << "|" << std::right << std::setw(4) << std::setfill('0')
+ * << std::hex << elem;
+ * buf.str();
+ *
+ * gdcm style code is
+ * Format("%04x|%04x", group , elem);
+ */
+
+std::string Util::Format(const char *format, ...)
+{
+ char buffer[2048];
+ va_list args;
+ va_start(args, format);
+ vsprintf(buffer, format, args); //might be a security flaw
+ va_end(args); // Each invocation of va_start should be matched
+ // by a corresponding invocation of va_end
+ // args is then 'undefined'
+ return buffer;
+}
+
+
+/**
+ * \ingroup Globals
+ * \brief Because not available in C++ (?)
+ */
+void Util::Tokenize (const std::string &str,
+ std::vector<std::string> &tokens,
+ const std::string& delimiters)
+{
+ std::string::size_type lastPos = str.find_first_not_of(delimiters,0);
+ std::string::size_type pos = str.find_first_of (delimiters,lastPos);
+ while (std::string::npos != pos || std::string::npos != lastPos)
+ {
+ tokens.push_back(str.substr(lastPos, pos - lastPos));
+ lastPos = str.find_first_not_of(delimiters, pos);
+ pos = str.find_first_of (delimiters, lastPos);
+ }
+}
+
+/**
+ * \ingroup Globals
+ * \brief Because not available in C++ (?)
+ * Counts the number of occurences of a substring within a string
+ */
+
+int Util::CountSubstring (const std::string &str,
+ const std::string &subStr)
+{
+ int count = 0; // counts how many times it appears
+ std::string::size_type x = 0; // The index position in the string
+
+ do
+ {
+ x = str.find(subStr,x); // Find the substring
+ if (x != std::string::npos) // If present
+ {
+ count++; // increase the count
+ x += subStr.length(); // Skip this word
+ }
+ }
+ while (x != std::string::npos); // Carry on until not present
+
+ return count;
+}
+
+/**
+ * \ingroup Globals
+ * \brief Weed out a string from the non-printable characters (in order
+ * to avoid corrupting the terminal of invocation when printing)
+ * @param s string to remove non printable characters from
+ */
+std::string Util::CreateCleanString(std::string const &s)
+{
+ std::string str = s;
+
+ for(unsigned int i=0; i<str.size(); i++)
+ {
+ if(!isprint((unsigned char)str[i]))
+ {
+ str[i] = '.';
+ }
+ }
+
+ if(str.size() > 0)
+ {
+ if(!isprint((unsigned char)s[str.size()-1]))
+ {
+ if(s[str.size()-1] == 0)
+ {
+ str[str.size()-1] = ' ';
+ }
+ }
+ }
+
+ return str;
+}
+
+/**
+ * \ingroup Globals
+ * \brief Add a SEPARATOR to the end of the name is necessary
+ * @param pathname file/directory name to normalize
+ */
+std::string Util::NormalizePath(std::string const &pathname)
+{
+ const char SEPARATOR_X = '/';
+ const char SEPARATOR_WIN = '\\';
+ const std::string SEPARATOR = "/";
+ std::string name = pathname;
+ int size = name.size();
+
+ if( name[size-1] != SEPARATOR_X && name[size-1] != SEPARATOR_WIN )
+ {
+ name += SEPARATOR;
+ }
+ return name;
+}
+
+/**
+ * \ingroup Globals
+ * \brief Get the (directory) path from a full path file name
+ * @param fullName file/directory name to extract Path from
+ */
+std::string Util::GetPath(std::string const &fullName)
+{
+ std::string res = fullName;
+ int pos1 = res.rfind("/");
+ int pos2 = res.rfind("\\");
+ if( pos1 > pos2)
+ {
+ res.resize(pos1);
+ }
+ else
+ {
+ res.resize(pos2);
+ }
+
+ return res;
+}
+
+/**
+ * \ingroup Util
+ * \brief Get the (last) name of a full path file name
+ * @param fullName file/directory name to extract end name from
+ */
+std::string Util::GetName(std::string const &fullName)
+{
+ std::string filename = fullName;
+
+ std::string::size_type slash_pos = filename.rfind("/");
+ std::string::size_type backslash_pos = filename.rfind("\\");
+ slash_pos = slash_pos > backslash_pos ? slash_pos : backslash_pos;
+ if(slash_pos != std::string::npos)
+ {
+ return filename.substr(slash_pos + 1);
+ }
+ else
+ {
+ return filename;
+ }
+}
+
+/**
+ * \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);
+ gdcmAssertMacro( !(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 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
+ */
+std::string Util::DicomString(const char *s)
+{
+ size_t l = strlen(s);
+ if( l%2 )
+ {
+ l++;
+ }
+ std::string r(s, s+l);
+ gdcmAssertMacro( !(r.size() % 2) );
+ return r;
+}
+
+/**
+ * \ingroup Util
+ * \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
+ */
+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 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 tells us if the processor we are working with is BigEndian or not
+ */
+bool Util::IsCurrentProcessorBigEndian()
+{
+ uint16_t intVal = 1;
+ uint8_t bigEndianRepr[4] = { 0x00, 0x00, 0x00, 0x01 };
+ int res = memcmp(reinterpret_cast<const void*>(&intVal),
+ reinterpret_cast<const void*>(bigEndianRepr), 4);
+ if (res == 0)
+ return true;
+ else
+ return false;
+}
+
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <snmp.h>
+#include <conio.h>
+typedef BOOL(WINAPI * pSnmpExtensionInit) (
+ IN DWORD dwTimeZeroReference,
+ OUT HANDLE * hPollForTrapEvent,
+ OUT AsnObjectIdentifier * supportedView);
+
+typedef BOOL(WINAPI * pSnmpExtensionTrap) (
+ OUT AsnObjectIdentifier * enterprise,
+ OUT AsnInteger * genericTrap,
+ OUT AsnInteger * specificTrap,
+ OUT AsnTimeticks * timeStamp,
+ OUT RFC1157VarBindList * variableBindings);
+
+typedef BOOL(WINAPI * pSnmpExtensionQuery) (
+ IN BYTE requestType,
+ IN OUT RFC1157VarBindList * variableBindings,
+ OUT AsnInteger * errorStatus,
+ OUT AsnInteger * errorIndex);
+
+typedef BOOL(WINAPI * pSnmpExtensionInitEx) (
+ OUT AsnObjectIdentifier * supportedView);
+#else
+#include <strings.h> //for bzero on unix
+#endif //_WIN32
+
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/if.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+#endif
+
+#ifdef __HP_aCC
+#include <netio.h>
+#endif
+
+#ifdef _AIX
+#include <sys/ndd_var.h>
+#include <sys/kinfo.h>
+#endif
+
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/network/IOEthernetInterface.h>
+#include <IOKit/network/IONetworkInterface.h>
+#include <IOKit/network/IOEthernetController.h>
+
+//static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
+//static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress);