1 using System;
  2 using System.Collections;
  3 
  4 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xml/XmlProcessor.hpp' using cpp2cm version 1.0.0
  5 
  6 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xml/XmlProcessor.cpp' using cpp2cm version 1.0.0
  7 
  8 namespace System.Xml
  9 {
 10     public class XmlProcessingException : Exception
 11     {
 12         public XmlProcessingException(const string& message_) : 
 13             base(message_)
 14         {
 15         }
 16     }
 17     public class Entity
 18     {
 19         public virtual ~Entity()
 20         {
 21         }
 22         public virtual bool IsInternalEntity() const
 23         {
 24             return false;
 25         }
 26     }
 27     public class InternalEntity : Entity
 28     {
 29         public InternalEntity(const ustring& value_) : 
 30             value(value_)
 31         {
 32         }
 33         public const ustring& Value() const
 34         {
 35             return value;
 36         }
 37         public override bool IsInternalEntity() const
 38         {
 39             return true;
 40         }
 41         private ustring value;
 42     }
 43     public class XmlProcessor
 44     {
 45         public suppress XmlProcessor(const XmlProcessor&);
 46         public suppress XmlProcessor(XmlProcessor&&);
 47         public XmlProcessor(TrivialLexer& lexer_XmlContentHandler* contentHandler_) : 
 48             lexer(lexer_)contentHandler(contentHandler_)attValue()
 49         {
 50             InternalEntity* quot = new InternalEntity(u"\"");
 51             entityMap[u"quot"] = quot;
 52             InternalEntity* amp = new InternalEntity(u"&");
 53             entityMap[u"amp"] = amp;
 54             InternalEntity* apos = new InternalEntity(u"\'");
 55             entityMap[u"apos"] = apos;
 56             InternalEntity* lt = new InternalEntity(u"<");
 57             entityMap[u"lt"] = lt;
 58             InternalEntity* gt = new InternalEntity(u">");
 59             entityMap[u"gt"] = gt;
 60             entities.Add(UniquePtr<Entity>(quot));
 61             entities.Add(UniquePtr<Entity>(amp));
 62             entities.Add(UniquePtr<Entity>(apos));
 63             entities.Add(UniquePtr<Entity>(lt));
 64             entities.Add(UniquePtr<Entity>(gt));
 65         }
 66         public suppress XmlProcessor& operator=(const XmlProcessor&);
 67         public suppress XmlProcessor&& operator=(XmlProcessor&&);
 68         public const ustring& AttValue() const
 69         {
 70             return attValue;
 71         }
 72         public ustring& AttValue()
 73         {
 74             return attValue;
 75         }
 76         public TrivialLexer& Lexer() const
 77         {
 78             return lexer;
 79         }
 80         public void StartDocument()
 81         {
 82             contentHandler->StartDocument();
 83         }
 84         public void EndDocument()
 85         {
 86             contentHandler->EndDocument();
 87         }
 88         public void Text(const ustring& text)
 89         {
 90             contentHandler->HandleText(text);
 91         }
 92         public void Comment(const ustring& text)
 93         {
 94             contentHandler->HandleComment(text);
 95         }
 96         public void PI(const ustring& targetconst ustring& data)
 97         {
 98             contentHandler->HandlePI(targetdata);
 99         }
100         public void CDataSection(const ustring& cdata)
101         {
102             contentHandler->HandleCDataSection(cdata);
103         }
104         public void Version(const ustring& version)
105         {
106             contentHandler->Version(version);
107         }
108         public void Standalone(bool standalone)
109         {
110             contentHandler->Standalone(standalone);
111         }
112         public void Encoding(const ustring& encoding)
113         {
114             contentHandler->Encoding(encoding);
115         }
116         public void BeginStartTag(const ustring& tagName)
117         {
118             tagStack.Push(currentTagName);
119             currentTagName = tagName;
120             namespaceUriStack.Push(currentNamespaceUri);
121             namespacePrefixStack.Push(currentNamespacePrefix);
122             attributes.Clear();
123         }
124         public void EndStartTag(const System.Lex.Span& spanconst string& systemId)
125         {
126             ustring localName;
127             ustring prefix;
128             ParseQualifiedName(currentTagNamelocalNameprefixspansystemId);
129             if (prefix == u"xmlns")
130             {
131                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": \'xmlns\' prefix cannot be declared for an element");
132             }
133             contentHandler->StartElement(GetNamespaceUri(prefixspansystemId)localNamecurrentTagNameattributes);
134         }
135         public void EndTag(const ustring& tagNameconst System.Lex.Span& spanconst string& systemId)
136         {
137             if (tagStack.IsEmpty())
138             {
139                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": end tag \'" + ToUtf8(tagName) + "\' has no corresponding start tag");
140             }
141             if (tagName != currentTagName)
142             {
143                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": end tag \'" + ToUtf8(tagName) + "\' does not match start tag \'" + ToUtf8(currentTagName) + "\'");
144             }
145             ustring localName;
146             ustring prefix;
147             ParseQualifiedName(currentTagNamelocalNameprefixspansystemId);
148             if (prefix == u"xmlns")
149             {
150                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": \'xmlns\' prefix cannot be declared for an element");
151             }
152             contentHandler->EndElement(GetNamespaceUri(prefixspansystemId)localNamecurrentTagName);
153             if (namespaceUriStack.IsEmpty())
154             {
155                 throw Exception("namespace URI stack is empty");
156             }
157             currentNamespaceUri = namespaceUriStack.Top();
158             namespaceUriStack.Pop();
159             namespacePrefixMap.Remove(currentNamespacePrefix);
160             if (namespacePrefixStack.IsEmpty())
161             {
162                 throw Exception("namespace prefix stack is empty");
163             }
164             currentNamespacePrefix = namespacePrefixStack.Top();
165             namespacePrefixStack.Pop();
166             namespacePrefixMap[currentNamespacePrefix] = currentNamespaceUri;
167             currentTagName = tagStack.Top();
168             tagStack.Pop();
169         }
170         public void AddAttribute(const ustring& attNameconst ustring& attValueconst System.Lex.Span& spanconst string& systemId)
171         {
172             ustring localName;
173             ustring prefix;
174             ParseQualifiedName(attNamelocalNameprefixspansystemId);
175             if (prefix == u"xmlns")
176             {
177                 currentNamespacePrefix = localName;
178                 currentNamespaceUri = attValue;
179                 namespacePrefixMap[currentNamespacePrefix] = currentNamespaceUri;
180             }
181             else if (localName == u"xmlns")
182             {
183                 currentNamespacePrefix.Clear();
184                 currentNamespaceUri = attValue;
185             }
186             else
187             {
188                 attributes.Add(Attribute(GetNamespaceUri(prefixspansystemId)localNameattNameattValue));
189             }
190         }
191         public void EntityRef(const ustring& entityNameconst System.Lex.Span& spanconst string& systemId)
192         {
193             HashMap<ustringEntity*>.ConstIterator it = entityMap.CFind(entityName);
194             if (it != entityMap.CEnd())
195             {
196                 Entity* entity = it->second;
197                 if (entity->IsInternalEntity())
198                 {
199                     InternalEntity* internalEntity = cast<InternalEntity*>(entity);
200                     const ustring& entityValue = internalEntity->Value();
201                     if (!attValueStack.IsEmpty())
202                     {
203                         attValue.Append(entityValue);
204                     }
205                     else
206                     {
207                         Text(entityValue);
208                     }
209                 }
210                 else
211                 {
212                     contentHandler->SkippedEntity(entityName);
213                 }
214             }
215             else
216             {
217                 contentHandler->SkippedEntity(entityName);
218             }
219         }
220         public void BeginAttributeValue()
221         {
222             attValueStack.Push(attValue);
223             attValue.Clear();
224         }
225         public void EndAttributeValue()
226         {
227             if (attValueStack.IsEmpty())
228             {
229                 throw Exception("attribute value stack is empty");
230             }
231             attValue = attValueStack.Top();
232             attValueStack.Pop();
233         }
234         public ustring GetNamespaceUri(const ustring& namespacePrefixconst System.Lex.Span& spanconst string& systemId)
235         {
236             if (namespacePrefix.IsEmpty())
237             {
238                 return currentNamespaceUri;
239             }
240             HashMap<ustringustring>.ConstIterator it = namespacePrefixMap.CFind(namespacePrefix);
241             if (it != namespacePrefixMap.CEnd())
242             {
243                 return it->second;
244             }
245             else
246             {
247                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": namespace prefix \'" + ToUtf8(namespacePrefix) + "\' not bound to any namespace URI");
248             }
249         }
250         public void ParseQualifiedName(const ustring& qualifiedNameustring& localNameustring& prefixconst System.Lex.Span& spanconst string& systemId)
251         {
252             List<ustring> parts = qualifiedName.Split(':');
253             if (parts.Count() > 2)
254             {
255                 throw XmlProcessingException(GetErrorLocationStr(systemIdspan) + ": qualified name \'" + ToUtf8(qualifiedName) + "\' has more than one \':\' character");
256             }
257             else if (parts.Count() == 2)
258             {
259                 prefix = parts[0];
260                 localName = parts[1];
261             }
262             else
263             {
264                 prefix.Clear();
265                 localName = qualifiedName;
266             }
267         }
268         public int GetErrorColumn(int index) const
269         {
270             int errorColumn = 0;
271             while (index > 0 && lexer.Start()[index] != '\n' && lexer.Start()[index] != '\r')
272             {
273                 ++errorColumn;
274                 --index;
275             }
276             if (errorColumn == 0)
277             {
278                 errorColumn = 1;
279             }
280             return errorColumn;
281         }
282         public string GetErrorLocationStr(const string& systemIdconst System.Lex.Span& span) const
283         {
284             System.Lex.Token token = lexer.GetToken(span.start);
285             int errorColumn = GetErrorColumn(cast<int>(token.match.begin - lexer.Start()));
286             return "error in \'" + systemId + "\' at line " + ToString(span.line) + " column " + ToString(errorColumn);
287         }
288         private TrivialLexer& lexer;
289         private XmlContentHandler* contentHandler;
290         private Stack<ustring> tagStack;
291         private ustring currentTagName;
292         private Stack<ustring> attValueStack;
293         private ustring attValue;
294         private Stack<ustring> namespaceUriStack;
295         private ustring currentNamespaceUri;
296         private Stack<ustring> namespacePrefixStack;
297         private ustring currentNamespacePrefix;
298         private HashMap<ustringustring> namespacePrefixMap;
299         private Attributes attributes;
300         private HashMap<ustringEntity*> entityMap;
301         private List<UniquePtr<Entity>> entities;
302     }
303 } // namespace System.Xml