GME  13
HexBin.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 // ---------------------------------------------------------------------------
00019 //  Includes
00020 // ---------------------------------------------------------------------------
00021 #include <xercesc/util/HexBin.hpp>
00022 #include <xercesc/util/XMLUniDefs.hpp>
00023 #include <xercesc/util/XMLString.hpp>
00024 #include <xercesc/util/Janitor.hpp>
00025 
00026 XERCES_CPP_NAMESPACE_BEGIN
00027 
00028 // ---------------------------------------------------------------------------
00029 //  constants
00030 // ---------------------------------------------------------------------------
00031 static const int BASELENGTH = 255;
00032 
00033 // ---------------------------------------------------------------------------
00034 //  class data member
00035 // ---------------------------------------------------------------------------
00036 const XMLByte HexBin::hexNumberTable[BASELENGTH] =
00037 {
00038     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00039     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00040     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00041     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00042     0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00043     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00044     0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00045     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00046     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00047     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00048     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00049     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00050     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00051     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00052     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00053     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00054 };
00055 
00056 
00057 int HexBin::getDataLength(const XMLCh* const hexData)
00058 {
00059     if (!isArrayByteHex(hexData))
00060         return -1;
00061 
00062     return (int)XMLString::stringLen(hexData)/2;
00063 }
00064 
00065 bool HexBin::isArrayByteHex(const XMLCh* const hexData)
00066 {
00067     if (( hexData == 0 ) || ( *hexData == 0 )) // zero length
00068         return true;
00069 
00070     XMLSize_t strLen = XMLString::stringLen(hexData);
00071     if ( strLen%2 != 0 )
00072         return false;
00073 
00074     for ( XMLSize_t i = 0; i < strLen; i++ )
00075         if( !isHex(hexData[i]) )
00076             return false;
00077 
00078     return true;
00079 }
00080 
00081 XMLCh* HexBin::getCanonicalRepresentation(const XMLCh*          const hexData
00082                                         ,       MemoryManager*  const manager)
00083 {
00084 
00085     if (getDataLength(hexData) == -1)
00086         return 0;
00087 
00088     XMLCh* retStr = XMLString::replicate(hexData, manager);
00089     XMLString::upperCaseASCII(retStr);
00090 
00091     return retStr;
00092 }
00093 
00094 XMLByte* HexBin::decodeToXMLByte(const XMLCh*          const   hexData
00095                     ,       MemoryManager*  const   manager)
00096 {
00097     if (( hexData == 0 ) || ( *hexData == 0 )) // zero length
00098         return 0;
00099 
00100     XMLSize_t strLen = XMLString::stringLen(hexData);
00101     if ( strLen%2 != 0 )
00102         return 0;
00103 
00104     //prepare the return string
00105     int decodeLength = (int)strLen/2;
00106     XMLByte *retVal = (XMLByte*) manager->allocate( (decodeLength + 1) * sizeof(XMLByte));
00107     ArrayJanitor<XMLByte> janFill(retVal, manager);
00108     
00109     XMLByte temp1, temp2;
00110     for( int i = 0; i<decodeLength; i++ ) {
00111         temp1 = hexNumberTable[hexData[i*2]];
00112         if (temp1 == (XMLByte) -1)
00113             return 0;
00114         temp2 = hexNumberTable[hexData[i*2+1]];
00115         if (temp2 == (XMLByte) -1)
00116             return 0;
00117         retVal[i] = ((temp1 << 4) | temp2);
00118     }
00119 
00120     janFill.release();
00121     retVal[decodeLength] = 0;
00122     return retVal;
00123 }
00124 
00125 
00126 // -----------------------------------------------------------------------
00127 //  Helper methods
00128 // -----------------------------------------------------------------------
00129 bool HexBin::isHex(const XMLCh& octet)
00130 {
00131     // sanity check to avoid out-of-bound index
00132     if ( octet >= BASELENGTH )
00133         return false;
00134 
00135     return (hexNumberTable[octet] != (XMLByte) -1);
00136 }
00137 
00138 XERCES_CPP_NAMESPACE_END