|
1 // pod_lexer.cpp |
|
2 // |
|
3 // Copyright (c) 2009 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include "pod_lexer.h" |
|
14 |
|
15 |
|
16 TPodLexer::TPodLexer(const TDesC& aString) |
|
17 : iLex(aString), iAttributes(0), iAttributeStackIndex(0) |
|
18 { |
|
19 } |
|
20 |
|
21 void TPodLexer::NextTokenL(TPtrC& aToken, TTokenType& aTokenType, TUint& aAttributes, TBool& aEop, TBool& aEos) |
|
22 { |
|
23 aTokenType = ETextBlock; |
|
24 iScratch.Zero(); |
|
25 TBool finished(EFalse); |
|
26 TBool setAttributes(ETrue); |
|
27 while (!iLex.Eos() && !finished && (iScratch.Length() < (iScratch.MaxLength() - 1))) |
|
28 { |
|
29 iLex.Mark(); |
|
30 TUint16 sequenceIdentifier; |
|
31 if ((iAttributeStackIndex > 0) && (iLex.Peek() == '>')) |
|
32 { |
|
33 if (iScratch.Length() > 0) |
|
34 { |
|
35 aAttributes = iAttributes; |
|
36 setAttributes = EFalse; |
|
37 finished = ETrue; |
|
38 } |
|
39 else |
|
40 { |
|
41 iLex.Get(); |
|
42 aTokenType = EAttributePop; |
|
43 aAttributes = PopAttribute(); |
|
44 setAttributes = EFalse; |
|
45 finished = ETrue; |
|
46 } |
|
47 } |
|
48 else if (IsInteriorSequenceStart(sequenceIdentifier)) |
|
49 { |
|
50 if (iScratch.Length() > 0) |
|
51 { |
|
52 iLex.UnGetToMark(); |
|
53 finished = ETrue; |
|
54 } |
|
55 else |
|
56 { |
|
57 switch (sequenceIdentifier) |
|
58 { |
|
59 case 'B': |
|
60 PushAttribute(EBold); |
|
61 aAttributes = EBold; |
|
62 setAttributes = EFalse; |
|
63 aTokenType = EAttributePush; |
|
64 finished = ETrue; |
|
65 break; |
|
66 case 'C': |
|
67 PushAttribute(ECode); |
|
68 aAttributes = ECode; |
|
69 setAttributes = EFalse; |
|
70 aTokenType = EAttributePush; |
|
71 finished = ETrue; |
|
72 break; |
|
73 case 'E': |
|
74 if (iLex.Remainder().Length() >= 3) |
|
75 { |
|
76 if (iLex.Remainder().Left(3) == _L("gt>")) |
|
77 { |
|
78 iLex.Inc(3); |
|
79 iScratch.Append('>'); |
|
80 } |
|
81 else if (iLex.Remainder().Left(3) == _L("lt>")) |
|
82 { |
|
83 iLex.Inc(3); |
|
84 iScratch.Append('<'); |
|
85 } |
|
86 else |
|
87 { |
|
88 TUint num; |
|
89 TInt err = iLex.Val(num); |
|
90 if (err == KErrNone) |
|
91 { |
|
92 iScratch.Append(num); |
|
93 } |
|
94 else |
|
95 { |
|
96 User::Leave(err); |
|
97 } |
|
98 } |
|
99 } |
|
100 break; |
|
101 case 'F': |
|
102 PushAttribute(EFileName); |
|
103 aAttributes = EFileName; |
|
104 setAttributes = EFalse; |
|
105 aTokenType = EAttributePush; |
|
106 finished = ETrue; |
|
107 break; |
|
108 case 'I': |
|
109 PushAttribute(EItalic); |
|
110 aAttributes = EItalic; |
|
111 setAttributes = EFalse; |
|
112 aTokenType = EAttributePush; |
|
113 finished = ETrue; |
|
114 break; |
|
115 case 'L': |
|
116 iLex.Mark(); |
|
117 SkipToClosingAngleBracket(); |
|
118 iLex.UnGet(); |
|
119 iScratch.Copy(iLex.MarkedToken()); |
|
120 iLex.Get(); |
|
121 aTokenType = ELink; |
|
122 finished = ETrue; |
|
123 break; |
|
124 case 'S': |
|
125 case 'X': |
|
126 PushAttribute(ENull); |
|
127 aAttributes = ENull; |
|
128 setAttributes = EFalse; |
|
129 aTokenType = EAttributePush; |
|
130 finished = ETrue; |
|
131 break; |
|
132 case 'Z': |
|
133 if (iLex.Peek() == '>') |
|
134 { |
|
135 iLex.Inc(); |
|
136 iLex.Mark(); |
|
137 } |
|
138 else |
|
139 { |
|
140 User::Leave(KErrArgument); |
|
141 } |
|
142 break; |
|
143 } |
|
144 } |
|
145 } |
|
146 else |
|
147 { |
|
148 iScratch.Append(iLex.Get()); |
|
149 } |
|
150 } |
|
151 |
|
152 if (setAttributes) |
|
153 { |
|
154 aAttributes = iAttributes; |
|
155 } |
|
156 aToken.Set(iScratch); |
|
157 aEop = Eop(); |
|
158 aEos = iLex.Eos(); |
|
159 } |
|
160 |
|
161 TInt TPodLexer::SkipToClosingAngleBracket() |
|
162 { |
|
163 TInt numSkippedChars = 0; |
|
164 while (!iLex.Eos()) |
|
165 { |
|
166 TUint16 sequenceIdentifier; |
|
167 if (IsInteriorSequenceStart(sequenceIdentifier)) |
|
168 { |
|
169 numSkippedChars = SkipToClosingAngleBracket(); |
|
170 } |
|
171 else if (iLex.Get() == '>') |
|
172 { |
|
173 break; |
|
174 } |
|
175 else |
|
176 { |
|
177 ++numSkippedChars; |
|
178 } |
|
179 } |
|
180 return numSkippedChars; |
|
181 } |
|
182 |
|
183 TBool TPodLexer::Eop() |
|
184 { |
|
185 _LIT(KParagraphEnd, "\r\n\r\n"); |
|
186 return ((iLex.Remainder().Length() >= 4) && (iLex.Remainder().Left(4) == KParagraphEnd)); |
|
187 } |
|
188 |
|
189 TBool TPodLexer::IsInteriorSequenceStart(TUint16& aSequenceIdentifier) |
|
190 { |
|
191 if (iLex.Remainder().Length() >= 2) |
|
192 { |
|
193 TUint16 first = iLex.Get(); |
|
194 TUint16 second = iLex.Get(); |
|
195 if (second == '<') |
|
196 { |
|
197 switch (first) |
|
198 { |
|
199 case 'B': |
|
200 case 'C': |
|
201 case 'E': |
|
202 case 'F': |
|
203 case 'I': |
|
204 case 'L': |
|
205 case 'S': |
|
206 case 'X': |
|
207 case 'Z': |
|
208 aSequenceIdentifier = first; |
|
209 return ETrue; |
|
210 } |
|
211 } |
|
212 iLex.Inc(-2); |
|
213 } |
|
214 return EFalse; |
|
215 } |
|
216 |
|
217 void TPodLexer::PushAttribute(TAttribute aAttribute) |
|
218 { |
|
219 iAttributes |= aAttribute; |
|
220 iAttributeStack[iAttributeStackIndex++] = aAttribute; |
|
221 } |
|
222 |
|
223 TPodLexer::TAttribute TPodLexer::PopAttribute() |
|
224 { |
|
225 TAttribute poppedAttribute = iAttributeStack[--iAttributeStackIndex]; |
|
226 iAttributes &= ~poppedAttribute; |
|
227 return poppedAttribute; |
|
228 } |
|
229 |