/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include #include #include XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // Constructors and Destructor // --------------------------------------------------------------------------- AnyURIDatatypeValidator::AnyURIDatatypeValidator(MemoryManager* const manager) :AbstractStringValidator(0, 0, 0, DatatypeValidator::AnyURI, manager) {} AnyURIDatatypeValidator::~AnyURIDatatypeValidator() { } AnyURIDatatypeValidator::AnyURIDatatypeValidator( DatatypeValidator* const baseValidator , RefHashTableOf* const facets , RefArrayVectorOf* const enums , const int finalSet , MemoryManager* const manager) :AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::AnyURI, manager) { init(enums, manager); } DatatypeValidator* AnyURIDatatypeValidator::newInstance( RefHashTableOf* const facets , RefArrayVectorOf* const enums , const int finalSet , MemoryManager* const manager) { return (DatatypeValidator*) new (manager) AnyURIDatatypeValidator(this, facets, enums, finalSet, manager); } // --------------------------------------------------------------------------- // Utilities // --------------------------------------------------------------------------- void AnyURIDatatypeValidator::checkValueSpace(const XMLCh* const content , MemoryManager* const manager) { bool validURI = true; // check 3.2.17.c0 must: URI (rfc 2396/2723) try { // Support for relative URLs // According to Java 1.1: URLs may also be specified with a // String and the URL object that it is related to. // XMLSize_t len = XMLString::stringLen(content); if (len) { // Encode special characters using XLink 5.4 algorithm XMLBuffer encoded((len*3)+1, manager); encode(content, len, encoded, manager); validURI = XMLUri::isValidURI(true, encoded.getRawBuffer(), true); } } catch(const OutOfMemoryException&) { throw; } catch (...) { ThrowXMLwithMemMgr1(InvalidDatatypeValueException , XMLExcepts::VALUE_URI_Malformed , content , manager); } if (!validURI) { ThrowXMLwithMemMgr1(InvalidDatatypeValueException , XMLExcepts::VALUE_URI_Malformed , content , manager); } } /*** * To encode special characters in anyURI, by using %HH to represent * special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', etc. * and non-ASCII characters (whose value >= 128). ***/ void AnyURIDatatypeValidator::encode(const XMLCh* const content, const XMLSize_t len, XMLBuffer& encoded, MemoryManager* const manager) { static const bool needEscapeMap[] = { true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , /* 0x00 to 0x0F need escape */ true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , /* 0x10 to 0x1F need escape */ true , false, true , false, false, false, false, false, false, false, false, false, false, false, false, false, /* 0x20:' ', 0x22:'"' */ false, false, false, false, false, false, false, false, false, false, false, false, true , false, true , false, /* 0x3C:'<', 0x3E:'>' */ false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true , false, true , false, /* 0x5C:'\\', 0x5E:'^' */ true , false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, /* 0x60:'`' */ false, false, false, false, false, false, false, false, false, false, false, true , true , true , true , true /* 0x7B:'{', 0x7C:'|', 0x7D:'}', 0x7E:'~', 0x7F:DEL */ }; // For each character in content XMLSize_t i; for (i = 0; i < len; i++) { int ch = (int)content[i]; // If it's not an ASCII character, break here, and use UTF-8 encoding if (ch >= 128) break; if (needEscapeMap[ch]) { char tempStr[3] = "\0"; sprintf(tempStr, "%02X", ch); encoded.append('%'); encoded.append((XMLCh)tempStr[0]); encoded.append((XMLCh)tempStr[1]); } else { encoded.append((XMLCh)ch); } } // we saw some non-ascii character if (i < len) { // get UTF-8 bytes for the remaining sub-string const XMLCh* remContent = (XMLCh*)&content[i]; const XMLSize_t remContentLen = len - i; XMLByte* UTF8Byte = (XMLByte*)manager->allocate((remContentLen*4+1) * sizeof(XMLByte)); XMLSize_t charsEaten; XMLUTF8Transcoder transcoder(XMLUni::fgUTF8EncodingString, remContentLen*4+1, manager); XMLSize_t utf8Len = transcoder.transcodeTo(remContent, remContentLen, UTF8Byte, remContentLen*4, charsEaten, XMLTranscoder::UnRep_RepChar); assert(charsEaten == remContentLen); XMLSize_t j; for (j = 0; j < utf8Len; j++) { XMLByte b = UTF8Byte[j]; if (b >= 128 || needEscapeMap[b]) { char tempStr[3] = "\0"; sprintf(tempStr, "%02X", b); encoded.append('%'); encoded.append((XMLCh)tempStr[0]); encoded.append((XMLCh)tempStr[1]); } else { encoded.append((XMLCh)b); } } manager->deallocate(UTF8Byte); } } /*** * Support for Serialization/De-serialization ***/ IMPL_XSERIALIZABLE_TOCREATE(AnyURIDatatypeValidator) void AnyURIDatatypeValidator::serialize(XSerializeEngine& serEng) { AbstractStringValidator::serialize(serEng); } XERCES_CPP_NAMESPACE_END /** * End of file AnyURIDatatypeValidator.cpp */