/* Note: Recursion may occur in the cb functions, be sure to update the offsets correctly if you don't use ucnv_cbXXX functions. Make sure you don't use the same callback within the same call stack if the complexity arises. */ U_CAPI void U_EXPORT2 ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args, const char* source, int32_t length, int32_t offsetIndex, UErrorCode * err) { if(U_FAILURE(*err)) { return; } ucnv_fromUWriteBytes( args->converter, source, length, &args->target, args->targetLimit, &args->offsets, offsetIndex, err); }
static void _UTF16BEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, UErrorCode *pErrorCode) { UConverter *cnv; const UChar *source; char *target; int32_t *offsets; uint32_t targetCapacity, length, sourceIndex; UChar c, trail; char overflow[4]; source=pArgs->source; length=(int32_t)(pArgs->sourceLimit-source); if(length<=0) { /* no input, nothing to do */ return; } cnv=pArgs->converter; /* write the BOM if necessary */ if(cnv->fromUnicodeStatus==UCNV_NEED_TO_WRITE_BOM) { static const char bom[]={ (char)0xfe, (char)0xff }; ucnv_fromUWriteBytes(cnv, bom, 2, &pArgs->target, pArgs->targetLimit, &pArgs->offsets, -1, pErrorCode); cnv->fromUnicodeStatus=0; } target=pArgs->target; if(target >= pArgs->targetLimit) { *pErrorCode=U_BUFFER_OVERFLOW_ERROR; return; } targetCapacity=(uint32_t)(pArgs->targetLimit-target); offsets=pArgs->offsets; sourceIndex=0; /* c!=0 indicates in several places outside the main loops that a surrogate was found */ if((c=(UChar)cnv->fromUChar32)!=0 && U16_IS_TRAIL(trail=*source) && targetCapacity>=4) { /* the last buffer ended with a lead surrogate, output the surrogate pair */ ++source; --length; target[0]=(uint8_t)(c>>8); target[1]=(uint8_t)c; target[2]=(uint8_t)(trail>>8); target[3]=(uint8_t)trail; target+=4; targetCapacity-=4; if(offsets!=NULL) { *offsets++=-1; *offsets++=-1; *offsets++=-1; *offsets++=-1; } sourceIndex=1; cnv->fromUChar32=c=0; }