#include "unicode/utypes.h"
#include "unicode/ucnv_cb.h"
#include "ucnv_bld.h"
#include "ucnv_cnv.h"
#include "cmemory.h"
U_CAPI void U_EXPORT2
ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args,
const char* source,
int32_t length,
int32_t offsetIndex,
UErrorCode * err)
{
int32_t togo;
int8_t toerr;
int32_t i;
if((args->targetLimit - args->target) >= length)
{
uprv_memcpy(args->target, source, length);
args->target += length;
if(args->offsets)
{
for(i=0;i<length;i++)
{
*(args->offsets++) = offsetIndex;
}
}
}
else
{
togo = (int32_t)(args->targetLimit - args->target);
uprv_memcpy(args->target, source, togo);
args->target += togo;
if(args->offsets)
{
for(i=0;i<togo;i++)
{
*(args->offsets++) = offsetIndex;
}
}
source += togo;
toerr = (int8_t)(length - togo);
uprv_memcpy(args->converter->charErrorBuffer +
args->converter->charErrorBufferLength,
source,
toerr * sizeof(source[0]));
args->converter->charErrorBufferLength += toerr;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
U_CAPI void U_EXPORT2
ucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args,
const UChar** source,
const UChar* sourceLimit,
int32_t offsetIndex,
UErrorCode * err)
{
char *oldTarget;
if(U_FAILURE(*err))
{
return;
}
oldTarget = args->target;
ucnv_fromUnicode(args->converter,
&args->target,
args->targetLimit,
source,
sourceLimit,
NULL,
FALSE,
err);
if(args->offsets)
{
while (args->target != oldTarget)
{
*(args->offsets)++ = offsetIndex;
oldTarget++;
}
}
if(*err == U_BUFFER_OVERFLOW_ERROR)
{
char *newTarget;
const char *newTargetLimit;
UErrorCode err2 = U_ZERO_ERROR;
int8_t errBuffLen;
errBuffLen = args->converter->charErrorBufferLength;
newTarget = (char *)(args->converter->charErrorBuffer + errBuffLen);
newTargetLimit = (char *)(args->converter->charErrorBuffer +
sizeof(args->converter->charErrorBuffer));
if(newTarget >= newTargetLimit)
{
*err = U_INTERNAL_PROGRAM_ERROR;
return;
}
args->converter->charErrorBufferLength = 0;
ucnv_fromUnicode(args->converter,
&newTarget,
newTargetLimit,
source,
sourceLimit,
NULL,
FALSE,
&err2);
args->converter->charErrorBufferLength = (int8_t)(
newTarget - (char*)args->converter->charErrorBuffer);
if((newTarget >= newTargetLimit) || (err2 == U_BUFFER_OVERFLOW_ERROR))
{
*err = U_INTERNAL_PROGRAM_ERROR;
return;
}
else
{
}
}
}
U_CAPI void U_EXPORT2
ucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args,
int32_t offsetIndex,
UErrorCode * err)
{
if(U_FAILURE(*err)) {
return;
}
if(args->converter->sharedData->impl->writeSub!=NULL) {
args->converter->sharedData->impl->writeSub(args, offsetIndex, err);
} else if(args->converter->subChar1!=0 && args->converter->invalidUCharBuffer[0]<=0xff) {
ucnv_cbFromUWriteBytes(args,
(const char *)&args->converter->subChar1, 1,
offsetIndex, err);
} else {
ucnv_cbFromUWriteBytes(args,
(const char *)args->converter->subChar, args->converter->subCharLen,
offsetIndex, err);
}
}
U_CAPI void U_EXPORT2
ucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args,
const UChar* source,
int32_t length,
int32_t offsetIndex,
UErrorCode * err)
{
int32_t togo;
int8_t toerr;
int32_t i;
if(U_FAILURE(*err))
{
return;
}
if((args->targetLimit - args->target) >= length)
{
uprv_memcpy(args->target, source, length * sizeof(args->target[0]) );
args->target += length;
if(args->offsets)
{
for(i=0;i<length;i++)
{
*(args->offsets++) = offsetIndex;
}
}
}
else
{
togo = (int32_t)(args->targetLimit - args->target);
uprv_memcpy(args->target, source, togo * sizeof(args->target[0]) );
args->target += togo;
if(args->offsets)
{
for(i=0;i<togo;i++)
{
*(args->offsets++) = offsetIndex;
}
}
source += togo;
toerr = (int8_t)(length - togo);
uprv_memcpy(args->converter->UCharErrorBuffer +
args->converter->UCharErrorBufferLength,
source,
toerr * sizeof(source[0]));
args->converter->UCharErrorBufferLength += toerr;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
U_CAPI void U_EXPORT2
ucnv_cbToUWriteSub (UConverterToUnicodeArgs *args,
int32_t offsetIndex,
UErrorCode * err)
{
static const UChar kSubstituteChar1 = 0x1A, kSubstituteChar = 0xFFFD;
if(args->converter->invalidCharLength == 1 && args->converter->subChar1 != 0) {
ucnv_cbToUWriteUChars(args, &kSubstituteChar1, 1, offsetIndex, err);
} else {
ucnv_cbToUWriteUChars(args, &kSubstituteChar, 1, offsetIndex, err);
}
}