保持与 .NET Framework Guid(全局唯一标识符)结构对称(及响应函数组)移植到 C/C++(Linux)

Guid.h

#pragma once

#include <string>

#pragma pack(push, 1)

class Guid // #include <uuid/uuid.h>
{
public:
	Guid();
    Guid(const std::string& s);
    Guid(unsigned char* buffer, int length);

public:
	enum ToStringFormat
	{
		TOSTRINGFORMAT_D,
		TOSTRINGFORMAT_N,
		TOSTRINGFORMAT_B,
		TOSTRINGFORMAT_P,
		TOSTRINGFORMAT_X
	};
    inline std::string                  ToString()
    {
        return ToString(TOSTRINGFORMAT_D);
    }
	std::string				            ToString(ToStringFormat fmt);
    void                                Clear();
    inline unsigned char*               ToArray()
    {
        return (unsigned char*)(void*)this;
    }
    inline std::string                  AsMemoryBytes()
    {
        unsigned char* buffer = this->ToArray();
        return std::string((char*)buffer, sizeof(Guid));
    }

public:
    static Guid				            NewGuid();
    static Guid				            NewGuid(uint64_t x, uint64_t y);
    static Guid&                        Empty();
    static Guid                         ParseExact(const std::string& s);
    static Guid&                        ParseExact(Guid& guid, const std::string& s);

public:
    template<typename TValue>
    static TValue                       HexToNumber(unsigned char*& stream_ptr, unsigned char* endoff_ptr)
    {
        TValue nu = 0;
        if (stream_ptr >= endoff_ptr)
        {
            return nu;
        }

        int x = (1 << 1) * sizeof(TValue);
        for (int c = 0; c < x; )
        {
            unsigned char ch = *stream_ptr++;
            if (ch == '-' || ch == '{' || ch == '}' || ch == ',' || ch == '(' || ch == ')')
            {
                if (stream_ptr >= endoff_ptr)
                {
                    break;
                }
                else
                {
                    continue;
                }
            }

            if (ch >= '0' && ch <= '9')
            {
                nu = nu << (c ? 4 : 0) | (TValue)(ch - '0');
            }
            else if (ch >= 'a' && ch <= 'f')
            {
                nu = nu << (c ? 4 : 0) | (TValue)(10 + (ch - 'a'));
            }
            else if (ch >= 'A' && ch <= 'F')
            {
                nu = nu << (c ? 4 : 0) | (TValue)(10 + (ch - 'A'));
            }
            else
            {
                break;
            }

            c++;
        }
        return nu;
    }
    bool                                operator==(const Guid& guid);
    inline bool                         operator!=(const Guid& guid)
    {
        Guid& right = const_cast<Guid&>(guid);
        Guid& left = *this;
        return right == left;
    }

public:
    union
    {
        struct
        {
            unsigned int			    Data1;
            unsigned short			    Data2;
            unsigned short			    Data3;
            unsigned char		        Data4[8];
        };
        struct
        {
            signed int                  _a;
            signed short                _b;
            signed short                _c;
            unsigned char               _d;
            unsigned char               _e;
            unsigned char               _f;
            unsigned char               _g;
            unsigned char               _h;
            unsigned char               _i;
            unsigned char               _j;
            unsigned char               _k;
        };
    };
};

#pragma pack(pop)

Guid.cpp

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <limits>
#include <limits.h>

#include "Guid.h"

#ifdef WIN32
#include <objbase.h>
#else
#include <uuid/uuid.h>
#endif

std::string Guid::ToString(ToStringFormat fmt)
{
	Guid& guid = *this;
	char buf[255];
	buf[0] = '\x0';
	if (fmt == TOSTRINGFORMAT_N)
	{
		snprintf(
			buf,
			sizeof(buf),
			"%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
			(uint32_t)guid.Data1, (uint32_t)guid.Data2, (uint32_t)guid.Data3,
			(uint32_t)guid.Data4[0], (uint32_t)guid.Data4[1],
			(uint32_t)guid.Data4[2], (uint32_t)guid.Data4[3],
			(uint32_t)guid.Data4[4], (uint32_t)guid.Data4[5],
			(uint32_t)guid.Data4[6], (uint32_t)guid.Data4[7]);
	}
	else if (fmt == TOSTRINGFORMAT_B)
	{
		snprintf(
			buf,
			sizeof(buf),
			"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
			(uint32_t)guid.Data1, (uint32_t)guid.Data2, (uint32_t)guid.Data3,
			(uint32_t)guid.Data4[0], (uint32_t)guid.Data4[1],
			(uint32_t)guid.Data4[2], (uint32_t)guid.Data4[3],
			(uint32_t)guid.Data4[4], (uint32_t)guid.Data4[5],
			(uint32_t)guid.Data4[6], (uint32_t)guid.Data4[7]);
	}
	else if (fmt == TOSTRINGFORMAT_P)
	{
		snprintf(
			buf,
			sizeof(buf),
			"(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
			(uint32_t)guid.Data1, (uint32_t)guid.Data2, (uint32_t)guid.Data3,
			(uint32_t)guid.Data4[0], (uint32_t)guid.Data4[1],
			(uint32_t)guid.Data4[2], (uint32_t)guid.Data4[3],
			(uint32_t)guid.Data4[4], (uint32_t)guid.Data4[5],
			(uint32_t)guid.Data4[6], (uint32_t)guid.Data4[7]);
	}
	else if (fmt == TOSTRINGFORMAT_X)
	{
		snprintf(
			buf,
			sizeof(buf),
			"{0x%08x,0x%04x,0x%04x,{0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x,0x%2x}}",
			(uint32_t)guid.Data1, (uint32_t)guid.Data2, (uint32_t)guid.Data3,
			(uint32_t)guid.Data4[0], (uint32_t)guid.Data4[1],
			(uint32_t)guid.Data4[2], (uint32_t)guid.Data4[3],
			(uint32_t)guid.Data4[4], (uint32_t)guid.Data4[5],
			(uint32_t)guid.Data4[6], (uint32_t)guid.Data4[7]);
	}
	else
	{
		snprintf(
			buf,
			sizeof(buf),
			"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
			(uint32_t)guid.Data1, (uint32_t)guid.Data2, (uint32_t)guid.Data3,
			(uint32_t)guid.Data4[0], (uint32_t)guid.Data4[1],
			(uint32_t)guid.Data4[2], (uint32_t)guid.Data4[3],
			(uint32_t)guid.Data4[4], (uint32_t)guid.Data4[5],
			(uint32_t)guid.Data4[6], (uint32_t)guid.Data4[7]);
	}
	return std::string(buf);
}

void Guid::Clear()
{
    ::memset(this, 0, sizeof(Guid));
}

Guid::Guid()
{
    Clear();
}

Guid::Guid(const std::string& s)
{
    Clear();
    ParseExact(*this, s);
}

Guid::Guid(unsigned char* buffer, int length)
{
    Clear();
    if (length > 0 && NULL != buffer)
    {
		int guid_sizeof = sizeof(Guid);
        if (length > guid_sizeof)
        {
            length = guid_sizeof;
        }
        memcpy(this, buffer, length);
    }
}

Guid Guid::NewGuid()
{
    Guid guid;
#ifdef WIN32
    CoCreateGuid((GUID*)&guid);
#else
    uuid_generate(*(uuid_t*)&guid); // uuid_unparse(uuid, szuuid);
#endif
    return guid;
}

Guid Guid::NewGuid(uint64_t x, uint64_t y)
{
    Guid guid;
    uint64_t* pBuf = (uint64_t*)&guid;
    pBuf[0] = x;
    pBuf[1] = y;
    return guid;
}

Guid& Guid::Empty()
{
    static Guid defaultGUID;
    return defaultGUID;
}

Guid Guid::ParseExact(const std::string& s)
{
    Guid guid;
    return ParseExact(guid, s);
}

Guid& Guid::ParseExact(Guid& guid, const std::string& s)
{
    guid = Guid::Empty();
    if (s.empty())
    {
        return guid;
    }

    size_t length = s.size();
    unsigned char* stream_ptr = (unsigned char*)s.data();
    unsigned char* endoff_ptr = stream_ptr + length;

    guid.Data1 = HexToNumber<int>(stream_ptr, endoff_ptr);
    guid.Data2 = HexToNumber<short>(stream_ptr, endoff_ptr);
    guid.Data3 = HexToNumber<short>(stream_ptr, endoff_ptr);
    for (int i = 0, l = sizeof(guid.Data4); i < l; i++)
    {
        guid.Data4[i] = HexToNumber<unsigned char>(stream_ptr, endoff_ptr);
    }
    return guid;
}

bool Guid::operator==(const Guid& guid)
{
    return 0 == memcmp(this, &guid, sizeof(guid));
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值