1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Copyright (C) 2000-2006, International Business Machines 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * ucnv_cb.c: 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * External APIs for the ICU's codeset conversion library 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Helena Shih 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Modification History: 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Date Name Description 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 7/28/2000 srl Implementation 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @name Character Conversion C API 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucnv_cb.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_bld.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucnv_cnv.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* need to update the offsets when the target moves. */ 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Note: Recursion may occur in the cb functions, be sure to update the offsets correctly 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruif you don't use ucnv_cbXXX functions. Make sure you don't use the same callback within 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruthe same call stack if the complexity arises. */ 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args, 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char* source, 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length, 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetIndex, 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_fromUWriteBytes( 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args->converter, 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, length, 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &args->target, args->targetLimit, 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &args->offsets, offsetIndex, 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru err); 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args, 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar** source, 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* sourceLimit, 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetIndex, 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This is a fun one. Recursion can occur - we're basically going to 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru just retry shoving data through the same converter. Note, if you got 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru here through some kind of invalid sequence, you maybe should emit a 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru reset sequence of some kind and/or call ucnv_reset(). Since this 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru IS an actual conversion, take care that you've changed the callback 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru or the data, or you'll get an infinite loop. 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Please set the err value to something reasonable before calling 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru into this. 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *oldTarget; 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru oldTarget = args->target; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_fromUnicode(args->converter, 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &args->target, 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args->targetLimit, 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, /* no offsets */ 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, /* no flush */ 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru err); 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(args->offsets) 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (args->target != oldTarget) /* if it moved at all.. */ 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *(args->offsets)++ = offsetIndex; 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru oldTarget++; 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Note, if you did something like used a Stop subcallback, things would get interesting. 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru In fact, here's where we want to return the partially consumed in-source! 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(*err == U_BUFFER_OVERFLOW_ERROR) 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* && (*source < sourceLimit && args->target >= args->targetLimit) 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru -- S. Hrcek */ 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Overflowed the target. Now, we'll write into the charErrorBuffer. 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru It's a fixed size. If we overflow it... Hmm */ 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *newTarget; 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *newTargetLimit; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode err2 = U_ZERO_ERROR; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t errBuffLen; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errBuffLen = args->converter->charErrorBufferLength; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* start the new target at the first free slot in the errbuff.. */ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newTarget = (char *)(args->converter->charErrorBuffer + errBuffLen); 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newTargetLimit = (char *)(args->converter->charErrorBuffer + 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sizeof(args->converter->charErrorBuffer)); 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(newTarget >= newTargetLimit) 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_INTERNAL_PROGRAM_ERROR; 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* We're going to tell the converter that the errbuff len is empty. 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This prevents the existing errbuff from being 'flushed' out onto 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itself. If the errbuff is needed by the converter this time, 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru we're hosed - we're out of space! */ 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args->converter->charErrorBufferLength = 0; 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_fromUnicode(args->converter, 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &newTarget, 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newTargetLimit, 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceLimit, 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FALSE, 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &err2); 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* We can go ahead and overwrite the length here. We know just how 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru to recalculate it. */ 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args->converter->charErrorBufferLength = (int8_t)( 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newTarget - (char*)args->converter->charErrorBuffer); 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((newTarget >= newTargetLimit) || (err2 == U_BUFFER_OVERFLOW_ERROR)) 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* now we're REALLY in trouble. 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Internal program error - callback shouldn't have written this much 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data! 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *err = U_INTERNAL_PROGRAM_ERROR; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*else {*/ 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* sub errs could be invalid/truncated/illegal chars or w/e. 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru These might want to be passed on up.. But the problem is, we already 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru need to pass U_BUFFER_OVERFLOW_ERROR. That has to override these 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru other errs.. */ 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(err2)) 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ?? 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /*}*/ 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args, 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetIndex, 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UConverter *converter; 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length; 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter = args->converter; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length = converter->subCharLen; 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length == 0) { 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length < 0) { 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Write/convert the substitution string. Its real length is -length. 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Unlike the escape callback, we need not change the converter's 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * callback function because ucnv_setSubstString() verified that 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the string can be converted, so we will not get a conversion error 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and will not recurse. 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * At worst we should get a U_BUFFER_OVERFLOW_ERROR. 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar *source = (const UChar *)converter->subChars; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_cbFromUWriteUChars(args, &source, source - length, offsetIndex, err); 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(converter->sharedData->impl->writeSub!=NULL) { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru converter->sharedData->impl->writeSub(args, offsetIndex, err); 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if(converter->subChar1!=0 && (uint16_t)converter->invalidUCharBuffer[0]<=(uint16_t)0xffu) { 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TODO: Is this untestable because the MBCS converter has a writeSub function to call 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru and the other converters don't use subChar1? 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_cbFromUWriteBytes(args, 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (const char *)&converter->subChar1, 1, 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsetIndex, err); 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_cbFromUWriteBytes(args, 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (const char *)converter->subChars, length, 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offsetIndex, err); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args, 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* source, 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length, 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetIndex, 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*err)) { 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_toUWriteUChars( 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru args->converter, 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru source, length, 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &args->target, args->targetLimit, 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru &args->offsets, offsetIndex, 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru err); 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruucnv_cbToUWriteSub (UConverterToUnicodeArgs *args, 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t offsetIndex, 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode * err) 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static const UChar kSubstituteChar1 = 0x1A, kSubstituteChar = 0xFFFD; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* could optimize this case, just one uchar */ 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(args->converter->invalidCharLength == 1 && args->converter->subChar1 != 0) { 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_cbToUWriteUChars(args, &kSubstituteChar1, 1, offsetIndex, err); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ucnv_cbToUWriteUChars(args, &kSubstituteChar, 1, offsetIndex, err); 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 260