+/**
+ * \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;
+}
+
+/**
+ * \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 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)
+ * 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;
+}
+
+/**
+ * \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;
+}
+
+/**
+ * \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;
+}
+
+
+
+/**
+ * \brief tells us if the processor we are working with is BigEndian or not
+ */
+bool Util::IsCurrentProcessorBigEndian()
+{
+#ifdef GDCM_WORDS_BIGENDIAN
+ return true;
+#else
+ return false;
+#endif
+}
+
+
+
+#ifdef _WIN32
+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);
+#endif //_WIN32
+
+
+int GetMacAddrSys ( unsigned char *addr )
+{
+#ifdef _WIN32
+ WSADATA WinsockData;
+ if (WSAStartup(MAKEWORD(2, 0), &WinsockData) != 0)
+ {
+ std::cerr << "This program requires Winsock 2.x!" << std::endl;
+ return -1;
+ }
+
+ HANDLE PollForTrapEvent;
+ AsnObjectIdentifier SupportedView;
+ UINT OID_ifEntryType[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 3 };
+ UINT OID_ifEntryNum[] = { 1, 3, 6, 1, 2, 1, 2, 1 };
+ UINT OID_ipMACEntAddr[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 6 };
+ AsnObjectIdentifier MIB_ifMACEntAddr = {
+ sizeof(OID_ipMACEntAddr) / sizeof(UINT), OID_ipMACEntAddr };
+ AsnObjectIdentifier MIB_ifEntryType = {
+ sizeof(OID_ifEntryType) / sizeof(UINT), OID_ifEntryType };
+ AsnObjectIdentifier MIB_ifEntryNum = {
+ sizeof(OID_ifEntryNum) / sizeof(UINT), OID_ifEntryNum };
+ RFC1157VarBindList varBindList;
+ RFC1157VarBind varBind[2];
+ AsnInteger errorStatus;
+ AsnInteger errorIndex;
+ AsnObjectIdentifier MIB_NULL = { 0, 0 };
+ int ret;
+ int dtmp;
+ int i = 0, j = 0;
+ BOOL found = FALSE;
+
+ // Load the SNMP dll and get the addresses of the functions necessary
+ HINSTANCE m_hInst = LoadLibrary("inetmib1.dll");
+ if (m_hInst < (HINSTANCE) HINSTANCE_ERROR)
+ {
+ m_hInst = NULL;
+ return -1;
+ }
+ pSnmpExtensionInit m_Init =
+ (pSnmpExtensionInit) GetProcAddress(m_hInst, "SnmpExtensionInit");
+ pSnmpExtensionInitEx m_InitEx =
+ (pSnmpExtensionInitEx) GetProcAddress(m_hInst, "SnmpExtensionInitEx");
+ pSnmpExtensionQuery m_Query =
+ (pSnmpExtensionQuery) GetProcAddress(m_hInst, "SnmpExtensionQuery");
+ pSnmpExtensionTrap m_Trap =
+ (pSnmpExtensionTrap) GetProcAddress(m_hInst, "SnmpExtensionTrap");
+ m_Init(GetTickCount(), &PollForTrapEvent, &SupportedView);
+
+ /* Initialize the variable list to be retrieved by m_Query */
+ varBindList.list = varBind;
+ varBind[0].name = MIB_NULL;
+ varBind[1].name = MIB_NULL;
+
+ // Copy in the OID to find the number of entries in the
+ // Inteface table
+ varBindList.len = 1; // Only retrieving one item
+ SNMP_oidcpy(&varBind[0].name, &MIB_ifEntryNum);
+ ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus,
+ &errorIndex);
+// printf("# of adapters in this system : %i\n",
+// varBind[0].value.asnValue.number);
+ varBindList.len = 2;
+
+ // Copy in the OID of ifType, the type of interface
+ SNMP_oidcpy(&varBind[0].name, &MIB_ifEntryType);
+
+ // Copy in the OID of ifPhysAddress, the address
+ SNMP_oidcpy(&varBind[1].name, &MIB_ifMACEntAddr);
+
+ do
+ {
+ // Submit the query. Responses will be loaded into varBindList.
+ // We can expect this call to succeed a # of times corresponding
+ // to the # of adapters reported to be in the system
+ ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus,
+ &errorIndex);
+ if (!ret)
+ {
+ ret = 1;
+ }
+ else
+ {
+ // Confirm that the proper type has been returned
+ ret = SNMP_oidncmp(&varBind[0].name, &MIB_ifEntryType,
+ MIB_ifEntryType.idLength);
+ }
+ if (!ret)
+ {
+ j++;
+ dtmp = varBind[0].value.asnValue.number;
+ std::cerr << "Interface #" << j << " type : " << dtmp << std::endl;
+
+ // Type 6 describes ethernet interfaces
+ if (dtmp == 6)
+ {
+ // Confirm that we have an address here
+ ret = SNMP_oidncmp(&varBind[1].name, &MIB_ifMACEntAddr,
+ MIB_ifMACEntAddr.idLength);
+ if ( !ret && varBind[1].value.asnValue.address.stream != NULL )
+ {
+ if ( (varBind[1].value.asnValue.address.stream[0] == 0x44)
+ && (varBind[1].value.asnValue.address.stream[1] == 0x45)
+ && (varBind[1].value.asnValue.address.stream[2] == 0x53)
+ && (varBind[1].value.asnValue.address.stream[3] == 0x54)
+ && (varBind[1].value.asnValue.address.stream[4] == 0x00) )
+ {
+ // Ignore all dial-up networking adapters
+ std::cerr << "Interface #" << j << " is a DUN adapter\n";
+ continue;
+ }
+ if ( (varBind[1].value.asnValue.address.stream[0] == 0x00)
+ && (varBind[1].value.asnValue.address.stream[1] == 0x00)
+ && (varBind[1].value.asnValue.address.stream[2] == 0x00)
+ && (varBind[1].value.asnValue.address.stream[3] == 0x00)
+ && (varBind[1].value.asnValue.address.stream[4] == 0x00)
+ && (varBind[1].value.asnValue.address.stream[5] == 0x00) )
+ {
+ // Ignore NULL addresses returned by other network
+ // interfaces
+ std::cerr << "Interface #" << j << " is a NULL address\n";
+ continue;
+ }
+ memcpy( addr, varBind[1].value.asnValue.address.stream, 6);
+ }
+ }
+ }
+ } while (!ret);
+
+ // Free the bindings
+ SNMP_FreeVarBind(&varBind[0]);
+ SNMP_FreeVarBind(&varBind[1]);
+ return 0;
+#endif //Win32 version
+
+
+// implementation for POSIX system
+#ifdef __sun
+ //The POSIX version is broken anyway on Solaris, plus would require full
+ //root power
+ struct arpreq parpreq;
+ struct sockaddr_in *psa;
+ struct hostent *phost;
+ char hostname[MAXHOSTNAMELEN];
+ char **paddrs;
+ int sock, status=0;