1 //---------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //---------------------------------------------------------------- 4 5 namespace System.ServiceModel.Discovery 6 { 7 using System; 8 using System.Diagnostics.CodeAnalysis; 9 using System.Globalization; 10 using System.Runtime; 11 using System.Xml; 12 using SR2 = System.ServiceModel.Discovery.SR; 13 14 [Fx.Tag.XamlVisible(false)] 15 [SuppressMessage("Microsoft.Design", "CA1036:OverrideMethodsOnComparableTypes")] 16 public class DiscoveryMessageSequence : 17 IComparable<DiscoveryMessageSequence>, 18 IEquatable<DiscoveryMessageSequence> 19 { DiscoveryMessageSequence()20 internal DiscoveryMessageSequence() 21 { 22 } 23 DiscoveryMessageSequence(long instanceId, Uri sequenceId, long messageNumber)24 internal DiscoveryMessageSequence(long instanceId, Uri sequenceId, long messageNumber) 25 { 26 Fx.Assert((instanceId >= 0) && (instanceId <= UInt32.MaxValue), "The instanceId must be within UInt32 range"); 27 Fx.Assert((messageNumber >= 0) && (messageNumber <= UInt32.MaxValue), "The messageNumber must be within UInt32 range"); 28 29 this.InstanceId = instanceId; 30 this.SequenceId = sequenceId; 31 this.MessageNumber = messageNumber; 32 } 33 34 public long InstanceId 35 { 36 get; 37 private set; 38 } 39 40 public Uri SequenceId 41 { 42 get; 43 private set; 44 } 45 46 public long MessageNumber 47 { 48 get; 49 private set; 50 } 51 operator ==(DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2)52 public static bool operator ==(DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2) 53 { 54 if (object.ReferenceEquals(messageSequence1, null) && object.ReferenceEquals(messageSequence2, null)) 55 { 56 return true; 57 } 58 if (object.ReferenceEquals(messageSequence1, null) || object.ReferenceEquals(messageSequence2, null)) 59 { 60 return false; 61 } 62 return messageSequence1.Equals(messageSequence2); 63 } 64 operator !=(DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2)65 public static bool operator !=(DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2) 66 { 67 return !(messageSequence1 == messageSequence2); 68 } 69 Equals(object obj)70 public override bool Equals(object obj) 71 { 72 DiscoveryMessageSequence other = obj as DiscoveryMessageSequence; 73 return this.Equals(other); 74 } 75 Equals(DiscoveryMessageSequence other)76 public bool Equals(DiscoveryMessageSequence other) 77 { 78 if (object.ReferenceEquals(other, null)) 79 { 80 return false; 81 } 82 if (object.ReferenceEquals(this, other)) 83 { 84 return true; 85 } 86 87 return (long.Equals(this.InstanceId, other.InstanceId) && 88 Uri.Equals(this.SequenceId, other.SequenceId) && 89 long.Equals(this.MessageNumber, other.MessageNumber)); 90 } 91 ToString()92 public override string ToString() 93 { 94 return SR.DiscoveryMessageSequenceToString(this.InstanceId, this.SequenceId, this.MessageNumber); 95 } 96 CanCompareTo(DiscoveryMessageSequence other)97 public bool CanCompareTo(DiscoveryMessageSequence other) 98 { 99 if (object.ReferenceEquals(other, null)) 100 { 101 return false; 102 } 103 else 104 { 105 return ((this.InstanceId != other.InstanceId) || 106 (Uri.Equals(this.SequenceId, other.SequenceId))); 107 } 108 } 109 GetHashCode()110 public override int GetHashCode() 111 { 112 return string.Format( 113 CultureInfo.InvariantCulture, "{0}:{1}:{2}", 114 this.InstanceId, 115 this.SequenceId, 116 this.MessageNumber).GetHashCode(); 117 } 118 CompareTo(DiscoveryMessageSequence other)119 public int CompareTo(DiscoveryMessageSequence other) 120 { 121 if (object.ReferenceEquals(other, null)) 122 { 123 throw FxTrace.Exception.ArgumentNull("other"); 124 } 125 126 int result = this.InstanceId.CompareTo(other.InstanceId); 127 if (result == 0) 128 { 129 if (!Uri.Equals(this.SequenceId, other.SequenceId)) 130 { 131 throw FxTrace.Exception.Argument("other", SR2.DiscoveryIncompatibleMessageSequence); 132 } 133 134 result = this.MessageNumber.CompareTo(other.MessageNumber); 135 } 136 137 return result; 138 } 139 140 [Fx.Tag.Throws(typeof(XmlException), "throws on incorrect xml data")] ReadFrom(XmlReader reader)141 internal void ReadFrom(XmlReader reader) 142 { 143 if (reader == null) 144 { 145 throw FxTrace.Exception.ArgumentNull("reader"); 146 } 147 148 string instanceIdString = reader.GetAttribute(ProtocolStrings.SchemaNames.AppSequenceInstanceId); 149 150 this.InstanceId = SerializationUtility.ReadUInt( 151 instanceIdString, 152 SR2.DiscoveryXmlMissingAppSequenceInstanceId, 153 SR2.DiscoveryXmlInvalidAppSequenceInstanceId); 154 155 string sequenceIdString = reader.GetAttribute(ProtocolStrings.SchemaNames.AppSequenceSequenceId); 156 157 if (sequenceIdString != null) 158 { 159 try 160 { 161 this.SequenceId = new Uri(sequenceIdString, UriKind.RelativeOrAbsolute); 162 } 163 catch (FormatException fe) 164 { 165 throw FxTrace.Exception.AsError(new XmlException(SR2.DiscoveryXmlUriFormatError(sequenceIdString), fe)); 166 } 167 } 168 169 string messageNumberString = reader.GetAttribute(ProtocolStrings.SchemaNames.AppSequenceMessageNumber); 170 171 this.MessageNumber = SerializationUtility.ReadUInt( 172 messageNumberString, 173 SR2.DiscoveryXmlMissingAppSequenceMessageNumber, 174 SR2.DiscoveryXmlInvalidAppSequenceMessageNumber); 175 } 176 WriteTo(XmlWriter writer)177 internal void WriteTo(XmlWriter writer) 178 { 179 if (writer == null) 180 { 181 throw FxTrace.Exception.ArgumentNull("writer"); 182 } 183 184 writer.WriteAttributeString( 185 ProtocolStrings.SchemaNames.AppSequenceInstanceId, 186 this.InstanceId.ToString(CultureInfo.InvariantCulture)); 187 188 if (this.SequenceId != null) 189 { 190 writer.WriteAttributeString( 191 ProtocolStrings.SchemaNames.AppSequenceSequenceId, 192 this.SequenceId.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped)); 193 } 194 195 writer.WriteAttributeString( 196 ProtocolStrings.SchemaNames.AppSequenceMessageNumber, 197 this.MessageNumber.ToString(CultureInfo.InvariantCulture)); 198 } 199 } 200 } 201