Guid.h
// Guid.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2004
#pragma once
#ifndef Ceda_cxUtils_Guid_H
#define Ceda_cxUtils_Guid_H
#include "cxUtils.h"
#include "xstring.h"
#include "Archive.h"
namespace ceda
{
class xostream;
///////////////////////////////////////////////////////////////////////////////////////////////////
// Guid
/*
Unfortunately Microsoft's objbase.h defines operator==() for GUIDs as follows
__inline BOOL operator==(const GUID& guidOne, const GUID& guidOther)
{
return !memcmp(&guidOne,&guidOther,sizeof(GUID));
}
This is terribly inefficient.
There are two reasons for writing our own Guid class
1. Our operator==() is 4 times faster than the one provided by Microsoft!
2. We will have better control over byte swapping issues when we address platform independence
*/
/*
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
*/
// 128 bits
struct Guid
{
uint32 Data1;
uint16 Data2;
uint16 Data3;
uint8 Data4[8];
};
///////////////////////////////////////////////////////////////////////////////////////////////////
cxUtils_API extern const Guid Guid_NULL;
cxUtils_API bool operator<(const Guid& g1, const Guid& g2);
cxUtils_API bool operator==(const Guid& g1, const Guid& g2);
inline bool operator!=(const Guid& g1, const Guid& g2) { return !(g1 == g2); }
inline bool operator>(const Guid& g1, const Guid& g2) { return g2 < g1; }
inline bool operator<=(const Guid& g1, const Guid& g2) { return !(g2 < g1); }
inline bool operator>=(const Guid& g1, const Guid& g2) { return !(g1 < g2); }
cxUtils_API Guid CreateGuid();
// Returns false if the given string is not formattted as a guid correctly
cxUtils_API bool StringToGuid(ConstStringZ s, Guid& g);
// Asserts if string is not formatted correctly as a guid
cxUtils_API Guid StringToGuid(ConstStringZ s);
/*
todo: follow .net concept of a format specifier:
N
32 digits:
00000000000000000000000000000000
D
32 digits separated by hyphens:
00000000-0000-0000-0000-000000000000
B
32 digits separated by hyphens, enclosed in braces:
{00000000-0000-0000-0000-000000000000}
P
32 digits separated by hyphens, enclosed in parentheses:
(00000000-0000-0000-0000-000000000000)
X
Four hexadecimal values enclosed in braces, where the fourth value is a subset of eight
hexadecimal values that is also enclosed in braces:
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
Currently this function corresponds to format 'B'
todo: define whether to use lowercase/uppercase for for the hexadecimal characters A,B,C,D,E,F.
*/
cxUtils_API void GuidToString(const Guid& g, xstring& s);
inline xstring GuidToString(const Guid& g)
{
xstring s;
GuidToString(g,s);
return s;
}
inline xstring CreateGuidString()
{
return GuidToString( CreateGuid() );
}
// Write the given guid using the C struct initialiser syntax.
// For example: {0x1BB8215E,0x2B74,0x48EF,{0x38,0xBE,0x3C,0x80,0x81,0x83,0xE3,0x7A}}
cxUtils_API void WriteGuidAsStructInitialiser(xostream& os, const Guid& guid);
cxUtils_API xostream& operator<<(xostream& os, const Guid& guid);
template<typename Archive>
inline void Serialise(Archive& ar, const Guid& guid)
{
#if CEDA_LITTLE_ENDIAN
ar.SerialisePod(guid);
#else
ar << guid.Data1
<< guid.Data2
<< guid.Data3
<< guid.Data4;
#endif
}
template<typename Archive>
inline void Deserialise(Archive& ar, Guid& guid)
{
#if CEDA_LITTLE_ENDIAN
ar.DeserialisePod(guid);
#else
ar >> guid.Data1
>> guid.Data2
>> guid.Data3
>> guid.Data4;
#endif
}
} // namespace ceda
#endif // include guard