e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
1298 lines
48 KiB
C#
1298 lines
48 KiB
C#
// ==++==
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ==--==
|
|
namespace System {
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using Microsoft.Win32;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Diagnostics.Contracts;
|
|
|
|
// Represents a Globally Unique Identifier.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
[Serializable]
|
|
[System.Runtime.InteropServices.ComVisible(true)]
|
|
[System.Runtime.Versioning.NonVersionable] // This only applies to field layout
|
|
public partial struct Guid : IFormattable, IComparable
|
|
#if GENERICS_WORK
|
|
, IComparable<Guid>, IEquatable<Guid>
|
|
#endif
|
|
{
|
|
public static readonly Guid Empty = new Guid();
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Member variables
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
private int _a;
|
|
private short _b;
|
|
private short _c;
|
|
private byte _d;
|
|
private byte _e;
|
|
private byte _f;
|
|
private byte _g;
|
|
private byte _h;
|
|
private byte _i;
|
|
private byte _j;
|
|
private byte _k;
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Constructors
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Creates a new guid from an array of bytes.
|
|
//
|
|
public Guid(byte[] b)
|
|
{
|
|
if (b==null)
|
|
throw new ArgumentNullException("b");
|
|
if (b.Length != 16)
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "16"));
|
|
Contract.EndContractBlock();
|
|
|
|
_a = ((int)b[3] << 24) | ((int)b[2] << 16) | ((int)b[1] << 8) | b[0];
|
|
_b = (short)(((int)b[5] << 8) | b[4]);
|
|
_c = (short)(((int)b[7] << 8) | b[6]);
|
|
_d = b[8];
|
|
_e = b[9];
|
|
_f = b[10];
|
|
_g = b[11];
|
|
_h = b[12];
|
|
_i = b[13];
|
|
_j = b[14];
|
|
_k = b[15];
|
|
}
|
|
|
|
[CLSCompliant(false)]
|
|
public Guid (uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
|
|
{
|
|
_a = (int)a;
|
|
_b = (short)b;
|
|
_c = (short)c;
|
|
_d = d;
|
|
_e = e;
|
|
_f = f;
|
|
_g = g;
|
|
_h = h;
|
|
_i = i;
|
|
_j = j;
|
|
_k = k;
|
|
}
|
|
|
|
|
|
// Creates a new GUID initialized to the value represented by the arguments.
|
|
//
|
|
public Guid(int a, short b, short c, byte[] d)
|
|
{
|
|
if (d==null)
|
|
throw new ArgumentNullException("d");
|
|
// Check that array is not too big
|
|
if(d.Length != 8)
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "8"));
|
|
Contract.EndContractBlock();
|
|
|
|
_a = a;
|
|
_b = b;
|
|
_c = c;
|
|
_d = d[0];
|
|
_e = d[1];
|
|
_f = d[2];
|
|
_g = d[3];
|
|
_h = d[4];
|
|
_i = d[5];
|
|
_j = d[6];
|
|
_k = d[7];
|
|
}
|
|
|
|
// Creates a new GUID initialized to the value represented by the
|
|
// arguments. The bytes are specified like this to avoid endianness issues.
|
|
//
|
|
public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
|
|
{
|
|
_a = a;
|
|
_b = b;
|
|
_c = c;
|
|
_d = d;
|
|
_e = e;
|
|
_f = f;
|
|
_g = g;
|
|
_h = h;
|
|
_i = i;
|
|
_j = j;
|
|
_k = k;
|
|
}
|
|
|
|
[Flags]
|
|
private enum GuidStyles {
|
|
None = 0x00000000,
|
|
AllowParenthesis = 0x00000001, //Allow the guid to be enclosed in parens
|
|
AllowBraces = 0x00000002, //Allow the guid to be enclosed in braces
|
|
AllowDashes = 0x00000004, //Allow the guid to contain dash group separators
|
|
AllowHexPrefix = 0x00000008, //Allow the guid to contain {0xdd,0xdd}
|
|
RequireParenthesis = 0x00000010, //Require the guid to be enclosed in parens
|
|
RequireBraces = 0x00000020, //Require the guid to be enclosed in braces
|
|
RequireDashes = 0x00000040, //Require the guid to contain dash group separators
|
|
RequireHexPrefix = 0x00000080, //Require the guid to contain {0xdd,0xdd}
|
|
|
|
HexFormat = RequireBraces | RequireHexPrefix, /* X */
|
|
NumberFormat = None, /* N */
|
|
DigitFormat = RequireDashes, /* D */
|
|
BraceFormat = RequireBraces | RequireDashes, /* B */
|
|
ParenthesisFormat = RequireParenthesis | RequireDashes, /* P */
|
|
|
|
Any = AllowParenthesis | AllowBraces | AllowDashes | AllowHexPrefix,
|
|
}
|
|
private enum GuidParseThrowStyle {
|
|
None = 0,
|
|
All = 1,
|
|
AllButOverflow = 2
|
|
}
|
|
private enum ParseFailureKind {
|
|
None = 0,
|
|
ArgumentNull = 1,
|
|
Format = 2,
|
|
FormatWithParameter = 3,
|
|
NativeException = 4,
|
|
FormatWithInnerException = 5
|
|
}
|
|
|
|
// This will store the result of the parsing. And it will eventually be used to construct a Guid instance.
|
|
private struct GuidResult {
|
|
internal Guid parsedGuid;
|
|
internal GuidParseThrowStyle throwStyle;
|
|
|
|
internal ParseFailureKind m_failure;
|
|
internal string m_failureMessageID;
|
|
internal object m_failureMessageFormatArgument;
|
|
internal string m_failureArgumentName;
|
|
internal Exception m_innerException;
|
|
|
|
internal void Init(GuidParseThrowStyle canThrow) {
|
|
parsedGuid = Guid.Empty;
|
|
throwStyle = canThrow;
|
|
}
|
|
internal void SetFailure(Exception nativeException) {
|
|
m_failure = ParseFailureKind.NativeException;
|
|
m_innerException = nativeException;
|
|
}
|
|
internal void SetFailure(ParseFailureKind failure, string failureMessageID) {
|
|
SetFailure(failure, failureMessageID, null, null, null);
|
|
}
|
|
internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) {
|
|
SetFailure(failure, failureMessageID, failureMessageFormatArgument, null, null);
|
|
}
|
|
internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument,
|
|
string failureArgumentName, Exception innerException) {
|
|
Contract.Assert(failure != ParseFailureKind.NativeException, "ParseFailureKind.NativeException should not be used with this overload");
|
|
m_failure = failure;
|
|
m_failureMessageID = failureMessageID;
|
|
m_failureMessageFormatArgument = failureMessageFormatArgument;
|
|
m_failureArgumentName = failureArgumentName;
|
|
m_innerException = innerException;
|
|
if (throwStyle != GuidParseThrowStyle.None) {
|
|
throw GetGuidParseException();
|
|
}
|
|
}
|
|
|
|
internal Exception GetGuidParseException() {
|
|
switch (m_failure) {
|
|
case ParseFailureKind.ArgumentNull:
|
|
return new ArgumentNullException(m_failureArgumentName, Environment.GetResourceString(m_failureMessageID));
|
|
|
|
case ParseFailureKind.FormatWithInnerException:
|
|
return new FormatException(Environment.GetResourceString(m_failureMessageID), m_innerException);
|
|
|
|
case ParseFailureKind.FormatWithParameter:
|
|
return new FormatException(Environment.GetResourceString(m_failureMessageID, m_failureMessageFormatArgument));
|
|
|
|
case ParseFailureKind.Format:
|
|
return new FormatException(Environment.GetResourceString(m_failureMessageID));
|
|
|
|
case ParseFailureKind.NativeException:
|
|
return m_innerException;
|
|
|
|
default:
|
|
Contract.Assert(false, "Unknown GuidParseFailure: " + m_failure);
|
|
return new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Creates a new guid based on the value in the string. The value is made up
|
|
// of hex digits speared by the dash ("-"). The string may begin and end with
|
|
// brackets ("{", "}").
|
|
//
|
|
// The string must be of the form dddddddd-dddd-dddd-dddd-dddddddddddd. where
|
|
// d is a hex digit. (That is 8 hex digits, followed by 4, then 4, then 4,
|
|
// then 12) such as: "CA761232-ED42-11CE-BACD-00AA0057B223"
|
|
//
|
|
public Guid(String g)
|
|
{
|
|
if (g==null) {
|
|
throw new ArgumentNullException("g");
|
|
}
|
|
Contract.EndContractBlock();
|
|
this = Guid.Empty;
|
|
|
|
GuidResult result = new GuidResult();
|
|
result.Init(GuidParseThrowStyle.All);
|
|
if (TryParseGuid(g, GuidStyles.Any, ref result)) {
|
|
this = result.parsedGuid;
|
|
}
|
|
else {
|
|
throw result.GetGuidParseException();
|
|
}
|
|
}
|
|
|
|
|
|
public static Guid Parse(String input)
|
|
{
|
|
if (input == null) {
|
|
throw new ArgumentNullException("input");
|
|
}
|
|
Contract.EndContractBlock();
|
|
|
|
GuidResult result = new GuidResult();
|
|
result.Init(GuidParseThrowStyle.AllButOverflow);
|
|
if (TryParseGuid(input, GuidStyles.Any, ref result)) {
|
|
return result.parsedGuid;
|
|
}
|
|
else {
|
|
throw result.GetGuidParseException();
|
|
}
|
|
}
|
|
|
|
public static bool TryParse(String input, out Guid result)
|
|
{
|
|
GuidResult parseResult = new GuidResult();
|
|
parseResult.Init(GuidParseThrowStyle.None);
|
|
if (TryParseGuid(input, GuidStyles.Any, ref parseResult)) {
|
|
result = parseResult.parsedGuid;
|
|
return true;
|
|
}
|
|
else {
|
|
result = Guid.Empty;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static Guid ParseExact(String input, String format)
|
|
{
|
|
if (input == null)
|
|
throw new ArgumentNullException("input");
|
|
|
|
if (format == null)
|
|
throw new ArgumentNullException("format");
|
|
|
|
if( format.Length != 1) {
|
|
// all acceptable format strings are of length 1
|
|
throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
|
|
}
|
|
|
|
GuidStyles style;
|
|
char formatCh = format[0];
|
|
if (formatCh == 'D' || formatCh == 'd') {
|
|
style = GuidStyles.DigitFormat;
|
|
}
|
|
else if (formatCh == 'N' || formatCh == 'n') {
|
|
style = GuidStyles.NumberFormat;
|
|
}
|
|
else if (formatCh == 'B' || formatCh == 'b') {
|
|
style = GuidStyles.BraceFormat;
|
|
}
|
|
else if (formatCh == 'P' || formatCh == 'p') {
|
|
style = GuidStyles.ParenthesisFormat;
|
|
}
|
|
else if (formatCh == 'X' || formatCh == 'x') {
|
|
style = GuidStyles.HexFormat;
|
|
}
|
|
else {
|
|
throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
|
|
}
|
|
|
|
GuidResult result = new GuidResult();
|
|
result.Init(GuidParseThrowStyle.AllButOverflow);
|
|
if (TryParseGuid(input, style, ref result)) {
|
|
return result.parsedGuid;
|
|
}
|
|
else {
|
|
throw result.GetGuidParseException();
|
|
}
|
|
}
|
|
|
|
public static bool TryParseExact(String input, String format, out Guid result)
|
|
{
|
|
if (format == null || format.Length != 1) {
|
|
result = Guid.Empty;
|
|
return false;
|
|
}
|
|
|
|
GuidStyles style;
|
|
char formatCh = format[0];
|
|
|
|
if (formatCh == 'D' || formatCh == 'd') {
|
|
style = GuidStyles.DigitFormat;
|
|
}
|
|
else if (formatCh == 'N' || formatCh == 'n') {
|
|
style = GuidStyles.NumberFormat;
|
|
}
|
|
else if (formatCh == 'B' || formatCh == 'b') {
|
|
style = GuidStyles.BraceFormat;
|
|
}
|
|
else if (formatCh == 'P' || formatCh == 'p') {
|
|
style = GuidStyles.ParenthesisFormat;
|
|
}
|
|
else if (formatCh == 'X' || formatCh == 'x') {
|
|
style = GuidStyles.HexFormat;
|
|
}
|
|
else {
|
|
// invalid guid format specification
|
|
result = Guid.Empty;
|
|
return false;
|
|
}
|
|
|
|
GuidResult parseResult = new GuidResult();
|
|
parseResult.Init(GuidParseThrowStyle.None);
|
|
if (TryParseGuid(input, style, ref parseResult)) {
|
|
result = parseResult.parsedGuid;
|
|
return true;
|
|
}
|
|
else {
|
|
result = Guid.Empty;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
private static bool TryParseGuid(String g, GuidStyles flags, ref GuidResult result)
|
|
{
|
|
if (g == null) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
String guidString = g.Trim(); //Remove Whitespace
|
|
|
|
if (guidString.Length == 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
|
|
// Check for dashes
|
|
bool dashesExistInString = (guidString.IndexOf('-', 0) >= 0);
|
|
|
|
if (dashesExistInString) {
|
|
if ((flags & (GuidStyles.AllowDashes | GuidStyles.RequireDashes)) == 0) {
|
|
// dashes are not allowed
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if ((flags & GuidStyles.RequireDashes) != 0) {
|
|
// dashes are required
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Check for braces
|
|
bool bracesExistInString = (guidString.IndexOf('{', 0) >= 0);
|
|
|
|
if (bracesExistInString) {
|
|
if ((flags & (GuidStyles.AllowBraces | GuidStyles.RequireBraces)) == 0) {
|
|
// braces are not allowed
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if ((flags & GuidStyles.RequireBraces) != 0) {
|
|
// braces are required
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Check for parenthesis
|
|
bool parenthesisExistInString = (guidString.IndexOf('(', 0) >= 0);
|
|
|
|
if (parenthesisExistInString) {
|
|
if ((flags & (GuidStyles.AllowParenthesis | GuidStyles.RequireParenthesis)) == 0) {
|
|
// parenthesis are not allowed
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if ((flags & GuidStyles.RequireParenthesis) != 0) {
|
|
// parenthesis are required
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
try {
|
|
// let's get on with the parsing
|
|
if (dashesExistInString) {
|
|
// Check if it's of the form [{|(]dddddddd-dddd-dddd-dddd-dddddddddddd[}|)]
|
|
return TryParseGuidWithDashes(guidString, ref result);
|
|
}
|
|
else if (bracesExistInString) {
|
|
// Check if it's of the form {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
|
|
return TryParseGuidWithHexPrefix(guidString, ref result);
|
|
}
|
|
else {
|
|
// Check if it's of the form dddddddddddddddddddddddddddddddd
|
|
return TryParseGuidWithNoStyle(guidString, ref result);
|
|
}
|
|
}
|
|
catch(IndexOutOfRangeException ex) {
|
|
result.SetFailure(ParseFailureKind.FormatWithInnerException, "Format_GuidUnrecognized", null, null, ex);
|
|
return false;
|
|
}
|
|
catch (ArgumentException ex) {
|
|
result.SetFailure(ParseFailureKind.FormatWithInnerException, "Format_GuidUnrecognized", null, null, ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// Check if it's of the form {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
|
|
private static bool TryParseGuidWithHexPrefix(String guidString, ref GuidResult result) {
|
|
int numStart = 0;
|
|
int numLen = 0;
|
|
|
|
// Eat all of the whitespace
|
|
guidString = EatAllWhitespace(guidString);
|
|
|
|
// Check for leading '{'
|
|
if(String.IsNullOrEmpty(guidString) || guidString[0] != '{') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidBrace");
|
|
return false;
|
|
}
|
|
|
|
// Check for '0x'
|
|
if(!IsHexPrefix(guidString, 1)) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, etc}");
|
|
return false;
|
|
}
|
|
|
|
// Find the end of this hex number (since it is not fixed length)
|
|
numStart = 3;
|
|
numLen = guidString.IndexOf(',', numStart) - numStart;
|
|
if(numLen <= 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
|
|
return false;
|
|
}
|
|
|
|
|
|
if (!StringToInt(guidString.Substring(numStart, numLen) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._a, ref result))
|
|
return false;
|
|
|
|
// Check for '0x'
|
|
if(!IsHexPrefix(guidString, numStart+numLen+1)) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, etc}");
|
|
return false;
|
|
}
|
|
// +3 to get by ',0x'
|
|
numStart = numStart + numLen + 3;
|
|
numLen = guidString.IndexOf(',', numStart) - numStart;
|
|
if(numLen <= 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
|
|
return false;
|
|
}
|
|
|
|
// Read in the number
|
|
if (!StringToShort(guidString.Substring(numStart, numLen) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._b, ref result))
|
|
return false;
|
|
// Check for '0x'
|
|
if(!IsHexPrefix(guidString, numStart+numLen+1)) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, 0xdddd, etc}");
|
|
return false;
|
|
}
|
|
// +3 to get by ',0x'
|
|
numStart = numStart + numLen + 3;
|
|
numLen = guidString.IndexOf(',', numStart) - numStart;
|
|
if(numLen <= 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
|
|
return false;
|
|
}
|
|
|
|
// Read in the number
|
|
if (!StringToShort(guidString.Substring(numStart, numLen) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._c, ref result))
|
|
return false;
|
|
|
|
// Check for '{'
|
|
if(guidString.Length <= numStart+numLen+1 || guidString[numStart+numLen+1] != '{') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidBrace");
|
|
return false;
|
|
}
|
|
|
|
// Prepare for loop
|
|
numLen++;
|
|
byte[] bytes = new byte[8];
|
|
|
|
for(int i = 0; i < 8; i++)
|
|
{
|
|
// Check for '0x'
|
|
if(!IsHexPrefix(guidString, numStart+numLen+1)) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{... { ... 0xdd, ...}}");
|
|
return false;
|
|
}
|
|
|
|
// +3 to get by ',0x' or '{0x' for first case
|
|
numStart = numStart + numLen + 3;
|
|
|
|
// Calculate number length
|
|
if(i < 7) // first 7 cases
|
|
{
|
|
numLen = guidString.IndexOf(',', numStart) - numStart;
|
|
if(numLen <= 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
|
|
return false;
|
|
}
|
|
}
|
|
else // last case ends with '}', not ','
|
|
{
|
|
numLen = guidString.IndexOf('}', numStart) - numStart;
|
|
if(numLen <= 0) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidBraceAfterLastNumber");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Read in the number
|
|
uint number = (uint)Convert.ToInt32(guidString.Substring(numStart, numLen),16);
|
|
// check for overflow
|
|
if(number > 255) {
|
|
result.SetFailure(ParseFailureKind.Format, "Overflow_Byte");
|
|
return false;
|
|
}
|
|
bytes[i] = (byte)number;
|
|
}
|
|
|
|
result.parsedGuid._d = bytes[0];
|
|
result.parsedGuid._e = bytes[1];
|
|
result.parsedGuid._f = bytes[2];
|
|
result.parsedGuid._g = bytes[3];
|
|
result.parsedGuid._h = bytes[4];
|
|
result.parsedGuid._i = bytes[5];
|
|
result.parsedGuid._j = bytes[6];
|
|
result.parsedGuid._k = bytes[7];
|
|
|
|
// Check for last '}'
|
|
if(numStart+numLen+1 >= guidString.Length || guidString[numStart+numLen+1] != '}') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidEndBrace");
|
|
return false;
|
|
}
|
|
|
|
// Check if we have extra characters at the end
|
|
if( numStart+numLen+1 != guidString.Length -1) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_ExtraJunkAtEnd");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Check if it's of the form dddddddddddddddddddddddddddddddd
|
|
private static bool TryParseGuidWithNoStyle(String guidString, ref GuidResult result) {
|
|
int startPos=0;
|
|
int temp;
|
|
long templ;
|
|
int currentPos = 0;
|
|
|
|
if(guidString.Length != 32) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
|
|
for(int i= 0; i< guidString.Length; i++) {
|
|
char ch = guidString[i];
|
|
if(ch >= '0' && ch <= '9') {
|
|
continue;
|
|
}
|
|
else {
|
|
char upperCaseCh = Char.ToUpper(ch, CultureInfo.InvariantCulture);
|
|
if(upperCaseCh >= 'A' && upperCaseCh <= 'F') {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvalidChar");
|
|
return false;
|
|
}
|
|
|
|
if (!StringToInt(guidString.Substring(startPos, 8) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._a, ref result))
|
|
return false;
|
|
|
|
startPos += 8;
|
|
if (!StringToShort(guidString.Substring(startPos, 4), -1, ParseNumbers.IsTight, out result.parsedGuid._b, ref result))
|
|
return false;
|
|
|
|
startPos += 4;
|
|
if (!StringToShort(guidString.Substring(startPos, 4), -1, ParseNumbers.IsTight, out result.parsedGuid._c, ref result))
|
|
return false;
|
|
|
|
startPos += 4;
|
|
if (!StringToInt(guidString.Substring(startPos, 4), -1, ParseNumbers.IsTight, out temp, ref result))
|
|
return false;
|
|
|
|
startPos += 4;
|
|
currentPos = startPos;
|
|
|
|
if (!StringToLong(guidString, ref currentPos, ParseNumbers.NoSpace, out templ, ref result))
|
|
return false;
|
|
|
|
if (currentPos - startPos!=12) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
|
|
result.parsedGuid._d = (byte)(temp>>8);
|
|
result.parsedGuid._e = (byte)(temp);
|
|
temp = (int)(templ >> 32);
|
|
result.parsedGuid._f = (byte)(temp>>8);
|
|
result.parsedGuid._g = (byte)(temp);
|
|
temp = (int)(templ);
|
|
result.parsedGuid._h = (byte)(temp>>24);
|
|
result.parsedGuid._i = (byte)(temp>>16);
|
|
result.parsedGuid._j = (byte)(temp>>8);
|
|
result.parsedGuid._k = (byte)(temp);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Check if it's of the form [{|(]dddddddd-dddd-dddd-dddd-dddddddddddd[}|)]
|
|
private static bool TryParseGuidWithDashes(String guidString, ref GuidResult result) {
|
|
int startPos=0;
|
|
int temp;
|
|
long templ;
|
|
int currentPos = 0;
|
|
|
|
// check to see that it's the proper length
|
|
if (guidString[0]=='{') {
|
|
if (guidString.Length!=38 || guidString[37]!='}') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
startPos=1;
|
|
}
|
|
else if (guidString[0]=='(') {
|
|
if (guidString.Length!=38 || guidString[37]!=')') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
startPos=1;
|
|
}
|
|
else if(guidString.Length != 36) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
|
|
if (guidString[8+startPos] != '-' ||
|
|
guidString[13+startPos] != '-' ||
|
|
guidString[18+startPos] != '-' ||
|
|
guidString[23+startPos] != '-') {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidDashes");
|
|
return false;
|
|
}
|
|
|
|
currentPos = startPos;
|
|
if (!StringToInt(guidString, ref currentPos, 8, ParseNumbers.NoSpace, out temp, ref result))
|
|
return false;
|
|
result.parsedGuid._a = temp;
|
|
++currentPos; //Increment past the '-';
|
|
|
|
if (!StringToInt(guidString, ref currentPos, 4, ParseNumbers.NoSpace, out temp, ref result))
|
|
return false;
|
|
result.parsedGuid._b = (short)temp;
|
|
++currentPos; //Increment past the '-';
|
|
|
|
if (!StringToInt(guidString, ref currentPos, 4, ParseNumbers.NoSpace, out temp, ref result))
|
|
return false;
|
|
result.parsedGuid._c = (short)temp;
|
|
++currentPos; //Increment past the '-';
|
|
|
|
if (!StringToInt(guidString, ref currentPos, 4, ParseNumbers.NoSpace, out temp, ref result))
|
|
return false;
|
|
++currentPos; //Increment past the '-';
|
|
startPos=currentPos;
|
|
|
|
if (!StringToLong(guidString, ref currentPos, ParseNumbers.NoSpace, out templ, ref result))
|
|
return false;
|
|
|
|
if (currentPos - startPos != 12) {
|
|
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
|
|
return false;
|
|
}
|
|
result.parsedGuid._d = (byte)(temp>>8);
|
|
result.parsedGuid._e = (byte)(temp);
|
|
temp = (int)(templ >> 32);
|
|
result.parsedGuid._f = (byte)(temp>>8);
|
|
result.parsedGuid._g = (byte)(temp);
|
|
temp = (int)(templ);
|
|
result.parsedGuid._h = (byte)(temp>>24);
|
|
result.parsedGuid._i = (byte)(temp>>16);
|
|
result.parsedGuid._j = (byte)(temp>>8);
|
|
result.parsedGuid._k = (byte)(temp);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//
|
|
// StringToShort, StringToInt, and StringToLong are wrappers around COMUtilNative integer parsing routines;
|
|
//<
|
|
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToShort(String str, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
|
|
return StringToShort(str, null, requiredLength, flags, out result, ref parseResult);
|
|
}
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToShort(String str, ref int parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
|
|
fixed(int * ppos = &parsePos) {
|
|
return StringToShort(str, ppos, requiredLength, flags, out result, ref parseResult);
|
|
}
|
|
}
|
|
[System.Security.SecurityCritical]
|
|
private static unsafe bool StringToShort(String str, int* parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
|
|
result = 0;
|
|
int x;
|
|
bool retValue = StringToInt(str, parsePos, requiredLength, flags, out x, ref parseResult);
|
|
result = (short)x;
|
|
return retValue;
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToInt(String str, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
|
|
return StringToInt(str, null, requiredLength, flags, out result, ref parseResult);
|
|
}
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToInt(String str, ref int parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
|
|
fixed(int * ppos = &parsePos) {
|
|
return StringToInt(str, ppos, requiredLength, flags, out result, ref parseResult);
|
|
}
|
|
}
|
|
[System.Security.SecurityCritical]
|
|
private static unsafe bool StringToInt(String str, int* parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
|
|
result = 0;
|
|
|
|
int currStart = (parsePos == null) ? 0 : (*parsePos);
|
|
try {
|
|
result = ParseNumbers.StringToInt(str, 16, flags, parsePos);
|
|
}
|
|
catch (OverflowException ex) {
|
|
if (parseResult.throwStyle == GuidParseThrowStyle.All) {
|
|
throw;
|
|
}
|
|
else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow) {
|
|
throw new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"), ex);
|
|
}
|
|
else {
|
|
parseResult.SetFailure(ex);
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
if (parseResult.throwStyle == GuidParseThrowStyle.None) {
|
|
parseResult.SetFailure(ex);
|
|
return false;
|
|
}
|
|
else {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
//If we didn't parse enough characters, there's clearly an error.
|
|
if (requiredLength != -1 && parsePos != null && (*parsePos) - currStart != requiredLength) {
|
|
parseResult.SetFailure(ParseFailureKind.Format, "Format_GuidInvalidChar");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToLong(String str, int flags, out long result, ref GuidResult parseResult) {
|
|
return StringToLong(str, null, flags, out result, ref parseResult);
|
|
}
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToLong(String str, ref int parsePos, int flags, out long result, ref GuidResult parseResult) {
|
|
fixed(int * ppos = &parsePos) {
|
|
return StringToLong(str, ppos, flags, out result, ref parseResult);
|
|
}
|
|
}
|
|
[System.Security.SecuritySafeCritical]
|
|
private static unsafe bool StringToLong(String str, int* parsePos, int flags, out long result, ref GuidResult parseResult) {
|
|
result = 0;
|
|
|
|
try {
|
|
result = ParseNumbers.StringToLong(str, 16, flags, parsePos);
|
|
}
|
|
catch (OverflowException ex) {
|
|
if (parseResult.throwStyle == GuidParseThrowStyle.All) {
|
|
throw;
|
|
}
|
|
else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow) {
|
|
throw new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"), ex);
|
|
}
|
|
else {
|
|
parseResult.SetFailure(ex);
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
if (parseResult.throwStyle == GuidParseThrowStyle.None) {
|
|
parseResult.SetFailure(ex);
|
|
return false;
|
|
}
|
|
else {
|
|
throw;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
private static String EatAllWhitespace(String str)
|
|
{
|
|
int newLength = 0;
|
|
char[] chArr = new char[str.Length];
|
|
char curChar;
|
|
|
|
// Now get each char from str and if it is not whitespace add it to chArr
|
|
for(int i = 0; i < str.Length; i++)
|
|
{
|
|
curChar = str[i];
|
|
if(!Char.IsWhiteSpace(curChar))
|
|
{
|
|
chArr[newLength++] = curChar;
|
|
}
|
|
}
|
|
|
|
// Return a new string based on chArr
|
|
return new String(chArr, 0, newLength);
|
|
}
|
|
|
|
private static bool IsHexPrefix(String str, int i)
|
|
{
|
|
if(str.Length > i+1 && str[i] == '0' && (Char.ToLower(str[i+1], CultureInfo.InvariantCulture) == 'x'))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
// Returns an unsigned byte array containing the GUID.
|
|
public byte[] ToByteArray()
|
|
{
|
|
byte[] g = new byte[16];
|
|
|
|
g[0] = (byte)(_a);
|
|
g[1] = (byte)(_a >> 8);
|
|
g[2] = (byte)(_a >> 16);
|
|
g[3] = (byte)(_a >> 24);
|
|
g[4] = (byte)(_b);
|
|
g[5] = (byte)(_b >> 8);
|
|
g[6] = (byte)(_c);
|
|
g[7] = (byte)(_c >> 8);
|
|
g[8] = _d;
|
|
g[9] = _e;
|
|
g[10] = _f;
|
|
g[11] = _g;
|
|
g[12] = _h;
|
|
g[13] = _i;
|
|
g[14] = _j;
|
|
g[15] = _k;
|
|
|
|
return g;
|
|
}
|
|
|
|
|
|
// Returns the guid in "registry" format.
|
|
public override String ToString()
|
|
{
|
|
return ToString("D",null);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return _a ^ (((int)_b << 16) | (int)(ushort)_c) ^ (((int)_f << 24) | _k);
|
|
}
|
|
|
|
// Returns true if and only if the guid represented
|
|
// by o is the same as this instance.
|
|
public override bool Equals(Object o)
|
|
{
|
|
Guid g;
|
|
// Check that o is a Guid first
|
|
if(o == null || !(o is Guid))
|
|
return false;
|
|
else g = (Guid) o;
|
|
|
|
// Now compare each of the elements
|
|
if(g._a != _a)
|
|
return false;
|
|
if(g._b != _b)
|
|
return false;
|
|
if(g._c != _c)
|
|
return false;
|
|
if (g._d != _d)
|
|
return false;
|
|
if (g._e != _e)
|
|
return false;
|
|
if (g._f != _f)
|
|
return false;
|
|
if (g._g != _g)
|
|
return false;
|
|
if (g._h != _h)
|
|
return false;
|
|
if (g._i != _i)
|
|
return false;
|
|
if (g._j != _j)
|
|
return false;
|
|
if (g._k != _k)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool Equals(Guid g)
|
|
{
|
|
// Now compare each of the elements
|
|
if(g._a != _a)
|
|
return false;
|
|
if(g._b != _b)
|
|
return false;
|
|
if(g._c != _c)
|
|
return false;
|
|
if (g._d != _d)
|
|
return false;
|
|
if (g._e != _e)
|
|
return false;
|
|
if (g._f != _f)
|
|
return false;
|
|
if (g._g != _g)
|
|
return false;
|
|
if (g._h != _h)
|
|
return false;
|
|
if (g._i != _i)
|
|
return false;
|
|
if (g._j != _j)
|
|
return false;
|
|
if (g._k != _k)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
private int GetResult(uint me, uint them) {
|
|
if (me<them) {
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
public int CompareTo(Object value) {
|
|
if (value == null) {
|
|
return 1;
|
|
}
|
|
if (!(value is Guid)) {
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeGuid"));
|
|
}
|
|
Guid g = (Guid)value;
|
|
|
|
if (g._a!=this._a) {
|
|
return GetResult((uint)this._a, (uint)g._a);
|
|
}
|
|
|
|
if (g._b!=this._b) {
|
|
return GetResult((uint)this._b, (uint)g._b);
|
|
}
|
|
|
|
if (g._c!=this._c) {
|
|
return GetResult((uint)this._c, (uint)g._c);
|
|
}
|
|
|
|
if (g._d!=this._d) {
|
|
return GetResult((uint)this._d, (uint)g._d);
|
|
}
|
|
|
|
if (g._e!=this._e) {
|
|
return GetResult((uint)this._e, (uint)g._e);
|
|
}
|
|
|
|
if (g._f!=this._f) {
|
|
return GetResult((uint)this._f, (uint)g._f);
|
|
}
|
|
|
|
if (g._g!=this._g) {
|
|
return GetResult((uint)this._g, (uint)g._g);
|
|
}
|
|
|
|
if (g._h!=this._h) {
|
|
return GetResult((uint)this._h, (uint)g._h);
|
|
}
|
|
|
|
if (g._i!=this._i) {
|
|
return GetResult((uint)this._i, (uint)g._i);
|
|
}
|
|
|
|
if (g._j!=this._j) {
|
|
return GetResult((uint)this._j, (uint)g._j);
|
|
}
|
|
|
|
if (g._k!=this._k) {
|
|
return GetResult((uint)this._k, (uint)g._k);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if GENERICS_WORK
|
|
public int CompareTo(Guid value)
|
|
{
|
|
if (value._a!=this._a) {
|
|
return GetResult((uint)this._a, (uint)value._a);
|
|
}
|
|
|
|
if (value._b!=this._b) {
|
|
return GetResult((uint)this._b, (uint)value._b);
|
|
}
|
|
|
|
if (value._c!=this._c) {
|
|
return GetResult((uint)this._c, (uint)value._c);
|
|
}
|
|
|
|
if (value._d!=this._d) {
|
|
return GetResult((uint)this._d, (uint)value._d);
|
|
}
|
|
|
|
if (value._e!=this._e) {
|
|
return GetResult((uint)this._e, (uint)value._e);
|
|
}
|
|
|
|
if (value._f!=this._f) {
|
|
return GetResult((uint)this._f, (uint)value._f);
|
|
}
|
|
|
|
if (value._g!=this._g) {
|
|
return GetResult((uint)this._g, (uint)value._g);
|
|
}
|
|
|
|
if (value._h!=this._h) {
|
|
return GetResult((uint)this._h, (uint)value._h);
|
|
}
|
|
|
|
if (value._i!=this._i) {
|
|
return GetResult((uint)this._i, (uint)value._i);
|
|
}
|
|
|
|
if (value._j!=this._j) {
|
|
return GetResult((uint)this._j, (uint)value._j);
|
|
}
|
|
|
|
if (value._k!=this._k) {
|
|
return GetResult((uint)this._k, (uint)value._k);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif // GENERICS_WORK
|
|
|
|
public static bool operator ==(Guid a, Guid b)
|
|
{
|
|
// Now compare each of the elements
|
|
if(a._a != b._a)
|
|
return false;
|
|
if(a._b != b._b)
|
|
return false;
|
|
if(a._c != b._c)
|
|
return false;
|
|
if(a._d != b._d)
|
|
return false;
|
|
if(a._e != b._e)
|
|
return false;
|
|
if(a._f != b._f)
|
|
return false;
|
|
if(a._g != b._g)
|
|
return false;
|
|
if(a._h != b._h)
|
|
return false;
|
|
if(a._i != b._i)
|
|
return false;
|
|
if(a._j != b._j)
|
|
return false;
|
|
if(a._k != b._k)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool operator !=(Guid a, Guid b)
|
|
{
|
|
return !(a == b);
|
|
}
|
|
#if !MONO
|
|
// This will create a new guid. Since we've now decided that constructors should 0-init,
|
|
// we need a method that allows users to create a guid.
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public static Guid NewGuid() {
|
|
// CoCreateGuid should never return Guid.Empty, since it attempts to maintain some
|
|
// uniqueness guarantees. It should also never return a known GUID, but it's unclear
|
|
// how extensively it checks for known values.
|
|
Contract.Ensures(Contract.Result<Guid>() != Guid.Empty);
|
|
|
|
Guid guid;
|
|
Marshal.ThrowExceptionForHR(Win32Native.CoCreateGuid(out guid), new IntPtr(-1));
|
|
return guid;
|
|
}
|
|
#endif
|
|
public String ToString(String format) {
|
|
return ToString(format, null);
|
|
}
|
|
|
|
private static char HexToChar(int a)
|
|
{
|
|
a = a & 0xf;
|
|
return (char) ((a > 9) ? a - 10 + 0x61 : a + 0x30);
|
|
}
|
|
|
|
[System.Security.SecurityCritical]
|
|
unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b)
|
|
{
|
|
return HexsToChars(guidChars, offset, a, b, false);
|
|
}
|
|
|
|
[System.Security.SecurityCritical]
|
|
unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b, bool hex)
|
|
{
|
|
if (hex) {
|
|
guidChars[offset++] = '0';
|
|
guidChars[offset++] = 'x';
|
|
}
|
|
guidChars[offset++] = HexToChar(a>>4);
|
|
guidChars[offset++] = HexToChar(a);
|
|
if (hex) {
|
|
guidChars[offset++] = ',';
|
|
guidChars[offset++] = '0';
|
|
guidChars[offset++] = 'x';
|
|
}
|
|
guidChars[offset++] = HexToChar(b>>4);
|
|
guidChars[offset++] = HexToChar(b);
|
|
return offset;
|
|
}
|
|
|
|
// IFormattable interface
|
|
// We currently ignore provider
|
|
[System.Security.SecuritySafeCritical]
|
|
public String ToString(String format, IFormatProvider provider)
|
|
{
|
|
if (format == null || format.Length == 0)
|
|
format = "D";
|
|
|
|
string guidString;
|
|
int offset = 0;
|
|
bool dash = true;
|
|
bool hex = false;
|
|
|
|
if( format.Length != 1) {
|
|
// all acceptable format strings are of length 1
|
|
throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
|
|
}
|
|
|
|
char formatCh = format[0];
|
|
if (formatCh == 'D' || formatCh == 'd') {
|
|
guidString = string.FastAllocateString(36);
|
|
}
|
|
else if (formatCh == 'N' || formatCh == 'n') {
|
|
guidString = string.FastAllocateString(32);
|
|
dash = false;
|
|
}
|
|
else if (formatCh == 'B' || formatCh == 'b') {
|
|
guidString = string.FastAllocateString(38);
|
|
unsafe {
|
|
fixed (char* guidChars = guidString) {
|
|
guidChars[offset++] = '{';
|
|
guidChars[37] = '}';
|
|
}
|
|
}
|
|
}
|
|
else if (formatCh == 'P' || formatCh == 'p') {
|
|
guidString = string.FastAllocateString(38);
|
|
unsafe {
|
|
fixed (char* guidChars = guidString) {
|
|
guidChars[offset++] = '(';
|
|
guidChars[37] = ')';
|
|
}
|
|
}
|
|
}
|
|
else if (formatCh == 'X' || formatCh == 'x') {
|
|
guidString = string.FastAllocateString(68);
|
|
unsafe {
|
|
fixed (char* guidChars = guidString) {
|
|
guidChars[offset++] = '{';
|
|
guidChars[67] = '}';
|
|
}
|
|
}
|
|
dash = false;
|
|
hex = true;
|
|
}
|
|
else {
|
|
throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
|
|
}
|
|
|
|
unsafe {
|
|
fixed (char* guidChars = guidString) {
|
|
if (hex) {
|
|
// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
|
|
guidChars[offset++] = '0';
|
|
guidChars[offset++] = 'x';
|
|
offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
|
|
offset = HexsToChars(guidChars, offset, _a >> 8, _a);
|
|
guidChars[offset++] = ',';
|
|
guidChars[offset++] = '0';
|
|
guidChars[offset++] = 'x';
|
|
offset = HexsToChars(guidChars, offset, _b >> 8, _b);
|
|
guidChars[offset++] = ',';
|
|
guidChars[offset++] = '0';
|
|
guidChars[offset++] = 'x';
|
|
offset = HexsToChars(guidChars, offset, _c >> 8, _c);
|
|
guidChars[offset++] = ',';
|
|
guidChars[offset++] = '{';
|
|
offset = HexsToChars(guidChars, offset, _d, _e, true);
|
|
guidChars[offset++] = ',';
|
|
offset = HexsToChars(guidChars, offset, _f, _g, true);
|
|
guidChars[offset++] = ',';
|
|
offset = HexsToChars(guidChars, offset, _h, _i, true);
|
|
guidChars[offset++] = ',';
|
|
offset = HexsToChars(guidChars, offset, _j, _k, true);
|
|
guidChars[offset++] = '}';
|
|
}
|
|
else {
|
|
// [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)]
|
|
offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
|
|
offset = HexsToChars(guidChars, offset, _a >> 8, _a);
|
|
if (dash) guidChars[offset++] = '-';
|
|
offset = HexsToChars(guidChars, offset, _b >> 8, _b);
|
|
if (dash) guidChars[offset++] = '-';
|
|
offset = HexsToChars(guidChars, offset, _c >> 8, _c);
|
|
if (dash) guidChars[offset++] = '-';
|
|
offset = HexsToChars(guidChars, offset, _d, _e);
|
|
if (dash) guidChars[offset++] = '-';
|
|
offset = HexsToChars(guidChars, offset, _f, _g);
|
|
offset = HexsToChars(guidChars, offset, _h, _i);
|
|
offset = HexsToChars(guidChars, offset, _j, _k);
|
|
}
|
|
}
|
|
}
|
|
return guidString;
|
|
}
|
|
}
|
|
}
|