1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2000-2009, International Business Machines 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************** 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: ucnvhz.c 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created on: 2000oct16 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Ram Viswanadha 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 10/31/2000 Ram Implemented offsets logic function 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnv.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnv_cb.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uset.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_bld.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_cnv.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_imp.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UCNV_TILDE 0x7E /* ~ */ 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UCNV_OPEN_BRACE 0x7B /* { */ 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define UCNV_CLOSE_BRACE 0x7D /* } */ 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SB_ESCAPE "\x7E\x7D" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DB_ESCAPE "\x7E\x7B" 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TILDE_ESCAPE "\x7E\x7E" 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ESC_LEN 2 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define CONCAT_ESCAPE_MACRO( args, targetIndex,targetLength,strToAppend, err, len,sourceIndex){ \ 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(len-->0){ \ 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(targetIndex < targetLength){ \ 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->target[targetIndex] = (unsigned char) *strToAppend; \ 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->offsets!=NULL){ \ 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(offsets++) = sourceIndex-1; \ 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } \ 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetIndex++; \ 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } \ 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ \ 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->charErrorBuffer[(int)args->converter->charErrorBufferLength++] = (unsigned char) *strToAppend; \ 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err =U_BUFFER_OVERFLOW_ERROR; \ 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } \ 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strToAppend++; \ 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } \ 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct{ 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter* gbConverter; 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t targetIndex; 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t sourceIndex; 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isEscapeAppended; 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isStateDBCS; 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isTargetUCharDBCS; 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isEmptySegment; 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}UConverterDataHZ; 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZOpen(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){ 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *gbConverter; 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pArgs->onlyTestIsLoadable) { 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_canCreateConverter("GBK", errorCode); /* errorCode carries result */ 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gbConverter = ucnv_open("GBK", errorCode); 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*errorCode)) { 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->toUnicodeStatus = 0; 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->fromUnicodeStatus= 0; 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->mode=0; 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->fromUChar32=0x0000; 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->extraInfo = uprv_malloc(sizeof(UConverterDataHZ)); 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cnv->extraInfo != NULL){ 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memset(cnv->extraInfo, 0, sizeof(UConverterDataHZ)); 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->gbConverter = gbConverter; 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close(gbConverter); 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *errorCode = U_MEMORY_ALLOCATION_ERROR; 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZClose(UConverter *cnv){ 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cnv->extraInfo != NULL) { 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_close (((UConverterDataHZ *) (cnv->extraInfo))->gbConverter); 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!cnv->isExtraLocal) { 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(cnv->extraInfo); 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->extraInfo = NULL; 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZReset(UConverter *cnv, UConverterResetChoice choice){ 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(choice<=UCNV_RESET_TO_UNICODE) { 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->toUnicodeStatus = 0; 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->mode=0; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cnv->extraInfo != NULL){ 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->isStateDBCS = FALSE; 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->isEmptySegment = FALSE; 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(choice!=UCNV_RESET_TO_UNICODE) { 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->fromUnicodeStatus= 0; 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cnv->fromUChar32=0x0000; 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cnv->extraInfo != NULL){ 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->isEscapeAppended = FALSE; 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->targetIndex = 0; 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->sourceIndex = 0; 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->isTargetUCharDBCS = FALSE; 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**************************************HZ Encoding************************************************* 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Rules for HZ encoding 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* In ASCII mode, a byte is interpreted as an ASCII character, unless a 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* '~' is encountered. The character '~' is an escape character. By 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* convention, it must be immediately followed ONLY by '~', '{' or '\n' 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* (<LF>), with the following special meaning. 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 1. The escape sequence '~~' is interpreted as a '~'. 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 2. The escape-to-GB sequence '~{' switches the mode from ASCII to GB. 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 3. The escape sequence '~\n' is a line-continuation marker to be 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* consumed with no output produced. 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* In GB mode, characters are interpreted two bytes at a time as (pure) 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* GB codes until the escape-from-GB code '~}' is read. This code 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* switches the mode from GB back to ASCII. (Note that the escape- 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* from-GB code '~}' ($7E7D) is outside the defined GB range.) 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Source: RFC 1842 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Note that the formal syntax in RFC 1842 is invalid. I assume that the 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* intended definition of single-byte-segment is as follows (pedberg): 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* single-byte-segment = single-byte-seq 1*single-byte-char 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UConverter_toUnicode_HZ_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* err){ 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char tempBuf[2]; 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *mySource = ( char *) args->source; 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *myTarget = args->target; 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *mySourceLimit = args->sourceLimit; 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 targetUniChar = 0x0000; 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t mySourceChar = 0x0000; 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterDataHZ* myData=(UConverterDataHZ*)(args->converter->extraInfo); 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf[0]=0; 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf[1]=0; 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Calling code already handles this situation. */ 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if ((args->converter == NULL) || (args->targetLimit < args->target) || (mySourceLimit < args->source)){ 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ILLEGAL_ARGUMENT_ERROR; 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(mySource< mySourceLimit){ 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(myTarget < args->targetLimit){ 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar= (unsigned char) *mySource++; 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->converter->mode == UCNV_TILDE) { 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* second byte after ~ */ 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->mode=0; 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(mySourceChar) { 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x0A: 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* no output for ~\n (line-continuation marker) */ 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCNV_TILDE: 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->offsets) { 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->offsets[myTarget - args->target]=(int32_t)(mySource - args->source - 2); 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(myTarget++)=(UChar)mySourceChar; 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCNV_OPEN_BRACE: 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCNV_CLOSE_BRACE: 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isStateDBCS = (mySourceChar == UCNV_OPEN_BRACE); 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (myData->isEmptySegment) { 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; /* we are handling it, reset to avoid future spurious errors */ 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ILLEGAL_ESCAPE_SEQUENCE; 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUCallbackReason = UCNV_IRREGULAR; 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[0] = UCNV_TILDE; 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[1] = mySourceChar; 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toULength = 2; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->target = myTarget; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->source = mySource; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = TRUE; 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if the first byte is equal to TILDE and the trail byte 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is not a valid byte then it is an error condition 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Ticket 5691: consistent illegal sequences: 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - We include at least the first byte in the illegal sequence. 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - If any of the non-initial bytes could be the start of a character, 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * we stop the illegal sequence before the first one of those. 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; /* different error here, reset this to avoid spurious future error */ 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ILLEGAL_ESCAPE_SEQUENCE; 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[0] = UCNV_TILDE; 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( myData->isStateDBCS ? 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (0x21 <= mySourceChar && mySourceChar <= 0x7e) : 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar <= 0x7f 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* The current byte could be the start of a character: Back it out. */ 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toULength = 1; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --mySource; 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Include the current byte in the illegal sequence. */ 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[1] = mySourceChar; 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toULength = 2; 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->target = myTarget; 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->source = mySource; 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(myData->isStateDBCS) { 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->converter->toUnicodeStatus == 0x00){ 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* lead byte */ 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(mySourceChar == UCNV_TILDE) { 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->mode = UCNV_TILDE; 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* add another bit to distinguish a 0 byte from not having seen a lead byte */ 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUnicodeStatus = (uint32_t) (mySourceChar | 0x100); 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; /* the segment has something, either valid or will produce a different error, so reset this */ 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* trail byte */ 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int leadIsOk, trailIsOk; 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t leadByte = args->converter->toUnicodeStatus & 0xff; 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = 0xffff; 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Ticket 5691: consistent illegal sequences: 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - We include at least the first byte in the illegal sequence. 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - If any of the non-initial bytes could be the start of a character, 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * we stop the illegal sequence before the first one of those. 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * In HZ DBCS, if the second byte is in the 21..7e range, 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * we report only the first byte as the illegal sequence. 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Otherwise we convert or report the pair of bytes. 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) leadIsOk = (uint8_t)(leadByte - 0x21) <= (0x7d - 0x21); 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) trailIsOk = (uint8_t)(mySourceChar - 0x21) <= (0x7e - 0x21); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (leadIsOk && trailIsOk) { 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf[0] = (char) (leadByte+0x80) ; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf[1] = (char) (mySourceChar+0x80); 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = ucnv_MBCSSimpleGetNextUChar(myData->gbConverter->sharedData, 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf, 2, args->converter->useFallback); 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar= (leadByte << 8) | mySourceChar; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if (trailIsOk) { 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* report a single illegal byte and continue with the following DBCS starter byte */ 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --mySource; 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar = (int32_t)leadByte; 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* report a pair of illegal bytes if the second byte is not a DBCS starter */ 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* add another bit so that the code below writes 2 bytes in case of error */ 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar= 0x10000 | (leadByte << 8) | mySourceChar; 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUnicodeStatus =0x00; 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(mySourceChar == UCNV_TILDE) { 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->mode = UCNV_TILDE; 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(mySourceChar <= 0x7f) { 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = (UChar)mySourceChar; /* ASCII */ 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; /* the segment has something valid */ 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = 0xffff; 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myData->isEmptySegment = FALSE; /* different error here, reset this to avoid spurious future error */ 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(targetUniChar < 0xfffe){ 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->offsets) { 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->offsets[myTarget - args->target]=(int32_t)(mySource - args->source - 1-(myData->isStateDBCS)); 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(myTarget++)=(UChar)targetUniChar; 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else /* targetUniChar>=0xfffe */ { 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(targetUniChar == 0xfffe){ 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_INVALID_CHAR_FOUND; 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ILLEGAL_CHAR_FOUND; 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(mySourceChar > 0xff){ 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[0] = (uint8_t)(mySourceChar >> 8); 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[1] = (uint8_t)mySourceChar; 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toULength=2; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toUBytes[0] = (uint8_t)mySourceChar; 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->toULength=1; 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err =U_BUFFER_OVERFLOW_ERROR; 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->target = myTarget; 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->source = mySource; 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UConverter_fromUnicode_HZ_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args, 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode * err){ 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *mySource = args->source; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *myTarget = args->target; 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t* offsets = args->offsets; 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t mySourceIndex = 0; 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t myTargetIndex = 0; 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t targetLength = (int32_t)(args->targetLimit - myTarget); 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t mySourceLength = (int32_t)(args->sourceLimit - args->source); 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length=0; 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t targetUniChar = 0x0000; 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 mySourceChar = 0x0000; 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterDataHZ *myConverterData=(UConverterDataHZ*)args->converter->extraInfo; 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isTargetUCharDBCS = (UBool) myConverterData->isTargetUCharDBCS; 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool oldIsTargetUCharDBCS = isTargetUCharDBCS; 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int len =0; 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char* escSeq=NULL; 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Calling code already handles this situation. */ 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if ((args->converter == NULL) || (args->targetLimit < myTarget) || (args->sourceLimit < args->source)){ 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ILLEGAL_ARGUMENT_ERROR; 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(args->converter->fromUChar32!=0 && myTargetIndex < targetLength) { 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto getTrail; 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*writing the char to the output stream */ 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (mySourceIndex < mySourceLength){ 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = missingCharMarker; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (myTargetIndex < targetLength){ 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar = (UChar) mySource[mySourceIndex++]; 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) oldIsTargetUCharDBCS = isTargetUCharDBCS; 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(mySourceChar ==UCNV_TILDE){ 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*concatEscape(args, &myTargetIndex, &targetLength,"\x7E\x7E",err,2,&mySourceIndex);*/ 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len = ESC_LEN; 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) escSeq = TILDE_ESCAPE; 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CONCAT_ESCAPE_MACRO(args, myTargetIndex, targetLength, escSeq,err,len,mySourceIndex); 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(mySourceChar <= 0x7f) { 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length = 1; 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = mySourceChar; 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length= ucnv_MBCSFromUChar32(myConverterData->gbConverter->sharedData, 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar,&targetUniChar,args->converter->useFallback); 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we can only use lead bytes 21..7D and trail bytes 21..7E */ 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( length == 2 && 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint16_t)(targetUniChar - 0xa1a1) <= (0xfdfe - 0xa1a1) && 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint8_t)(targetUniChar - 0xa1) <= (0xfe - 0xa1) 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar -= 0x8080; 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar = missingCharMarker; 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (targetUniChar != missingCharMarker){ 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myConverterData->isTargetUCharDBCS = isTargetUCharDBCS = (UBool)(targetUniChar>0x00FF); 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(oldIsTargetUCharDBCS != isTargetUCharDBCS || !myConverterData->isEscapeAppended ){ 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*Shifting from a double byte to single byte mode*/ 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!isTargetUCharDBCS){ 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len =ESC_LEN; 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) escSeq = SB_ESCAPE; 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CONCAT_ESCAPE_MACRO(args, myTargetIndex, targetLength, escSeq,err,len,mySourceIndex); 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myConverterData->isEscapeAppended = TRUE; 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ /* Shifting from a single byte to double byte mode*/ 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len =ESC_LEN; 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) escSeq = DB_ESCAPE; 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CONCAT_ESCAPE_MACRO(args, myTargetIndex, targetLength, escSeq,err,len,mySourceIndex); 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myConverterData->isEscapeAppended = TRUE; 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(isTargetUCharDBCS){ 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( myTargetIndex <targetLength){ 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myTarget[myTargetIndex++] =(char) (targetUniChar >> 8); 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsets){ 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(offsets++) = mySourceIndex-1; 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(myTargetIndex < targetLength){ 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myTarget[myTargetIndex++] =(char) targetUniChar; 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsets){ 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(offsets++) = mySourceIndex-1; 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (char) targetUniChar; 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_BUFFER_OVERFLOW_ERROR; 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] =(char) (targetUniChar >> 8); 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (char) targetUniChar; 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_BUFFER_OVERFLOW_ERROR; 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( myTargetIndex <targetLength){ 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myTarget[myTargetIndex++] = (char) (targetUniChar ); 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(offsets){ 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *(offsets++) = mySourceIndex-1; 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->charErrorBuffer[args->converter->charErrorBufferLength++] = (char) targetUniChar; 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_BUFFER_OVERFLOW_ERROR; 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* oops.. the code point is unassigned */ 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*Handle surrogates */ 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*check if the char is a First surrogate*/ 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UTF_IS_SURROGATE(mySourceChar)) { 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UTF_IS_SURROGATE_FIRST(mySourceChar)) { 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->fromUChar32=mySourceChar; 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTrail: 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*look ahead to find the trail surrogate*/ 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(mySourceIndex < mySourceLength) { 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test the following code unit */ 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar trail=(UChar) args->source[mySourceIndex]; 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UTF_IS_SECOND_SURROGATE(trail)) { 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++mySourceIndex; 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mySourceChar=UTF16_GET_PAIR_VALUE(args->converter->fromUChar32, trail); 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->fromUChar32=0x00; 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* there are no surrogates in GB2312*/ 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_INVALID_CHAR_FOUND; 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* exit this condition tree */ 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* this is an unmatched lead code unit (1st surrogate) */ 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* callback(illegal) */ 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err=U_ILLEGAL_CHAR_FOUND; 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* no more input */ 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_ZERO_ERROR; 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* this is an unmatched trail code unit (2nd surrogate) */ 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* callback(illegal) */ 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err=U_ILLEGAL_CHAR_FOUND; 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* callback(unassigned) for a BMP code point */ 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_INVALID_CHAR_FOUND; 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->converter->fromUChar32=mySourceChar; 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *err = U_BUFFER_OVERFLOW_ERROR; 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetUniChar=missingCharMarker; 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->target += myTargetIndex; 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args->source += mySourceIndex; 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) myConverterData->isTargetUCharDBCS = isTargetUCharDBCS; 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err) { 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *cnv = args->converter; 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterDataHZ *convData=(UConverterDataHZ *) cnv->extraInfo; 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *p; 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[4]; 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) p = buffer; 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( convData->isTargetUCharDBCS){ 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *p++= UCNV_TILDE; 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *p++= UCNV_CLOSE_BRACE; 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) convData->isTargetUCharDBCS=FALSE; 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *p++= (char)cnv->subChars[0]; 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_cbFromUWriteBytes(args, 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer, (int32_t)(p - buffer), 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsetIndex, err); 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Structure for cloning an HZ converter into a single memory block. 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ucnv_safeClone() of the HZ converter will align the entire cloneHZStruct, 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and then ucnv_safeClone() of the sub-converter may additionally align 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * subCnv inside the cloneHZStruct, for which we need the deadSpace after 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * subCnv. This is because UAlignedMemory may be larger than the actually 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * necessary alignment size for the platform. 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The other cloneHZStruct fields will not be moved around, 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and are aligned properly with cloneHZStruct's alignment. 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct cloneHZStruct 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter cnv; 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter subCnv; 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UAlignedMemory deadSpace; 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterDataHZ mydata; 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UConverter * 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZ_SafeClone(const UConverter *cnv, 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *stackBuffer, 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *pBufferSize, 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) struct cloneHZStruct * localClone; 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t size, bufferSizeNeeded = sizeof(struct cloneHZStruct); 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)){ 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */ 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pBufferSize = bufferSizeNeeded; 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) localClone = (struct cloneHZStruct *)stackBuffer; 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* ucnv.c/ucnv_safeClone() copied the main UConverter already */ 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(&localClone->mydata, cnv->extraInfo, sizeof(UConverterDataHZ)); 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) localClone->cnv.extraInfo = &localClone->mydata; 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) localClone->cnv.isExtraLocal = TRUE; 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* deep-clone the sub-converter */ 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */ 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)localClone->cnv.extraInfo)->gbConverter = 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_safeClone(((UConverterDataHZ*)cnv->extraInfo)->gbConverter, &localClone->subCnv, &size, status); 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &localClone->cnv; 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_HZ_GetUnicodeSet(const UConverter *cnv, 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const USetAdder *sa, 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverterUnicodeSet which, 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* HZ converts all of ASCII */ 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sa->addRange(sa->set, 0, 0x7f); 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* add all of the code points that the sub-converter handles */ 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_MBCSGetFilteredUnicodeSetForUnicode( 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((UConverterDataHZ*)cnv->extraInfo)->gbConverter->sharedData, 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sa, which, UCNV_SET_FILTER_HZ, 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UConverterImpl _HZImpl={ 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCNV_HZ, 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZOpen, 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZClose, 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZReset, 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter_toUnicode_HZ_OFFSETS_LOGIC, 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter_toUnicode_HZ_OFFSETS_LOGIC, 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter_fromUnicode_HZ_OFFSETS_LOGIC, 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter_fromUnicode_HZ_OFFSETS_LOGIC, 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZ_WriteSub, 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZ_SafeClone, 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _HZ_GetUnicodeSet 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UConverterStaticData _HZStaticData={ 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(UConverterStaticData), 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "HZ", 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0, 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCNV_IBM, 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCNV_HZ, 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1, 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 4, 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0x1a, 0, 0, 0 }, 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1, 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FALSE, 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FALSE, 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0, 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0, 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* reserved */ 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UConverterSharedData _HZData={ 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(UConverterSharedData), 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ~((uint32_t) 0), 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &_HZStaticData, 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FALSE, 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &_HZImpl, 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_LEGACY_CONVERSION */ 641