//---------------------------------------------------------------------- // Class nsUnicodeDecodeHelper [implementation] nsresult nsUnicodeDecodeHelper::ConvertByTable( const char * aSrc, PRInt32 * aSrcLength, PRUnichar * aDest, PRInt32 * aDestLength, uScanClassID aScanClass, uShiftInTable * aShiftInTable, uMappingTable * aMappingTable) { const char * src = aSrc; PRInt32 srcLen = *aSrcLength; PRUnichar * dest = aDest; PRUnichar * destEnd = aDest + *aDestLength; PRUnichar med; PRInt32 bcr; // byte count for read nsresult res = NS_OK; while ((srcLen > 0) && (dest < destEnd)) { PRBool charFound; if (aScanClass == uMultibytesCharset) { NS_ASSERTION(aShiftInTable, "shift table missing"); charFound = uScanShift(aShiftInTable, NULL, (PRUint8 *)src, reinterpret_cast<PRUint16*>(&med), srcLen, (PRUint32 *)&bcr); } else { charFound = uScan(aScanClass, NULL, (PRUint8 *)src, reinterpret_cast<PRUint16*>(&med), srcLen, (PRUint32 *)&bcr); } if (!charFound) { res = NS_OK_UDEC_MOREINPUT; break; } if (!uMapCode((uTable*) aMappingTable, static_cast<PRUint16>(med), reinterpret_cast<PRUint16*>(dest))) { if (med < 0x20) { // somehow some table miss the 0x00 - 0x20 part *dest = med; } else { // Unicode replacement value for unmappable chars *dest = 0xfffd; } } src += bcr; srcLen -= bcr; dest++; } if ((srcLen > 0) && (res == NS_OK)) res = NS_OK_UDEC_MOREOUTPUT; *aSrcLength = src - aSrc; *aDestLength = dest - aDest; return res; }
nsresult nsUnicodeDecodeHelper::ConvertByMultiTable( const char * aSrc, PRInt32 * aSrcLength, PRUnichar * aDest, PRInt32 * aDestLength, PRInt32 aTableCount, const uRange * aRangeArray, uScanClassID * aScanClassArray, uMappingTable ** aMappingTable) { PRUint8 * src = (PRUint8 *)aSrc; PRInt32 srcLen = *aSrcLength; PRUnichar * dest = aDest; PRUnichar * destEnd = aDest + *aDestLength; PRUnichar med; PRInt32 bcr; // byte count for read nsresult res = NS_OK; PRInt32 i; while ((srcLen > 0) && (dest < destEnd)) { PRBool done= PR_FALSE; PRBool passRangeCheck = PR_FALSE; PRBool passScan = PR_FALSE; for (i=0; (!done) && (i<aTableCount); i++) { if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) { passRangeCheck = PR_TRUE; if (uScan(aScanClassArray[i], NULL, src, reinterpret_cast<PRUint16*>(&med), srcLen, (PRUint32 *)&bcr)) { passScan = PR_TRUE; done = uMapCode((uTable*) aMappingTable[i], static_cast<PRUint16>(med), reinterpret_cast<PRUint16*>(dest)); } // if (uScan ... ) } // if Range } // for loop if(passRangeCheck && (! passScan)) { res = NS_OK_UDEC_MOREINPUT; break; } if(! done) { bcr = 1; if ((PRUint8)*src < 0x20) { // somehow some table miss the 0x00 - 0x20 part *dest = *src; } else if(*src == (PRUint8) 0xa0) { // handle nbsp *dest = 0x00a0; } else { // we need to decide how many byte we skip. We can use uScan to do this for (i=0; i<aTableCount; i++) { if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) { if (uScan(aScanClassArray[i], NULL, src, reinterpret_cast<PRUint16*>(&med), srcLen, (PRUint32*)&bcr)) { // match the patten PRInt32 k; for(k = 1; k < bcr; k++) { if(0 == (src[k] & 0x80)) { // only skip if all bytes > 0x80 // if we hit bytes <= 0x80, skip only one byte bcr = 1; break; } } break; } } } // treat it as NSBR if bcr == 1 and it is 0xa0 *dest = ((1==bcr)&&(*src == (PRUint8)0xa0 )) ? 0x00a0 : 0xfffd; } } src += bcr; srcLen -= bcr; dest++; } // while if ((srcLen > 0) && (res == NS_OK)) res = NS_OK_UDEC_MOREOUTPUT; *aSrcLength = src - (PRUint8 *)aSrc; *aDestLength = dest - aDest; return res; }
nsresult nsUnicodeDecodeHelper::ConvertByMultiTable( const char * aSrc, int32_t * aSrcLength, PRUnichar * aDest, int32_t * aDestLength, int32_t aTableCount, const uRange * aRangeArray, uScanClassID * aScanClassArray, uMappingTable ** aMappingTable, bool aErrorSignal) { uint8_t * src = (uint8_t *)aSrc; int32_t srcLen = *aSrcLength; PRUnichar * dest = aDest; PRUnichar * destEnd = aDest + *aDestLength; PRUnichar med; int32_t bcr; // byte count for read nsresult res = NS_OK; int32_t i; while ((srcLen > 0) && (dest < destEnd)) { bool done= false; bool passRangeCheck = false; bool passScan = false; for (i=0; (!done) && (i<aTableCount); i++) { if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) { passRangeCheck = true; if (uScan(aScanClassArray[i], nullptr, src, reinterpret_cast<uint16_t*>(&med), srcLen, (uint32_t *)&bcr)) { passScan = true; done = uMapCode((uTable*) aMappingTable[i], static_cast<uint16_t>(med), reinterpret_cast<uint16_t*>(dest)); } // if (uScan ... ) } // if Range } // for loop if(passRangeCheck && (! passScan)) { if (res != NS_ERROR_ILLEGAL_INPUT) res = NS_OK_UDEC_MOREINPUT; break; } if(! done) { bcr = 1; if ((uint8_t)*src < 0x20) { // somehow some table miss the 0x00 - 0x20 part *dest = *src; } else if(*src == (uint8_t) 0xa0) { // handle nbsp *dest = 0x00a0; } else { // we need to decide how many byte we skip. We can use uScan to do this for (i=0; i<aTableCount; i++) { if ((aRangeArray[i].min <= *src) && (*src <= aRangeArray[i].max)) { if (uScan(aScanClassArray[i], nullptr, src, reinterpret_cast<uint16_t*>(&med), srcLen, (uint32_t*)&bcr)) { // match the patten int32_t k; for(k = 1; k < bcr; k++) { if(0 == (src[k] & 0x80)) { // only skip if all bytes > 0x80 // if we hit bytes <= 0x80, skip only one byte bcr = 1; break; } } break; } } } // treat it as NSBR if bcr == 1 and it is 0xa0 if ((1==bcr)&&(*src == (uint8_t)0xa0 )) { *dest = 0x00a0; } else { if (aErrorSignal) { res = NS_ERROR_ILLEGAL_INPUT; break; } *dest = 0xfffd; } } } src += bcr; srcLen -= bcr; dest++; } // while if ((srcLen > 0) && (res == NS_OK)) res = NS_OK_UDEC_MOREOUTPUT; *aSrcLength = src - (uint8_t *)aSrc; *aDestLength = dest - aDest; return res; }