source: icXML/icXML-devel/src/icxercesc/util/XMLChar.cpp

Last change on this file was 3158, checked in by cameron, 6 years ago

A few more updates missing from the last check-in

File size: 17.1 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: XMLChar.cpp 676911 2008-07-15 13:27:32Z amassari $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <icxercesc/util/XMLChar.hpp>
26#include <icxercesc/util/XMLString.hpp>
27#include <xercesc/internal/CharTypeTables.hpp>
28#include <icxmlc/XMLNameChars.hpp>
29#include <string.h>
30
31XERCES_CPP_NAMESPACE_BEGIN
32
33// ---------------------------------------------------------------------------
34//  XMLChar1_0: static data initialization
35// ---------------------------------------------------------------------------
36bool XMLChar1_0::enableNEL = false;
37XMLByte XMLChar1_0::fgCharCharsTable1_0[1] = {0};
38XMLByte XMLChar1_1::fgCharCharsTable1_1[1] = {0};
39
40
41// ---------------------------------------------------------------------------
42//  XMLChar1_0: Public, static methods
43// ---------------------------------------------------------------------------
44//  Checks whether all of the chars in the passed buffer are whitespace or
45//  not. Breaks out on the first non-whitespace.
46//
47bool XMLChar1_0::isAllSpaces(const   XMLCh* const    toCheck
48                            , const XMLSize_t        count)
49{
50    if (count == 0)
51        return false;
52
53    const XMLCh* curCh = toCheck;
54    const XMLCh* endPtr = toCheck + count;
55    while (curCh < endPtr)
56    {
57        if (!isWhitespace(*curCh++))
58            return false;
59    }
60    return true;
61}
62
63
64//
65//  Checks whether at least one of the chars in the passed buffer are whitespace or
66//  not.
67//
68bool XMLChar1_0::containsWhiteSpace(const   XMLCh* const    toCheck
69                                   , const XMLSize_t        count)
70{
71    if (count == 0)
72        return false;
73
74    const XMLCh* curCh = toCheck;
75    const XMLCh* endPtr = toCheck + count;
76    while (curCh < endPtr)
77    {
78        if (isWhitespace(*curCh++))
79            return true;
80    }
81    return false;
82}
83
84bool XMLChar1_0::isValidNCName(const   XMLCh* const    toCheck
85                               , const XMLSize_t       count)
86{
87    if (count == 0)
88        return false;
89
90    const XMLCh* curCh = toCheck;
91    const XMLCh* endPtr = toCheck + count;
92    if (!isFirstNCNameChar(*curCh++))
93        return false;
94
95    while (curCh < endPtr)
96    {
97        if (!isNCNameChar(*curCh++))
98            return false;
99    }
100    return true;
101}
102
103bool XMLChar1_0::isValidNmtoken(const   XMLCh*       const    toCheck
104                              , const   XMLSize_t             count)
105{
106    if (count == 0)
107        return false;
108
109    const XMLCh* curCh = toCheck;
110    const XMLCh* endPtr = toCheck + count;
111
112    while (curCh < endPtr)
113    {
114        if (!isNameChar(*curCh++))
115            return false;
116    }
117    return true;
118}
119
120bool XMLChar1_0::isValidName(const   XMLCh* const    toCheck
121                            , const XMLSize_t        count)
122{
123    if (count == 0)
124        return false;
125
126    const XMLCh* curCh = toCheck;
127    const XMLCh* endPtr = toCheck + count;
128    if (!isFirstNameChar(*curCh++))
129        return false;
130
131    while (curCh < endPtr)
132    {
133        if (!isNameChar(*curCh++))
134            return false;
135    }
136    return true;
137}
138
139bool XMLChar1_0::isValidName(const   XMLCh* const    toCheck)
140{
141    const XMLCh* curCh = toCheck;
142
143    if (isFirstNameChar(*curCh++))
144        {
145        while (isNameChar(*curCh))
146                {
147                        curCh++;
148                }
149
150                if (*curCh == 0)
151                {
152                        return true;
153                }
154        }
155        return false;
156}
157
158/**
159  * isValidQName
160  *
161  * [6]  QName ::=  (Prefix ':')? LocalPart
162  * [7]  Prefix ::=  NCName
163  * [8]  LocalPart ::=  NCName
164  *
165  */
166bool XMLChar1_0::isValidQName(const   XMLCh* const    toCheck
167                            , const XMLSize_t         count)
168{
169    if (count == 0)
170        return false;
171    XMLSize_t colonPos=0;
172    // don't use XMLString::indexOf, we must stop after 'count' chars
173    while(colonPos<count && toCheck[colonPos]!=chColon)
174        colonPos++;
175    if ((colonPos == 0) ||        // ":abcd"
176        (colonPos+1 == count))    // "abcd:"
177        return false;
178
179    if(colonPos != count)
180    {
181        // prefix & local part
182        return isValidNCName(toCheck, colonPos) && 
183               isValidNCName(toCheck+colonPos+1, count-colonPos-1);
184    }
185    return isValidNCName(toCheck, count);
186}
187
188//
189//  This one is not called terribly often, so it's done manually in order
190//  give up more bits in the character characteristics table for more often
191//  used characteristics.
192//
193bool XMLChar1_0::isPublicIdChar(const XMLCh toCheck, const XMLCh toCheck2)
194{
195    if (!toCheck2) {
196        const XMLCh* curTable = gPublicIdChars;
197
198        // Check the ranges
199        while (*curTable)
200        {
201            //
202            //  If the test char is less than the low range, then it's never
203            //  going to match any other range, so break out. But we have to
204            //  run up to the range terminator first.
205            //
206            if (toCheck < *curTable++)
207            {
208                while (*curTable++)
209                {
210                    // Purposefully empty, we are just running up the pointer
211                }
212                break;
213            }
214
215            // If it's less than or equal to the top of the range, then a match
216            if (toCheck <= *curTable++)
217                return true;
218        }
219
220        // And now test against singles
221        while (*curTable)
222        {
223            if (toCheck == *curTable++)
224                return true;
225        }
226        return false;
227    }
228    return false;
229}
230
231
232void XMLChar1_0::enableNELWS()
233{
234    enableNEL = true;
235}
236
237// ---------------------------------------------------------------------------
238//  XMLChar1_1: Public, static methods
239// ---------------------------------------------------------------------------
240//  Checks whether all of the chars in the passed buffer are whitespace or
241//  not. Breaks out on the first non-whitespace.
242//
243bool XMLChar1_1::isAllSpaces(const   XMLCh* const    toCheck
244                            , const XMLSize_t        count)
245{
246    if (count == 0)
247        return false;
248
249    const XMLCh* curCh = toCheck;
250    const XMLCh* endPtr = toCheck + count;
251    while (curCh < endPtr)
252    {
253        if (!(isWhitespace(*curCh++)))
254            return false;
255    }
256    return true;
257}
258
259
260//
261//  Checks whether at least one of the chars in the passed buffer are whitespace or
262//  not.
263//
264bool XMLChar1_1::containsWhiteSpace(const   XMLCh* const    toCheck
265                                    , const XMLSize_t       count)
266{
267    if (count == 0)
268        return false;
269
270    const XMLCh* curCh = toCheck;
271    const XMLCh* endPtr = toCheck + count;
272    while (curCh < endPtr)
273    {
274        if (isWhitespace(*curCh++))
275            return true;
276    }
277    return false;
278}
279
280
281bool XMLChar1_1::isValidNCName(const   XMLCh* const    toCheck
282                               , const XMLSize_t       count)
283{
284    if (count == 0)
285        return false;
286
287    const XMLCh* curCh = toCheck;
288    const XMLCh* endPtr = toCheck + count;
289
290    XMLCh nextCh = *curCh++;
291    if ((nextCh >= 0xD800) && (nextCh <= 0xDB7F)) {
292        nextCh = *curCh++;
293        if ((nextCh < 0xDC00) || (nextCh > 0xDFFF))
294            return false;
295    }
296    else if (nextCh== chColon || !isFirstNameChar(nextCh))
297            return false;
298
299    bool    gotLeadingSurrogate = false;
300    while (curCh < endPtr)
301    {
302        nextCh = *curCh++;
303
304        // Deal with surrogate pairs
305        if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
306        {
307            //  It's a leading surrogate. If we already got one, then
308            //  issue an error, else set leading flag to make sure that
309            //  we look for a trailing next time.
310            if (nextCh > 0xDB7F || gotLeadingSurrogate)
311            {
312                return false;
313            }
314            else
315                gotLeadingSurrogate = true;
316        }
317        else
318        {
319            //  If it's a trailing surrogate, make sure that we are
320            //  prepared for that. Else, it's just a regular char so make
321            //  sure that we were not expected a trailing surrogate.
322            if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
323            {
324                // It's trailing, so make sure we were expecting it
325                if (!gotLeadingSurrogate)
326                    return false;
327            }
328            else
329            {
330                //  It's just a char, so make sure we were not expecting a
331                //  trailing surrogate.
332                if (gotLeadingSurrogate)
333                {
334                    return false;
335                }
336                // It's got to at least be a valid XML character
337                else if (!isNCNameChar(nextCh))
338                {
339                    return false;
340                }
341            }
342            gotLeadingSurrogate = false;
343        }
344    }
345    return true;
346}
347
348bool XMLChar1_1::isValidNmtoken(const   XMLCh*        const    toCheck
349                              , const   XMLSize_t              count)
350{
351    if (count == 0)
352        return false;
353
354    const XMLCh* curCh = toCheck;
355    const XMLCh* endPtr = toCheck + count;
356    XMLCh nextCh;
357
358    bool    gotLeadingSurrogate = false;
359    while (curCh < endPtr)
360    {
361        nextCh = *curCh++;
362
363        // Deal with surrogate pairs
364        if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
365        {
366            //  It's a leading surrogate. If we already got one, then
367            //  issue an error, else set leading flag to make sure that
368            //  we look for a trailing next time.
369            if (nextCh > 0xDB7F || gotLeadingSurrogate)
370            {
371                return false;
372            }
373            else
374                gotLeadingSurrogate = true;
375        }
376        else
377        {
378            //  If it's a trailing surrogate, make sure that we are
379            //  prepared for that. Else, it's just a regular char so make
380            //  sure that we were not expected a trailing surrogate.
381            if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
382            {
383                // It's trailing, so make sure we were expecting it
384                if (!gotLeadingSurrogate)
385                    return false;
386            }
387            else
388            {
389                //  It's just a char, so make sure we were not expecting a
390                //  trailing surrogate.
391                if (gotLeadingSurrogate) {
392                    return false;
393                }
394                // It's got to at least be a valid XML character
395                else if (!isNameChar(nextCh))
396                {
397                    return false;
398                }
399            }
400            gotLeadingSurrogate = false;
401        }
402    }
403    return true;
404}
405
406bool XMLChar1_1::isValidName(const   XMLCh* const    toCheck
407                            , const XMLSize_t        count)
408{
409    if (count == 0)
410        return false;
411
412    const XMLCh* curCh = toCheck;
413    const XMLCh* endPtr = toCheck + count;
414
415    XMLCh nextCh = *curCh++;
416    if ((nextCh >= 0xD800) && (nextCh <= 0xDB7F)) {
417        nextCh = *curCh++;
418        if ((nextCh < 0xDC00) || (nextCh > 0xDFFF))
419            return false;
420    }
421    else if (!isFirstNameChar(nextCh))
422            return false;
423
424    bool    gotLeadingSurrogate = false;
425    while (curCh < endPtr)
426    {
427        nextCh = *curCh++;
428
429        // Deal with surrogate pairs
430        if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
431        {
432            //  It's a leading surrogate. If we already got one, then
433            //  issue an error, else set leading flag to make sure that
434            //  we look for a trailing next time.
435            if (nextCh > 0xDB7F || gotLeadingSurrogate)
436            {
437                return false;
438            }
439            else
440                gotLeadingSurrogate = true;
441        }
442        else
443        {
444            //  If it's a trailing surrogate, make sure that we are
445            //  prepared for that. Else, it's just a regular char so make
446            //  sure that we were not expected a trailing surrogate.
447            if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
448            {
449                // It's trailing, so make sure we were expecting it
450                if (!gotLeadingSurrogate)
451                    return false;
452            }
453            else
454            {
455                //  It's just a char, so make sure we were not expecting a
456                //  trailing surrogate.
457                if (gotLeadingSurrogate) {
458                    return false;
459                }
460                // It's got to at least be a valid XML character
461                else if (!isNameChar(nextCh))
462                {
463                    return false;
464                }
465            }
466            gotLeadingSurrogate = false;
467        }
468    }
469    return true;
470}
471
472bool XMLChar1_1::isValidName(const   XMLCh* const    toCheck)
473{
474    const XMLCh* curCh = toCheck;
475
476    XMLCh nextCh = *curCh++;
477    if ((nextCh >= 0xD800) && (nextCh <= 0xDB7F))
478        {
479        nextCh = *curCh++;
480        if ((nextCh < 0xDC00) || (nextCh > 0xDFFF))
481                {
482            return false;
483                }
484    }
485    else if (!isFirstNameChar(nextCh))
486        {
487            return false;
488        }
489
490    bool    gotLeadingSurrogate = false;
491
492    while (*curCh != 0)
493    {
494        nextCh = *curCh++;
495
496        // Deal with surrogate pairs
497        if ((nextCh >= 0xD800) && (nextCh <= 0xDBFF))
498        {
499            //  It's a leading surrogate. If we already got one, then
500            //  issue an error, else set leading flag to make sure that
501            //  we look for a trailing next time.
502            if (nextCh > 0xDB7F || gotLeadingSurrogate)
503            {
504                return false;
505            }
506            else
507                        {
508                gotLeadingSurrogate = true;
509                        }
510        }
511        else
512        {
513            //  If it's a trailing surrogate, make sure that we are
514            //  prepared for that. Else, it's just a regular char so make
515            //  sure that we were not expected a trailing surrogate.
516           if ((nextCh >= 0xDC00) && (nextCh <= 0xDFFF))
517           {
518                // It's trailing, so make sure we were expecting it
519                if (!gotLeadingSurrogate)
520                    return false;
521            }
522            else
523            {
524                //  It's just a char, so make sure we were not expecting a
525                //  trailing surrogate.
526                if (gotLeadingSurrogate)
527                                {
528                    return false;
529                }
530                // It's got to at least be a valid XML character
531                else if (!isNameChar(nextCh))
532                {
533                    return false;
534                }
535            }
536           gotLeadingSurrogate = false;
537        }
538    }
539    return true;
540}
541
542/**
543  * isValidQName
544  *
545  * [6]  QName ::=  (Prefix ':')? LocalPart
546  * [7]  Prefix ::=  NCName
547  * [8]  LocalPart ::=  NCName
548  *
549  */
550bool XMLChar1_1::isValidQName(const   XMLCh* const    toCheck
551                            , const XMLSize_t         count)
552{
553    if (count == 0)
554        return false;
555
556    XMLSize_t length = count;
557    int colonPos = XMLString::indexOf(toCheck, chColon);
558    if ((colonPos == 0) ||         // ":abcd"
559        (colonPos == ((int)length)-1))    // "abcd:"
560        return false;
561
562    //
563    // prefix
564    //
565    if (colonPos != -1)
566    {
567        if (isValidNCName(toCheck, colonPos) == false)
568            return false;
569    }
570
571    //
572    // LocalPart
573    //
574    return isValidNCName(toCheck+colonPos+1, length-colonPos-1);
575}
576
577
578//
579//  This one is not called terribly often, so it's done manually in order
580//  give up more bits in the character characteristics table for more often
581//  used characteristics.
582//
583bool XMLChar1_1::isPublicIdChar(const XMLCh toCheck, const XMLCh toCheck2)
584{
585    if (!toCheck2) {
586        const XMLCh* curTable = gPublicIdChars;
587
588        // Check the ranges
589        while (*curTable)
590        {
591            //
592            //  If the test char is less than the low range, then it's never
593            //  going to match any other range, so break out. But we have to
594            //  run up to the range terminator first.
595            //
596            if (toCheck < *curTable++)
597            {
598                while (*curTable++)
599                {
600                    // Purposefully empty, we are just running up the pointer
601                }
602                break;
603            }
604
605            // If it's less than or equal to the top of the range, then a match
606            if (toCheck <= *curTable++)
607                return true;
608        }
609
610        // And now test against singles
611        while (*curTable)
612        {
613            if (toCheck == *curTable++)
614                return true;
615        }
616        return false;
617    }
618    return false;
619}
620
621XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.