📄 gdcmutil.cxx
字号:
/*=========================================================================
Program: gdcm
Module: $RCSfile: gdcmUtil.cxx,v $
Language: C++
Date: $Date: 2008-05-19 07:14:39 $
Version: $Revision: 1.44 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "gdcmUtil.h"
#include "gdcmDebug.h"
#include <iostream>
#include <stdarg.h> // for va_list
// For GetCurrentDate, GetCurrentTime
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__)
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <stdarg.h> //only included in implementation file
#include <stdio.h> //only included in implementation file
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__)
#include <winsock.h> // for gethostname and gethostbyname and GetTickCount...
// I haven't find a way to determine wether we need to under GetCurrentTime or not...
// I think the best solution would simply to get rid of this problematic function
// and use a 'less' common name...
#if !defined(__BORLANDC__) || (__BORLANDC__ >= 0x0560)
#undef GetCurrentTime
#endif
#else
#include <unistd.h> // for gethostname
#include <netdb.h> // for gethostbyname
#endif
// For GetMACAddress
#ifdef _WIN32
#include <snmp.h>
#include <conio.h>
#else
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#endif
#ifdef CMAKE_HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> // For SIOCGIFCONF on Linux
#endif
#ifdef CMAKE_HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef CMAKE_HAVE_SYS_SOCKIO_H
#include <sys/sockio.h> // For SIOCGIFCONF on SunOS
#endif
#ifdef CMAKE_HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef CMAKE_HAVE_NETINET_IN_H
#include <netinet/in.h> //For IPPROTO_IP
#endif
#ifdef CMAKE_HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif
#if defined(CMAKE_HAVE_NET_IF_ARP_H) && defined(__sun)
// This is absolutely necessary on SunOS
#include <net/if_arp.h>
#endif
// For GetCurrentThreadID()
#ifdef __linux__
#include <sys/types.h>
#include <linux/unistd.h>
#endif
#ifdef __sun
#include <thread.h>
#endif
#if _WIN32
#define HAVE_UUIDCREATE
#else
#ifdef GDCM_SYSTEM_UUID_FOUND
#define HAVE_UUID_GENERATE
#include "uuid/uuid.h"
#endif
#endif
#include <bitset>
namespace gdcm
{
//-------------------------------------------------------------------------
const std::string Util::GDCM_UID = "1.2.826.0.1.3680043.2.1143";
std::string Util::RootUID = GDCM_UID;
/*
* File Meta Information Version (0002,0001) shall contain a two byte OB
* value consisting of a 0x00 byte, followed by 0x01 byte, and not the
* value 0x0001 encoded as a little endian 16 bit short value,
* which would be the other way around...
*/
const uint16_t Util::FMIV = 0x0100;
uint8_t *Util::FileMetaInformationVersion = (uint8_t *)&FMIV;
#if defined(HAVE_UUIDCREATE) || defined(HAVE_UUID_GENERATE) || defined(HAVE_UUID_CREATE)
std::string Util::GDCM_MAC_ADDRESS = "";
#else
std::string Util::GDCM_MAC_ADDRESS = GetMACAddress();
#endif
//-------------------------------------------------------------------------
// Public
/**
* \brief Provide a better 'c++' approach for sprintf
* For example c code is:
* char result[2048]; // hope 2048 is enough
* sprintf(result, "%04x|%04x", group , elem);
*
* c++ code is
* itksys_ios::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
* string result;
* result = gdcm::Util::Format("%04x|%04x", group , elem);
*/
std::string Util::Format(const char *format, ...)
{
char buffer[2048]; // hope 2048 is enough
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;
}
/**
* \brief Because not available in C++ (?)
* @param str string to check
* @param tokens std::vector to receive the tokenized substrings
* @param delimiters string containing the character delimitors
*/
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);
}
}
/**
* \brief Because not available in C++ (?)
* Counts the number of occurences of a substring within a string
* @param str string to check
* @param subStr substring to count
*/
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;
}
/**
* \brief Checks whether a 'string' is printable or not (in order
* to avoid corrupting the terminal of invocation when printing)
* @param s string to check
*/
bool Util::IsCleanString(std::string const &s)
{
for(unsigned int i=0; i<s.size(); i++)
{
if (!isprint((unsigned char)s[i]) )
{
return false;
}
}
return true;
}
/**
* \brief Checks whether an 'area' is printable or not (in order
* to avoid corrupting the terminal of invocation when printing)
* @param s area to check (uint8_t is just for prototyping. feel free to cast)
* @param l area length to check
*/
bool Util::IsCleanArea(uint8_t *s, int l)
{
for( int i=0; i<l; i++)
{
if (!isprint((unsigned char)s[i]) )
{
return false;
}
}
return true;
}
/**
* \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 check (uint8_t is just for prototyping. feel free to cast)
*/
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;
}
/**
* \brief Weed out a string from the non-printable characters (in order
* to avoid corrupting the terminal of invocation when printing)
* @param s area to process (uint8_t is just for prototyping. feel free to cast)
* @param l area length to check
*/
std::string Util::CreateCleanString(uint8_t *s, int l)
{
std::string str;
for( int i=0; i<l; i++)
{
if (!isprint((unsigned char)s[i]) )
{
str = str + '.';
}
else
{
str = str + (char )s[i];
}
}
return str;
}
/**
* \brief Add a SEPARATOR to the end of the name if 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;
std::string::size_type size = name.size();
if ( name[size-1] != SEPARATOR_X && name[size-1] != SEPARATOR_WIN )
{
name += SEPARATOR;
}
return name;
}
/**
* \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;
std::string::size_type pos1 = res.rfind("/");
std::string::size_type pos2 = res.rfind("\\");
if ( pos1 > pos2 )
{
res.resize(pos1);
}
else
{
res.resize(pos2);
}
return res;
}
/**
* \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;
}
}
/**
* \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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -