1 using System;
  2 using System.Collections;
  3 
  4 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xpath/XPathFunction.hpp' using cpp2cm version 1.0.0
  5 
  6 // this file has been semiautomatically generated from 'D:/work/soulng-project/sngxml/xpath/XPathFunction.cpp' using cpp2cm version 1.0.0
  7 
  8 namespace System.XPath
  9 {
 10     using NodeType = System.Dom.NodeType;
 11     public abstract class XPathFunction
 12     {
 13         public XPathFunction(const ustring& name_int minArity_int maxArity_) : 
 14             name(name_)minArity(minArity_)maxArity(maxArity_)
 15         {
 16         }
 17         public virtual ~XPathFunction()
 18         {
 19         }
 20         public const ustring& Name() const
 21         {
 22             return name;
 23         }
 24         public int MinArity() const
 25         {
 26             return minArity;
 27         }
 28         public int MaxArity() const
 29         {
 30             return maxArity;
 31         }
 32         public abstract UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments);
 33         private ustring name;
 34         private int minArity;
 35         private int maxArity;
 36     }
 37     public class ElementAndDocumentStringValueComputer : System.Dom.Visitor
 38     {
 39         public ustring stringValue;
 40         public override void Visit(System.Dom.Text* text)
 41         {
 42             stringValue.Append(text->Data());
 43         }
 44     }
 45     public ustring StringValue(System.Dom.Node* node)
 46     {
 47         switch (node->GetNodeType())
 48         {
 49             case NodeType.documentNode: case NodeType.elementNode:
 50             {
 51                 ElementAndDocumentStringValueComputer stringValueComputer;
 52                 node->Accept(stringValueComputer);
 53                 return stringValueComputer.stringValue;
 54             }
 55             case NodeType.attributeNode:
 56             {
 57                 System.Dom.Attr* attr = cast<System.Dom.Attr*>(node);
 58                 return attr->Value();
 59             }
 60             case NodeType.processingInstructionNode:
 61             {
 62                 System.Dom.ProcessingInstruction* pi = cast<System.Dom.ProcessingInstruction*>(node);
 63                 return pi->Data();
 64             }
 65             case NodeType.commentNode:
 66             {
 67                 System.Dom.Comment* comment = cast<System.Dom.Comment*>(node);
 68                 return comment->Data();
 69             }
 70             case NodeType.textNode:
 71             {
 72                 System.Dom.Text* text = cast<System.Dom.Text*>(node);
 73                 return text->Data();
 74             }
 75             case NodeType.cdataSectionNode:
 76             {
 77                 System.Dom.CDataSection* cdataSection = cast<System.Dom.CDataSection*>(node);
 78                 return cdataSection->Data();
 79             }
 80         }
 81         return ustring();
 82     }
 83     public class XPathBooleanFunction : XPathFunction
 84     {
 85         public XPathBooleanFunction() : 
 86             base(u"boolean"11)
 87         {
 88         }
 89         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
 90         {
 91             if (arguments.Count() != 1)
 92             {
 93                 throw Exception("sngxml::xpath::boolean() function requires one argument");
 94             }
 95             XPathObject* argument = arguments[0];
 96             switch (argument->Type())
 97             {
 98                 case XPathObjectType.boolean:
 99                 {
100                     XPathBoolean* arg = cast<XPathBoolean*>(argument);
101                     return UniquePtr<XPathObject>(new XPathBoolean(arg->Value()));
102                 }
103                 case XPathObjectType.number:
104                 {
105                     XPathNumber* arg = cast<XPathNumber*>(argument);
106                     return UniquePtr<XPathObject>(new XPathBoolean(arg->Value() != 0));
107                 }
108                 case XPathObjectType.nodeSet:
109                 {
110                     XPathNodeSet* arg = cast<XPathNodeSet*>(argument);
111                     return UniquePtr<XPathObject>(new XPathBoolean(arg->Length() != 0));
112                 }
113                 case XPathObjectType.string:
114                 {
115                     XPathString* arg = cast<XPathString*>(argument);
116                     return UniquePtr<XPathObject>(new XPathBoolean(!arg->Value().IsEmpty()));
117                 }
118             }
119             return UniquePtr<XPathObject>(new XPathBoolean(false));
120         }
121     }
122     public class XPathNumberFunction : XPathFunction
123     {
124         public XPathNumberFunction() : 
125             base(u"number"01)
126         {
127         }
128         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
129         {
130             XPathObject* argument = null;
131             XPathNodeSet nodeSet;
132             if (arguments.IsEmpty())
133             {
134                 nodeSet.Add(context.Node());
135                 argument = &nodeSet;
136             }
137             else
138             {
139                 if (arguments.Count() != 1)
140                 {
141                     throw Exception("sngxml::xpath::number() function requires zero or one arguments");
142                 }
143                 argument = arguments[0];
144             }
145             switch (argument->Type())
146             {
147                 case XPathObjectType.number:
148                 {
149                     XPathNumber* number = cast<XPathNumber*>(argument);
150                     return UniquePtr<XPathObject>(new XPathNumber(number->Value()));
151                 }
152                 case XPathObjectType.string:
153                 {
154                     XPathString* string = cast<XPathString*>(argument);
155                     double result = ParseDouble(ToUtf8(Trim(string->Value())));
156                     return UniquePtr<XPathObject>(new XPathNumber(result));
157                 }
158                 case XPathObjectType.boolean:
159                 {
160                     XPathBoolean* boolean = cast<XPathBoolean*>(argument);
161                     double result = 0;
162                     if (boolean->Value())
163                     {
164                         result = 1;
165                     }
166                     return UniquePtr<XPathObject>(new XPathNumber(result));
167                 }
168                 case XPathObjectType.nodeSet:
169                 {
170                     XPathFunction* stringFunction = GetXPathLibraryFunction(u"string");
171                     List<XPathObject*> stringArgs;
172                     stringArgs.Add(argument);
173                     UniquePtr<XPathObject> asString = stringFunction->Evaluate(contextstringArgs);
174                     if (asString->Type() != XPathObjectType.string)
175                     {
176                         throw Exception("string result expected");
177                     }
178                     XPathString* string = cast<XPathString*>(asString.Get());
179                     double result = ParseDouble(ToUtf8(Trim(string->Value())));
180                     return UniquePtr<XPathObject>(new XPathNumber(result));
181                 }
182             }
183             throw Exception("invalid argument to System.XPath.number()() function");
184             return UniquePtr<XPathObject>();
185         }
186     }
187     public class XPathStringFunction : XPathFunction
188     {
189         public XPathStringFunction() : 
190             base(u"string"01)
191         {
192         }
193         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
194         {
195             XPathObject* argument = null;
196             XPathNodeSet nodeSet;
197             if (arguments.IsEmpty())
198             {
199                 nodeSet.Add(context.Node());
200                 argument = &nodeSet;
201             }
202             else
203             {
204                 if (arguments.Count() != 1)
205                 {
206                     throw Exception("System.XPath.string() function requires zero or one arguments");
207                 }
208                 argument = arguments[0];
209             }
210             switch (argument->Type())
211             {
212                 case XPathObjectType.nodeSet:
213                 {
214                     XPathNodeSet* nodeSet = cast<XPathNodeSet*>(argument);
215                     if (nodeSet->Length() == 0)
216                     {
217                         return UniquePtr<XPathObject>(new XPathString(ustring()));
218                     }
219                     else
220                     {
221                         System.Dom.Node* node = (*nodeSet)[0];
222                         return UniquePtr<XPathObject>(new XPathString(StringValue(node)));
223                     }
224                 }
225                 case XPathObjectType.number:
226                 {
227                     XPathNumber* number = cast<XPathNumber*>(argument);
228                     return UniquePtr<XPathObject>(new XPathString(ToUtf32(ToString(number->Value()))));
229                 }
230                 case XPathObjectType.boolean:
231                 {
232                     XPathBoolean* boolean = cast<XPathBoolean*>(argument);
233                     ustring val = u"true";
234                     if (!boolean->Value())
235                     {
236                         val = u"false";
237                     }
238                     return UniquePtr<XPathObject>(new XPathString(val));
239                 }
240                 case XPathObjectType.string:
241                 {
242                     XPathString* string = cast<XPathString*>(argument);
243                     return UniquePtr<XPathObject>(new XPathString(string->Value()));
244                 }
245             }
246             throw Exception("invalid argument to System.XPath.string() function");
247             return UniquePtr<XPathObject>();
248         }
249     }
250     public class XPathLastFunction : XPathFunction
251     {
252         public XPathLastFunction() : 
253             base(u"last"00)
254         {
255         }
256         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
257         {
258             if (!arguments.IsEmpty())
259             {
260                 throw Exception("sngxml::xpath::last() function requires no arguments");
261             }
262             return UniquePtr<XPathObject>(new XPathNumber(context.Size()));
263         }
264     }
265     public class XPathPositionFunction : XPathFunction
266     {
267         public XPathPositionFunction() : 
268             base(u"position"00)
269         {
270         }
271         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
272         {
273             if (!arguments.IsEmpty())
274             {
275                 throw Exception("System.XPath.position() function requires no arguments");
276             }
277             return UniquePtr<XPathObject>(new XPathNumber(context.Position()));
278         }
279     }
280     public class XPathCountFunction : XPathFunction
281     {
282         public XPathCountFunction() : 
283             base(u"count"11)
284         {
285         }
286         public override UniquePtr<XPathObject> Evaluate(XPathContext& contextList<XPathObject*>& arguments)
287         {
288             if (arguments.Count() != 1)
289             {
290                 throw Exception("System.XPath.count() function requires one node-set argument");
291             }
292             else if (arguments.Count() == 1)
293             {
294                 XPathObject* arg = arguments[0];
295                 if (arg->Type() != XPathObjectType.nodeSet)
296                 {
297                     throw Exception("sngxml::xpath::count() function requires one node-set argument");
298                 }
299             }
300             XPathNodeSet* nodeSet = cast<XPathNodeSet*>(arguments[0]);
301             return UniquePtr<XPathObject>(new XPathNumber(nodeSet->Length()));
302         }
303     }
304     public class XPathFunctionLibrary
305     {
306         static XPathFunctionLibrary() : instance(new XPathFunctionLibrary())
307         {
308         }
309         private XPathFunctionLibrary()
310         {
311             functions.Add(UniquePtr<XPathFunction>(new XPathBooleanFunction()));
312             functions.Add(UniquePtr<XPathFunction>(new XPathNumberFunction()));
313             functions.Add(UniquePtr<XPathFunction>(new XPathStringFunction()));
314             functions.Add(UniquePtr<XPathFunction>(new XPathLastFunction()));
315             functions.Add(UniquePtr<XPathFunction>(new XPathPositionFunction()));
316             functions.Add(UniquePtr<XPathFunction>(new XPathCountFunction()));
317             for (const UniquePtr<XPathFunction>& function : functions)
318             {
319                 functionMap[function->Name()] = function.Get();
320             }
321         }
322         public static XPathFunctionLibrary& Instance()
323         {
324             return *instance;
325         }
326         public static UniquePtr<XPathFunctionLibrary> instance;
327         public XPathFunction* GetFunction(const ustring& functionName)
328         {
329             HashMap<ustringXPathFunction*>.ConstIterator it = functionMap.CFind(functionName);
330             if (it != functionMap.CEnd())
331             {
332                 return it->second;
333             }
334             else
335             {
336                 throw Exception("sngxml::xpath function \'" + ToUtf8(functionName) + "\' not found");
337             }
338         }
339         private HashMap<ustringXPathFunction*> functionMap;
340         private List<UniquePtr<XPathFunction>> functions;
341     }
342     public XPathFunction* GetXPathLibraryFunction(const ustring& functionName)
343     {
344         return XPathFunctionLibrary.Instance().GetFunction(functionName);
345     }
346 } // namespace System.XPath