| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> | 3 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 #include "wtf/Assertions.h" | 30 #include "wtf/Assertions.h" |
| 31 #include "wtf/StringExtras.h" | 31 #include "wtf/StringExtras.h" |
| 32 #include "wtf/Threading.h" | 32 #include "wtf/Threading.h" |
| 33 #include "wtf/WTFThreadData.h" | 33 #include "wtf/WTFThreadData.h" |
| 34 #include "wtf/text/CString.h" | 34 #include "wtf/text/CString.h" |
| 35 #include "wtf/text/CharacterNames.h" | 35 #include "wtf/text/CharacterNames.h" |
| 36 #include "wtf/text/StringBuilder.h" | 36 #include "wtf/text/StringBuilder.h" |
| 37 #include <unicode/ucnv.h> | 37 #include <unicode/ucnv.h> |
| 38 #include <unicode/ucnv_cb.h> | 38 #include <unicode/ucnv_cb.h> |
| 39 | 39 |
| 40 using std::min; | |
| 41 | |
| 42 namespace WTF { | 40 namespace WTF { |
| 43 | 41 |
| 44 const size_t ConversionBufferSize = 16384; | 42 const size_t ConversionBufferSize = 16384; |
| 45 | 43 |
| 46 ICUConverterWrapper::~ICUConverterWrapper() | 44 ICUConverterWrapper::~ICUConverterWrapper() |
| 47 { | 45 { |
| 48 if (converter) | 46 if (converter) |
| 49 ucnv_close(converter); | 47 ucnv_close(converter); |
| 50 } | 48 } |
| 51 | 49 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 | 308 |
| 311 class ErrorCallbackSetter { | 309 class ErrorCallbackSetter { |
| 312 public: | 310 public: |
| 313 ErrorCallbackSetter(UConverter* converter, bool stopOnError) | 311 ErrorCallbackSetter(UConverter* converter, bool stopOnError) |
| 314 : m_converter(converter) | 312 : m_converter(converter) |
| 315 , m_shouldStopOnEncodingErrors(stopOnError) | 313 , m_shouldStopOnEncodingErrors(stopOnError) |
| 316 { | 314 { |
| 317 if (m_shouldStopOnEncodingErrors) { | 315 if (m_shouldStopOnEncodingErrors) { |
| 318 UErrorCode err = U_ZERO_ERROR; | 316 UErrorCode err = U_ZERO_ERROR; |
| 319 ucnv_setToUCallBack(m_converter, UCNV_TO_U_CALLBACK_SUBSTITUTE, | 317 ucnv_setToUCallBack(m_converter, UCNV_TO_U_CALLBACK_SUBSTITUTE, |
| 320 UCNV_SUB_STOP_ON_ILLEGAL, &m_savedAction, | 318 UCNV_SUB_STOP_ON_ILLEGAL, &m_savedAction, |
| 321 &m_savedContext, &err); | 319 &m_savedContext, &err); |
| 322 ASSERT(err == U_ZERO_ERROR); | 320 ASSERT(err == U_ZERO_ERROR); |
| 323 } | 321 } |
| 324 } | 322 } |
| 325 ~ErrorCallbackSetter() | 323 ~ErrorCallbackSetter() |
| 326 { | 324 { |
| 327 if (m_shouldStopOnEncodingErrors) { | 325 if (m_shouldStopOnEncodingErrors) { |
| 328 UErrorCode err = U_ZERO_ERROR; | 326 UErrorCode err = U_ZERO_ERROR; |
| 329 const void* oldContext; | 327 const void* oldContext; |
| 330 UConverterToUCallback oldAction; | 328 UConverterToUCallback oldAction; |
| 331 ucnv_setToUCallBack(m_converter, m_savedAction, | 329 ucnv_setToUCallBack(m_converter, m_savedAction, m_savedContext, &old
Action, &oldContext, &err); |
| 332 m_savedContext, &oldAction, | |
| 333 &oldContext, &err); | |
| 334 ASSERT(oldAction == UCNV_TO_U_CALLBACK_SUBSTITUTE); | 330 ASSERT(oldAction == UCNV_TO_U_CALLBACK_SUBSTITUTE); |
| 335 ASSERT(!strcmp(static_cast<const char*>(oldContext), UCNV_SUB_STOP_O
N_ILLEGAL)); | 331 ASSERT(!strcmp(static_cast<const char*>(oldContext), UCNV_SUB_STOP_O
N_ILLEGAL)); |
| 336 ASSERT(err == U_ZERO_ERROR); | 332 ASSERT(err == U_ZERO_ERROR); |
| 337 } | 333 } |
| 338 } | 334 } |
| 339 | 335 |
| 340 private: | 336 private: |
| 341 UConverter* m_converter; | 337 UConverter* m_converter; |
| 342 bool m_shouldStopOnEncodingErrors; | 338 bool m_shouldStopOnEncodingErrors; |
| 343 const void* m_savedContext; | 339 const void* m_savedContext; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 357 } | 353 } |
| 358 | 354 |
| 359 ErrorCallbackSetter callbackSetter(m_converterICU, stopOnError); | 355 ErrorCallbackSetter callbackSetter(m_converterICU, stopOnError); |
| 360 | 356 |
| 361 StringBuilder result; | 357 StringBuilder result; |
| 362 | 358 |
| 363 UChar buffer[ConversionBufferSize]; | 359 UChar buffer[ConversionBufferSize]; |
| 364 UChar* bufferLimit = buffer + ConversionBufferSize; | 360 UChar* bufferLimit = buffer + ConversionBufferSize; |
| 365 const char* source = reinterpret_cast<const char*>(bytes); | 361 const char* source = reinterpret_cast<const char*>(bytes); |
| 366 const char* sourceLimit = source + length; | 362 const char* sourceLimit = source + length; |
| 367 int32_t* offsets = NULL; | 363 int32_t* offsets = nullptr; |
| 368 UErrorCode err = U_ZERO_ERROR; | 364 UErrorCode err = U_ZERO_ERROR; |
| 369 | 365 |
| 370 do { | 366 do { |
| 371 int ucharsDecoded = decodeToBuffer(buffer, bufferLimit, source, sourceLi
mit, offsets, flush != DoNotFlush, err); | 367 int ucharsDecoded = decodeToBuffer(buffer, bufferLimit, source, sourceLi
mit, offsets, flush != DoNotFlush, err); |
| 372 result.append(buffer, ucharsDecoded); | 368 result.append(buffer, ucharsDecoded); |
| 373 } while (err == U_BUFFER_OVERFLOW_ERROR); | 369 } while (err == U_BUFFER_OVERFLOW_ERROR); |
| 374 | 370 |
| 375 if (U_FAILURE(err)) { | 371 if (U_FAILURE(err)) { |
| 376 // flush the converter so it can be reused, and not be bothered by this
error. | 372 // flush the converter so it can be reused, and not be bothered by this
error. |
| 377 do { | 373 do { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 // characters. See the declaration of TextCodec::encode for more. | 416 // characters. See the declaration of TextCodec::encode for more. |
| 421 static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeA
rgs* fromUArgs, const UChar* codeUnits, int32_t length, | 417 static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeA
rgs* fromUArgs, const UChar* codeUnits, int32_t length, |
| 422 UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) | 418 UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
| 423 { | 419 { |
| 424 if (reason == UCNV_UNASSIGNED) { | 420 if (reason == UCNV_UNASSIGNED) { |
| 425 *err = U_ZERO_ERROR; | 421 *err = U_ZERO_ERROR; |
| 426 | 422 |
| 427 UnencodableReplacementArray entity; | 423 UnencodableReplacementArray entity; |
| 428 int entityLen = TextCodec::getUnencodableReplacement(codePoint, URLEncod
edEntitiesForUnencodables, entity); | 424 int entityLen = TextCodec::getUnencodableReplacement(codePoint, URLEncod
edEntitiesForUnencodables, entity); |
| 429 ucnv_cbFromUWriteBytes(fromUArgs, entity, entityLen, 0, err); | 425 ucnv_cbFromUWriteBytes(fromUArgs, entity, entityLen, 0, err); |
| 430 } else | 426 } else { |
| 431 UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codeP
oint, reason, err); | 427 UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codeP
oint, reason, err); |
| 428 } |
| 432 } | 429 } |
| 433 | 430 |
| 434 #if defined(USING_SYSTEM_ICU) | 431 #if defined(USING_SYSTEM_ICU) |
| 435 // Substitutes special GBK characters, escaping all other unassigned entities. | 432 // Substitutes special GBK characters, escaping all other unassigned entities. |
| 436 static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fr
omUArgs, const UChar* codeUnits, int32_t length, | 433 static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fr
omUArgs, const UChar* codeUnits, int32_t length, |
| 437 UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) | 434 UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
| 438 { | 435 { |
| 439 UChar outChar; | 436 UChar outChar; |
| 440 if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { | 437 if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { |
| 441 const UChar* source = &outChar; | 438 const UChar* source = &outChar; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 }; | 500 }; |
| 504 | 501 |
| 505 CString TextCodecICU::encodeInternal(const TextCodecInput& input, UnencodableHan
dling handling) | 502 CString TextCodecICU::encodeInternal(const TextCodecInput& input, UnencodableHan
dling handling) |
| 506 { | 503 { |
| 507 const UChar* source = input.begin(); | 504 const UChar* source = input.begin(); |
| 508 const UChar* end = input.end(); | 505 const UChar* end = input.end(); |
| 509 | 506 |
| 510 UErrorCode err = U_ZERO_ERROR; | 507 UErrorCode err = U_ZERO_ERROR; |
| 511 | 508 |
| 512 switch (handling) { | 509 switch (handling) { |
| 513 case QuestionMarksForUnencodables: | 510 case QuestionMarksForUnencodables: |
| 514 ucnv_setSubstChars(m_converterICU, "?", 1, &err); | 511 ucnv_setSubstChars(m_converterICU, "?", 1, &err); |
| 515 #if !defined(USING_SYSTEM_ICU) | 512 #if !defined(USING_SYSTEM_ICU) |
| 516 ucnv_setFromUCallBack(m_converterICU, UCNV_FROM_U_CALLBACK_SUBSTITUT
E, 0, 0, 0, &err); | 513 ucnv_setFromUCallBack(m_converterICU, UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0
, 0, 0, &err); |
| 517 #else | 514 #else |
| 518 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCallb
ackSubstitute : UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0, 0, 0, &err); | 515 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCallbackS
ubstitute : UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0, 0, 0, &err); |
| 519 #endif | 516 #endif |
| 520 break; | 517 break; |
| 521 case EntitiesForUnencodables: | 518 case EntitiesForUnencodables: |
| 522 #if !defined(USING_SYSTEM_ICU) | 519 #if !defined(USING_SYSTEM_ICU) |
| 523 ucnv_setFromUCallBack(m_converterICU, UCNV_FROM_U_CALLBACK_ESCAPE, U
CNV_ESCAPE_XML_DEC, 0, 0, &err); | 520 ucnv_setFromUCallBack(m_converterICU, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_
ESCAPE_XML_DEC, 0, 0, &err); |
| 524 #else | 521 #else |
| 525 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCallb
ackEscape : UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_XML_DEC, 0, 0, &err); | 522 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCallbackE
scape : UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_XML_DEC, 0, 0, &err); |
| 526 #endif | 523 #endif |
| 527 break; | 524 break; |
| 528 case URLEncodedEntitiesForUnencodables: | 525 case URLEncodedEntitiesForUnencodables: |
| 529 #if !defined(USING_SYSTEM_ICU) | 526 #if !defined(USING_SYSTEM_ICU) |
| 530 ucnv_setFromUCallBack(m_converterICU, urlEscapedEntityCallback, 0, 0
, 0, &err); | 527 ucnv_setFromUCallBack(m_converterICU, urlEscapedEntityCallback, 0, 0, 0,
&err); |
| 531 #else | 528 #else |
| 532 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkUrlEs
capedEntityCallack : urlEscapedEntityCallback, 0, 0, 0, &err); | 529 ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkUrlEscape
dEntityCallack : urlEscapedEntityCallback, 0, 0, 0, &err); |
| 533 #endif | 530 #endif |
| 534 break; | 531 break; |
| 535 } | 532 } |
| 536 | 533 |
| 537 ASSERT(U_SUCCESS(err)); | 534 ASSERT(U_SUCCESS(err)); |
| 538 if (U_FAILURE(err)) | 535 if (U_FAILURE(err)) |
| 539 return CString(); | 536 return CString(); |
| 540 | 537 |
| 541 Vector<char> result; | 538 Vector<char> result; |
| 542 size_t size = 0; | 539 size_t size = 0; |
| 543 do { | 540 do { |
| 544 char buffer[ConversionBufferSize]; | 541 char buffer[ConversionBufferSize]; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 574 { | 571 { |
| 575 return encodeCommon(characters, length, handling); | 572 return encodeCommon(characters, length, handling); |
| 576 } | 573 } |
| 577 | 574 |
| 578 CString TextCodecICU::encode(const LChar* characters, size_t length, Unencodable
Handling handling) | 575 CString TextCodecICU::encode(const LChar* characters, size_t length, Unencodable
Handling handling) |
| 579 { | 576 { |
| 580 return encodeCommon(characters, length, handling); | 577 return encodeCommon(characters, length, handling); |
| 581 } | 578 } |
| 582 | 579 |
| 583 } // namespace WTF | 580 } // namespace WTF |
| OLD | NEW |