#include "unicode/utypes.h"
#include "unicode/ucnv_err.h"
#include "unicode/ucnv.h"
#include "unicode/uset.h"
#include "ucnv_cnv.h"
#include "cmemory.h"
void ucnv_flushInternalUnicodeBuffer (UConverter * _this,
UChar * myTarget,
int32_t * myTargetIndex,
int32_t targetLength,
int32_t** offsets,
UErrorCode * err)
{
int32_t myUCharErrorBufferLength = _this->UCharErrorBufferLength;
if (myUCharErrorBufferLength <= targetLength)
{
uprv_memcpy (myTarget,
_this->UCharErrorBuffer,
sizeof (UChar) * myUCharErrorBufferLength);
if (offsets)
{
int32_t i=0;
for (i=0; i<myUCharErrorBufferLength;i++) (*offsets)[i] = -1;
*offsets += myUCharErrorBufferLength;
}
*myTargetIndex += myUCharErrorBufferLength;
_this->UCharErrorBufferLength = 0;
}
else
{
uprv_memcpy (myTarget, _this->UCharErrorBuffer, sizeof (UChar) * targetLength);
if (offsets)
{
int32_t i=0;
for (i=0; i< targetLength;i++) (*offsets)[i] = -1;
*offsets += targetLength;
}
uprv_memmove (_this->UCharErrorBuffer,
_this->UCharErrorBuffer + targetLength,
sizeof (UChar) * (myUCharErrorBufferLength - targetLength));
_this->UCharErrorBufferLength -= (int8_t) targetLength;
*myTargetIndex = targetLength;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
void ucnv_flushInternalCharBuffer (UConverter * _this,
char *myTarget,
int32_t * myTargetIndex,
int32_t targetLength,
int32_t** offsets,
UErrorCode * err)
{
int32_t myCharErrorBufferLength = _this->charErrorBufferLength;
if (myCharErrorBufferLength <= targetLength)
{
uprv_memcpy (myTarget, _this->charErrorBuffer, myCharErrorBufferLength);
if (offsets)
{
int32_t i=0;
for (i=0; i<myCharErrorBufferLength;i++) (*offsets)[i] = -1;
*offsets += myCharErrorBufferLength;
}
*myTargetIndex += myCharErrorBufferLength;
_this->charErrorBufferLength = 0;
}
else
{
uprv_memcpy (myTarget, _this->charErrorBuffer, targetLength);
if (offsets)
{
int32_t i=0;
for (i=0; i< targetLength;i++) (*offsets)[i] = -1;
*offsets += targetLength;
}
uprv_memmove (_this->charErrorBuffer,
_this->charErrorBuffer + targetLength,
(myCharErrorBufferLength - targetLength));
_this->charErrorBufferLength -= (int8_t) targetLength;
*myTargetIndex = targetLength;
*err = U_BUFFER_OVERFLOW_ERROR;
}
}
U_CFUNC UChar32
ucnv_getUChar32KeepOverflow(UConverter *cnv, const UChar *buffer, int32_t length) {
UChar32 c;
int32_t i;
if(length<=0) {
return 0xffff;
}
i=0;
UTF_NEXT_CHAR(buffer, i, length, c);
if(i<length) {
UChar *overflow=cnv->UCharErrorBuffer;
int32_t j=cnv->UCharErrorBufferLength;
if(j>0) {
int32_t k;
cnv->UCharErrorBufferLength=(int8_t)(k=(length-i)+j);
do {
overflow[--k]=overflow[--j];
} while(j>0);
} else {
cnv->UCharErrorBufferLength=(int8_t)(length-i);
}
do {
overflow[j++]=buffer[i++];
} while(i<length);
}
return c;
}
U_CFUNC int32_t *
ucnv_updateCallbackOffsets(int32_t *offsets, int32_t length, int32_t sourceIndex) {
if(offsets!=NULL) {
if(sourceIndex>=0) {
while(length>0) {
*offsets+=sourceIndex;
++offsets;
--length;
}
} else {
while(length>0) {
*offsets=-1;
++offsets;
--length;
}
}
return offsets;
} else {
return NULL;
}
}
U_CFUNC UChar32
ucnv_getNextUCharFromToUImpl(UConverterToUnicodeArgs *pArgs,
T_ToUnicodeFunction toU,
UBool collectPairs,
UErrorCode *pErrorCode) {
UChar buffer[UTF_MAX_CHAR_LENGTH];
const char *realLimit=pArgs->sourceLimit;
pArgs->target=buffer;
pArgs->targetLimit=buffer+UTF_MAX_CHAR_LENGTH;
while(pArgs->source<realLimit) {
pArgs->sourceLimit=pArgs->source+1;
pArgs->flush= (UBool)(pArgs->sourceLimit==realLimit);
toU(pArgs, pErrorCode);
if(U_SUCCESS(*pErrorCode)) {
int32_t length=(int32_t)(pArgs->target-buffer);
if(
length>0 &&
(pArgs->flush || !collectPairs || !UTF_IS_FIRST_SURROGATE(buffer[0]) || length==2)
) {
return ucnv_getUChar32KeepOverflow(pArgs->converter, buffer, length);
}
} else if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
*pErrorCode=U_ZERO_ERROR;
return ucnv_getUChar32KeepOverflow(pArgs->converter, buffer, UTF_MAX_CHAR_LENGTH);
} else {
return 0xffff;
}
}
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0xffff;
}
U_CFUNC void
ucnv_getCompleteUnicodeSet(const UConverter *cnv,
USet *set,
UConverterUnicodeSet which,
UErrorCode *pErrorCode) {
uset_addRange(set, 0, 0x10ffff);
}
U_CFUNC void
ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv,
USet *set,
UConverterUnicodeSet which,
UErrorCode *pErrorCode) {
uset_addRange(set, 0, 0xd7ff);
uset_addRange(set, 0xe000, 0x10ffff);
}