2
******************************************************************************
4
* Copyright (C) 2000-2001, International Business Machines
5
* Corporation and others. All Rights Reserved.
7
******************************************************************************
10
* Implements all the low level conversion functions
11
* T_UnicodeConverter_{to,from}Unicode_$ConversionType
15
* 06/29/2000 helena Major rewrite of the callback APIs.
18
#include "unicode/utypes.h"
19
#include "unicode/ucnv_err.h"
21
#include "unicode/ucnv.h"
24
/*Empties the internal unicode output buffer */
25
void ucnv_flushInternalUnicodeBuffer (UConverter * _this,
27
int32_t * myTargetIndex,
32
int32_t myUCharErrorBufferLength = _this->UCharErrorBufferLength;
34
if (myUCharErrorBufferLength <= targetLength)
36
/*we have enough space
37
*So we just copy the whole Error Buffer in to the output stream
39
uprv_memcpy (myTarget,
40
_this->UCharErrorBuffer,
41
sizeof (UChar) * myUCharErrorBufferLength);
45
for (i=0; i<myUCharErrorBufferLength;i++) (*offsets)[i] = -1;
46
*offsets += myUCharErrorBufferLength;
48
*myTargetIndex += myUCharErrorBufferLength;
49
_this->UCharErrorBufferLength = 0;
53
/* We don't have enough space so we copy as much as we can
54
* on the output stream and update the object
55
* by updating the internal buffer*/
56
uprv_memcpy (myTarget, _this->UCharErrorBuffer, sizeof (UChar) * targetLength);
60
for (i=0; i< targetLength;i++) (*offsets)[i] = -1;
61
*offsets += targetLength;
63
uprv_memmove (_this->UCharErrorBuffer,
64
_this->UCharErrorBuffer + targetLength,
65
sizeof (UChar) * (myUCharErrorBufferLength - targetLength));
66
_this->UCharErrorBufferLength -= (int8_t) targetLength;
67
*myTargetIndex = targetLength;
68
*err = U_BUFFER_OVERFLOW_ERROR;
72
/*Empties the internal codepage output buffer */
73
void ucnv_flushInternalCharBuffer (UConverter * _this,
75
int32_t * myTargetIndex,
80
int32_t myCharErrorBufferLength = _this->charErrorBufferLength;
82
/*we have enough space */
83
if (myCharErrorBufferLength <= targetLength)
85
uprv_memcpy (myTarget, _this->charErrorBuffer, myCharErrorBufferLength);
89
for (i=0; i<myCharErrorBufferLength;i++) (*offsets)[i] = -1;
90
*offsets += myCharErrorBufferLength;
93
*myTargetIndex += myCharErrorBufferLength;
94
_this->charErrorBufferLength = 0;
98
/* We don't have enough space so we copy as much as we can
99
* on the output stream and update the object
101
uprv_memcpy (myTarget, _this->charErrorBuffer, targetLength);
105
for (i=0; i< targetLength;i++) (*offsets)[i] = -1;
106
*offsets += targetLength;
108
uprv_memmove (_this->charErrorBuffer,
109
_this->charErrorBuffer + targetLength,
110
(myCharErrorBufferLength - targetLength));
111
_this->charErrorBufferLength -= (int8_t) targetLength;
112
*myTargetIndex = targetLength;
113
*err = U_BUFFER_OVERFLOW_ERROR;
118
* This function is useful for implementations of getNextUChar().
119
* After a call to a callback function or to toUnicode(), an output buffer
120
* begins with a Unicode code point that needs to be returned as UChar32,
121
* and all following code units must be prepended to the - potentially
122
* prefilled - overflow buffer in the UConverter.
123
* The buffer should be at least of capacity UTF_MAX_CHAR_LENGTH so that a
124
* complete UChar32's UChars fit into it.
126
* @param cnv The converter that will get remaining UChars copied to its overflow area.
127
* @param buffer An array of UChars that was passed into a callback function
128
* or a toUnicode() function.
129
* @param length The number of code units (UChars) that are actually in the buffer.
131
* @return The code point from the first UChars in the buffer.
134
ucnv_getUChar32KeepOverflow(UConverter *cnv, const UChar *buffer, int32_t length) {
142
/* get the first code point in the buffer */
144
UTF_NEXT_CHAR_SAFE(buffer, i, length, c, FALSE);
146
/* there are UChars left in the buffer that need to go into the overflow buffer */
147
UChar *overflow=cnv->UCharErrorBuffer;
148
int32_t j=cnv->UCharErrorBufferLength;
151
/* move the overflow buffer contents to make room for the extra UChars */
154
cnv->UCharErrorBufferLength=(int8_t)(k=(length-i)+j);
156
overflow[--k]=overflow[--j];
159
cnv->UCharErrorBufferLength=(int8_t)(length-i);
162
/* copy the remaining UChars to the beginning of the overflow buffer */
164
overflow[j++]=buffer[i++];
170
/* update target offsets after a callback call */
172
ucnv_updateCallbackOffsets(int32_t *offsets, int32_t length, int32_t sourceIndex) {
175
/* add the sourceIndex to the relative offsets that the callback wrote */
177
*offsets+=sourceIndex;
182
/* sourceIndex==-1, set -1 offsets */
196
* This is a simple implementation of ucnv_getNextUChar() that uses the
197
* converter's toUnicode() function. See ucnv_cnv.h for details.
200
ucnv_getNextUCharFromToUImpl(UConverterToUnicodeArgs *pArgs,
201
T_ToUnicodeFunction toU,
203
UErrorCode *pErrorCode) {
204
UChar buffer[UTF_MAX_CHAR_LENGTH];
205
const char *realLimit=pArgs->sourceLimit;
207
pArgs->target=buffer;
208
pArgs->targetLimit=buffer+UTF_MAX_CHAR_LENGTH;
210
while(pArgs->source<realLimit) {
211
/* feed in one byte at a time to make sure to get only one character out */
212
pArgs->sourceLimit=pArgs->source+1;
213
pArgs->flush= (UBool)(pArgs->sourceLimit==realLimit);
215
/* convert this byte and check the result */
216
toU(pArgs, pErrorCode);
217
if(U_SUCCESS(*pErrorCode)) {
218
int32_t length=pArgs->target-buffer;
220
/* this test is UTF-16 specific */
221
if(/* some output and
222
(source consumed or don't collect surrogate pairs or not a surrogate or a surrogate pair) */
224
(pArgs->flush || !collectPairs || !UTF_IS_FIRST_SURROGATE(buffer[0]) || length==2)
226
return ucnv_getUChar32KeepOverflow(pArgs->converter, buffer, length);
228
/* else continue with the loop */
229
} else if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
230
*pErrorCode=U_ZERO_ERROR;
231
return ucnv_getUChar32KeepOverflow(pArgs->converter, buffer, UTF_MAX_CHAR_LENGTH);
238
/* no output because of empty input or only state changes and skipping callbacks */
239
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;