GME  13
XML256TableTranscoder.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 // ---------------------------------------------------------------------------
00020 //  Includes
00021 // ---------------------------------------------------------------------------
00022 #include <xercesc/util/BitOps.hpp>
00023 #include <xercesc/util/TranscodingException.hpp>
00024 #include <xercesc/util/XML256TableTranscoder.hpp>
00025 #include <xercesc/util/XMLString.hpp>
00026 #include <string.h>
00027 
00028 XERCES_CPP_NAMESPACE_BEGIN
00029 
00030 
00031 // ---------------------------------------------------------------------------
00032 //  XML256TableTranscoder: Public Destructor
00033 // ---------------------------------------------------------------------------
00034 XML256TableTranscoder::~XML256TableTranscoder()
00035 {
00036     // We don't own the tables, we just reference them
00037 }
00038 
00039 
00040 // ---------------------------------------------------------------------------
00041 //  XML256TableTranscoder: Implementation of the transcoder API
00042 // ---------------------------------------------------------------------------
00043 XMLSize_t
00044 XML256TableTranscoder::transcodeFrom(const  XMLByte* const       srcData
00045                                     , const XMLSize_t            srcCount
00046                                     ,       XMLCh* const         toFill
00047                                     , const XMLSize_t            maxChars
00048                                     ,       XMLSize_t&           bytesEaten
00049                                     ,       unsigned char* const charSizes)
00050 {
00051     //
00052     //  Calculate the max chars we can do here. Its the lesser of the
00053     //  max output chars and the number of chars in the source.
00054     //
00055     const XMLSize_t countToDo = srcCount < maxChars ? srcCount : maxChars;
00056 
00057     //
00058     //  Loop through the count we have to do and map each char via the
00059     //  lookup table.
00060     //
00061     const XMLByte*  srcPtr = srcData;
00062     const XMLByte*  endPtr = (srcPtr + countToDo);
00063     XMLCh*          outPtr = toFill;
00064     while (srcPtr < endPtr)
00065     {
00066         const XMLCh uniCh = fFromTable[*srcPtr++];
00067         if (uniCh != 0xFFFF)
00068         {
00069             *outPtr++ = uniCh;
00070             continue;
00071         }
00072     }
00073 
00074 
00075     // Set the bytes eaten
00076     bytesEaten = countToDo;
00077 
00078     // Set the character sizes to the fixed size
00079     memset(charSizes, 1, countToDo);
00080 
00081     // Return the chars we transcoded
00082     return countToDo;
00083 }
00084 
00085 
00086 XMLSize_t
00087 XML256TableTranscoder::transcodeTo( const   XMLCh* const    srcData
00088                                     , const XMLSize_t       srcCount
00089                                     ,       XMLByte* const  toFill
00090                                     , const XMLSize_t       maxBytes
00091                                     ,       XMLSize_t&      charsEaten
00092                                     , const UnRepOpts       options)
00093 {
00094     //
00095     //  Calculate the max chars we can do here. Its the lesser of the
00096     //  max output chars and the number of chars in the source.
00097     //
00098     const XMLSize_t countToDo = srcCount < maxBytes ? srcCount : maxBytes;
00099 
00100     //
00101     //  Loop through the count we have to do and map each char via the
00102     //  lookup table.
00103     //
00104     const XMLCh*    srcPtr = srcData;
00105     const XMLCh*    endPtr = (srcPtr + countToDo);
00106     XMLByte*        outPtr = toFill;
00107     XMLByte         nextOut;
00108     while (srcPtr < endPtr)
00109     {
00110         //
00111         //  Get the next src char out to a temp, then do a binary search
00112         //  of the 'to' table for this entry.
00113         //
00114         if ((nextOut = xlatOneTo(*srcPtr))!=0)
00115         {
00116             *outPtr++ = nextOut;
00117             srcPtr++;
00118             continue;
00119         }
00120 
00121         //
00122         //  Its not representable so, according to the options, either
00123         //  throw or use the replacement.
00124         //
00125         if (options == UnRep_Throw)
00126         {
00127             XMLCh tmpBuf[17];
00128             XMLString::binToText((unsigned int)*srcPtr, tmpBuf, 16, 16, getMemoryManager());
00129             ThrowXMLwithMemMgr2
00130             (
00131                 TranscodingException
00132                 , XMLExcepts::Trans_Unrepresentable
00133                 , tmpBuf
00134                 , getEncodingName()
00135                 , getMemoryManager()
00136             );
00137         }
00138 
00139         // Eat the source char and use the replacement char
00140         srcPtr++;
00141         *outPtr++ = 0x3F;
00142     }
00143 
00144     // Set the chars eaten
00145     charsEaten = countToDo;
00146 
00147     // Return the bytes we transcoded
00148     return countToDo;
00149 }
00150 
00151 
00152 bool XML256TableTranscoder::canTranscodeTo(const unsigned int toCheck)
00153 {
00154     return (xlatOneTo(toCheck) != 0);
00155 }
00156 
00157 
00158 // ---------------------------------------------------------------------------
00159 //  XML256TableTranscoder: Hidden constructor
00160 // ---------------------------------------------------------------------------
00161 XML256TableTranscoder::
00162 XML256TableTranscoder(  const   XMLCh* const                     encodingName
00163                         , const XMLSize_t                        blockSize
00164                         , const XMLCh* const                     fromTable
00165                         , const XMLTransService::TransRec* const toTable
00166                         , const XMLSize_t                        toTableSize
00167                         , MemoryManager* const                   manager) :
00168 
00169     XMLTranscoder(encodingName, blockSize, manager)
00170     , fFromTable(fromTable)
00171     , fToSize(toTableSize)
00172     , fToTable(toTable)
00173 {
00174 }
00175 
00176 
00177 // ---------------------------------------------------------------------------
00178 //  XML256TableTranscoder: Private helper methods
00179 // ---------------------------------------------------------------------------
00180 XMLByte XML256TableTranscoder::xlatOneTo(const XMLCh toXlat) const
00181 {
00182     XMLSize_t lowOfs = 0;
00183     XMLSize_t hiOfs = fToSize - 1;
00184     do
00185     {
00186         // Calc the mid point of the low and high offset.
00187         const XMLSize_t midOfs = ((hiOfs - lowOfs) / 2) + lowOfs;
00188 
00189         //
00190         //  If our test char is greater than the mid point char, then
00191         //  we move up to the upper half. Else we move to the lower
00192         //  half. If its equal, then its our guy.
00193         //
00194         if (toXlat > fToTable[midOfs].intCh)
00195         {
00196             lowOfs = midOfs;
00197         }
00198          else if (toXlat < fToTable[midOfs].intCh)
00199         {
00200             hiOfs = midOfs;
00201         }
00202          else
00203         {
00204             return fToTable[midOfs].extCh;
00205         }
00206     }   while (lowOfs + 1 < hiOfs);
00207 
00208     // Check the high end of the range otherwise the
00209     // last item in the table may never be found.
00210         if (toXlat == fToTable[hiOfs].intCh)
00211         {
00212             return fToTable[hiOfs].extCh;
00213         }
00214 
00215     return 0;
00216 }
00217 
00218 XERCES_CPP_NAMESPACE_END