1 2 //------------------------------------------------------------ 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 //------------------------------------------------------------ 5 6 namespace System.ServiceModel 7 { 8 using System.Collections.Generic; 9 using System.Collections.ObjectModel; 10 using System.ComponentModel; 11 using System.Runtime; 12 using System.ServiceModel.Channels; 13 using System.Xml; 14 15 public class EndpointAddress 16 { 17 static Uri anonymousUri; 18 static Uri noneUri; 19 static EndpointAddress anonymousAddress; 20 21 /* 22 Conceptually, the agnostic EndpointAddress class represents all of UNION(v200408,v10) data thusly: 23 - Address Uri (both versions - the Address) 24 - AddressHeaderCollection (both versions - RefProp&RefParam both project into here) 25 - PSP blob (200408 - this is PortType, ServiceName, Policy, it is not surfaced in OM) 26 - metadata (both versions, but weird semantics in 200408) 27 - identity (both versions, this is the one 'extension' that we know about) 28 - extensions (both versions, the "any*" stuff at the end) 29 30 When reading from 200408: 31 - Address is projected into Uri 32 - both RefProps and RefParams are projected into AddressHeaderCollection, 33 they (internally) remember 'which kind' they are 34 - PortType, ServiceName, Policy are projected into the (internal) PSP blob 35 - if we see a wsx:metadata element next, we project that element and that element only into the metadata reader 36 - we read the rest, recognizing and fishing out identity if there, projecting rest to extensions reader 37 When reading from 10: 38 - Address is projected into Uri 39 - RefParams are projected into AddressHeaderCollection; they (internally) remember 'which kind' they are 40 - nothing is projected into the (internal) PSP blob (it's empty) 41 - if there's a wsa10:metadata element, everything inside it projects into metadatareader 42 - we read the rest, recognizing and fishing out identity if there, projecting rest to extensions reader 43 44 When writing to 200408: 45 - Uri is written as Address 46 - AddressHeaderCollection is written as RefProps & RefParams, based on what they internally remember selves to be 47 - PSP blob is written out verbatim (will have: PortType?, ServiceName?, Policy?) 48 - metadata reader is written out verbatim 49 - identity is written out as extension 50 - extension reader is written out verbatim 51 When writing to 10: 52 - Uri is written as Address 53 - AddressHeaderCollection is all written as RefParams, regardless of what they internally remember selves to be 54 - PSP blob is ignored 55 - if metadata reader is non-empty, we write its value out verbatim inside a wsa10:metadata element 56 - identity is written out as extension 57 - extension reader is written out verbatim 58 59 EndpointAddressBuilder: 60 - you can set metadata to any value you like; we don't (cannot) validate because 10 allows anything 61 - you can set any extensions you like 62 63 Known Weirdnesses: 64 - PSP blob does not surface in OM - it can only roundtrip 200408wire->OM->200408wire 65 - RefProperty distinction does not surface in OM - it can only roundtrip 200408wire->OM->200408wire 66 - regardless of what metadata in reader, when you roundtrip OM->200408wire->OM, only wsx:metadata 67 as first element after PSP will stay in metadata, anything else gets dumped in extensions 68 - PSP blob is lost when doing OM->10wire->OM 69 - RefProps turn into RefParams when doing OM->10wire->OM 70 - Identity is always shuffled to front of extensions when doing anyWire->OM->anyWire 71 */ 72 73 AddressingVersion addressingVersion; 74 AddressHeaderCollection headers; 75 EndpointIdentity identity; 76 Uri uri; 77 XmlBuffer buffer; // invariant: each section in the buffer will start with a dummy wrapper element 78 int extensionSection; 79 int metadataSection; 80 int pspSection; 81 bool isAnonymous; 82 bool isNone; 83 // these are the element name/namespace for the dummy wrapper element that wraps each buffer section 84 internal const string DummyName = "Dummy"; 85 internal const string DummyNamespace = "http://Dummy"; 86 EndpointAddress(AddressingVersion version, Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection)87 EndpointAddress(AddressingVersion version, Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection) 88 { 89 Init(version, uri, identity, headers, buffer, metadataSection, extensionSection, pspSection); 90 } 91 EndpointAddress(string uri)92 public EndpointAddress(string uri) 93 { 94 if (uri == null) 95 { 96 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); 97 } 98 99 Uri u = new Uri(uri); 100 101 Init(u, (EndpointIdentity)null, (AddressHeaderCollection)null, null, -1, -1, -1); 102 } 103 EndpointAddress(Uri uri, params AddressHeader[] addressHeaders)104 public EndpointAddress(Uri uri, params AddressHeader[] addressHeaders) 105 : this(uri, (EndpointIdentity)null, addressHeaders) 106 { 107 } 108 EndpointAddress(Uri uri, EndpointIdentity identity, params AddressHeader[] addressHeaders)109 public EndpointAddress(Uri uri, EndpointIdentity identity, params AddressHeader[] addressHeaders) 110 { 111 if (uri == null) 112 { 113 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); 114 } 115 116 Init(uri, identity, addressHeaders); 117 } 118 EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers)119 public EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers) 120 { 121 if (uri == null) 122 { 123 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); 124 } 125 126 Init(uri, identity, headers, null, -1, -1, -1); 127 } 128 EndpointAddress(Uri newUri, EndpointAddress oldEndpointAddress)129 internal EndpointAddress(Uri newUri, EndpointAddress oldEndpointAddress) 130 { 131 Init(oldEndpointAddress.addressingVersion, newUri, oldEndpointAddress.identity, oldEndpointAddress.headers, oldEndpointAddress.buffer, oldEndpointAddress.metadataSection, oldEndpointAddress.extensionSection, oldEndpointAddress.pspSection); 132 } 133 EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlDictionaryReader metadataReader, XmlDictionaryReader extensionReader, XmlDictionaryReader pspReader)134 internal EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlDictionaryReader metadataReader, XmlDictionaryReader extensionReader, XmlDictionaryReader pspReader) 135 { 136 if (uri == null) 137 { 138 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); 139 } 140 141 XmlBuffer buffer = null; 142 PossiblyPopulateBuffer(metadataReader, ref buffer, out metadataSection); 143 144 EndpointIdentity ident2; 145 int extSection; 146 buffer = ReadExtensions(extensionReader, null, buffer, out ident2, out extSection); 147 148 if (identity != null && ident2 != null) 149 { 150 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleIdentities), "extensionReader")); 151 } 152 153 PossiblyPopulateBuffer(pspReader, ref buffer, out pspSection); 154 155 if (buffer != null) 156 { 157 buffer.Close(); 158 } 159 160 Init(uri, identity ?? ident2, headers, buffer, metadataSection, extSection, pspSection); 161 } 162 163 // metadataReader and extensionReader are assumed to not have a starting dummy wrapper element EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlDictionaryReader metadataReader, XmlDictionaryReader extensionReader)164 public EndpointAddress(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlDictionaryReader metadataReader, XmlDictionaryReader extensionReader) 165 : this(uri, identity, headers, metadataReader, extensionReader, null) 166 { 167 } 168 Init(Uri uri, EndpointIdentity identity, AddressHeader[] headers)169 void Init(Uri uri, EndpointIdentity identity, AddressHeader[] headers) 170 { 171 if (headers == null || headers.Length == 0) 172 { 173 Init(uri, identity, (AddressHeaderCollection)null, null, -1, -1, -1); 174 } 175 else 176 { 177 Init(uri, identity, new AddressHeaderCollection(headers), null, -1, -1, -1); 178 } 179 } 180 Init(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection)181 void Init(Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection) 182 { 183 Init(null, uri, identity, headers, buffer, metadataSection, extensionSection, pspSection); 184 } 185 Init(AddressingVersion version, Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection)186 void Init(AddressingVersion version, Uri uri, EndpointIdentity identity, AddressHeaderCollection headers, XmlBuffer buffer, int metadataSection, int extensionSection, int pspSection) 187 { 188 if (!uri.IsAbsoluteUri) 189 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("uri", SR.GetString(SR.UriMustBeAbsolute)); 190 191 this.addressingVersion = version; 192 this.uri = uri; 193 this.identity = identity; 194 this.headers = headers; 195 this.buffer = buffer; 196 this.metadataSection = metadataSection; 197 this.extensionSection = extensionSection; 198 this.pspSection = pspSection; 199 200 if (version != null) 201 { 202 this.isAnonymous = uri == version.AnonymousUri; 203 this.isNone = uri == version.NoneUri; 204 } 205 else 206 { 207 this.isAnonymous = object.ReferenceEquals(uri, AnonymousUri) || uri == AnonymousUri; 208 this.isNone = object.ReferenceEquals(uri, NoneUri) || uri == NoneUri; 209 } 210 if (this.isAnonymous) 211 { 212 this.uri = AnonymousUri; 213 } 214 if (this.isNone) 215 { 216 this.uri = NoneUri; 217 } 218 } 219 220 internal static EndpointAddress AnonymousAddress 221 { 222 get 223 { 224 if (anonymousAddress == null) 225 anonymousAddress = new EndpointAddress(AnonymousUri); 226 return anonymousAddress; 227 } 228 } 229 230 public static Uri AnonymousUri 231 { 232 get 233 { 234 if (anonymousUri == null) 235 anonymousUri = new Uri(AddressingStrings.AnonymousUri); 236 return anonymousUri; 237 } 238 } 239 240 public static Uri NoneUri 241 { 242 get 243 { 244 if (noneUri == null) 245 noneUri = new Uri(AddressingStrings.NoneUri); 246 return noneUri; 247 } 248 } 249 250 internal XmlBuffer Buffer 251 { 252 get 253 { 254 return this.buffer; 255 } 256 } 257 258 public AddressHeaderCollection Headers 259 { 260 get 261 { 262 if (this.headers == null) 263 { 264 this.headers = new AddressHeaderCollection(); 265 } 266 267 return this.headers; 268 } 269 } 270 271 public EndpointIdentity Identity 272 { 273 get 274 { 275 return this.identity; 276 } 277 } 278 279 public bool IsAnonymous 280 { 281 get 282 { 283 return this.isAnonymous; 284 } 285 } 286 287 public bool IsNone 288 { 289 get 290 { 291 return this.isNone; 292 } 293 } 294 295 [TypeConverter(typeof(UriTypeConverter))] 296 public Uri Uri 297 { 298 get 299 { 300 return uri; 301 } 302 } 303 ApplyTo(Message message)304 public void ApplyTo(Message message) 305 { 306 if (message == null) 307 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); 308 309 Uri uri = this.Uri; 310 if (IsAnonymous) 311 { 312 #pragma warning suppress 56506 313 if (message.Version.Addressing == AddressingVersion.WSAddressing10) 314 { 315 message.Headers.To = null; 316 } 317 else if (message.Version.Addressing == AddressingVersion.WSAddressingAugust2004) 318 { 319 #pragma warning suppress 56506 320 message.Headers.To = message.Version.Addressing.AnonymousUri; 321 } 322 else 323 { 324 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 325 new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, message.Version.Addressing))); 326 } 327 } 328 else if (IsNone) 329 { 330 message.Headers.To = message.Version.Addressing.NoneUri; 331 } 332 else 333 { 334 message.Headers.To = uri; 335 } 336 message.Properties.Via = message.Headers.To; 337 if (this.headers != null) 338 { 339 this.headers.AddHeadersTo(message); 340 } 341 } 342 343 // NOTE: UserInfo, Query, and Fragment are ignored when comparing Uris as addresses 344 // this is the WCF logic for comparing Uris that represent addresses 345 // this method must be kept in sync with UriGetHashCode UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHostInComparison)346 internal static bool UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHostInComparison) 347 { 348 return UriEquals(u1, u2, ignoreCase, includeHostInComparison, true); 349 } 350 UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHostInComparison, bool includePortInComparison)351 internal static bool UriEquals(Uri u1, Uri u2, bool ignoreCase, bool includeHostInComparison, bool includePortInComparison) 352 { 353 // PERF: Equals compares everything but UserInfo and Fragments. It's more strict than 354 // we are, and faster, so it is done first. 355 if (u1.Equals(u2)) 356 { 357 return true; 358 } 359 360 if (u1.Scheme != u2.Scheme) // Uri.Scheme is always lowercase 361 { 362 return false; 363 } 364 if (includePortInComparison) 365 { 366 if (u1.Port != u2.Port) 367 { 368 return false; 369 } 370 } 371 if (includeHostInComparison) 372 { 373 if (string.Compare(u1.Host, u2.Host, StringComparison.OrdinalIgnoreCase) != 0) 374 { 375 return false; 376 } 377 } 378 379 if (string.Compare(u1.AbsolutePath, u2.AbsolutePath, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0) 380 { 381 return true; 382 } 383 384 // Normalize for trailing slashes 385 string u1Path = u1.GetComponents(UriComponents.Path, UriFormat.Unescaped); 386 string u2Path = u2.GetComponents(UriComponents.Path, UriFormat.Unescaped); 387 int u1Len = (u1Path.Length > 0 && u1Path[u1Path.Length - 1] == '/') ? u1Path.Length - 1 : u1Path.Length; 388 int u2Len = (u2Path.Length > 0 && u2Path[u2Path.Length - 1] == '/') ? u2Path.Length - 1 : u2Path.Length; 389 if (u2Len != u1Len) 390 { 391 return false; 392 } 393 return string.Compare(u1Path, 0, u2Path, 0, u1Len, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) == 0; 394 } 395 396 // this method must be kept in sync with UriEquals UriGetHashCode(Uri uri, bool includeHostInComparison)397 internal static int UriGetHashCode(Uri uri, bool includeHostInComparison) 398 { 399 return UriGetHashCode(uri, includeHostInComparison, true); 400 } 401 UriGetHashCode(Uri uri, bool includeHostInComparison, bool includePortInComparison)402 internal static int UriGetHashCode(Uri uri, bool includeHostInComparison, bool includePortInComparison) 403 { 404 UriComponents components = UriComponents.Scheme | UriComponents.Path; 405 406 if (includePortInComparison) 407 { 408 components = components | UriComponents.Port; 409 } 410 if (includeHostInComparison) 411 { 412 components = components | UriComponents.Host; 413 } 414 415 // Normalize for trailing slashes 416 string uriString = uri.GetComponents(components, UriFormat.Unescaped); 417 if (uriString.Length > 0 && uriString[uriString.Length - 1] != '/') 418 uriString = string.Concat(uriString, "/"); 419 420 return StringComparer.OrdinalIgnoreCase.GetHashCode(uriString); 421 } 422 EndpointEquals(EndpointAddress endpointAddress)423 internal bool EndpointEquals(EndpointAddress endpointAddress) 424 { 425 if (endpointAddress == null) 426 { 427 return false; 428 } 429 430 if (object.ReferenceEquals(this, endpointAddress)) 431 { 432 return true; 433 } 434 435 Uri thisTo = this.Uri; 436 Uri otherTo = endpointAddress.Uri; 437 438 if (!UriEquals(thisTo, otherTo, false /* ignoreCase */, true /* includeHostInComparison */)) 439 { 440 return false; 441 } 442 443 if (this.Identity == null) 444 { 445 if (endpointAddress.Identity != null) 446 { 447 return false; 448 } 449 } 450 else if (!this.Identity.Equals(endpointAddress.Identity)) 451 { 452 return false; 453 } 454 455 if (!this.Headers.IsEquivalent(endpointAddress.Headers)) 456 { 457 return false; 458 } 459 460 return true; 461 } 462 Equals(object obj)463 public override bool Equals(object obj) 464 { 465 if (object.ReferenceEquals(obj, this)) 466 { 467 return true; 468 } 469 470 if (obj == null) 471 { 472 return false; 473 } 474 475 EndpointAddress address = obj as EndpointAddress; 476 if (address == null) 477 { 478 return false; 479 } 480 481 return EndpointEquals(address); 482 } 483 GetHashCode()484 public override int GetHashCode() 485 { 486 return UriGetHashCode(this.uri, true /* includeHostInComparison */); 487 } 488 489 // returns reader without starting dummy wrapper element GetReaderAtPsp()490 internal XmlDictionaryReader GetReaderAtPsp() 491 { 492 return GetReaderAtSection(this.buffer, this.pspSection); 493 } 494 495 // returns reader without starting dummy wrapper element GetReaderAtMetadata()496 public XmlDictionaryReader GetReaderAtMetadata() 497 { 498 return GetReaderAtSection(this.buffer, this.metadataSection); 499 } 500 501 // returns reader without starting dummy wrapper element GetReaderAtExtensions()502 public XmlDictionaryReader GetReaderAtExtensions() 503 { 504 return GetReaderAtSection(this.buffer, this.extensionSection); 505 } 506 GetReaderAtSection(XmlBuffer buffer, int section)507 static XmlDictionaryReader GetReaderAtSection(XmlBuffer buffer, int section) 508 { 509 if (buffer == null || section < 0) 510 return null; 511 512 XmlDictionaryReader reader = buffer.GetReader(section); 513 reader.MoveToContent(); 514 Fx.Assert(reader.Name == DummyName, "EndpointAddress: Expected dummy element not found"); 515 reader.Read(); // consume the dummy wrapper element 516 return reader; 517 } 518 PossiblyPopulateBuffer(XmlDictionaryReader reader, ref XmlBuffer buffer, out int section)519 void PossiblyPopulateBuffer(XmlDictionaryReader reader, ref XmlBuffer buffer, out int section) 520 { 521 if (reader == null) 522 { 523 section = -1; 524 } 525 else 526 { 527 if (buffer == null) 528 { 529 buffer = new XmlBuffer(short.MaxValue); 530 } 531 section = buffer.SectionCount; 532 XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas); 533 writer.WriteStartElement(DummyName, DummyNamespace); 534 Copy(writer, reader); 535 buffer.CloseSection(); 536 } 537 } 538 ReadFrom(XmlDictionaryReader reader)539 public static EndpointAddress ReadFrom(XmlDictionaryReader reader) 540 { 541 AddressingVersion dummyVersion; 542 return ReadFrom(reader, out dummyVersion); 543 } 544 ReadFrom(XmlDictionaryReader reader, out AddressingVersion version)545 internal static EndpointAddress ReadFrom(XmlDictionaryReader reader, out AddressingVersion version) 546 { 547 if (reader == null) 548 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 549 550 reader.ReadFullStartElement(); 551 reader.MoveToContent(); 552 553 if (reader.IsNamespaceUri(AddressingVersion.WSAddressing10.DictionaryNamespace)) 554 { 555 version = AddressingVersion.WSAddressing10; 556 } 557 else if (reader.IsNamespaceUri(AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 558 { 559 version = AddressingVersion.WSAddressingAugust2004; 560 } 561 else if (reader.NodeType != XmlNodeType.Element) 562 { 563 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( 564 "reader", SR.GetString(SR.CannotDetectAddressingVersion)); 565 } 566 else 567 { 568 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( 569 "reader", SR.GetString(SR.AddressingVersionNotSupported, reader.NamespaceURI)); 570 } 571 572 EndpointAddress ea = ReadFromDriver(version, reader); 573 reader.ReadEndElement(); 574 return ea; 575 } 576 ReadFrom(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns)577 public static EndpointAddress ReadFrom(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns) 578 { 579 AddressingVersion version; 580 return ReadFrom(reader, localName, ns, out version); 581 } 582 ReadFrom(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns, out AddressingVersion version)583 internal static EndpointAddress ReadFrom(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns, out AddressingVersion version) 584 { 585 if (reader == null) 586 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 587 588 reader.ReadFullStartElement(localName, ns); 589 reader.MoveToContent(); 590 591 if (reader.IsNamespaceUri(AddressingVersion.WSAddressing10.DictionaryNamespace)) 592 { 593 version = AddressingVersion.WSAddressing10; 594 } 595 else if (reader.IsNamespaceUri(AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 596 { 597 version = AddressingVersion.WSAddressingAugust2004; 598 } 599 else if (reader.NodeType != XmlNodeType.Element) 600 { 601 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( 602 "reader", SR.GetString(SR.CannotDetectAddressingVersion)); 603 } 604 else 605 { 606 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( 607 "reader", SR.GetString(SR.AddressingVersionNotSupported, reader.NamespaceURI)); 608 } 609 610 EndpointAddress ea = ReadFromDriver(version, reader); 611 reader.ReadEndElement(); 612 return ea; 613 } 614 ReadFrom(AddressingVersion addressingVersion, XmlReader reader)615 public static EndpointAddress ReadFrom(AddressingVersion addressingVersion, XmlReader reader) 616 { 617 return ReadFrom(addressingVersion, XmlDictionaryReader.CreateDictionaryReader(reader)); 618 } 619 ReadFrom(AddressingVersion addressingVersion, XmlReader reader, string localName, string ns)620 public static EndpointAddress ReadFrom(AddressingVersion addressingVersion, XmlReader reader, string localName, string ns) 621 { 622 if (reader == null) 623 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 624 if (addressingVersion == null) 625 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 626 627 XmlDictionaryReader dictReader = XmlDictionaryReader.CreateDictionaryReader(reader); 628 dictReader.ReadFullStartElement(localName, ns); 629 EndpointAddress ea = ReadFromDriver(addressingVersion, dictReader); 630 reader.ReadEndElement(); 631 return ea; 632 } 633 ReadFrom(AddressingVersion addressingVersion, XmlDictionaryReader reader)634 public static EndpointAddress ReadFrom(AddressingVersion addressingVersion, XmlDictionaryReader reader) 635 { 636 if (reader == null) 637 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 638 if (addressingVersion == null) 639 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 640 641 reader.ReadFullStartElement(); 642 EndpointAddress ea = ReadFromDriver(addressingVersion, reader); 643 reader.ReadEndElement(); 644 return ea; 645 } 646 ReadFrom(AddressingVersion addressingVersion, XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns)647 public static EndpointAddress ReadFrom(AddressingVersion addressingVersion, XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns) 648 { 649 if (reader == null) 650 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); 651 if (addressingVersion == null) 652 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 653 654 reader.ReadFullStartElement(localName, ns); 655 EndpointAddress ea = ReadFromDriver(addressingVersion, reader); 656 reader.ReadEndElement(); 657 return ea; 658 } 659 ReadFromDriver(AddressingVersion addressingVersion, XmlDictionaryReader reader)660 static EndpointAddress ReadFromDriver(AddressingVersion addressingVersion, XmlDictionaryReader reader) 661 { 662 AddressHeaderCollection headers; 663 EndpointIdentity identity; 664 Uri uri; 665 XmlBuffer buffer; 666 bool isAnonymous; 667 int extensionSection; 668 int metadataSection; 669 int pspSection = -1; 670 671 if (addressingVersion == AddressingVersion.WSAddressing10) 672 { 673 isAnonymous = ReadContentsFrom10(reader, out uri, out headers, out identity, out buffer, out metadataSection, out extensionSection); 674 } 675 else if (addressingVersion == AddressingVersion.WSAddressingAugust2004) 676 { 677 isAnonymous = ReadContentsFrom200408(reader, out uri, out headers, out identity, out buffer, out metadataSection, out extensionSection, out pspSection); 678 } 679 else 680 { 681 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("addressingVersion", 682 SR.GetString(SR.AddressingVersionNotSupported, addressingVersion)); 683 } 684 685 if (isAnonymous && headers == null && identity == null && buffer == null) 686 { 687 return AnonymousAddress; 688 } 689 else 690 { 691 return new EndpointAddress(addressingVersion, uri, identity, headers, buffer, metadataSection, extensionSection, pspSection); 692 } 693 } 694 ReadExtensions(XmlDictionaryReader reader, AddressingVersion version, XmlBuffer buffer, out EndpointIdentity identity, out int section)695 internal static XmlBuffer ReadExtensions(XmlDictionaryReader reader, AddressingVersion version, XmlBuffer buffer, out EndpointIdentity identity, out int section) 696 { 697 if (reader == null) 698 { 699 identity = null; 700 section = -1; 701 return buffer; 702 } 703 704 // EndpointIdentity and extensions 705 identity = null; 706 XmlDictionaryWriter bufferWriter = null; 707 reader.MoveToContent(); 708 while (reader.IsStartElement()) 709 { 710 if (reader.IsStartElement(XD.AddressingDictionary.Identity, XD.AddressingDictionary.IdentityExtensionNamespace)) 711 { 712 if (identity != null) 713 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.UnexpectedDuplicateElement, XD.AddressingDictionary.Identity.Value, XD.AddressingDictionary.IdentityExtensionNamespace.Value))); 714 identity = EndpointIdentity.ReadIdentity(reader); 715 } 716 else if (version != null && reader.NamespaceURI == version.Namespace) 717 { 718 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.AddressingExtensionInBadNS, reader.LocalName, reader.NamespaceURI))); 719 } 720 else 721 { 722 if (bufferWriter == null) 723 { 724 if (buffer == null) 725 buffer = new XmlBuffer(short.MaxValue); 726 bufferWriter = buffer.OpenSection(reader.Quotas); 727 bufferWriter.WriteStartElement(DummyName, DummyNamespace); 728 } 729 730 bufferWriter.WriteNode(reader, true); 731 } 732 reader.MoveToContent(); 733 } 734 735 if (bufferWriter != null) 736 { 737 bufferWriter.WriteEndElement(); 738 buffer.CloseSection(); 739 section = buffer.SectionCount - 1; 740 } 741 else 742 { 743 section = -1; 744 } 745 746 return buffer; 747 } 748 ReadContentsFrom200408(XmlDictionaryReader reader, out Uri uri, out AddressHeaderCollection headers, out EndpointIdentity identity, out XmlBuffer buffer, out int metadataSection, out int extensionSection, out int pspSection)749 static bool ReadContentsFrom200408(XmlDictionaryReader reader, out Uri uri, out AddressHeaderCollection headers, out EndpointIdentity identity, out XmlBuffer buffer, out int metadataSection, out int extensionSection, out int pspSection) 750 { 751 buffer = null; 752 headers = null; 753 extensionSection = -1; 754 metadataSection = -1; 755 pspSection = -1; 756 757 // Cache address string 758 reader.MoveToContent(); 759 if (!reader.IsStartElement(XD.AddressingDictionary.Address, AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 760 { 761 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.UnexpectedElementExpectingElement, reader.LocalName, reader.NamespaceURI, XD.AddressingDictionary.Address.Value, XD.Addressing200408Dictionary.Namespace.Value))); 762 } 763 string address = reader.ReadElementContentAsString(); 764 765 // ReferenceProperites 766 reader.MoveToContent(); 767 if (reader.IsStartElement(XD.AddressingDictionary.ReferenceProperties, AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 768 { 769 headers = AddressHeaderCollection.ReadServiceParameters(reader, true); 770 } 771 772 // ReferenceParameters 773 reader.MoveToContent(); 774 if (reader.IsStartElement(XD.AddressingDictionary.ReferenceParameters, AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 775 { 776 if (headers != null) 777 { 778 List<AddressHeader> headerList = new List<AddressHeader>(); 779 foreach (AddressHeader ah in headers) 780 { 781 headerList.Add(ah); 782 } 783 AddressHeaderCollection tmp = AddressHeaderCollection.ReadServiceParameters(reader); 784 foreach (AddressHeader ah in tmp) 785 { 786 headerList.Add(ah); 787 } 788 headers = new AddressHeaderCollection(headerList); 789 } 790 else 791 { 792 headers = AddressHeaderCollection.ReadServiceParameters(reader); 793 } 794 } 795 796 XmlDictionaryWriter bufferWriter = null; 797 798 // PortType 799 reader.MoveToContent(); 800 if (reader.IsStartElement(XD.AddressingDictionary.PortType, AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 801 { 802 if (bufferWriter == null) 803 { 804 if (buffer == null) 805 buffer = new XmlBuffer(short.MaxValue); 806 bufferWriter = buffer.OpenSection(reader.Quotas); 807 bufferWriter.WriteStartElement(DummyName, DummyNamespace); 808 } 809 bufferWriter.WriteNode(reader, true); 810 } 811 812 // ServiceName 813 reader.MoveToContent(); 814 if (reader.IsStartElement(XD.AddressingDictionary.ServiceName, AddressingVersion.WSAddressingAugust2004.DictionaryNamespace)) 815 { 816 if (bufferWriter == null) 817 { 818 if (buffer == null) 819 buffer = new XmlBuffer(short.MaxValue); 820 bufferWriter = buffer.OpenSection(reader.Quotas); 821 bufferWriter.WriteStartElement(DummyName, DummyNamespace); 822 } 823 bufferWriter.WriteNode(reader, true); 824 } 825 826 // Policy 827 reader.MoveToContent(); 828 while (reader.IsNamespaceUri(XD.PolicyDictionary.Namespace)) 829 { 830 if (bufferWriter == null) 831 { 832 if (buffer == null) 833 buffer = new XmlBuffer(short.MaxValue); 834 bufferWriter = buffer.OpenSection(reader.Quotas); 835 bufferWriter.WriteStartElement(DummyName, DummyNamespace); 836 } 837 bufferWriter.WriteNode(reader, true); 838 reader.MoveToContent(); 839 } 840 841 // Finish PSP 842 if (bufferWriter != null) 843 { 844 bufferWriter.WriteEndElement(); 845 buffer.CloseSection(); 846 pspSection = buffer.SectionCount - 1; 847 bufferWriter = null; 848 } 849 else 850 { 851 pspSection = -1; 852 } 853 854 855 // Metadata 856 if (reader.IsStartElement(System.ServiceModel.Description.MetadataStrings.MetadataExchangeStrings.Metadata, 857 System.ServiceModel.Description.MetadataStrings.MetadataExchangeStrings.Namespace)) 858 { 859 if (bufferWriter == null) 860 { 861 if (buffer == null) 862 buffer = new XmlBuffer(short.MaxValue); 863 bufferWriter = buffer.OpenSection(reader.Quotas); 864 bufferWriter.WriteStartElement(DummyName, DummyNamespace); 865 } 866 bufferWriter.WriteNode(reader, true); 867 } 868 869 // Finish metadata 870 if (bufferWriter != null) 871 { 872 bufferWriter.WriteEndElement(); 873 buffer.CloseSection(); 874 metadataSection = buffer.SectionCount - 1; 875 bufferWriter = null; 876 } 877 else 878 { 879 metadataSection = -1; 880 } 881 882 // Extensions 883 reader.MoveToContent(); 884 buffer = ReadExtensions(reader, AddressingVersion.WSAddressingAugust2004, buffer, out identity, out extensionSection); 885 886 // Finished reading 887 if (buffer != null) 888 buffer.Close(); 889 890 // Process Address 891 if (address == Addressing200408Strings.Anonymous) 892 { 893 uri = AddressingVersion.WSAddressingAugust2004.AnonymousUri; 894 if (headers == null && identity == null) 895 return true; 896 } 897 else 898 { 899 if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) 900 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.InvalidUriValue, address, XD.AddressingDictionary.Address.Value, AddressingVersion.WSAddressingAugust2004.Namespace))); 901 } 902 return false; 903 } 904 ReadContentsFrom10(XmlDictionaryReader reader, out Uri uri, out AddressHeaderCollection headers, out EndpointIdentity identity, out XmlBuffer buffer, out int metadataSection, out int extensionSection)905 static bool ReadContentsFrom10(XmlDictionaryReader reader, out Uri uri, out AddressHeaderCollection headers, out EndpointIdentity identity, out XmlBuffer buffer, out int metadataSection, out int extensionSection) 906 { 907 buffer = null; 908 extensionSection = -1; 909 metadataSection = -1; 910 911 // Cache address string 912 if (!reader.IsStartElement(XD.AddressingDictionary.Address, XD.Addressing10Dictionary.Namespace)) 913 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.UnexpectedElementExpectingElement, reader.LocalName, reader.NamespaceURI, XD.AddressingDictionary.Address.Value, XD.Addressing10Dictionary.Namespace.Value))); 914 string address = reader.ReadElementContentAsString(); 915 916 // Headers 917 if (reader.IsStartElement(XD.AddressingDictionary.ReferenceParameters, XD.Addressing10Dictionary.Namespace)) 918 { 919 headers = AddressHeaderCollection.ReadServiceParameters(reader); 920 } 921 else 922 { 923 headers = null; 924 } 925 926 // Metadata 927 if (reader.IsStartElement(XD.Addressing10Dictionary.Metadata, XD.Addressing10Dictionary.Namespace)) 928 { 929 reader.ReadFullStartElement(); // the wsa10:Metadata element is never stored in the buffer 930 buffer = new XmlBuffer(short.MaxValue); 931 metadataSection = 0; 932 XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas); 933 writer.WriteStartElement(DummyName, DummyNamespace); 934 while (reader.NodeType != XmlNodeType.EndElement && !reader.EOF) 935 { 936 writer.WriteNode(reader, true); 937 } 938 writer.Flush(); 939 buffer.CloseSection(); 940 reader.ReadEndElement(); 941 } 942 943 // Extensions 944 buffer = ReadExtensions(reader, AddressingVersion.WSAddressing10, buffer, out identity, out extensionSection); 945 if (buffer != null) 946 { 947 buffer.Close(); 948 } 949 950 // Process Address 951 if (address == Addressing10Strings.Anonymous) 952 { 953 uri = AddressingVersion.WSAddressing10.AnonymousUri; 954 if (headers == null && identity == null) 955 { 956 return true; 957 } 958 } 959 else if (address == Addressing10Strings.NoneAddress) 960 { 961 uri = AddressingVersion.WSAddressing10.NoneUri; 962 return false; 963 } 964 else 965 { 966 if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) 967 { 968 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.InvalidUriValue, address, XD.AddressingDictionary.Address.Value, XD.Addressing10Dictionary.Namespace.Value))); 969 } 970 } 971 return false; 972 } 973 CreateXmlException(XmlDictionaryReader reader, string message)974 static XmlException CreateXmlException(XmlDictionaryReader reader, string message) 975 { 976 IXmlLineInfo lineInfo = reader as IXmlLineInfo; 977 if (lineInfo != null) 978 { 979 return new XmlException(message, null, lineInfo.LineNumber, lineInfo.LinePosition); 980 } 981 982 return new XmlException(message); 983 } 984 985 // this function has a side-effect on the reader (MoveToContent) Done(XmlDictionaryReader reader)986 static bool Done(XmlDictionaryReader reader) 987 { 988 reader.MoveToContent(); 989 return (reader.NodeType == XmlNodeType.EndElement || reader.EOF); 990 } 991 992 // copy all of reader to writer Copy(XmlDictionaryWriter writer, XmlDictionaryReader reader)993 static internal void Copy(XmlDictionaryWriter writer, XmlDictionaryReader reader) 994 { 995 while (!Done(reader)) 996 { 997 writer.WriteNode(reader, true); 998 } 999 } 1000 ToString()1001 public override string ToString() 1002 { 1003 return uri.ToString(); 1004 } 1005 WriteContentsTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer)1006 public void WriteContentsTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer) 1007 { 1008 if (writer == null) 1009 { 1010 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); 1011 } 1012 1013 if (addressingVersion == null) 1014 { 1015 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 1016 } 1017 1018 if (addressingVersion == AddressingVersion.WSAddressing10) 1019 { 1020 WriteContentsTo10(writer); 1021 } 1022 else if (addressingVersion == AddressingVersion.WSAddressingAugust2004) 1023 { 1024 WriteContentsTo200408(writer); 1025 } 1026 else if (addressingVersion == AddressingVersion.None) 1027 { 1028 WriteContentsToNone(writer); 1029 } 1030 else 1031 { 1032 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("addressingVersion", 1033 SR.GetString(SR.AddressingVersionNotSupported, addressingVersion)); 1034 } 1035 } 1036 WriteContentsToNone(XmlDictionaryWriter writer)1037 void WriteContentsToNone(XmlDictionaryWriter writer) 1038 { 1039 writer.WriteString(this.Uri.AbsoluteUri); 1040 } 1041 WriteContentsTo200408(XmlDictionaryWriter writer)1042 void WriteContentsTo200408(XmlDictionaryWriter writer) 1043 { 1044 // Address 1045 writer.WriteStartElement(XD.AddressingDictionary.Address, XD.Addressing200408Dictionary.Namespace); 1046 if (isAnonymous) 1047 { 1048 writer.WriteString(XD.Addressing200408Dictionary.Anonymous); 1049 } 1050 else if (isNone) 1051 { 1052 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("addressingVersion", SR.GetString(SR.SFxNone2004)); 1053 } 1054 else 1055 { 1056 writer.WriteString(this.Uri.AbsoluteUri); 1057 } 1058 writer.WriteEndElement(); 1059 1060 // ReferenceProperties 1061 if (this.headers != null && this.headers.HasReferenceProperties) 1062 { 1063 writer.WriteStartElement(XD.AddressingDictionary.ReferenceProperties, XD.Addressing200408Dictionary.Namespace); 1064 this.headers.WriteReferencePropertyContentsTo(writer); 1065 writer.WriteEndElement(); 1066 } 1067 1068 // ReferenceParameters 1069 if (this.headers != null && this.headers.HasNonReferenceProperties) 1070 { 1071 writer.WriteStartElement(XD.AddressingDictionary.ReferenceParameters, XD.Addressing200408Dictionary.Namespace); 1072 this.headers.WriteNonReferencePropertyContentsTo(writer); 1073 writer.WriteEndElement(); 1074 } 1075 1076 // PSP (PortType, ServiceName, Policy) 1077 XmlDictionaryReader reader = null; 1078 if (pspSection >= 0) 1079 { 1080 reader = GetReaderAtSection(buffer, pspSection); 1081 Copy(writer, reader); 1082 } 1083 1084 // Metadata 1085 reader = null; 1086 if (metadataSection >= 0) 1087 { 1088 reader = GetReaderAtSection(buffer, metadataSection); 1089 Copy(writer, reader); 1090 } 1091 1092 // EndpointIdentity 1093 if (this.Identity != null) 1094 { 1095 this.Identity.WriteTo(writer); 1096 } 1097 1098 // Extensions 1099 if (this.extensionSection >= 0) 1100 { 1101 reader = GetReaderAtSection(this.buffer, extensionSection); 1102 while (reader.IsStartElement()) 1103 { 1104 if (reader.NamespaceURI == AddressingVersion.WSAddressingAugust2004.Namespace) 1105 { 1106 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.AddressingExtensionInBadNS, reader.LocalName, reader.NamespaceURI))); 1107 } 1108 1109 writer.WriteNode(reader, true); 1110 } 1111 } 1112 } 1113 WriteContentsTo10(XmlDictionaryWriter writer)1114 void WriteContentsTo10(XmlDictionaryWriter writer) 1115 { 1116 // Address 1117 writer.WriteStartElement(XD.AddressingDictionary.Address, XD.Addressing10Dictionary.Namespace); 1118 if (isAnonymous) 1119 { 1120 writer.WriteString(XD.Addressing10Dictionary.Anonymous); 1121 } 1122 else if (isNone) 1123 { 1124 writer.WriteString(XD.Addressing10Dictionary.NoneAddress); 1125 } 1126 else 1127 { 1128 writer.WriteString(this.Uri.AbsoluteUri); 1129 } 1130 writer.WriteEndElement(); 1131 1132 // Headers 1133 if (this.headers != null && this.headers.Count > 0) 1134 { 1135 writer.WriteStartElement(XD.AddressingDictionary.ReferenceParameters, XD.Addressing10Dictionary.Namespace); 1136 this.headers.WriteContentsTo(writer); 1137 writer.WriteEndElement(); 1138 } 1139 1140 // Metadata 1141 if (this.metadataSection >= 0) 1142 { 1143 XmlDictionaryReader reader = GetReaderAtSection(this.buffer, metadataSection); 1144 writer.WriteStartElement(XD.Addressing10Dictionary.Metadata, XD.Addressing10Dictionary.Namespace); 1145 Copy(writer, reader); 1146 writer.WriteEndElement(); 1147 } 1148 1149 // EndpointIdentity 1150 if (this.Identity != null) 1151 { 1152 this.Identity.WriteTo(writer); 1153 } 1154 1155 // Extensions 1156 if (this.extensionSection >= 0) 1157 { 1158 XmlDictionaryReader reader = GetReaderAtSection(this.buffer, this.extensionSection); 1159 while (reader.IsStartElement()) 1160 { 1161 if (reader.NamespaceURI == AddressingVersion.WSAddressing10.Namespace) 1162 { 1163 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateXmlException(reader, SR.GetString(SR.AddressingExtensionInBadNS, reader.LocalName, reader.NamespaceURI))); 1164 } 1165 1166 writer.WriteNode(reader, true); 1167 } 1168 } 1169 } 1170 WriteContentsTo(AddressingVersion addressingVersion, XmlWriter writer)1171 public void WriteContentsTo(AddressingVersion addressingVersion, XmlWriter writer) 1172 { 1173 XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer); 1174 WriteContentsTo(addressingVersion, dictionaryWriter); 1175 } 1176 WriteTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer)1177 public void WriteTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer) 1178 { 1179 WriteTo(addressingVersion, writer, XD.AddressingDictionary.EndpointReference, 1180 addressingVersion.DictionaryNamespace); 1181 } 1182 WriteTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer, XmlDictionaryString localName, XmlDictionaryString ns)1183 public void WriteTo(AddressingVersion addressingVersion, XmlDictionaryWriter writer, XmlDictionaryString localName, XmlDictionaryString ns) 1184 { 1185 if (writer == null) 1186 { 1187 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); 1188 } 1189 if (addressingVersion == null) 1190 { 1191 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 1192 } 1193 if (localName == null) 1194 { 1195 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); 1196 } 1197 if (ns == null) 1198 { 1199 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns"); 1200 } 1201 writer.WriteStartElement(localName, ns); 1202 WriteContentsTo(addressingVersion, writer); 1203 writer.WriteEndElement(); 1204 } 1205 WriteTo(AddressingVersion addressingVersion, XmlWriter writer)1206 public void WriteTo(AddressingVersion addressingVersion, XmlWriter writer) 1207 { 1208 XmlDictionaryString dictionaryNamespace = addressingVersion.DictionaryNamespace; 1209 if (dictionaryNamespace == null) 1210 { 1211 dictionaryNamespace = XD.AddressingDictionary.Empty; 1212 } 1213 1214 WriteTo(addressingVersion, XmlDictionaryWriter.CreateDictionaryWriter(writer), 1215 XD.AddressingDictionary.EndpointReference, dictionaryNamespace); 1216 } 1217 WriteTo(AddressingVersion addressingVersion, XmlWriter writer, string localName, string ns)1218 public void WriteTo(AddressingVersion addressingVersion, XmlWriter writer, string localName, string ns) 1219 { 1220 if (writer == null) 1221 { 1222 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); 1223 } 1224 if (addressingVersion == null) 1225 { 1226 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addressingVersion"); 1227 } 1228 if (localName == null) 1229 { 1230 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); 1231 } 1232 if (ns == null) 1233 { 1234 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns"); 1235 } 1236 writer.WriteStartElement(localName, ns); 1237 WriteContentsTo(addressingVersion, writer); 1238 writer.WriteEndElement(); 1239 } 1240 operator ==(EndpointAddress address1, EndpointAddress address2)1241 public static bool operator ==(EndpointAddress address1, EndpointAddress address2) 1242 { 1243 if (object.ReferenceEquals(address2, null)) 1244 { 1245 return (object.ReferenceEquals(address1, null)); 1246 } 1247 1248 return address2.Equals(address1); 1249 } 1250 operator !=(EndpointAddress address1, EndpointAddress address2)1251 public static bool operator !=(EndpointAddress address1, EndpointAddress address2) 1252 { 1253 if (object.ReferenceEquals(address2, null)) 1254 { 1255 return !object.ReferenceEquals(address1, null); 1256 } 1257 1258 return !address2.Equals(address1); 1259 } 1260 } 1261 1262 public class EndpointAddressBuilder 1263 { 1264 Uri uri; 1265 EndpointIdentity identity; 1266 Collection<AddressHeader> headers; 1267 XmlBuffer extensionBuffer; // this buffer is wrapped just like in EndpointAddress 1268 XmlBuffer metadataBuffer; // this buffer is wrapped just like in EndpointAddress 1269 bool hasExtension; 1270 bool hasMetadata; 1271 EndpointAddress epr; 1272 EndpointAddressBuilder()1273 public EndpointAddressBuilder() 1274 { 1275 this.headers = new Collection<AddressHeader>(); 1276 } 1277 EndpointAddressBuilder(EndpointAddress address)1278 public EndpointAddressBuilder(EndpointAddress address) 1279 { 1280 if (address == null) 1281 { 1282 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address"); 1283 } 1284 1285 this.epr = address; 1286 this.uri = address.Uri; 1287 this.identity = address.Identity; 1288 this.headers = new Collection<AddressHeader>(); 1289 #pragma warning suppress 56506 1290 for (int i = 0; i < address.Headers.Count; i++) 1291 { 1292 this.headers.Add(address.Headers[i]); 1293 } 1294 } 1295 1296 public Uri Uri 1297 { 1298 get { return this.uri; } 1299 set { this.uri = value; } 1300 } 1301 1302 public EndpointIdentity Identity 1303 { 1304 get { return this.identity; } 1305 set { this.identity = value; } 1306 } 1307 1308 public Collection<AddressHeader> Headers 1309 { 1310 get { return this.headers; } 1311 } 1312 GetReaderAtMetadata()1313 public XmlDictionaryReader GetReaderAtMetadata() 1314 { 1315 if (!this.hasMetadata) 1316 { 1317 return epr == null ? null : epr.GetReaderAtMetadata(); 1318 } 1319 1320 if (this.metadataBuffer == null) 1321 { 1322 return null; 1323 } 1324 1325 XmlDictionaryReader reader = this.metadataBuffer.GetReader(0); 1326 reader.MoveToContent(); 1327 Fx.Assert(reader.Name == EndpointAddress.DummyName, "EndpointAddressBuilder: Expected dummy element not found"); 1328 reader.Read(); // consume the wrapper element 1329 return reader; 1330 } 1331 SetMetadataReader(XmlDictionaryReader reader)1332 public void SetMetadataReader(XmlDictionaryReader reader) 1333 { 1334 hasMetadata = true; 1335 metadataBuffer = null; 1336 if (reader != null) 1337 { 1338 metadataBuffer = new XmlBuffer(short.MaxValue); 1339 XmlDictionaryWriter writer = metadataBuffer.OpenSection(reader.Quotas); 1340 writer.WriteStartElement(EndpointAddress.DummyName, EndpointAddress.DummyNamespace); 1341 EndpointAddress.Copy(writer, reader); 1342 metadataBuffer.CloseSection(); 1343 metadataBuffer.Close(); 1344 } 1345 } 1346 GetReaderAtExtensions()1347 public XmlDictionaryReader GetReaderAtExtensions() 1348 { 1349 if (!this.hasExtension) 1350 { 1351 return epr == null ? null : epr.GetReaderAtExtensions(); 1352 } 1353 1354 if (this.extensionBuffer == null) 1355 { 1356 return null; 1357 } 1358 1359 XmlDictionaryReader reader = this.extensionBuffer.GetReader(0); 1360 reader.MoveToContent(); 1361 Fx.Assert(reader.Name == EndpointAddress.DummyName, "EndpointAddressBuilder: Expected dummy element not found"); 1362 reader.Read(); // consume the wrapper element 1363 return reader; 1364 } 1365 SetExtensionReader(XmlDictionaryReader reader)1366 public void SetExtensionReader(XmlDictionaryReader reader) 1367 { 1368 hasExtension = true; 1369 EndpointIdentity identity; 1370 int tmp; 1371 this.extensionBuffer = EndpointAddress.ReadExtensions(reader, null, null, out identity, out tmp); 1372 if (this.extensionBuffer != null) 1373 { 1374 this.extensionBuffer.Close(); 1375 } 1376 if (identity != null) 1377 { 1378 this.identity = identity; 1379 } 1380 } 1381 ToEndpointAddress()1382 public EndpointAddress ToEndpointAddress() 1383 { 1384 return new EndpointAddress( 1385 this.uri, 1386 this.identity, 1387 new AddressHeaderCollection(this.headers), 1388 this.GetReaderAtMetadata(), 1389 this.GetReaderAtExtensions(), 1390 epr == null ? null : epr.GetReaderAtPsp()); 1391 } 1392 } 1393 } 1394 1395