U_CAPI void U_EXPORT2 ucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode * err) { UConverter *converter; int32_t length; if(U_FAILURE(*err)) { return; } converter = args->converter; length = converter->subCharLen; if(length == 0) { return; } if(length < 0) { /* * Write/convert the substitution string. Its real length is -length. * Unlike the escape callback, we need not change the converter's * callback function because ucnv_setSubstString() verified that * the string can be converted, so we will not get a conversion error * and will not recurse. * At worst we should get a U_BUFFER_OVERFLOW_ERROR. */ const UChar *source = (const UChar *)converter->subChars; ucnv_cbFromUWriteUChars(args, &source, source - length, offsetIndex, err); return; } if(converter->sharedData->impl->writeSub!=NULL) { converter->sharedData->impl->writeSub(args, offsetIndex, err); } else if(converter->subChar1!=0 && (uint16_t)converter->invalidUCharBuffer[0]<=(uint16_t)0xffu) { /* TODO: Is this untestable because the MBCS converter has a writeSub function to call and the other converters don't use subChar1? */ ucnv_cbFromUWriteBytes(args, (const char *)&converter->subChar1, 1, offsetIndex, err); } else { ucnv_cbFromUWriteBytes(args, (const char *)converter->subChars, length, offsetIndex, err); } }
static void encoderReplaceCallback(const void* rawContext, UConverterFromUnicodeArgs* fromArgs, const UChar*, int32_t, UChar32, UConverterCallbackReason, UErrorCode * err) { if (rawContext == NULL) { return; } const EncoderCallbackContext* context = reinterpret_cast<const EncoderCallbackContext*>(rawContext); *err = U_ZERO_ERROR; ucnv_cbFromUWriteBytes(fromArgs, context->replacementBytes, context->replacementByteCount, 0, err); }
// Invalid character handler when writing escaped entities for unrepresentable // characters. See the declaration of TextCodec::encode for more. static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { if (reason == UCNV_UNASSIGNED) { *err = U_ZERO_ERROR; UnencodableReplacementArray entity; int entityLen = TextCodec::getUnencodableReplacement(codePoint, URLEncodedEntitiesForUnencodables, entity); ucnv_cbFromUWriteBytes(fromUArgs, entity, entityLen, 0, err); } else UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err); }
void CIRCSocket::IcuExtFromUCallback( UConverterFromUnicodeArgs* fromArgs, const UChar* codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { // See comment in CIRCSocket::IcuExtToUCallback static const std::set<UChar32> scAllowedChars = {0x02, 0x03, 0x04, 0x0F, 0x12, 0x16, 0x1D, 0x1F}; if (reason == UCNV_ILLEGAL && scAllowedChars.count(codePoint)) { *err = U_ZERO_ERROR; char c = codePoint; ucnv_cbFromUWriteBytes(fromArgs, &c, 1, 0, err); return; } Csock::IcuExtFromUCallback(fromArgs, codeUnits, length, codePoint, reason, err); }