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