source: icXML/icXML-devel/src/xercesc/validators/datatype/AnyURIDatatypeValidator.cpp @ 2722

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

Original Xerces files with import mods for icxercesc

File size: 7.7 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: AnyURIDatatypeValidator.cpp 676796 2008-07-15 05:04:13Z dbertoni $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <stdio.h>
26#include <xercesc/util/OutOfMemoryException.hpp>
27#include <icxercesc/util/XMLUTF8Transcoder.hpp>
28#include <icxercesc/framework/XMLBuffer.hpp>
29#include <xercesc/validators/datatype/AnyURIDatatypeValidator.hpp>
30#include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
31#include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
32
33XERCES_CPP_NAMESPACE_BEGIN
34
35// ---------------------------------------------------------------------------
36//  Constructors and Destructor
37// ---------------------------------------------------------------------------
38AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager)
39:AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager)
40{}
41
42AnyURIDatatypeValidator::~AnyURIDatatypeValidator()
43{ 
44}
45
46AnyURIDatatypeValidator::AnyURIDatatypeValidator(
47                          DatatypeValidator*            const baseValidator
48                        , RefHashTableOf<KVStringPair>* const facets
49                        , RefArrayVectorOf<XMLCh>*      const enums
50                        , const int                           finalSet
51                        , MemoryManager* const manager)
52:AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager)
53{
54    init(enums, manager);
55}
56
57DatatypeValidator* AnyURIDatatypeValidator::newInstance(
58                                      RefHashTableOf<KVStringPair>* const facets
59                                    , RefArrayVectorOf<XMLCh>*           const enums
60                                    , const int                           finalSet
61                                    , MemoryManager* const manager)
62{
63    return (DatatypeValidator*) new (manager) AnyURIDatatypeValidator(this, facets, enums, finalSet, manager);
64}
65
66// ---------------------------------------------------------------------------
67//  Utilities
68// ---------------------------------------------------------------------------
69
70void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content
71                                              , MemoryManager* const manager)
72{
73    bool validURI = true;
74
75    // check 3.2.17.c0 must: URI (rfc 2396/2723)
76    try
77    {
78        // Support for relative URLs
79        // According to Java 1.1: URLs may also be specified with a
80        // String and the URL object that it is related to.
81        //
82        XMLSize_t len = XMLString::stringLen(content);
83        if (len)
84        {         
85            // Encode special characters using XLink 5.4 algorithm
86                        XMLBuffer encoded((len*3)+1, manager);
87            encode(content, len, encoded, manager);
88            validURI = XMLUri::isValidURI(true, encoded.getRawBuffer(), true);           
89        }
90    }
91    catch(const OutOfMemoryException&)
92    {
93        throw;
94    }
95    catch (...)
96    {
97        ThrowXMLwithMemMgr1(InvalidDatatypeValueException
98                , XMLExcepts::VALUE_URI_Malformed
99                , content
100                , manager);
101    }
102   
103    if (!validURI) {
104        ThrowXMLwithMemMgr1(InvalidDatatypeValueException
105                    , XMLExcepts::VALUE_URI_Malformed
106                    , content
107                    , manager);
108    }
109}
110
111/***
112 * To encode special characters in anyURI, by using %HH to represent
113 * special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', etc.
114 * and non-ASCII characters (whose value >= 128).
115 ***/
116void AnyURIDatatypeValidator::encode(const XMLCh* const content, const XMLSize_t len, XMLBuffer& encoded, MemoryManager* const manager)
117{
118    static const bool needEscapeMap[] = {
119        true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , /* 0x00 to 0x0F need escape */
120        true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , /* 0x10 to 0x1F need escape */
121        true , false, true , false, false, false, false, false, false, false, false, false, false, false, false, false, /* 0x20:' ', 0x22:'"' */
122        false, false, false, false, false, false, false, false, false, false, false, false, true , false, true , false, /* 0x3C:'<', 0x3E:'>' */
123        false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
124        false, false, false, false, false, false, false, false, false, false, false, false, true , false, true , false, /* 0x5C:'\\', 0x5E:'^' */
125        true , false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, /* 0x60:'`' */
126        false, false, false, false, false, false, false, false, false, false, false, true , true , true , true , true   /* 0x7B:'{', 0x7C:'|', 0x7D:'}', 0x7E:'~', 0x7F:DEL */
127    };
128
129    // For each character in content
130    XMLSize_t i;
131    for (i = 0; i < len; i++)
132    {
133        int ch = (int)content[i];
134        // If it's not an ASCII character, break here, and use UTF-8 encoding
135        if (ch >= 128)
136            break;
137
138        if (needEscapeMap[ch])
139        {
140            char tempStr[3] = "\0";
141            sprintf(tempStr, "%02X", ch);
142            encoded.append('%');
143            encoded.append((XMLCh)tempStr[0]);
144            encoded.append((XMLCh)tempStr[1]);
145        }
146        else
147        {
148            encoded.append((XMLCh)ch);
149        }
150    }
151
152    // we saw some non-ascii character
153    if (i < len) {
154        // get UTF-8 bytes for the remaining sub-string
155        const XMLCh* remContent = (XMLCh*)&content[i];
156        const XMLSize_t remContentLen = len - i;
157        XMLByte* UTF8Byte = (XMLByte*)manager->allocate((remContentLen*4+1) * sizeof(XMLByte));
158        XMLSize_t charsEaten;
159
160        XMLUTF8Transcoder transcoder(XMLUni::fgUTF8EncodingString, remContentLen*4+1, manager);
161        XMLSize_t utf8Len = transcoder.transcodeTo(remContent, remContentLen, UTF8Byte, remContentLen*4, charsEaten, XMLTranscoder::UnRep_RepChar);
162        assert(charsEaten == remContentLen);
163
164        XMLSize_t j;
165        for (j = 0; j < utf8Len; j++) {
166            XMLByte b = UTF8Byte[j];
167            if (b >= 128 || needEscapeMap[b])
168            {
169                char tempStr[3] = "\0";
170                sprintf(tempStr, "%02X", b);
171                encoded.append('%');
172                encoded.append((XMLCh)tempStr[0]);
173                encoded.append((XMLCh)tempStr[1]);
174            }
175            else
176            {
177                encoded.append((XMLCh)b);
178            }
179        }
180        manager->deallocate(UTF8Byte);
181    }
182}
183
184/***
185 * Support for Serialization/De-serialization
186 ***/
187
188IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator)
189
190void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng)
191{
192    AbstractStringValidator::serialize(serEng);
193}
194
195XERCES_CPP_NAMESPACE_END
196
197/**
198  * End of file AnyURIDatatypeValidator.cpp
199  */
Note: See TracBrowser for help on using the repository browser.