1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5
6
7
8
9
10 namespace System.Lex
11 {
12 public class XmlParsingLog : ParsingLog
13 {
14 public XmlParsingLog(StreamWriter& stream_) :
15 base(), formatter(stream_)
16 {
17 formatter.SetIndentSize(1);
18 }
19 public XmlParsingLog(StreamWriter& stream_, int maxLineLength_) :
20 base(maxLineLength_), formatter(stream_)
21 {
22 formatter.SetIndentSize(1);
23 }
24 public CodeFormatter& Formatter()
25 {
26 return formatter;
27 }
28 public void WriteElement(const ustring& elementName, const ustring& elementContent)
29 {
30 ustring converted = XmlEscape(elementContent);
31 int convertedLength = cast<int>(converted.Length());
32 int lineLength = 2 * cast<int>(elementName.Length()) + 5 + convertedLength;
33 ustring s = converted;
34 if (lineLength > MaxLineLength())
35 {
36 lineLength = lineLength + 3;
37 s = converted.Substring(0, Max(cast<int>(0), convertedLength - (lineLength - MaxLineLength()))) + u"...";
38 }
39 Write(u"<" + elementName + u">" + s + u"</" + elementName + u">");
40 }
41 public void Write(const ustring& s)
42 {
43 formatter.WriteLine(ToUtf8(s));
44 }
45 public override void IncIndent()
46 {
47 formatter.IncIndent();
48 }
49 public override void DecIndent()
50 {
51 formatter.DecIndent();
52 }
53 public override void WriteBeginRule(const ustring& ruleName)
54 {
55 Write(u"<" + ruleName + u">");
56 }
57 public override void WriteEndRule(const ustring& ruleName)
58 {
59 Write(u"</" + ruleName + u">");
60 }
61 public override void WriteTry(const ustring& s)
62 {
63 WriteElement(u"try", s);
64 }
65 public override void WriteSuccess(const ustring& match)
66 {
67 WriteElement(u"success", match);
68 }
69 public override void WriteFail()
70 {
71 Write(u"<fail/>");
72 }
73 private CodeFormatter formatter;
74 }
75 public ustring XmlHexEscape(uchar c)
76 {
77 StringWriter writer;
78 writer << "&#x" << ToHexString(cast<uint>(c)) << ";";
79 return ToUtf32(writer.GetString());
80 }
81 public ustring XmlCharStr(uchar c)
82 {
83 switch (c)
84 {
85 case '&': return u"&";
86 case '<': return u"<";
87 case '>': return u">";
88 case '\a': return u"\\a";
89 case '\b': return u"\\b";
90 case '\f': return u"\\f";
91 case '\n': return u"\\n";
92 case '\r': return u"\\r";
93 case '\t': return u"\\t";
94 case '\v': return u"\\v";
95 default:
96 {
97 if ((cast<int>(c) >= 32 && cast<int>(c) <= 126))
98 {
99 return ustring(c, 1);
100 }
101 else
102 {
103 return XmlHexEscape(c);
104 }
105 }
106 }
107 return ustring();
108 }
109 public ustring XmlEscape(const ustring& s)
110 {
111 ustring result;
112 result.Reserve(2 * s.Length());
113 String<uchar>.ConstIterator e = s.CEnd();
114 for (String<uchar>.ConstIterator i = s.CBegin(); i != e; ++i;)
115 {
116 result.Append(XmlCharStr(*i));
117 }
118 return result;
119 }
120 }