intl/uconv/util/nsUnicodeDecodeHelper.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "unicpriv.h"
     7 #include "nsUnicodeDecodeHelper.h"
     8 #include "nsAutoPtr.h"
    10 //----------------------------------------------------------------------
    11 // Class nsUnicodeDecodeHelper [implementation]
    12 nsresult nsUnicodeDecodeHelper::ConvertByTable(
    13                                      const char * aSrc, 
    14                                      int32_t * aSrcLength, 
    15                                      char16_t * aDest, 
    16                                      int32_t * aDestLength, 
    17                                      uScanClassID aScanClass,
    18                                      uShiftInTable * aShiftInTable, 
    19                                      uMappingTable  * aMappingTable,
    20                                      bool aErrorSignal)
    21 {
    22   const char * src = aSrc;
    23   int32_t srcLen = *aSrcLength;
    24   char16_t * dest = aDest;
    25   char16_t * destEnd = aDest + *aDestLength;
    27   char16_t med;
    28   int32_t bcr; // byte count for read
    29   nsresult res = NS_OK;
    31   while ((srcLen > 0) && (dest < destEnd)) {
    32     bool charFound;
    33     if (aScanClass == uMultibytesCharset) {
    34       NS_ASSERTION(aShiftInTable, "shift table missing");
    35       charFound = uScanShift(aShiftInTable, nullptr, (uint8_t *)src,
    36                              reinterpret_cast<uint16_t*>(&med), srcLen, 
    37                              (uint32_t *)&bcr);
    38     } else {
    39       charFound = uScan(aScanClass, nullptr, (uint8_t *)src,
    40                         reinterpret_cast<uint16_t*>(&med),
    41                         srcLen, (uint32_t *)&bcr);
    42     }
    43     if (!charFound) {
    44       res = NS_OK_UDEC_MOREINPUT;
    45       break;
    46     }
    48     if (!uMapCode((uTable*) aMappingTable, static_cast<uint16_t>(med), reinterpret_cast<uint16_t*>(dest))) {
    49       if (med < 0x20) {
    50         // somehow some table miss the 0x00 - 0x20 part
    51         *dest = med;
    52       } else {
    53         if (aErrorSignal) {
    54           res = NS_ERROR_ILLEGAL_INPUT;
    55           break;
    56         }
    57         // Unicode replacement value for unmappable chars
    58         *dest = 0xfffd;
    59       }
    60     }
    62     src += bcr;
    63     srcLen -= bcr;
    64     dest++;
    65   }
    67   if ((srcLen > 0) && (res == NS_OK)) res = NS_OK_UDEC_MOREOUTPUT;
    69   *aSrcLength = src - aSrc;
    70   *aDestLength  = dest - aDest;
    71   return res;
    72 }
    74 nsresult nsUnicodeDecodeHelper::ConvertByMultiTable(
    75                                      const char * aSrc, 
    76                                      int32_t * aSrcLength, 
    77                                      char16_t * aDest, 
    78                                      int32_t * aDestLength, 
    79                                      int32_t aTableCount, 
    80                                      const uRange * aRangeArray, 
    81                                      uScanClassID * aScanClassArray,
    82                                      uMappingTable ** aMappingTable,
    83                                      bool aErrorSignal)
    84 {
    85   uint8_t * src = (uint8_t *)aSrc;
    86   int32_t srcLen = *aSrcLength;
    87   char16_t * dest = aDest;
    88   char16_t * destEnd = aDest + *aDestLength;
    90   char16_t med;
    91   int32_t bcr; // byte count for read
    92   nsresult res = NS_OK;
    93   int32_t i;
    95   while ((srcLen > 0) && (dest < destEnd)) 
    96   {
    97     bool done= false;
    98     bool passRangeCheck = false;
    99     bool passScan = false;
   100     for (i=0; (!done) && (i<aTableCount); i++)  
   101     {
   102       if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) 
   103       {
   104         passRangeCheck = true;
   105         if (uScan(aScanClassArray[i], nullptr, src, 
   106                    reinterpret_cast<uint16_t*>(&med), srcLen, 
   107                    (uint32_t *)&bcr)) 
   108         {
   109           passScan = true;
   110           done = uMapCode((uTable*) aMappingTable[i], 
   111                           static_cast<uint16_t>(med), 
   112                           reinterpret_cast<uint16_t*>(dest)); 
   113         } // if (uScan ... )
   114       } // if Range
   115     } // for loop
   117     if(passRangeCheck && (! passScan))
   118     {
   119       if (res != NS_ERROR_ILLEGAL_INPUT)
   120         res = NS_OK_UDEC_MOREINPUT;
   121       break;
   122     }
   123     if(! done)
   124     {
   125       bcr = 1;
   126       if ((uint8_t)*src < 0x20) {
   127         // somehow some table miss the 0x00 - 0x20 part
   128         *dest = *src;
   129       } else if(*src == (uint8_t) 0xa0) {
   130         // handle nbsp
   131         *dest = 0x00a0;
   132       } else {
   133         // we need to decide how many byte we skip. We can use uScan to do this
   134         for (i=0; i<aTableCount; i++)  
   135         {
   136           if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) 
   137           {
   138             if (uScan(aScanClassArray[i], nullptr, src, 
   139                    reinterpret_cast<uint16_t*>(&med), srcLen, 
   140                    (uint32_t*)&bcr)) 
   141             { 
   142                // match the patten
   144                int32_t k; 
   145                for(k = 1; k < bcr; k++)
   146                {
   147                  if(0 == (src[k]  & 0x80))
   148                  { // only skip if all bytes > 0x80
   149                    // if we hit bytes <= 0x80, skip only one byte
   150                    bcr = 1;
   151                    break; 
   152                  }
   153                }
   154                break;
   155             }
   156           }
   157         }
   158         // treat it as NSBR if bcr == 1 and it is 0xa0
   159         if ((1==bcr)&&(*src == (uint8_t)0xa0 )) {
   160           *dest = 0x00a0;
   161         } else {
   162           if (aErrorSignal) {
   163             res = NS_ERROR_ILLEGAL_INPUT;
   164             break;
   165           }
   166           *dest = 0xfffd;
   167         }
   168       }
   169     }
   171     src += bcr;
   172     srcLen -= bcr;
   173     dest++;
   174   } // while
   176   if ((srcLen > 0) && (res == NS_OK)) res = NS_OK_UDEC_MOREOUTPUT;
   178   *aSrcLength = src - (uint8_t *)aSrc;
   179   *aDestLength  = dest - aDest;
   180   return res;
   181 }
   183 nsresult nsUnicodeDecodeHelper::ConvertByFastTable(
   184                                      const char * aSrc, 
   185                                      int32_t * aSrcLength, 
   186                                      char16_t * aDest, 
   187                                      int32_t * aDestLength, 
   188                                      const char16_t * aFastTable, 
   189                                      int32_t aTableSize,
   190                                      bool aErrorSignal)
   191 {
   192   uint8_t * src = (uint8_t *)aSrc;
   193   uint8_t * srcEnd = src;
   194   char16_t * dest = aDest;
   196   nsresult res;
   197   if (*aSrcLength > *aDestLength) {
   198     srcEnd += (*aDestLength);
   199     res = NS_PARTIAL_MORE_OUTPUT;
   200   } else {
   201     srcEnd += (*aSrcLength);
   202     res = NS_OK;
   203   }
   205   for (; src<srcEnd;) {
   206     *dest = aFastTable[*src];
   207     if (*dest == 0xfffd && aErrorSignal) {
   208       res = NS_ERROR_ILLEGAL_INPUT;
   209       break;
   210     }
   211     src++;
   212     dest++;
   213   }
   215   *aSrcLength = src - (uint8_t *)aSrc;
   216   *aDestLength  = dest - aDest;
   217   return res;
   218 }
   220 nsresult nsUnicodeDecodeHelper::CreateFastTable(
   221                                      uMappingTable  * aMappingTable,
   222                                      char16_t * aFastTable, 
   223                                      int32_t aTableSize)
   224 {
   225   int32_t tableSize = aTableSize;
   226   int32_t buffSize = aTableSize;
   227   nsAutoArrayPtr<char> buff(new char [buffSize]);
   229   char * p = buff;
   230   for (int32_t i=0; i<aTableSize; i++) *(p++) = i;
   231   return ConvertByTable(buff, &buffSize, aFastTable, &tableSize, 
   232                         u1ByteCharset, nullptr, aMappingTable);
   233 }

mercurial