1 #include "XmlUniformiser.h"
2
3
4 int
notEqualIndex(std::string expectedXml,std::string actualXml)5 notEqualIndex( std::string expectedXml,
6 std::string actualXml )
7 {
8 unsigned int index = 0;
9 while ( index < actualXml.length() &&
10 index < expectedXml.length() &&
11 actualXml[index] == expectedXml[index] )
12 ++index;
13
14 return index;
15 }
16
17
18 /// Asserts that two XML string are equivalent.
19 void
checkXmlEqual(std::string expectedXml,std::string actualXml,CPPUNIT_NS::SourceLine sourceLine)20 checkXmlEqual( std::string expectedXml,
21 std::string actualXml,
22 CPPUNIT_NS::SourceLine sourceLine )
23 {
24 std::string expected = XmlUniformiser( expectedXml ).stripped();
25 std::string actual = XmlUniformiser( actualXml ).stripped();
26
27 if ( expected == actual )
28 return;
29
30 int index = notEqualIndex( expected, actual );
31 CPPUNIT_NS::OStringStream message;
32 message << "differ at index: " << index << "\n"
33 << "expected: " << expected.substr(index) << "\n"
34 << "but was : " << actual.substr( index );
35 CPPUNIT_NS::Asserter::failNotEqual( expected,
36 actual,
37 sourceLine,
38 message.str() );
39 }
40
41
42
XmlUniformiser(const std::string & xml)43 XmlUniformiser::XmlUniformiser( const std::string &xml ) :
44 m_index( 0 ),
45 m_xml( xml )
46 {
47 }
48
49
50 std::string
stripped()51 XmlUniformiser::stripped()
52 {
53 while ( isValidIndex() )
54 {
55 skipSpaces();
56 if ( startsWith( "<?" ) )
57 skipProcessed();
58 else if ( startsWith( "<!--" ) )
59 skipComment();
60 else if ( startsWith( "<" ) )
61 copyElement();
62 else
63 copyElementContent();
64 }
65 return m_stripped;
66 }
67
68
69 void
skipSpaces()70 XmlUniformiser::skipSpaces()
71 {
72 while ( isSpace() )
73 skipNext();
74 }
75
76
77 bool
isSpace(char c)78 XmlUniformiser::isSpace( char c )
79 {
80 return c < 33;
81 }
82
83
84 bool
isSpace()85 XmlUniformiser::isSpace()
86 {
87 return isValidIndex() && isSpace( m_xml[m_index] );
88 }
89
90
91 bool
isValidIndex()92 XmlUniformiser::isValidIndex()
93 {
94 return m_index < m_xml.length();
95 }
96
97
98 void
skipNext(int count)99 XmlUniformiser::skipNext( int count )
100 {
101 while ( count-- > 0 )
102 ++m_index;
103 }
104
105
106 void
copyNext(int count)107 XmlUniformiser::copyNext( int count )
108 {
109 while ( count-- > 0 && isValidIndex() )
110 m_stripped += m_xml[ m_index++ ];
111 }
112
113
114 bool
startsWith(std::string expected)115 XmlUniformiser::startsWith( std::string expected )
116 {
117 std::string actual = m_xml.substr( m_index, expected.length() );
118 return actual == expected;
119 }
120
121
122 void
skipProcessed()123 XmlUniformiser::skipProcessed()
124 {
125 while ( isValidIndex() && !startsWith( "?>" ) )
126 skipNext();
127 if ( isValidIndex() )
128 skipNext( 2 );
129 }
130
131
132 void
skipComment()133 XmlUniformiser::skipComment()
134 {
135 while ( isValidIndex() && !startsWith( "-->" ) )
136 skipNext();
137 if ( isValidIndex() )
138 skipNext( 3 );
139 }
140
141
142 void
copyElement()143 XmlUniformiser::copyElement()
144 {
145 copyElementName();
146 copyElementAttributes();
147 }
148
149
150 void
copyElementName()151 XmlUniformiser::copyElementName()
152 {
153 while ( isValidIndex() &&
154 !( isSpace() || startsWith( ">" ) ) )
155 copyNext();
156 }
157
158
159 void
copyElementAttributes()160 XmlUniformiser::copyElementAttributes()
161 {
162 do
163 {
164 bool hadSpace = isSpace();
165 skipSpaces();
166 if ( startsWith( ">" ) )
167 break;
168
169 if ( hadSpace )
170 m_stripped += ' ';
171
172 copyAttributeName();
173 skipSpaces();
174 if ( startsWith( "=" ) )
175 {
176 copyNext();
177 copyAttributeValue();
178 }
179 else // attribute should always be valued, ne ?
180 m_stripped += ' ';
181 }
182 while ( isValidIndex() );
183 copyNext();
184 }
185
186
187 void
copyAttributeName()188 XmlUniformiser::copyAttributeName()
189 {
190 while ( isValidIndex() && !isEndOfAttributeName() )
191 copyNext();
192 }
193
194
195 bool
isEndOfAttributeName()196 XmlUniformiser::isEndOfAttributeName()
197 {
198 return isSpace() || startsWith( ">" ) || startsWith( "=" );
199 }
200
201
202 void
copyAttributeValue()203 XmlUniformiser::copyAttributeValue()
204 {
205 skipSpaces();
206 copyUntilDoubleQuote();
207 copyUntilDoubleQuote();
208 }
209
210
211 void
copyUntilDoubleQuote()212 XmlUniformiser::copyUntilDoubleQuote()
213 {
214 while ( isValidIndex() && !startsWith("\"") )
215 copyNext();
216 copyNext(); // '"'
217 }
218
219
220 void
copyElementContent()221 XmlUniformiser::copyElementContent()
222 {
223 while ( isValidIndex() && !startsWith( "<" ) )
224 copyNext();
225 removeTrailingSpaces();
226 }
227
228
229 void
removeTrailingSpaces()230 XmlUniformiser::removeTrailingSpaces()
231 {
232 int index = m_stripped.length();
233 while ( index-1 > 0 && isSpace( m_stripped[index-1] ) )
234 --index;
235 m_stripped.resize( index );
236 }
237