2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Data . Common ;
5
+ using System . Diagnostics ;
6
+ using System . Runtime . CompilerServices ;
7
+ using System . Runtime . InteropServices ;
8
+ using System . Runtime . Serialization ;
5
9
using System . Xml ;
6
10
using System . Xml . Schema ;
7
11
using System . Xml . Serialization ;
@@ -16,71 +20,60 @@ namespace System.Data.SqlTypes
16
20
[ Serializable ]
17
21
[ XmlSchemaProvider ( "GetXsdType" ) ]
18
22
[ System . Runtime . CompilerServices . TypeForwardedFrom ( "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
19
- public struct SqlGuid : INullable , IComparable , IXmlSerializable , IEquatable < SqlGuid >
23
+ public struct SqlGuid : INullable , IComparable , ISerializable , IXmlSerializable , IEquatable < SqlGuid >
20
24
{
21
- private const int SizeOfGuid = 16 ;
25
+ private const int SizeOfGuid = 16 ; // sizeof(Guid)
22
26
23
27
// NOTE: If any instance fields change, update SqlTypeWorkarounds type in System.Data.SqlClient.
24
- private byte [ ] ? m_value ; // the SqlGuid is null if m_value is null
28
+ private Guid ? _value ; // the SqlGuid is null if _value is null
25
29
26
30
// constructor
27
- // construct a SqlGuid.Null
28
- private SqlGuid ( bool _ )
29
- {
30
- m_value = null ;
31
- }
32
-
33
31
public SqlGuid ( byte [ ] value )
34
32
{
35
33
if ( value == null || value . Length != SizeOfGuid )
36
34
throw new ArgumentException ( SQLResource . InvalidArraySizeMessage ) ;
37
35
38
- m_value = new byte [ SizeOfGuid ] ;
39
- value . CopyTo ( m_value , 0 ) ;
40
- }
41
-
42
- internal SqlGuid ( byte [ ] value , bool _ )
43
- {
44
- if ( value == null || value . Length != SizeOfGuid )
45
- throw new ArgumentException ( SQLResource . InvalidArraySizeMessage ) ;
46
-
47
- m_value = value ;
36
+ _value = new Guid ( value ) ;
48
37
}
49
38
50
39
public SqlGuid ( string s )
51
40
{
52
- m_value = ( new Guid ( s ) ) . ToByteArray ( ) ;
41
+ _value = new Guid ( s ) ;
53
42
}
54
43
55
44
public SqlGuid ( Guid g )
56
45
{
57
- m_value = g . ToByteArray ( ) ;
46
+ _value = g ;
58
47
}
59
48
60
49
public SqlGuid ( int a , short b , short c , byte d , byte e , byte f , byte g , byte h , byte i , byte j , byte k )
61
50
: this ( new Guid ( a , b , c , d , e , f , g , h , i , j , k ) )
62
51
{
63
52
}
64
53
65
-
66
- // INullable
67
- public bool IsNull
54
+ // Maintains backwards-compatible binary serialization for the `private byte[] m_value` field
55
+ // see src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs
56
+ // for test data
57
+ private SqlGuid ( SerializationInfo info , StreamingContext context )
68
58
{
69
- get { return ( m_value is null ) ; }
59
+ byte [ ] ? value = ( byte [ ] ? ) info . GetValue ( "m_value" , typeof ( byte [ ] ) ) ;
60
+ if ( value is null )
61
+ _value = null ;
62
+ else
63
+ _value = new Guid ( value ) ;
70
64
}
71
65
72
- // property: Value
73
- public Guid Value
66
+ void ISerializable . GetObjectData ( SerializationInfo info , StreamingContext context )
74
67
{
75
- get
76
- {
77
- if ( m_value is null )
78
- throw new SqlNullValueException ( ) ;
79
- else
80
- return new Guid ( m_value ) ;
81
- }
68
+ info . AddValue ( "m_value" , ToByteArray ( ) , typeof ( byte [ ] ) ) ;
82
69
}
83
70
71
+ // INullable
72
+ public bool IsNull => _value is null ;
73
+
74
+ // property: Value
75
+ public Guid Value => _value ?? throw new SqlNullValueException ( ) ;
76
+
84
77
// Implicit conversion from Guid to SqlGuid
85
78
public static implicit operator SqlGuid ( Guid x )
86
79
{
@@ -95,18 +88,17 @@ public static explicit operator Guid(SqlGuid x)
95
88
96
89
public byte [ ] ? ToByteArray ( )
97
90
{
98
- byte [ ] ret = new byte [ SizeOfGuid ] ;
99
- m_value ! . CopyTo ( ret , 0 ) ; // TODO: NRE
100
- return ret ;
91
+ if ( _value is null )
92
+ return null ;
93
+ return _value . GetValueOrDefault ( ) . ToByteArray ( ) ;
101
94
}
102
95
103
96
public override string ToString ( )
104
97
{
105
- if ( m_value is null )
98
+ if ( _value is null )
106
99
return SQLResource . NullString ;
107
100
108
- Guid g = new Guid ( m_value ) ;
109
- return g . ToString ( ) ;
101
+ return _value . GetValueOrDefault ( ) . ToString ( ) ;
110
102
}
111
103
112
104
public static SqlGuid Parse ( string s )
@@ -117,16 +109,24 @@ public static SqlGuid Parse(string s)
117
109
return new SqlGuid ( s ) ;
118
110
}
119
111
120
-
121
112
// Comparison operators
122
113
private static EComparison Compare ( SqlGuid x , SqlGuid y )
123
114
{
124
115
// Comparison orders.
125
- ReadOnlySpan < byte > rgiGuidOrder = new byte [ 16 ] { 10 , 11 , 12 , 13 , 14 , 15 , 8 , 9 , 6 , 7 , 4 , 5 , 0 , 1 , 2 , 3 } ;
116
+ ReadOnlySpan < byte > rgiGuidOrder = new byte [ SizeOfGuid ] { 10 , 11 , 12 , 13 , 14 , 15 , 8 , 9 , 6 , 7 , 4 , 5 , 0 , 1 , 2 , 3 } ;
117
+
118
+ Debug . Assert ( ! x . IsNull ) ;
119
+ Debug . Assert ( ! y . IsNull ) ;
126
120
127
121
// Swap to the correct order to be compared
128
- ReadOnlySpan < byte > xBytes = x . m_value ;
129
- ReadOnlySpan < byte > yBytes = y . m_value ;
122
+ Span < byte > xBytes = stackalloc byte [ SizeOfGuid ] ;
123
+ bool xWrote = x . _value . GetValueOrDefault ( ) . TryWriteBytes ( xBytes ) ;
124
+ Debug . Assert ( xWrote ) ;
125
+
126
+ Span < byte > yBytes = stackalloc byte [ SizeOfGuid ] ;
127
+ bool yWrote = y . _value . GetValueOrDefault ( ) . TryWriteBytes ( yBytes ) ;
128
+ Debug . Assert ( yWrote ) ;
129
+
130
130
for ( int i = 0 ; i < SizeOfGuid ; i ++ )
131
131
{
132
132
byte b1 = xBytes [ rgiGuidOrder [ i ] ] ;
@@ -140,8 +140,6 @@ private static EComparison Compare(SqlGuid x, SqlGuid y)
140
140
return EComparison . EQ ;
141
141
}
142
142
143
-
144
-
145
143
// Implicit conversions
146
144
147
145
// Explicit conversions
@@ -161,7 +159,8 @@ public static explicit operator SqlGuid(SqlBinary x)
161
159
// Overloading comparison operators
162
160
public static SqlBoolean operator == ( SqlGuid x , SqlGuid y )
163
161
{
164
- return ( x . IsNull || y . IsNull ) ? SqlBoolean . Null : new SqlBoolean ( Compare ( x , y ) == EComparison . EQ ) ;
162
+ return ( x . IsNull || y . IsNull ) ? SqlBoolean . Null :
163
+ new SqlBoolean ( x . _value . GetValueOrDefault ( ) == y . _value . GetValueOrDefault ( ) ) ;
165
164
}
166
165
167
166
public static SqlBoolean operator != ( SqlGuid x , SqlGuid y )
@@ -249,7 +248,6 @@ public SqlBinary ToSqlBinary()
249
248
return ( SqlBinary ) this ;
250
249
}
251
250
252
-
253
251
// IComparable
254
252
// Compares this object to another object, returning an integer that
255
253
// indicates the relationship.
@@ -287,12 +285,10 @@ public override bool Equals([NotNullWhen(true)] object? value) =>
287
285
/// <summary>Indicates whether the current instance is equal to another instance of the same type.</summary>
288
286
/// <param name="other">An instance to compare with this instance.</param>
289
287
/// <returns>true if the current instance is equal to the other instance; otherwise, false.</returns>
290
- public bool Equals ( SqlGuid other ) =>
291
- other . IsNull || IsNull ? other . IsNull && IsNull :
292
- ( this == other ) . Value ;
288
+ public bool Equals ( SqlGuid other ) => _value == other . _value ;
293
289
294
290
// For hashing purpose
295
- public override int GetHashCode ( ) => IsNull ? 0 : Value . GetHashCode ( ) ;
291
+ public override int GetHashCode ( ) => _value . GetHashCode ( ) ;
296
292
297
293
XmlSchema ? IXmlSerializable . GetSchema ( ) { return null ; }
298
294
@@ -303,23 +299,23 @@ void IXmlSerializable.ReadXml(XmlReader reader)
303
299
{
304
300
// Read the next value.
305
301
reader . ReadElementString ( ) ;
306
- m_value = null ;
302
+ _value = null ;
307
303
}
308
304
else
309
305
{
310
- m_value = new Guid ( reader . ReadElementString ( ) ) . ToByteArray ( ) ;
306
+ _value = new Guid ( reader . ReadElementString ( ) ) ;
311
307
}
312
308
}
313
309
314
310
void IXmlSerializable . WriteXml ( XmlWriter writer )
315
311
{
316
- if ( m_value is null )
312
+ if ( _value is null )
317
313
{
318
314
writer . WriteAttributeString ( "xsi" , "nil" , XmlSchema . InstanceNamespace , "true" ) ;
319
315
}
320
316
else
321
317
{
322
- writer . WriteString ( XmlConvert . ToString ( new Guid ( m_value ) ) ) ;
318
+ writer . WriteString ( XmlConvert . ToString ( _value . GetValueOrDefault ( ) ) ) ;
323
319
}
324
320
}
325
321
@@ -328,6 +324,6 @@ public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet)
328
324
return new XmlQualifiedName ( "string" , XmlSchema . Namespace ) ;
329
325
}
330
326
331
- public static readonly SqlGuid Null = new SqlGuid ( true ) ;
327
+ public static readonly SqlGuid Null ;
332
328
} // SqlGuid
333
329
} // namespace System.Data.SqlTypes
0 commit comments