1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright (c) 2003-2012 by AG-Software 											 *
3  * All Rights Reserved.																 *
4  * Contact information for AG-Software is available at http://www.ag-software.de	 *
5  *																					 *
6  * Licence:																			 *
7  * The agsXMPP SDK is released under a dual licence									 *
8  * agsXMPP can be used under either of two licences									 *
9  * 																					 *
10  * A commercial licence which is probably the most appropriate for commercial 		 *
11  * corporate use and closed source projects. 										 *
12  *																					 *
13  * The GNU Public License (GPL) is probably most appropriate for inclusion in		 *
14  * other open source projects.														 *
15  *																					 *
16  * See README.html for details.														 *
17  *																					 *
18  * For general enquiries visit our website at:										 *
19  * http://www.ag-software.de														 *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21 /*
22  * xpnet is a deriviative of James Clark's XP parser.
23  * See copying.txt for more info.
24  */
25 using System.Collections.Generic;
26 
27 namespace agsXMPP.Xml.Xpnet
28 {
29     /// <summary>
30     /// Namespace stack.
31     /// </summary>
32     public class NamespaceStack
33     {
34         private readonly Stack<Dictionary<string, string>> stack = new Stack<Dictionary<string, string>>();
35 
36         /// <summary>
37         /// Create a new stack, primed with xmlns and xml as prefixes.
38         /// </summary>
NamespaceStack()39         public NamespaceStack()
40         {
41             Push();
42             AddNamespace("xmlns", "http://www.w3.org/2000/xmlns/");
43             AddNamespace("xml", "http://www.w3.org/XML/1998/namespace");
44         }
45 
46         /// <summary>
47         /// Declare a new scope, typically at the start of each element
48         /// </summary>
Push()49         public void Push()
50         {
51             stack.Push(new Dictionary<string, string>());
52         }
53 
54         /// <summary>
55         /// Pop the current scope off the stack.  Typically at the end of each element.
56         /// </summary>
Pop()57         public void Pop()
58         {
59             stack.Pop();
60         }
61 
62         /// <summary>
63         /// Add a namespace to the current scope.
64         /// </summary>
65         /// <param name="prefix"></param>
66         /// <param name="uri"></param>
AddNamespace(string prefix, string uri)67         public void AddNamespace(string prefix, string uri)
68         {
69             stack.Peek().Add(prefix, uri);
70         }
71 
72         /// <summary>
73         /// Lookup a prefix to find a namespace.  Searches down the stack, starting at the current scope.
74         /// </summary>
75         /// <param name="prefix"></param>
76         /// <returns></returns>
LookupNamespace(string prefix)77         public string LookupNamespace(string prefix)
78         {
79             foreach (Dictionary<string, string> ht in stack)
80             {
81                 if ((ht.Count > 0) && (ht.ContainsKey(prefix)))
82                     return ht[prefix];
83             }
84             return "";
85         }
86 
87         /// <summary>
88         /// The current default namespace.
89         /// </summary>
90         public string DefaultNamespace
91         {
92             get { return LookupNamespace(string.Empty); }
93         }
94 
95         /// <summary>
96         /// Clears this instance.
97         /// </summary>
Clear()98 		public void Clear()
99 		{
100 #if !CF
101 		    stack.Clear();
102 #else
103 			while (m_stack.Count > 0)
104 			    m_stack.Pop();
105 #endif
106 		}
107     }
108 }