Index: icu46/source/tools/icuswap/icuswap.cpp |
=================================================================== |
--- icu46/source/tools/icuswap/icuswap.cpp (revision 0) |
+++ icu46/source/tools/icuswap/icuswap.cpp (revision 0) |
@@ -0,0 +1,648 @@ |
+/* |
+******************************************************************************* |
+* |
+* Copyright (C) 2003-2007, International Business Machines |
+* Corporation and others. All Rights Reserved. |
+* |
+******************************************************************************* |
+* file name: icuswap.cpp |
+* encoding: US-ASCII |
+* tab size: 8 (not used) |
+* indentation:4 |
+* |
+* created on: 2003aug08 |
+* created by: Markus W. Scherer |
+* |
+* This tool takes an ICU data file and "swaps" it, that is, changes its |
+* platform properties between big-/little-endianness and ASCII/EBCDIC charset |
+* families. |
+* The modified data file is written to a new file. |
+* Useful as an install-time tool for shipping only one flavor of ICU data |
+* and preparing data files for the target platform. |
+* Will not work with data DLLs (shared libraries). |
+*/ |
+ |
+#include "unicode/utypes.h" |
+#include "unicode/putil.h" |
+#include "unicode/udata.h" |
+#include "cmemory.h" |
+#include "cstring.h" |
+#include "uinvchar.h" |
+#include "uarrsort.h" |
+#include "ucmndata.h" |
+#include "udataswp.h" |
+#include "swapimpl.h" |
+#include "toolutil.h" |
+#include "uoptions.h" |
+ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+/* definitions */ |
+ |
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) |
+#define DEFAULT_PADDING_LENGTH 15 |
+ |
+static UOption options[]={ |
+ UOPTION_HELP_H, |
+ UOPTION_HELP_QUESTION_MARK, |
+ UOPTION_DEF("type", 't', UOPT_REQUIRES_ARG) |
+}; |
+ |
+enum { |
+ OPT_HELP_H, |
+ OPT_HELP_QUESTION_MARK, |
+ OPT_OUT_TYPE |
+}; |
+ |
+static int32_t |
+fileSize(FILE *f) { |
+ int32_t size; |
+ |
+ fseek(f, 0, SEEK_END); |
+ size=(int32_t)ftell(f); |
+ fseek(f, 0, SEEK_SET); |
+ return size; |
+} |
+ |
+/** |
+ * Swap an ICU .dat package, including swapping of enclosed items. |
+ */ |
+U_CFUNC int32_t U_CALLCONV |
+udata_swapPackage(const char *inFilename, const char *outFilename, |
+ const UDataSwapper *ds, |
+ const void *inData, int32_t length, void *outData, |
+ UErrorCode *pErrorCode); |
+ |
+U_CDECL_BEGIN |
+static void U_CALLCONV |
+printError(void *context, const char *fmt, va_list args) { |
+ vfprintf((FILE *)context, fmt, args); |
+} |
+U_CDECL_END |
+ |
+static int |
+printUsage(const char *pname, UBool ishelp) { |
+ fprintf(stderr, |
+ "%csage: %s [ -h, -?, --help ] -tl|-tb|-te|--type=b|... infilename outfilename\n", |
+ ishelp ? 'U' : 'u', pname); |
+ if(ishelp) { |
+ fprintf(stderr, |
+ "\nOptions: -h, -?, --help print this message and exit\n" |
+ " Read the input file, swap its platform properties according\n" |
+ " to the -t or --type option, and write the result to the output file.\n" |
+ " -tl change to little-endian/ASCII charset family\n" |
+ " -tb change to big-endian/ASCII charset family\n" |
+ " -te change to big-endian/EBCDIC charset family\n"); |
+ } |
+ |
+ return !ishelp; |
+} |
+ |
+extern int |
+main(int argc, char *argv[]) { |
+ FILE *in, *out; |
+ const char *pname; |
+ char *data; |
+ int32_t length; |
+ UBool ishelp; |
+ int rc; |
+ |
+ UDataSwapper *ds; |
+ const UDataInfo *pInfo; |
+ UErrorCode errorCode; |
+ uint8_t outCharset; |
+ UBool outIsBigEndian; |
+ |
+ U_MAIN_INIT_ARGS(argc, argv); |
+ |
+ fprintf(stderr, "Warning: icuswap is an obsolete tool and it will be removed in the next ICU release.\nPlease use the icupkg tool instead.\n"); |
+ |
+ /* get the program basename */ |
+ pname=strrchr(argv[0], U_FILE_SEP_CHAR); |
+ if(pname==NULL) { |
+ pname=strrchr(argv[0], '/'); |
+ } |
+ if(pname!=NULL) { |
+ ++pname; |
+ } else { |
+ pname=argv[0]; |
+ } |
+ |
+ argc=u_parseArgs(argc, argv, LENGTHOF(options), options); |
+ ishelp=options[OPT_HELP_H].doesOccur || options[OPT_HELP_QUESTION_MARK].doesOccur; |
+ if(ishelp || argc!=3) { |
+ return printUsage(pname, ishelp); |
+ } |
+ |
+ /* parse the output type option */ |
+ data=(char *)options[OPT_OUT_TYPE].value; |
+ if(data[0]==0 || data[1]!=0) { |
+ /* the type must be exactly one letter */ |
+ return printUsage(pname, FALSE); |
+ } |
+ switch(data[0]) { |
+ case 'l': |
+ outIsBigEndian=FALSE; |
+ outCharset=U_ASCII_FAMILY; |
+ break; |
+ case 'b': |
+ outIsBigEndian=TRUE; |
+ outCharset=U_ASCII_FAMILY; |
+ break; |
+ case 'e': |
+ outIsBigEndian=TRUE; |
+ outCharset=U_EBCDIC_FAMILY; |
+ break; |
+ default: |
+ return printUsage(pname, FALSE); |
+ } |
+ |
+ in=out=NULL; |
+ data=NULL; |
+ |
+ /* open the input file, get its length, allocate memory for it, read the file */ |
+ in=fopen(argv[1], "rb"); |
+ if(in==NULL) { |
+ fprintf(stderr, "%s: unable to open input file \"%s\"\n", pname, argv[1]); |
+ rc=2; |
+ goto done; |
+ } |
+ |
+ length=fileSize(in); |
+ if(length<DEFAULT_PADDING_LENGTH) { |
+ fprintf(stderr, "%s: empty input file \"%s\"\n", pname, argv[1]); |
+ rc=2; |
+ goto done; |
+ } |
+ |
+ /* |
+ * +15: udata_swapPackage() may need to add a few padding bytes to the |
+ * last item if charset swapping is done, |
+ * because the last item may be resorted into the middle and then needs |
+ * additional padding bytes |
+ */ |
+ data=(char *)malloc(length+DEFAULT_PADDING_LENGTH); |
+ if(data==NULL) { |
+ fprintf(stderr, "%s: error allocating memory for \"%s\"\n", pname, argv[1]); |
+ rc=2; |
+ goto done; |
+ } |
+ |
+ /* set the last 15 bytes to the usual padding byte, see udata_swapPackage() */ |
+ uprv_memset(data+length-DEFAULT_PADDING_LENGTH, 0xaa, DEFAULT_PADDING_LENGTH); |
+ |
+ if(length!=(int32_t)fread(data, 1, length, in)) { |
+ fprintf(stderr, "%s: error reading \"%s\"\n", pname, argv[1]); |
+ rc=3; |
+ goto done; |
+ } |
+ |
+ fclose(in); |
+ in=NULL; |
+ |
+ /* swap the data in-place */ |
+ errorCode=U_ZERO_ERROR; |
+ ds=udata_openSwapperForInputData(data, length, outIsBigEndian, outCharset, &errorCode); |
+ if(U_FAILURE(errorCode)) { |
+ fprintf(stderr, "%s: udata_openSwapperForInputData(\"%s\") failed - %s\n", |
+ pname, argv[1], u_errorName(errorCode)); |
+ rc=4; |
+ goto done; |
+ } |
+ |
+ ds->printError=printError; |
+ ds->printErrorContext=stderr; |
+ |
+ /* speculative cast, protected by the following length check */ |
+ pInfo=(const UDataInfo *)((const char *)data+4); |
+ |
+ if( length>=20 && |
+ pInfo->dataFormat[0]==0x43 && /* dataFormat="CmnD" */ |
+ pInfo->dataFormat[1]==0x6d && |
+ pInfo->dataFormat[2]==0x6e && |
+ pInfo->dataFormat[3]==0x44 |
+ ) { |
+ /* |
+ * swap the .dat package |
+ * udata_swapPackage() needs to rename ToC name entries from the old package |
+ * name to the new one. |
+ * We pass it the filenames, and udata_swapPackage() will extract the |
+ * package names. |
+ */ |
+ length=udata_swapPackage(argv[1], argv[2], ds, data, length, data, &errorCode); |
+ udata_closeSwapper(ds); |
+ if(U_FAILURE(errorCode)) { |
+ fprintf(stderr, "%s: udata_swapPackage(\"%s\") failed - %s\n", |
+ pname, argv[1], u_errorName(errorCode)); |
+ rc=4; |
+ goto done; |
+ } |
+ } else { |
+ /* swap the data, which is not a .dat package */ |
+ length=udata_swap(ds, data, length, data, &errorCode); |
+ udata_closeSwapper(ds); |
+ if(U_FAILURE(errorCode)) { |
+ fprintf(stderr, "%s: udata_swap(\"%s\") failed - %s\n", |
+ pname, argv[1], u_errorName(errorCode)); |
+ rc=4; |
+ goto done; |
+ } |
+ } |
+ |
+ out=fopen(argv[2], "wb"); |
+ if(out==NULL) { |
+ fprintf(stderr, "%s: unable to open output file \"%s\"\n", pname, argv[2]); |
+ rc=5; |
+ goto done; |
+ } |
+ |
+ if(length!=(int32_t)fwrite(data, 1, length, out)) { |
+ fprintf(stderr, "%s: error writing \"%s\"\n", pname, argv[2]); |
+ rc=6; |
+ goto done; |
+ } |
+ |
+ fclose(out); |
+ out=NULL; |
+ |
+ /* all done */ |
+ rc=0; |
+ |
+done: |
+ if(in!=NULL) { |
+ fclose(in); |
+ } |
+ if(out!=NULL) { |
+ fclose(out); |
+ } |
+ if(data!=NULL) { |
+ free(data); |
+ } |
+ return rc; |
+} |
+ |
+/* swap .dat package files -------------------------------------------------- */ |
+ |
+static int32_t |
+extractPackageName(const UDataSwapper *ds, const char *filename, |
+ char pkg[], int32_t capacity, |
+ UErrorCode *pErrorCode) { |
+ const char *basename; |
+ int32_t len; |
+ |
+ if(U_FAILURE(*pErrorCode)) { |
+ return 0; |
+ } |
+ |
+ basename=findBasename(filename); |
+ len=(int32_t)uprv_strlen(basename)-4; /* -4: subtract the length of ".dat" */ |
+ |
+ if(len<=0 || 0!=uprv_strcmp(basename+len, ".dat")) { |
+ udata_printError(ds, "udata_swapPackage(): \"%s\" is not recognized as a package filename (must end with .dat)\n", |
+ basename); |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ if(len>=capacity) { |
+ udata_printError(ds, "udata_swapPackage(): the package name \"%s\" is too long (>=%ld)\n", |
+ (long)capacity); |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ uprv_memcpy(pkg, basename, len); |
+ pkg[len]=0; |
+ return len; |
+} |
+ |
+struct ToCEntry { |
+ uint32_t nameOffset, inOffset, outOffset, length; |
+}; |
+ |
+U_CDECL_BEGIN |
+static int32_t U_CALLCONV |
+compareToCEntries(const void *context, const void *left, const void *right) { |
+ const char *chars=(const char *)context; |
+ return (int32_t)uprv_strcmp(chars+((const ToCEntry *)left)->nameOffset, |
+ chars+((const ToCEntry *)right)->nameOffset); |
+} |
+U_CDECL_END |
+ |
+U_CFUNC int32_t U_CALLCONV |
+udata_swapPackage(const char *inFilename, const char *outFilename, |
+ const UDataSwapper *ds, |
+ const void *inData, int32_t length, void *outData, |
+ UErrorCode *pErrorCode) { |
+ const UDataInfo *pInfo; |
+ int32_t headerSize; |
+ |
+ const uint8_t *inBytes; |
+ uint8_t *outBytes; |
+ |
+ uint32_t itemCount, offset, i; |
+ int32_t itemLength; |
+ |
+ const UDataOffsetTOCEntry *inEntries; |
+ UDataOffsetTOCEntry *outEntries; |
+ |
+ ToCEntry *table; |
+ |
+ char inPkgName[32], outPkgName[32]; |
+ int32_t inPkgNameLength, outPkgNameLength; |
+ |
+ /* udata_swapDataHeader checks the arguments */ |
+ headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); |
+ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { |
+ return 0; |
+ } |
+ |
+ /* check data format and format version */ |
+ pInfo=(const UDataInfo *)((const char *)inData+4); |
+ if(!( |
+ pInfo->dataFormat[0]==0x43 && /* dataFormat="CmnD" */ |
+ pInfo->dataFormat[1]==0x6d && |
+ pInfo->dataFormat[2]==0x6e && |
+ pInfo->dataFormat[3]==0x44 && |
+ pInfo->formatVersion[0]==1 |
+ )) { |
+ udata_printError(ds, "udata_swapPackage(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as an ICU .dat package\n", |
+ pInfo->dataFormat[0], pInfo->dataFormat[1], |
+ pInfo->dataFormat[2], pInfo->dataFormat[3], |
+ pInfo->formatVersion[0]); |
+ *pErrorCode=U_UNSUPPORTED_ERROR; |
+ return 0; |
+ } |
+ |
+ /* |
+ * We need to change the ToC name entries so that they have the correct |
+ * package name prefix. |
+ * Extract the package names from the in/out filenames. |
+ */ |
+ inPkgNameLength=extractPackageName( |
+ ds, inFilename, |
+ inPkgName, (int32_t)sizeof(inPkgName), |
+ pErrorCode); |
+ outPkgNameLength=extractPackageName( |
+ ds, outFilename, |
+ outPkgName, (int32_t)sizeof(outPkgName), |
+ pErrorCode); |
+ if(U_FAILURE(*pErrorCode)) { |
+ return 0; |
+ } |
+ |
+ /* |
+ * It is possible to work with inPkgNameLength!=outPkgNameLength, |
+ * but then the length of the data file would change more significantly, |
+ * which we are not currently prepared for. |
+ */ |
+ if(inPkgNameLength!=outPkgNameLength) { |
+ udata_printError(ds, "udata_swapPackage(): the package names \"%s\" and \"%s\" must have the same length\n", |
+ inPkgName, outPkgName); |
+ *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; |
+ return 0; |
+ } |
+ |
+ inBytes=(const uint8_t *)inData+headerSize; |
+ inEntries=(const UDataOffsetTOCEntry *)(inBytes+4); |
+ |
+ if(length<0) { |
+ /* preflighting */ |
+ itemCount=ds->readUInt32(*(const uint32_t *)inBytes); |
+ if(itemCount==0) { |
+ /* no items: count only the item count and return */ |
+ return headerSize+4; |
+ } |
+ |
+ /* read the last item's offset and preflight it */ |
+ offset=ds->readUInt32(inEntries[itemCount-1].dataOffset); |
+ itemLength=udata_swap(ds, inBytes+offset, -1, NULL, pErrorCode); |
+ |
+ if(U_SUCCESS(*pErrorCode)) { |
+ return headerSize+offset+(uint32_t)itemLength; |
+ } else { |
+ return 0; |
+ } |
+ } else { |
+ /* check that the itemCount fits, then the ToC table, then at least the header of the last item */ |
+ length-=headerSize; |
+ if(length<4) { |
+ /* itemCount does not fit */ |
+ offset=0xffffffff; |
+ itemCount=0; /* make compilers happy */ |
+ } else { |
+ itemCount=ds->readUInt32(*(const uint32_t *)inBytes); |
+ if(itemCount==0) { |
+ offset=4; |
+ } else if((uint32_t)length<(4+8*itemCount)) { |
+ /* ToC table does not fit */ |
+ offset=0xffffffff; |
+ } else { |
+ /* offset of the last item plus at least 20 bytes for its header */ |
+ offset=20+ds->readUInt32(inEntries[itemCount-1].dataOffset); |
+ } |
+ } |
+ if((uint32_t)length<offset) { |
+ udata_printError(ds, "udata_swapPackage(): too few bytes (%d after header) for a .dat package\n", |
+ length); |
+ *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
+ return 0; |
+ } |
+ |
+ outBytes=(uint8_t *)outData+headerSize; |
+ |
+ /* swap the item count */ |
+ ds->swapArray32(ds, inBytes, 4, outBytes, pErrorCode); |
+ |
+ if(itemCount==0) { |
+ /* no items: just return now */ |
+ return headerSize+4; |
+ } |
+ |
+ /* swap the item name strings */ |
+ offset=4+8*itemCount; |
+ itemLength=(int32_t)(ds->readUInt32(inEntries[0].dataOffset)-offset); |
+ udata_swapInvStringBlock(ds, inBytes+offset, itemLength, outBytes+offset, pErrorCode); |
+ if(U_FAILURE(*pErrorCode)) { |
+ udata_printError(ds, "udata_swapPackage() failed to swap the data item name strings\n"); |
+ return 0; |
+ } |
+ /* keep offset and itemLength in case we allocate and copy the strings below */ |
+ |
+ /* swap the package names into the output charset */ |
+ if(ds->outCharset!=U_CHARSET_FAMILY) { |
+ UDataSwapper *ds2; |
+ ds2=udata_openSwapper(TRUE, U_CHARSET_FAMILY, TRUE, ds->outCharset, pErrorCode); |
+ ds2->swapInvChars(ds2, inPkgName, inPkgNameLength, inPkgName, pErrorCode); |
+ ds2->swapInvChars(ds2, outPkgName, outPkgNameLength, outPkgName, pErrorCode); |
+ udata_closeSwapper(ds2); |
+ if(U_FAILURE(*pErrorCode)) { |
+ udata_printError(ds, "udata_swapPackage() failed to swap the input/output package names\n"); |
+ } |
+ } |
+ |
+ /* change the prefix of each ToC entry name from the old to the new package name */ |
+ { |
+ char *entryName; |
+ |
+ for(i=0; i<itemCount; ++i) { |
+ entryName=(char *)inBytes+ds->readUInt32(inEntries[i].nameOffset); |
+ |
+ if(0==uprv_memcmp(entryName, inPkgName, inPkgNameLength)) { |
+ uprv_memcpy(entryName, outPkgName, inPkgNameLength); |
+ } else { |
+ udata_printError(ds, "udata_swapPackage() failed: ToC item %ld does not have the input package name as a prefix\n", |
+ (long)i); |
+ *pErrorCode=U_INVALID_FORMAT_ERROR; |
+ return 0; |
+ } |
+ } |
+ } |
+ |
+ /* |
+ * Allocate the ToC table and, if necessary, a temporary buffer for |
+ * pseudo-in-place swapping. |
+ * |
+ * We cannot swap in-place because: |
+ * |
+ * 1. If the swapping of an item fails mid-way, then in-place swapping |
+ * has destroyed its data. |
+ * Out-of-place swapping allows us to then copy its original data. |
+ * |
+ * 2. If swapping changes the charset family, then we must resort |
+ * not only the ToC table but also the data items themselves. |
+ * This requires a permutation and is best done with separate in/out |
+ * buffers. |
+ * |
+ * We swapped the strings above to avoid the malloc below if string swapping fails. |
+ */ |
+ if(inData==outData) { |
+ /* +15: prepare for extra padding of a newly-last item */ |
+ table=(ToCEntry *)uprv_malloc(itemCount*sizeof(ToCEntry)+length+DEFAULT_PADDING_LENGTH); |
+ if(table!=NULL) { |
+ outBytes=(uint8_t *)(table+itemCount); |
+ |
+ /* copy the item count and the swapped strings */ |
+ uprv_memcpy(outBytes, inBytes, 4); |
+ uprv_memcpy(outBytes+offset, inBytes+offset, itemLength); |
+ } |
+ } else { |
+ table=(ToCEntry *)uprv_malloc(itemCount*sizeof(ToCEntry)); |
+ } |
+ if(table==NULL) { |
+ udata_printError(ds, "udata_swapPackage(): out of memory allocating %d bytes\n", |
+ inData==outData ? |
+ itemCount*sizeof(ToCEntry)+length+DEFAULT_PADDING_LENGTH : |
+ itemCount*sizeof(ToCEntry)); |
+ *pErrorCode=U_MEMORY_ALLOCATION_ERROR; |
+ return 0; |
+ } |
+ outEntries=(UDataOffsetTOCEntry *)(outBytes+4); |
+ |
+ /* read the ToC table */ |
+ for(i=0; i<itemCount; ++i) { |
+ table[i].nameOffset=ds->readUInt32(inEntries[i].nameOffset); |
+ table[i].inOffset=ds->readUInt32(inEntries[i].dataOffset); |
+ if(i>0) { |
+ table[i-1].length=table[i].inOffset-table[i-1].inOffset; |
+ } |
+ } |
+ table[itemCount-1].length=(uint32_t)length-table[itemCount-1].inOffset; |
+ |
+ if(ds->inCharset==ds->outCharset) { |
+ /* no charset swapping, no resorting: keep item offsets the same */ |
+ for(i=0; i<itemCount; ++i) { |
+ table[i].outOffset=table[i].inOffset; |
+ } |
+ } else { |
+ /* charset swapping: resort items by their swapped names */ |
+ |
+ /* |
+ * Before the actual sorting, we need to make sure that each item |
+ * has a length that is a multiple of 16 bytes so that all items |
+ * are 16-aligned. |
+ * Only the old last item may be missing up to 15 padding bytes. |
+ * Add padding bytes for it. |
+ * Since the icuswap main() function has already allocated enough |
+ * input buffer space and set the last 15 bytes there to 0xaa, |
+ * we only need to increase the total data length and the length |
+ * of the last item here. |
+ */ |
+ if((length&0xf)!=0) { |
+ int32_t delta=16-(length&0xf); |
+ length+=delta; |
+ table[itemCount-1].length+=(uint32_t)delta; |
+ } |
+ |
+ /* Save the offset before we sort the TOC. */ |
+ offset=table[0].inOffset; |
+ /* sort the TOC entries */ |
+ uprv_sortArray(table, (int32_t)itemCount, (int32_t)sizeof(ToCEntry), |
+ compareToCEntries, outBytes, FALSE, pErrorCode); |
+ |
+ /* |
+ * Note: Before sorting, the inOffset values were in order. |
+ * Now the outOffset values are in order. |
+ */ |
+ |
+ /* assign outOffset values */ |
+ for(i=0; i<itemCount; ++i) { |
+ table[i].outOffset=offset; |
+ offset+=table[i].length; |
+ } |
+ } |
+ |
+ /* write the output ToC table */ |
+ for(i=0; i<itemCount; ++i) { |
+ ds->writeUInt32(&outEntries[i].nameOffset, table[i].nameOffset); |
+ ds->writeUInt32(&outEntries[i].dataOffset, table[i].outOffset); |
+ } |
+ |
+ /* swap each data item */ |
+ for(i=0; i<itemCount; ++i) { |
+ /* first copy the item bytes to make sure that unreachable bytes are copied */ |
+ uprv_memcpy(outBytes+table[i].outOffset, inBytes+table[i].inOffset, table[i].length); |
+ |
+ /* swap the item */ |
+ udata_swap(ds, inBytes+table[i].inOffset, (int32_t)table[i].length, |
+ outBytes+table[i].outOffset, pErrorCode); |
+ |
+ if(U_FAILURE(*pErrorCode)) { |
+ if(ds->outCharset==U_CHARSET_FAMILY) { |
+ udata_printError(ds, "warning: udata_swapPackage() failed to swap item \"%s\"\n" |
+ " at inOffset 0x%x length 0x%x - %s\n" |
+ " the data item will be copied, not swapped\n\n", |
+ (char *)outBytes+table[i].nameOffset, |
+ table[i].inOffset, table[i].length, u_errorName(*pErrorCode)); |
+ } else { |
+ udata_printError(ds, "warning: udata_swapPackage() failed to swap an item\n" |
+ " at inOffset 0x%x length 0x%x - %s\n" |
+ " the data item will be copied, not swapped\n\n", |
+ table[i].inOffset, table[i].length, u_errorName(*pErrorCode)); |
+ } |
+ /* reset the error code, copy the data item, and continue */ |
+ *pErrorCode=U_ZERO_ERROR; |
+ uprv_memcpy(outBytes+table[i].outOffset, inBytes+table[i].inOffset, table[i].length); |
+ } |
+ } |
+ |
+ if(inData==outData) { |
+ /* copy the data from the temporary buffer to the in-place buffer */ |
+ uprv_memcpy((uint8_t *)outData+headerSize, outBytes, length); |
+ } |
+ uprv_free(table); |
+ |
+ return headerSize+length; |
+ } |
+} |
+ |
+/* |
+ * Hey, Emacs, please set the following: |
+ * |
+ * Local Variables: |
+ * indent-tabs-mode: nil |
+ * End: |
+ * |
+ */ |
Property changes on: icu46/source/tools/icuswap/icuswap.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |