From b0eb1e1f5d2a157bbd7ff9286bcc99edefbbe15e Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Tue, 12 Aug 2003 00:20:20 +0000 Subject: [PATCH] ICU-2235 test arguments and data instead of noop even if the data need not change, to catch data problems early X-SVN-Rev: 12805 --- icu4c/source/common/putil.c | 84 +++++++++++++++++++++++++++++++++- icu4c/source/common/udataswp.c | 73 +++++++++++++++++------------ icu4c/source/common/udataswp.h | 18 ++++++++ 3 files changed, 145 insertions(+), 30 deletions(-) diff --git a/icu4c/source/common/putil.c b/icu4c/source/common/putil.c index b45f6332cc..17dd04aaff 100644 --- a/icu4c/source/common/putil.c +++ b/icu4c/source/common/putil.c @@ -2146,6 +2146,7 @@ uprv_isInvariantUString(const UChar *s, int32_t length) { /* UDataSwapFn implementations used in udataswp.c ------- */ +/* convert ASCII to EBCDIC and verify that all characters are invariant */ U_CFUNC int32_t uprv_ebcdicFromAscii(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, @@ -2159,7 +2160,7 @@ uprv_ebcdicFromAscii(const UDataSwapper *ds, if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } - if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData!=NULL) { + if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } @@ -2183,6 +2184,46 @@ uprv_ebcdicFromAscii(const UDataSwapper *ds, return length; } +/* this function only checks and copies ASCII strings without conversion */ +U_CFUNC int32_t +uprv_copyAscii(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + const uint8_t *s; + uint8_t c; + + int32_t count; + + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + /* setup and checking */ + s=(const uint8_t *)inData; + count=length; + while(count>0) { + c=*s++; + if(!CHAR_IS_INVARIANT(c)) { + udata_printError(ds, "uprv_copyFromAscii() string[%] contains a variant character in position %d\n", + length, length-count); + *pErrorCode=U_INVALID_CHAR_FOUND; + return 0; + } + --count; + } + + if(length>0 && inData!=outData) { + uprv_memcpy(outData, inData, length); + } + + return length; +} + +/* convert EBCDIC to ASCII and verify that all characters are invariant */ U_CFUNC int32_t uprv_asciiFromEbcdic(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, @@ -2196,7 +2237,7 @@ uprv_asciiFromEbcdic(const UDataSwapper *ds, if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } - if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData!=NULL) { + if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } @@ -2220,6 +2261,45 @@ uprv_asciiFromEbcdic(const UDataSwapper *ds, return length; } +/* this function only checks and copies EBCDIC strings without conversion */ +U_CFUNC int32_t +uprv_copyEbcdic(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + const uint8_t *s; + uint8_t c; + + int32_t count; + + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + /* setup and checking */ + s=(const uint8_t *)inData; + count=length; + while(count>0) { + c=*s++; + if(c!=0 && ((c=asciiFromEbcdic[c])==0 || !CHAR_IS_INVARIANT(c))) { + udata_printError(ds, "uprv_copyEbcdic() string[%] contains a variant character in position %d\n", + length, length-count); + *pErrorCode=U_INVALID_CHAR_FOUND; + return 0; + } + --count; + } + + if(length>0 && inData!=outData) { + uprv_memcpy(outData, inData, length); + } + + return length; +} + /* compare invariant strings; variant characters compare less than others and unlike each other */ U_CFUNC int32_t uprv_compareInvAscii(const UDataSwapper *ds, diff --git a/icu4c/source/common/udataswp.c b/icu4c/source/common/udataswp.c index 1e0131f974..47a8ac2815 100644 --- a/icu4c/source/common/udataswp.c +++ b/icu4c/source/common/udataswp.c @@ -27,26 +27,6 @@ /* swapping primitives ------------------------------------------------------ */ -/* generic noop swapper for when nothing needs to be done */ -static int32_t U_CALLCONV -uprv_swapNone(const UDataSwapper *ds, - const void *inData, int32_t length, void *outData, - UErrorCode *pErrorCode) { - if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { - return 0; - } - if(ds==NULL || inData==NULL || length<0 || outData==NULL) { - *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; - return 0; - } - - if(length>0 && inData!=outData) { - uprv_memcpy(outData, inData, length); - } - - return length; -} - static int32_t U_CALLCONV uprv_swapArray16(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, @@ -77,6 +57,24 @@ uprv_swapArray16(const UDataSwapper *ds, return length; } +static int32_t U_CALLCONV +uprv_copyArray16(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + if(length>0 && inData!=outData) { + uprv_memcpy(outData, inData, length); + } + return length; +} + static int32_t U_CALLCONV uprv_swapArray32(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, @@ -107,6 +105,24 @@ uprv_swapArray32(const UDataSwapper *ds, return length; } +static int32_t U_CALLCONV +uprv_copyArray32(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + if(ds==NULL || inData==NULL || length<0 || (length&3)!=0 || outData==NULL) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + if(length>0 && inData!=outData) { + uprv_memcpy(outData, inData, length); + } + return length; +} + static uint16_t U_CALLCONV uprv_readSwapUInt16(uint16_t x) { return (uint16_t)((x<<8)|(x>>8)); @@ -257,15 +273,16 @@ udata_openSwapper(UBool inIsBigEndian, uint8_t inCharset, swapper->readUInt16= inIsBigEndian==U_IS_BIG_ENDIAN ? uprv_readDirectUInt16 : uprv_readSwapUInt16; swapper->readUInt32= inIsBigEndian==U_IS_BIG_ENDIAN ? uprv_readDirectUInt32 : uprv_readSwapUInt32; - swapper->compareInvChars= inCharset==U_ASCII_FAMILY ? uprv_compareInvAscii : uprv_compareInvEbcdic; + if(inCharset==U_ASCII_FAMILY) { + swapper->compareInvChars=uprv_compareInvAscii; + swapper->swapInvChars= outCharset==U_ASCII_FAMILY ? uprv_copyAscii : uprv_ebcdicFromAscii; + } else /* U_EBCDIC_FAMILY */ { + swapper->compareInvChars=uprv_compareInvEbcdic; + swapper->swapInvChars= outCharset==U_EBCDIC_FAMILY ? uprv_copyEbcdic : uprv_asciiFromEbcdic; + } - swapper->swapArray16= inIsBigEndian==outIsBigEndian ? uprv_swapNone : uprv_swapArray16; - swapper->swapArray32= inIsBigEndian==outIsBigEndian ? uprv_swapNone : uprv_swapArray32; - - swapper->swapInvChars= - inCharset==outCharset ? uprv_swapNone : - inCharset==U_ASCII_FAMILY ? uprv_ebcdicFromAscii : - uprv_asciiFromEbcdic; + swapper->swapArray16= inIsBigEndian==outIsBigEndian ? uprv_copyArray16 : uprv_swapArray16; + swapper->swapArray32= inIsBigEndian==outIsBigEndian ? uprv_copyArray32 : uprv_swapArray32; return swapper; } diff --git a/icu4c/source/common/udataswp.h b/icu4c/source/common/udataswp.h index ffa4fd652c..5107f0f78b 100644 --- a/icu4c/source/common/udataswp.h +++ b/icu4c/source/common/udataswp.h @@ -208,6 +208,15 @@ uprv_ebcdicFromAscii(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, UErrorCode *pErrorCode); +/** + * Copy invariant ASCII char * strings and verify they are invariant. + * @internal + */ +U_CFUNC int32_t +uprv_copyAscii(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode); + /** * Swap invariant char * strings EBCDIC->ASCII. * @internal @@ -217,6 +226,15 @@ uprv_asciiFromEbcdic(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, UErrorCode *pErrorCode); +/** + * Copy invariant EBCDIC char * strings and verify they are invariant. + * @internal + */ +U_CFUNC int32_t +uprv_copyEbcdic(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode); + /** * Compare ASCII invariant char * with Unicode invariant UChar * * @internal