⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uuidgenerator.cpp

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 CPP
字号:
//// UUIDGenerator.cpp//// $Id: //poco/1.2/Foundation/src/UUIDGenerator.cpp#1 $//// Library: Foundation// Package: UUID// Module:  UUID//// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/UUIDGenerator.h"#include "Poco/Thread.h"#include "Poco/RandomStream.h"#include "Poco/DigestEngine.h"#include "Poco/MD5Engine.h"#include "Poco/SingletonHolder.h"#include <string.h>namespace Poco {UUIDGenerator::UUIDGenerator(): _ticks(0), _haveNode(false){}UUIDGenerator::~UUIDGenerator(){}UUID UUIDGenerator::create(){	FastMutex::ScopedLock lock(_mutex);	if (!_haveNode)	{		getNode();		_haveNode = true;	}	Timestamp::UtcTimeVal tv = timeStamp();	UInt32 timeLow = UInt32(tv & 0xFFFFFFFF);	UInt16 timeMid = UInt16((tv >> 32) & 0xFFFF);	UInt16 timeHiAndVersion = UInt16((tv >> 48) & 0x0FFF) + (UUID::UUID_TIME_BASED << 12);	UInt16 clockSeq = (UInt16(_random.next() >> 4) & 0x3FFF) | 0x8000;	return UUID(timeLow, timeMid, timeHiAndVersion, clockSeq, _node);}UUID UUIDGenerator::createFromName(const UUID& nsid, const std::string& name){	MD5Engine md5;	return createFromName(nsid, name, md5);}UUID UUIDGenerator::createFromName(const UUID& nsid, const std::string& name, DigestEngine& de){	poco_assert_dbg (de.digestLength() >= 16);	UUID netNsid = nsid;	netNsid.toNetwork();	de.reset();	de.update(&netNsid, sizeof(netNsid));	de.update(name);	char buffer[16];	const DigestEngine::Digest& d = de.digest();	for (int i = 0; i < 16; ++i)	{		buffer[i] = d[i];	}	return UUID(buffer, UUID::UUID_NAME_BASED);}	UUID UUIDGenerator::createRandom(){	char buffer[16];	RandomInputStream ris;	ris.read(buffer, sizeof(buffer));	return UUID(buffer, UUID::UUID_RANDOM);}Timestamp::UtcTimeVal UUIDGenerator::timeStamp(){	Timestamp now;	for (;;)	{		if (now != _lastTime)		{			_lastTime = now;			_ticks = 0;			break;		}		if (_ticks < 100)		{			++_ticks;			break;		}		now.update();	}	Timestamp::UtcTimeVal tv = now.utcTime();	return tv + _ticks;}UUID UUIDGenerator::createOne(){	try	{		return create();	}	catch (Exception&)	{		return createRandom();	}}UUIDGenerator& UUIDGenerator::defaultGenerator(){	static SingletonHolder<UUIDGenerator> sh;	return *sh.get();}} // namespace Poco//// platform-specific code below//#if defined(POCO_OS_FAMILY_WINDOWS)//// Windows//#include <windows.h>#include <iphlpapi.h>namespace Poco {void UUIDGenerator::getNode(){	PIP_ADAPTER_INFO pAdapterInfo;	PIP_ADAPTER_INFO pAdapter = 0;	ULONG len    = sizeof(IP_ADAPTER_INFO);	pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);	// Make an initial call to GetAdaptersInfo to get	// the necessary size into len	DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);	if (rc == ERROR_BUFFER_OVERFLOW) 	{		delete [] reinterpret_cast<char*>(pAdapterInfo);		pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);	}	else if (rc != ERROR_SUCCESS)	{		throw SystemException("cannot get network adapter list");	}	try	{		bool found = false;		if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR) 		{			pAdapter = pAdapterInfo;			while (pAdapter && !found) 			{				if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(_node))				{					memcpy(_node, pAdapter->Address, pAdapter->AddressLength);					found = true;				}			}		}		else throw SystemException("cannot get network adapter list");		if (!found) throw SystemException("no Ethernet adapter found");	}	catch (Exception&)	{		delete [] reinterpret_cast<char*>(pAdapterInfo);		throw;	}	delete [] reinterpret_cast<char*>(pAdapterInfo);}} // namespace Poco#elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX//// BSD variants//#include <sys/types.h>#include <sys/socket.h>#include <ifaddrs.h>#include <net/if_dl.h>namespace Poco {void UUIDGenerator::getNode(){	struct ifaddrs* ifaphead;	int rc = getifaddrs(&ifaphead);	if (rc) throw SystemException("cannot get network adapter list");	bool foundAdapter = false;	for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next) 	{		if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK) 		{			struct sockaddr_dl* sdl = reinterpret_cast<struct sockaddr_dl*>(ifap->ifa_addr);			caddr_t ap = (caddr_t) (sdl->sdl_data + sdl->sdl_nlen);			int alen = sdl->sdl_alen;			if (ap && alen > 0) 			{				memcpy(_node, ap, sizeof(_node));				foundAdapter = true;				break;			}		}	}	freeifaddrs(ifaphead);	if (!foundAdapter) throw SystemException("cannot determine MAC address (no suitable network adapter found)");}} // namespace Poco#elif defined(__CYGWIN__) || POCO_OS == POCO_OS_LINUX//// Linux//#include <sys/ioctl.h>#include <sys/socket.h>#include <netinet/in.h>#include <net/if.h>#include <arpa/inet.h>#include <unistd.h>namespace Poco {void UUIDGenerator::getNode(){	struct ifreq ifr;	int s = socket(PF_INET, SOCK_DGRAM, 0);	if (s == -1) throw SystemException("cannot open socket");	strcpy(ifr.ifr_name, "eth0");	int rc = ioctl(s, SIOCGIFHWADDR, &ifr);	close(s);	if (rc < 0) throw SystemException("cannot get MAC address");	struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&ifr.ifr_addr);	memcpy(_node, sa->sa_data, sizeof(_node));}} // namespace Poco#elif defined(POCO_OS_FAMILY_UNIX) || defined(POCO_OS_FAMILY_VMS)//// Unix/VMS//#if defined(__VMS)#include <ioctl.h>#else#include <sys/ioctl.h>#endif#if defined(sun) || defined(__sun)#include <sys/sockio.h>#endif#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <net/if.h>#if defined(__VMS)#include <inet.h>#else#include <arpa/inet.h>#endif#include <netdb.h>#include <net/if.h>#include <net/if_arp.h>#include <unistd.h>#if defined(__VMS)#define MAXHOSTNAMELEN 64#endifnamespace Poco {void UUIDGenerator::getNode(){	char name[MAXHOSTNAMELEN];	if (gethostname(name, sizeof(name)))		throw SystemException("cannot get host name");	struct hostent* pHost = gethostbyname(name);	if (!pHost) throw SystemException("cannot get host IP address");	int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (s == -1) throw SystemException("cannot open socket");	struct arpreq ar;	memset(&ar, 0, sizeof(ar));	struct sockaddr_in* pAddr = reinterpret_cast<struct sockaddr_in*>(&ar.arp_pa);	pAddr->sin_family = AF_INET;	memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr));	int rc = ioctl(s, SIOCGARP, &ar);	close(s);	if (rc < 0) throw SystemException("cannot get MAC address");	memcpy(_node, ar.arp_ha.sa_data, sizeof(_node));}} // namespace Poco#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -