Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "sal/config.h"
21 : :
22 : : #include <cassert>
23 : : #include <climits>
24 : : #include <cstddef>
25 : :
26 : : #include "com/sun/star/container/NoSuchElementException.hpp"
27 : : #include "com/sun/star/uno/Reference.hxx"
28 : : #include "com/sun/star/uno/RuntimeException.hpp"
29 : : #include "com/sun/star/uno/XInterface.hpp"
30 : : #include "osl/file.h"
31 : : #include "rtl/oustringostreaminserter.hxx"
32 : : #include "rtl/string.h"
33 : : #include "rtl/ustring.h"
34 : : #include "rtl/ustring.hxx"
35 : : #include "sal/log.hxx"
36 : : #include "sal/types.h"
37 : : #include "xmlreader/pad.hxx"
38 : : #include "xmlreader/span.hxx"
39 : : #include "xmlreader/xmlreader.hxx"
40 : :
41 : : namespace xmlreader {
42 : :
43 : : namespace {
44 : :
45 : : namespace css = com::sun::star;
46 : :
47 : 129122335 : bool isSpace(char c) {
48 [ + + ]: 129122335 : switch (c) {
49 : : case '\x09':
50 : : case '\x0A':
51 : : case '\x0D':
52 : : case ' ':
53 : 19662276 : return true;
54 : : default:
55 : 129122335 : return false;
56 : : }
57 : : }
58 : :
59 : : }
60 : :
61 : 49377 : XmlReader::XmlReader(rtl::OUString const & fileUrl)
62 : : SAL_THROW((
63 : : css::container::NoSuchElementException, css::uno::RuntimeException)):
64 [ + - ][ + - ]: 49763 : fileUrl_(fileUrl)
[ + - ][ + - ]
[ + - ][ + - ]
65 : : {
66 : : oslFileError e = osl_openFile(
67 [ + - ]: 49377 : fileUrl_.pData, &fileHandle_, osl_File_OpenFlag_Read);
68 [ + + - ]: 49377 : switch (e)
69 : : {
70 : : case osl_File_E_None:
71 : 48995 : break;
72 : : case osl_File_E_NOENT:
73 : : throw css::container::NoSuchElementException(
74 [ + - ]: 382 : fileUrl_, css::uno::Reference< css::uno::XInterface >());
75 : : default:
76 : : throw css::uno::RuntimeException(
77 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cannot open ")) +
78 : : fileUrl_ + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(": ")) +
79 : : rtl::OUString::valueOf(static_cast< sal_Int32 >(e))),
80 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
[ # # ]
81 : : }
82 [ + - ]: 48995 : e = osl_getFileSize(fileHandle_, &fileSize_);
83 [ + - ]: 48995 : if (e == osl_File_E_None) {
84 : : e = osl_mapFile(
85 : : fileHandle_, &fileAddress_, fileSize_, 0,
86 [ + - ]: 48995 : osl_File_MapFlag_WillNeed);
87 : : }
88 [ + + ]: 48995 : if (e != osl_File_E_None) {
89 [ + - ]: 4 : oslFileError e2 = osl_closeFile(fileHandle_);
90 : : if (e2 != osl_File_E_None) {
91 : : SAL_WARN(
92 : : "xmlreader",
93 : : "osl_closeFile of \"" << fileUrl_ << "\" failed with " << +e2);
94 : : }
95 : : throw css::uno::RuntimeException(
96 : : ("cannot mmap " + fileUrl_ + " (" +
97 : : rtl::OUString::valueOf(static_cast< sal_Int32 >(e)) + ")"),
98 [ + - ]: 4 : css::uno::Reference< css::uno::XInterface >());
99 : : }
100 : : namespaceIris_.push_back(
101 : : Span(
102 : : RTL_CONSTASCII_STRINGPARAM(
103 [ + - ]: 48991 : "http://www.w3.org/XML/1998/namespace")));
104 : : namespaces_.push_back(
105 [ + - ]: 48991 : NamespaceData(Span(RTL_CONSTASCII_STRINGPARAM("xml")), NAMESPACE_XML));
106 : 48991 : pos_ = static_cast< char * >(fileAddress_);
107 : 48991 : end_ = pos_ + fileSize_;
108 : 48991 : state_ = STATE_CONTENT;
109 : 48991 : firstAttribute_ = true;
110 : 48991 : }
111 : :
112 [ + - ]: 48991 : XmlReader::~XmlReader() {
113 [ + - ]: 48991 : oslFileError e = osl_unmapMappedFile(fileHandle_, fileAddress_, fileSize_);
114 : : if (e != osl_File_E_None) {
115 : : SAL_WARN(
116 : : "xmlreader",
117 : : "osl_unmapMappedFile of \"" << fileUrl_ << "\" failed with " << +e);
118 : : }
119 [ + - ]: 48991 : e = osl_closeFile(fileHandle_);
120 : : if (e != osl_File_E_None) {
121 : : SAL_WARN(
122 : : "xmlreader",
123 : : "osl_closeFile of \"" << fileUrl_ << "\" failed with " << +e);
124 : : }
125 : 48991 : }
126 : :
127 : 137889 : int XmlReader::registerNamespaceIri(Span const & iri) {
128 : 137889 : int id = toNamespaceId(namespaceIris_.size());
129 : 137889 : namespaceIris_.push_back(iri);
130 [ + + ]: 137889 : if (iri.equals(
131 : : Span(
132 : : RTL_CONSTASCII_STRINGPARAM(
133 : 137889 : "http://www.w3.org/2001/XMLSchema-instance"))))
134 : : {
135 : : // Old user layer .xcu files used the xsi namespace prefix without
136 : : // declaring a corresponding namespace binding, see issue 77174; reading
137 : : // those files during migration would fail without this hack that can be
138 : : // removed once migration is no longer relevant (see
139 : : // configmgr::Components::parseModificationLayer):
140 : : namespaces_.push_back(
141 [ + - ]: 44449 : NamespaceData(Span(RTL_CONSTASCII_STRINGPARAM("xsi")), id));
142 : : }
143 : 137889 : return id;
144 : : }
145 : :
146 : 45305189 : XmlReader::Result XmlReader::nextItem(Text reportText, Span * data, int * nsId)
147 : : {
148 [ + + + + : 45305189 : switch (state_) {
+ ]
149 : : case STATE_CONTENT:
150 [ + + + - ]: 37757051 : switch (reportText) {
151 : : case TEXT_NONE:
152 : 31448195 : return handleSkippedText(data, nsId);
153 : : case TEXT_RAW:
154 : 4468880 : return handleRawText(data);
155 : : case TEXT_NORMALIZED:
156 : 1839976 : return handleNormalizedText(data);
157 : : }
158 : : case STATE_START_TAG:
159 : 14244 : return handleStartTag(nsId, data);
160 : : case STATE_END_TAG:
161 : 6294612 : return handleEndTag();
162 : : case STATE_EMPTY_ELEMENT_TAG:
163 : 1190487 : handleElementEnd();
164 : 1190487 : return RESULT_END;
165 : : default: // STATE_DONE
166 : 45304993 : return RESULT_DONE;
167 : : }
168 : : }
169 : :
170 : 36827420 : bool XmlReader::nextAttribute(int * nsId, Span * localName) {
171 : : assert(nsId != 0 && localName != 0);
172 [ + + ]: 36827420 : if (firstAttribute_) {
173 : 17511113 : currentAttribute_ = attributes_.begin();
174 : 17511113 : firstAttribute_ = false;
175 : : } else {
176 : 19316307 : ++currentAttribute_;
177 : : }
178 [ + - ][ + + ]: 36827420 : if (currentAttribute_ == attributes_.end()) {
179 : 17511113 : return false;
180 : : }
181 [ + + ]: 19316307 : if (currentAttribute_->nameColon == 0) {
182 : 602025 : *nsId = NAMESPACE_NONE;
183 : : *localName = Span(
184 : 602025 : currentAttribute_->nameBegin,
185 : 1204050 : currentAttribute_->nameEnd - currentAttribute_->nameBegin);
186 : : } else {
187 : : *nsId = getNamespaceId(
188 : : Span(
189 : 18714282 : currentAttribute_->nameBegin,
190 [ + - ]: 37428564 : currentAttribute_->nameColon - currentAttribute_->nameBegin));
191 : : *localName = Span(
192 : 18714282 : currentAttribute_->nameColon + 1,
193 : 37428564 : currentAttribute_->nameEnd - (currentAttribute_->nameColon + 1));
194 : : }
195 : 36827420 : return true;
196 : : }
197 : :
198 : 19272867 : Span XmlReader::getAttributeValue(bool fullyNormalize) {
199 : : return handleAttributeValue(
200 : 19272867 : currentAttribute_->valueBegin, currentAttribute_->valueEnd,
201 : 19272867 : fullyNormalize);
202 : : }
203 : :
204 : 21486410 : int XmlReader::getNamespaceId(Span const & prefix) const {
205 [ + - + - ]: 125577382 : for (NamespaceList::const_reverse_iterator i(namespaces_.rbegin());
[ + - ]
206 : 62788691 : i != namespaces_.rend(); ++i)
207 : : {
208 [ + - ][ + + ]: 62788691 : if (prefix.equals(i->prefix)) {
209 [ + - ]: 21486410 : return i->nsId;
210 : : }
211 : : }
212 : 21486410 : return NAMESPACE_UNKNOWN;
213 : : }
214 : :
215 : 38270 : rtl::OUString XmlReader::getUrl() const {
216 : 38270 : return fileUrl_;
217 : : }
218 : :
219 : 0 : void XmlReader::normalizeLineEnds(Span const & text) {
220 : 0 : char const * p = text.begin;
221 : 0 : sal_Int32 n = text.length;
222 : 0 : for (;;) {
223 : 0 : sal_Int32 i = rtl_str_indexOfChar_WithLength(p, n, '\x0D');
224 [ # # ]: 0 : if (i < 0) {
225 : 0 : break;
226 : : }
227 : 0 : pad_.add(p, i);
228 : 0 : p += i + 1;
229 : 0 : n -= i + 1;
230 [ # # ][ # # ]: 0 : if (n == 0 || *p != '\x0A') {
231 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM("\x0A"));
232 : : }
233 : : }
234 : 0 : pad_.add(p, n);
235 : 0 : }
236 : :
237 : 96656339 : void XmlReader::skipSpace() {
238 [ + + ]: 116318615 : while (isSpace(peek())) {
239 : 19662276 : ++pos_;
240 : : }
241 : 96656339 : }
242 : :
243 : 5758 : bool XmlReader::skipComment() {
244 [ + + ]: 5758 : if (rtl_str_shortenedCompare_WithLength(
245 : : pos_, end_ - pos_, RTL_CONSTASCII_STRINGPARAM("--"),
246 : 5758 : RTL_CONSTASCII_LENGTH("--")) !=
247 : : 0)
248 : : {
249 : 294 : return false;
250 : : }
251 : 5464 : pos_ += RTL_CONSTASCII_LENGTH("--");
252 : : sal_Int32 i = rtl_str_indexOfStr_WithLength(
253 : 5464 : pos_, end_ - pos_, RTL_CONSTASCII_STRINGPARAM("--"));
254 [ - + ]: 5464 : if (i < 0) {
255 : : throw css::uno::RuntimeException(
256 : : (rtl::OUString(
257 : : RTL_CONSTASCII_USTRINGPARAM(
258 : : "premature end (within comment) of ")) +
259 : : fileUrl_),
260 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
261 : : }
262 : 5464 : pos_ += i + RTL_CONSTASCII_LENGTH("--");
263 [ - + ]: 5464 : if (read() != '>') {
264 : : throw css::uno::RuntimeException(
265 : : (rtl::OUString(
266 : : RTL_CONSTASCII_USTRINGPARAM(
267 : : "illegal \"--\" within comment in ")) +
268 : : fileUrl_),
269 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
270 : : }
271 : 5758 : return true;
272 : : }
273 : :
274 : 48795 : void XmlReader::skipProcessingInstruction() {
275 : : sal_Int32 i = rtl_str_indexOfStr_WithLength(
276 : 48795 : pos_, end_ - pos_, RTL_CONSTASCII_STRINGPARAM("?>"));
277 [ - + ]: 48795 : if (i < 0) {
278 : : throw css::uno::RuntimeException(
279 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad '<?' in ")) +
280 : : fileUrl_),
281 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
282 : : }
283 : 48795 : pos_ += i + RTL_CONSTASCII_LENGTH("?>");
284 : 48795 : }
285 : :
286 : 10584 : void XmlReader::skipDocumentTypeDeclaration() {
287 : : // Neither is it checked that the doctypedecl is at the correct position in
288 : : // the document, nor that it is well-formed:
289 : 10584 : for (;;) {
290 : 10584 : char c = read();
291 [ - + + - : 10584 : switch (c) {
+ ]
292 : : case '\0': // i.e., EOF
293 : : throw css::uno::RuntimeException(
294 : : (rtl::OUString(
295 : : RTL_CONSTASCII_USTRINGPARAM(
296 : : "premature end (within DTD) of ")) +
297 : : fileUrl_),
298 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
299 : : case '"':
300 : : case '\'':
301 : : {
302 : : sal_Int32 i = rtl_str_indexOfChar_WithLength(
303 : 294 : pos_, end_ - pos_, c);
304 [ - + ]: 294 : if (i < 0) {
305 : : throw css::uno::RuntimeException(
306 : : (rtl::OUString(
307 : : RTL_CONSTASCII_USTRINGPARAM(
308 : : "premature end (within DTD) of ")) +
309 : : fileUrl_),
310 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
311 : : }
312 : 294 : pos_ += i + 1;
313 : : }
314 : 294 : break;
315 : : case '>':
316 : 294 : return;
317 : : case '[':
318 : 0 : for (;;) {
319 : 0 : c = read();
320 [ # # # # : 0 : switch (c) {
# ]
321 : : case '\0': // i.e., EOF
322 : : throw css::uno::RuntimeException(
323 : : (rtl::OUString(
324 : : RTL_CONSTASCII_USTRINGPARAM(
325 : : "premature end (within DTD) of ")) +
326 : : fileUrl_),
327 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
328 : : case '"':
329 : : case '\'':
330 : : {
331 : : sal_Int32 i = rtl_str_indexOfChar_WithLength(
332 : 0 : pos_, end_ - pos_, c);
333 [ # # ]: 0 : if (i < 0) {
334 : : throw css::uno::RuntimeException(
335 : : (rtl::OUString(
336 : : RTL_CONSTASCII_USTRINGPARAM(
337 : : "premature end (within DTD) of ")) +
338 : : fileUrl_),
339 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
340 : : }
341 : 0 : pos_ += i + 1;
342 : : }
343 : 0 : break;
344 : : case '<':
345 [ # # # # ]: 0 : switch (read()) {
346 : : case '\0': // i.e., EOF
347 : : throw css::uno::RuntimeException(
348 : : (rtl::OUString(
349 : : RTL_CONSTASCII_USTRINGPARAM(
350 : : "premature end (within DTD) of ")) +
351 : : fileUrl_),
352 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
353 : : case '!':
354 : 0 : skipComment();
355 : 0 : break;
356 : : case '?':
357 : 0 : skipProcessingInstruction();
358 : 0 : break;
359 : : default:
360 : 0 : break;
361 : : }
362 : 0 : break;
363 : : case ']':
364 : 0 : skipSpace();
365 [ # # ]: 0 : if (read() != '>') {
366 : : throw css::uno::RuntimeException(
367 : : (rtl::OUString(
368 : : RTL_CONSTASCII_USTRINGPARAM(
369 : : "missing \">\" of DTD in ")) +
370 : : fileUrl_),
371 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
372 : : }
373 : 0 : return;
374 : : default:
375 : 0 : break;
376 : : }
377 : : }
378 : : default:
379 : 9996 : break;
380 : : }
381 : : }
382 : : }
383 : :
384 : 294 : Span XmlReader::scanCdataSection() {
385 [ + - ]: 294 : if (rtl_str_shortenedCompare_WithLength(
386 : : pos_, end_ - pos_, RTL_CONSTASCII_STRINGPARAM("[CDATA["),
387 : 294 : RTL_CONSTASCII_LENGTH("[CDATA[")) !=
388 : : 0)
389 : : {
390 : 294 : return Span();
391 : : }
392 : 0 : pos_ += RTL_CONSTASCII_LENGTH("[CDATA[");
393 : 0 : char const * begin = pos_;
394 : : sal_Int32 i = rtl_str_indexOfStr_WithLength(
395 : 0 : pos_, end_ - pos_, RTL_CONSTASCII_STRINGPARAM("]]>"));
396 [ # # ]: 0 : if (i < 0) {
397 : : throw css::uno::RuntimeException(
398 : : (rtl::OUString(
399 : : RTL_CONSTASCII_USTRINGPARAM(
400 : : "premature end (within CDATA section) of ")) +
401 : : fileUrl_),
402 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
403 : : }
404 : 0 : pos_ += i + RTL_CONSTASCII_LENGTH("]]>");
405 : 294 : return Span(begin, i);
406 : : }
407 : :
408 : 57390147 : bool XmlReader::scanName(char const ** nameColon) {
409 : : assert(nameColon != 0 && *nameColon == 0);
410 : 389404525 : for (char const * begin = pos_;; ++pos_) {
411 [ + + + ]: 389404525 : switch (peek()) {
412 : : case '\0': // i.e., EOF
413 : : case '\x09':
414 : : case '\x0A':
415 : : case '\x0D':
416 : : case ' ':
417 : : case '/':
418 : : case '=':
419 : : case '>':
420 : 57390147 : return pos_ != begin;
421 : : case ':':
422 : 19194832 : *nameColon = pos_;
423 : 19194832 : break;
424 : : default:
425 : 312819546 : break;
426 : : }
427 : : }
428 : : }
429 : :
430 : 167097 : int XmlReader::scanNamespaceIri(char const * begin, char const * end) {
431 : : assert(begin != 0 && begin <= end);
432 [ + - ]: 167097 : Span iri(handleAttributeValue(begin, end, false));
433 [ + + ]: 562897 : for (NamespaceIris::size_type i = 0; i < namespaceIris_.size(); ++i) {
434 [ + - ][ + + ]: 526676 : if (namespaceIris_[i].equals(iri)) {
435 : 130876 : return toNamespaceId(i);
436 : : }
437 : : }
438 : 167097 : return XmlReader::NAMESPACE_UNKNOWN;
439 : : }
440 : :
441 : 40296 : char const * XmlReader::handleReference(char const * position, char const * end)
442 : : {
443 : : assert(position != 0 && *position == '&' && position < end);
444 : 40296 : ++position;
445 [ + + ]: 40296 : if (*position == '#') {
446 : 1920 : ++position;
447 : 1920 : sal_Int32 val = 0;
448 : : char const * p;
449 [ + - ]: 1920 : if (*position == 'x') {
450 : 1920 : ++position;
451 : 1920 : p = position;
452 : 9600 : for (;; ++position) {
453 : 9600 : char c = *position;
454 [ + - ][ + + ]: 9600 : if (c >= '0' && c <= '9') {
455 : 3520 : val = 16 * val + (c - '0');
456 [ + + ][ + - ]: 6080 : } else if (c >= 'A' && c <= 'F') {
457 : 4160 : val = 16 * val + (c - 'A') + 10;
458 [ - + ][ # # ]: 1920 : } else if (c >= 'a' && c <= 'f') {
459 : 0 : val = 16 * val + (c - 'a') + 10;
460 : : } else {
461 : 1920 : break;
462 : : }
463 [ - + ]: 7680 : if (val > 0x10FFFF) { // avoid overflow
464 : : throw css::uno::RuntimeException(
465 : : (rtl::OUString(
466 : : RTL_CONSTASCII_USTRINGPARAM(
467 : : "'&#x...' too large in ")) +
468 : : fileUrl_),
469 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
470 : : }
471 : : }
472 : : } else {
473 : 0 : p = position;
474 : 0 : for (;; ++position) {
475 : 0 : char c = *position;
476 [ # # ][ # # ]: 0 : if (c >= '0' && c <= '9') {
477 : 0 : val = 10 * val + (c - '0');
478 : : } else {
479 : 0 : break;
480 : : }
481 [ # # ]: 0 : if (val > 0x10FFFF) { // avoid overflow
482 : : throw css::uno::RuntimeException(
483 : : (rtl::OUString(
484 : : RTL_CONSTASCII_USTRINGPARAM(
485 : : "'&#...' too large in ")) +
486 : : fileUrl_),
487 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
488 : : }
489 : : }
490 : : }
491 [ + - ][ - + ]: 1920 : if (position == p || *position++ != ';') {
[ - + ]
492 : : throw css::uno::RuntimeException(
493 : : (rtl::OUString(
494 : : RTL_CONSTASCII_USTRINGPARAM("'&#...' missing ';' in ")) +
495 : : fileUrl_),
496 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
497 : : }
498 : : assert(val >= 0 && val <= 0x10FFFF);
499 [ - + ][ # # ]: 1920 : if ((val < 0x20 && val != 0x9 && val != 0xA && val != 0xD) ||
[ # # ][ # # ]
[ - + ][ # # ]
[ + - ][ - + ]
500 : : (val >= 0xD800 && val <= 0xDFFF) || val == 0xFFFE || val == 0xFFFF)
501 : : {
502 : : throw css::uno::RuntimeException(
503 : : (rtl::OUString(
504 : : RTL_CONSTASCII_USTRINGPARAM(
505 : : "character reference denoting invalid character in ")) +
506 : : fileUrl_),
507 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
508 : : }
509 : : char buf[4];
510 : : sal_Int32 len;
511 [ - + ]: 1920 : if (val < 0x80) {
512 : 0 : buf[0] = static_cast< char >(val);
513 : 0 : len = 1;
514 [ - + ]: 1920 : } else if (val < 0x800) {
515 : 0 : buf[0] = static_cast< char >((val >> 6) | 0xC0);
516 : 0 : buf[1] = static_cast< char >((val & 0x3F) | 0x80);
517 : 0 : len = 2;
518 [ + - ]: 1920 : } else if (val < 0x10000) {
519 : 1920 : buf[0] = static_cast< char >((val >> 12) | 0xE0);
520 : 1920 : buf[1] = static_cast< char >(((val >> 6) & 0x3F) | 0x80);
521 : 1920 : buf[2] = static_cast< char >((val & 0x3F) | 0x80);
522 : 1920 : len = 3;
523 : : } else {
524 : 0 : buf[0] = static_cast< char >((val >> 18) | 0xF0);
525 : 0 : buf[1] = static_cast< char >(((val >> 12) & 0x3F) | 0x80);
526 : 0 : buf[2] = static_cast< char >(((val >> 6) & 0x3F) | 0x80);
527 : 0 : buf[3] = static_cast< char >((val & 0x3F) | 0x80);
528 : 0 : len = 4;
529 : : }
530 [ + - ]: 1920 : pad_.addEphemeral(buf, len);
531 : 1920 : return position;
532 : : } else {
533 : : struct EntityRef {
534 : : char const * inBegin;
535 : : sal_Int32 inLength;
536 : : char const * outBegin;
537 : : sal_Int32 outLength;
538 : : };
539 : : static EntityRef const refs[] = {
540 : : { RTL_CONSTASCII_STRINGPARAM("amp;"),
541 : : RTL_CONSTASCII_STRINGPARAM("&") },
542 : : { RTL_CONSTASCII_STRINGPARAM("lt;"),
543 : : RTL_CONSTASCII_STRINGPARAM("<") },
544 : : { RTL_CONSTASCII_STRINGPARAM("gt;"),
545 : : RTL_CONSTASCII_STRINGPARAM(">") },
546 : : { RTL_CONSTASCII_STRINGPARAM("apos;"),
547 : : RTL_CONSTASCII_STRINGPARAM("'") },
548 : : { RTL_CONSTASCII_STRINGPARAM("quot;"),
549 : : RTL_CONSTASCII_STRINGPARAM("\"") } };
550 [ + - ]: 69372 : for (std::size_t i = 0; i < sizeof refs / sizeof refs[0]; ++i) {
551 [ + + ]: 69372 : if (rtl_str_shortenedCompare_WithLength(
552 : : position, end - position, refs[i].inBegin, refs[i].inLength,
553 : 69372 : refs[i].inLength) ==
554 : : 0)
555 : : {
556 : 38376 : position += refs[i].inLength;
557 : 38376 : pad_.add(refs[i].outBegin, refs[i].outLength);
558 : 38376 : return position;
559 : : }
560 : : }
561 : : throw css::uno::RuntimeException(
562 : : (rtl::OUString(
563 : : RTL_CONSTASCII_USTRINGPARAM("unknown entity reference in ")) +
564 : : fileUrl_),
565 [ # # ][ # # ]: 40296 : css::uno::Reference< css::uno::XInterface >());
566 : : }
567 : : }
568 : :
569 : 19439964 : Span XmlReader::handleAttributeValue(
570 : : char const * begin, char const * end, bool fullyNormalize)
571 : : {
572 : 19439964 : pad_.clear();
573 [ + + ]: 19439964 : if (fullyNormalize) {
574 [ + - ][ - + ]: 6401860 : while (begin != end && isSpace(*begin)) {
[ - + ]
575 : 0 : ++begin;
576 : : }
577 [ + - ][ - + ]: 6401860 : while (end != begin && isSpace(end[-1])) {
[ - + ]
578 : 0 : --end;
579 : : }
580 : 6401860 : char const * p = begin;
581 : : enum Space { SPACE_NONE, SPACE_SPAN, SPACE_BREAK };
582 : : // a single true space character can go into the current span,
583 : : // everything else breaks the span
584 : 6401860 : Space space = SPACE_NONE;
585 [ + + ]: 53278111 : while (p != end) {
586 [ - + - + ]: 46876251 : switch (*p) {
587 : : case '\x09':
588 : : case '\x0A':
589 : : case '\x0D':
590 [ # # # # ]: 0 : switch (space) {
591 : : case SPACE_NONE:
592 : 0 : pad_.add(begin, p - begin);
593 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
594 : 0 : space = SPACE_BREAK;
595 : 0 : break;
596 : : case SPACE_SPAN:
597 : 0 : pad_.add(begin, p - begin);
598 : 0 : space = SPACE_BREAK;
599 : 0 : break;
600 : : case SPACE_BREAK:
601 : 0 : break;
602 : : }
603 : 0 : begin = ++p;
604 : 0 : break;
605 : : case ' ':
606 [ + - - - ]: 8445 : switch (space) {
607 : : case SPACE_NONE:
608 : 8445 : ++p;
609 : 8445 : space = SPACE_SPAN;
610 : 8445 : break;
611 : : case SPACE_SPAN:
612 : 0 : pad_.add(begin, p - begin);
613 : 0 : begin = ++p;
614 : 0 : space = SPACE_BREAK;
615 : 0 : break;
616 : : case SPACE_BREAK:
617 : 0 : begin = ++p;
618 : 0 : break;
619 : : }
620 : 8445 : break;
621 : : case '&':
622 : 0 : pad_.add(begin, p - begin);
623 : 0 : p = handleReference(p, end);
624 : 0 : begin = p;
625 : 0 : space = SPACE_NONE;
626 : 0 : break;
627 : : default:
628 : 46867806 : ++p;
629 : 46867806 : space = SPACE_NONE;
630 : 46867806 : break;
631 : : }
632 : : }
633 : 6401860 : pad_.add(begin, p - begin);
634 : : } else {
635 : 13038104 : char const * p = begin;
636 [ + + ]: 156191767 : while (p != end) {
637 [ - - + + ]: 143153663 : switch (*p) {
638 : : case '\x09':
639 : : case '\x0A':
640 : 0 : pad_.add(begin, p - begin);
641 : 0 : begin = ++p;
642 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
643 : 0 : break;
644 : : case '\x0D':
645 : 0 : pad_.add(begin, p - begin);
646 : 0 : ++p;
647 [ # # ]: 0 : if (peek() == '\x0A') {
648 : 0 : ++p;
649 : : }
650 : 0 : begin = p;
651 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
652 : 0 : break;
653 : : case '&':
654 : 1920 : pad_.add(begin, p - begin);
655 : 1920 : p = handleReference(p, end);
656 : 1920 : begin = p;
657 : 1920 : break;
658 : : default:
659 : 143151743 : ++p;
660 : 143151743 : break;
661 : : }
662 : : }
663 : 13038104 : pad_.add(begin, p - begin);
664 : : }
665 : 19439964 : return pad_.get();
666 : : }
667 : :
668 : 19473867 : XmlReader::Result XmlReader::handleStartTag(int * nsId, Span * localName) {
669 : : assert(nsId != 0 && localName);
670 : 19473867 : char const * nameBegin = pos_;
671 : 19473867 : char const * nameColon = 0;
672 [ - + ]: 19473867 : if (!scanName(&nameColon)) {
673 : : throw css::uno::RuntimeException(
674 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad tag name in ")) +
675 : : fileUrl_),
676 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
677 : : }
678 : 19473867 : char const * nameEnd = pos_;
679 : 19473867 : NamespaceList::size_type inheritedNamespaces = namespaces_.size();
680 : 19473867 : bool hasDefaultNs = false;
681 : 19473867 : int defaultNsId = NAMESPACE_NONE;
682 : 19473867 : attributes_.clear();
683 : 19633096 : for (;;) {
684 : 39106963 : char const * p = pos_;
685 : 39106963 : skipSpace();
686 [ + + ][ + + ]: 39106963 : if (peek() == '/' || peek() == '>') {
[ + + ]
687 : : break;
688 : : }
689 [ + + ]: 19633292 : if (pos_ == p) {
690 : : throw css::uno::RuntimeException(
691 : : (rtl::OUString(
692 : : RTL_CONSTASCII_USTRINGPARAM(
693 : : "missing whitespace before attribute in ")) +
694 : : fileUrl_),
695 [ + - ][ + - ]: 196 : css::uno::Reference< css::uno::XInterface >());
696 : : }
697 : 19633096 : char const * attrNameBegin = pos_;
698 : 19633096 : char const * attrNameColon = 0;
699 [ - + ]: 19633096 : if (!scanName(&attrNameColon)) {
700 : : throw css::uno::RuntimeException(
701 : : (rtl::OUString(
702 : : RTL_CONSTASCII_USTRINGPARAM("bad attribute name in ")) +
703 : : fileUrl_),
704 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
705 : : }
706 : 19633096 : char const * attrNameEnd = pos_;
707 : 19633096 : skipSpace();
708 [ - + ]: 19633096 : if (read() != '=') {
709 : : throw css::uno::RuntimeException(
710 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("missing '=' in ")) +
711 : : fileUrl_),
712 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
713 : : }
714 : 19633096 : skipSpace();
715 : 19633096 : char del = read();
716 [ - + ][ + - ]: 19633096 : if (del != '\'' && del != '"') {
717 : : throw css::uno::RuntimeException(
718 : : (rtl::OUString(
719 : : RTL_CONSTASCII_USTRINGPARAM("bad attribute value in ")) +
720 : : fileUrl_),
721 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
722 : : }
723 : 19633096 : char const * valueBegin = pos_;
724 : 19633096 : sal_Int32 i = rtl_str_indexOfChar_WithLength(pos_, end_ - pos_, del);
725 [ - + ]: 19633096 : if (i < 0) {
726 : : throw css::uno::RuntimeException(
727 : : (rtl::OUString(
728 : : RTL_CONSTASCII_USTRINGPARAM(
729 : : "unterminated attribute value in ")) +
730 : : fileUrl_),
731 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
732 : : }
733 : 19633096 : char const * valueEnd = pos_ + i;
734 : 19633096 : pos_ += i + 1;
735 [ + + + + ]: 39872563 : if (attrNameColon == 0 &&
[ + + ]
736 : : Span(attrNameBegin, attrNameEnd - attrNameBegin).equals(
737 [ + + ]: 20239467 : RTL_CONSTASCII_STRINGPARAM("xmlns")))
738 : : {
739 : 4346 : hasDefaultNs = true;
740 [ + - ]: 4346 : defaultNsId = scanNamespaceIri(valueBegin, valueEnd);
741 [ + + + + ]: 58284225 : } else if (attrNameColon != 0 &&
[ + + ]
742 : : Span(attrNameBegin, attrNameColon - attrNameBegin).equals(
743 [ + + ]: 38655475 : RTL_CONSTASCII_STRINGPARAM("xmlns")))
744 : : {
745 : : namespaces_.push_back(
746 : : NamespaceData(
747 : 162751 : Span(attrNameColon + 1, attrNameEnd - (attrNameColon + 1)),
748 [ + - ][ + - ]: 162751 : scanNamespaceIri(valueBegin, valueEnd)));
749 : : } else {
750 : : attributes_.push_back(
751 : : AttributeData(
752 : : attrNameBegin, attrNameEnd, attrNameColon, valueBegin,
753 [ + - ]: 19466195 : valueEnd));
754 : : }
755 : : }
756 [ + + ][ + - ]: 19473671 : if (!hasDefaultNs && !elements_.empty()) {
[ + + ][ + + ]
757 [ + - ]: 19424876 : defaultNsId = elements_.top().defaultNamespaceId;
758 : : }
759 : 19473671 : firstAttribute_ = true;
760 [ + + ]: 19473671 : if (peek() == '/') {
761 : 1190487 : state_ = STATE_EMPTY_ELEMENT_TAG;
762 : 1190487 : ++pos_;
763 : : } else {
764 : 18283184 : state_ = STATE_CONTENT;
765 : : }
766 [ - + ]: 19473671 : if (peek() != '>') {
767 : : throw css::uno::RuntimeException(
768 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("missing '>' in ")) +
769 : : fileUrl_),
770 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
771 : : }
772 : 19473671 : ++pos_;
773 : : elements_.push(
774 : : ElementData(
775 : : Span(nameBegin, nameEnd - nameBegin), inheritedNamespaces,
776 [ + - ]: 19473671 : defaultNsId));
777 [ + + ]: 19473671 : if (nameColon == 0) {
778 : 19388754 : *nsId = defaultNsId;
779 : 19388754 : *localName = Span(nameBegin, nameEnd - nameBegin);
780 : : } else {
781 [ + - ]: 85113 : *nsId = getNamespaceId(Span(nameBegin, nameColon - nameBegin));
782 : 84917 : *localName = Span(nameColon + 1, nameEnd - (nameColon + 1));
783 : : }
784 : 19473671 : return RESULT_BEGIN;
785 : : }
786 : :
787 : 18283184 : XmlReader::Result XmlReader::handleEndTag() {
788 [ + - ][ - + ]: 18283184 : if (elements_.empty()) {
789 : : throw css::uno::RuntimeException(
790 : : (rtl::OUString(
791 : : RTL_CONSTASCII_USTRINGPARAM("spurious end tag in ")) +
792 : : fileUrl_),
793 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
794 : : }
795 : 18283184 : char const * nameBegin = pos_;
796 : 18283184 : char const * nameColon = 0;
797 [ + - - + ]: 36566368 : if (!scanName(&nameColon) ||
[ - + ]
798 [ + - ]: 18283184 : !elements_.top().name.equals(nameBegin, pos_ - nameBegin))
799 : : {
800 : : throw css::uno::RuntimeException(
801 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("tag mismatch in ")) +
802 : : fileUrl_),
803 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
804 : : }
805 [ + - ]: 18283184 : handleElementEnd();
806 : 18283184 : skipSpace();
807 [ - + ]: 18283184 : if (peek() != '>') {
808 : : throw css::uno::RuntimeException(
809 : : (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("missing '>' in ")) +
810 : : fileUrl_),
811 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
812 : : }
813 : 18283184 : ++pos_;
814 : 18283184 : return RESULT_END;
815 : : }
816 : :
817 : 19473671 : void XmlReader::handleElementEnd() {
818 : : assert(!elements_.empty());
819 : 19473671 : namespaces_.resize(elements_.top().inheritedNamespaces);
820 : 19473671 : elements_.pop();
821 [ + + ]: 19473671 : state_ = elements_.empty() ? STATE_DONE : STATE_CONTENT;
822 : 19473671 : }
823 : :
824 : 31501928 : XmlReader::Result XmlReader::handleSkippedText(Span * data, int * nsId) {
825 : 31501732 : for (;;) {
826 : 31501928 : sal_Int32 i = rtl_str_indexOfChar_WithLength(pos_, end_ - pos_, '<');
827 [ - + ]: 31501928 : if (i < 0) {
828 : : throw css::uno::RuntimeException(
829 : : (rtl::OUString(
830 : : RTL_CONSTASCII_USTRINGPARAM("premature end of ")) +
831 : : fileUrl_),
832 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
833 : : }
834 : 31501928 : pos_ += i + 1;
835 [ + + + + ]: 31501928 : switch (peek()) {
836 : : case '!':
837 : 4938 : ++pos_;
838 [ + - ][ + + ]: 4938 : if (!skipComment() && !scanCdataSection().is()) {
[ + - ][ + - ]
[ + + ]
[ + + # # ]
839 : 294 : skipDocumentTypeDeclaration();
840 : : }
841 : 4938 : break;
842 : : case '/':
843 : 11988572 : ++pos_;
844 : 11988572 : return handleEndTag();
845 : : case '?':
846 : 48795 : ++pos_;
847 : 48795 : skipProcessingInstruction();
848 : 48795 : break;
849 : : default:
850 : 19459623 : return handleStartTag(nsId, data);
851 : : }
852 : : }
853 : : }
854 : :
855 : 4468880 : XmlReader::Result XmlReader::handleRawText(Span * text) {
856 : 4468880 : pad_.clear();
857 : 134989730 : for (char const * begin = pos_;;) {
858 [ - - + + : 130520850 : switch (peek()) {
+ ]
859 : : case '\0': // i.e., EOF
860 : : throw css::uno::RuntimeException(
861 : : (rtl::OUString(
862 : : RTL_CONSTASCII_USTRINGPARAM("premature end of ")) +
863 : : fileUrl_),
864 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
865 : : case '\x0D':
866 : 0 : pad_.add(begin, pos_ - begin);
867 : 0 : ++pos_;
868 [ # # ]: 0 : if (peek() != '\x0A') {
869 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM("\x0A"));
870 : : }
871 : 0 : begin = pos_;
872 : 0 : break;
873 : : case '&':
874 : 38376 : pad_.add(begin, pos_ - begin);
875 : 38376 : pos_ = handleReference(pos_, end_);
876 : 38376 : begin = pos_;
877 : 38376 : break;
878 : : case '<':
879 : 4468880 : pad_.add(begin, pos_ - begin);
880 : 4468880 : ++pos_;
881 [ - + - + ]: 4468880 : switch (peek()) {
882 : : case '!':
883 : 0 : ++pos_;
884 [ # # ]: 0 : if (!skipComment()) {
885 [ # # ]: 0 : Span cdata(scanCdataSection());
886 [ # # ]: 0 : if (cdata.is()) {
887 [ # # ]: 0 : normalizeLineEnds(cdata);
888 : : } else {
889 [ # # ]: 0 : skipDocumentTypeDeclaration();
890 : : }
891 : : }
892 : 0 : begin = pos_;
893 : 0 : break;
894 : : case '/':
895 : 4454636 : *text = pad_.get();
896 : 4454636 : ++pos_;
897 : 4454636 : state_ = STATE_END_TAG;
898 : 4454636 : return RESULT_TEXT;
899 : : case '?':
900 : 0 : ++pos_;
901 : 0 : skipProcessingInstruction();
902 : 0 : begin = pos_;
903 : 0 : break;
904 : : default:
905 : 14244 : *text = pad_.get();
906 : 14244 : state_ = STATE_START_TAG;
907 : 14244 : return RESULT_TEXT;
908 : : }
909 : 0 : break;
910 : : default:
911 : 126013594 : ++pos_;
912 : 126013594 : break;
913 : : }
914 : : }
915 : : }
916 : :
917 : 1839976 : XmlReader::Result XmlReader::handleNormalizedText(Span * text) {
918 : 1839976 : pad_.clear();
919 : 1839976 : char const * flowBegin = pos_;
920 : 1839976 : char const * flowEnd = pos_;
921 : : enum Space { SPACE_START, SPACE_NONE, SPACE_SPAN, SPACE_BREAK };
922 : : // a single true space character can go into the current flow,
923 : : // everything else breaks the flow
924 : 1839976 : Space space = SPACE_START;
925 : 6866682 : for (;;) {
926 [ - + + - : 6866682 : switch (peek()) {
+ + ]
927 : : case '\0': // i.e., EOF
928 : : throw css::uno::RuntimeException(
929 : : (rtl::OUString(
930 : : RTL_CONSTASCII_USTRINGPARAM("premature end of ")) +
931 : : fileUrl_),
932 [ # # ][ # # ]: 0 : css::uno::Reference< css::uno::XInterface >());
933 : : case '\x09':
934 : : case '\x0A':
935 : : case '\x0D':
936 [ + + - ]: 3564 : switch (space) {
937 : : case SPACE_START:
938 : : case SPACE_BREAK:
939 : 1944 : break;
940 : : case SPACE_NONE:
941 : : case SPACE_SPAN:
942 : 1620 : space = SPACE_BREAK;
943 : 1620 : break;
944 : : }
945 : 3564 : ++pos_;
946 : 3564 : break;
947 : : case ' ':
948 [ + + - - ]: 30132 : switch (space) {
949 : : case SPACE_START:
950 : : case SPACE_BREAK:
951 : 13932 : break;
952 : : case SPACE_NONE:
953 : 16200 : space = SPACE_SPAN;
954 : 16200 : break;
955 : : case SPACE_SPAN:
956 : 0 : space = SPACE_BREAK;
957 : 0 : break;
958 : : }
959 : 30132 : ++pos_;
960 : 30132 : break;
961 : : case '&':
962 [ # # # # ]: 0 : switch (space) {
963 : : case SPACE_START:
964 : 0 : break;
965 : : case SPACE_NONE:
966 : : case SPACE_SPAN:
967 : 0 : pad_.add(flowBegin, pos_ - flowBegin);
968 : 0 : break;
969 : : case SPACE_BREAK:
970 : 0 : pad_.add(flowBegin, flowEnd - flowBegin);
971 : 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
972 : 0 : break;
973 : : }
974 : 0 : pos_ = handleReference(pos_, end_);
975 : 0 : flowBegin = pos_;
976 : 0 : flowEnd = pos_;
977 : 0 : space = SPACE_NONE;
978 : 0 : break;
979 : : case '<':
980 : 1840796 : ++pos_;
981 [ + + - - ]: 1840796 : switch (peek()) {
982 : : case '!':
983 : 820 : ++pos_;
984 [ + - ]: 820 : if (skipComment()) {
985 : 820 : space = SPACE_BREAK;
986 : : } else {
987 [ # # ]: 0 : Span cdata(scanCdataSection());
988 [ # # ]: 0 : if (cdata.is()) {
989 : : // CDATA is not normalized (similar to character
990 : : // references; it keeps the code simple), but it might
991 : : // arguably be better to normalize it:
992 [ # # # # ]: 0 : switch (space) {
993 : : case SPACE_START:
994 : 0 : break;
995 : : case SPACE_NONE:
996 : : case SPACE_SPAN:
997 [ # # ]: 0 : pad_.add(flowBegin, pos_ - flowBegin);
998 : 0 : break;
999 : : case SPACE_BREAK:
1000 [ # # ]: 0 : pad_.add(flowBegin, flowEnd - flowBegin);
1001 [ # # ]: 0 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
1002 : 0 : break;
1003 : : }
1004 [ # # ]: 0 : normalizeLineEnds(cdata);
1005 : 0 : flowBegin = pos_;
1006 : 0 : flowEnd = pos_;
1007 : 0 : space = SPACE_NONE;
1008 : : } else {
1009 [ # # ]: 0 : skipDocumentTypeDeclaration();
1010 : : }
1011 : : }
1012 : 820 : break;
1013 : : case '/':
1014 : 1839976 : ++pos_;
1015 : 1839976 : pad_.add(flowBegin, flowEnd - flowBegin);
1016 : 1839976 : *text = pad_.get();
1017 : 1839976 : state_ = STATE_END_TAG;
1018 : 1839976 : return RESULT_TEXT;
1019 : : case '?':
1020 : 0 : ++pos_;
1021 : 0 : skipProcessingInstruction();
1022 : 0 : space = SPACE_BREAK;
1023 : 0 : break;
1024 : : default:
1025 : 0 : pad_.add(flowBegin, flowEnd - flowBegin);
1026 : 0 : *text = pad_.get();
1027 : 0 : state_ = STATE_START_TAG;
1028 : 0 : return RESULT_TEXT;
1029 : : }
1030 : 820 : break;
1031 : : default:
1032 [ + + + - ]: 4992190 : switch (space) {
1033 : : case SPACE_START:
1034 : 1839812 : flowBegin = pos_;
1035 : 1839812 : break;
1036 : : case SPACE_NONE:
1037 : : case SPACE_SPAN:
1038 : 3150918 : break;
1039 : : case SPACE_BREAK:
1040 : 1460 : pad_.add(flowBegin, flowEnd - flowBegin);
1041 : 1460 : pad_.add(RTL_CONSTASCII_STRINGPARAM(" "));
1042 : 1460 : flowBegin = pos_;
1043 : 1460 : break;
1044 : : }
1045 : 4992190 : flowEnd = ++pos_;
1046 : 4992190 : space = SPACE_NONE;
1047 : 4992190 : break;
1048 : : }
1049 : : }
1050 : : }
1051 : :
1052 : 268765 : int XmlReader::toNamespaceId(NamespaceIris::size_type pos) {
1053 : : assert(pos <= INT_MAX);
1054 : 268765 : return static_cast< int >(pos);
1055 : : }
1056 : :
1057 : : }
1058 : :
1059 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|