1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 4f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Copyright (C) 2003-2014, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file name: icuswap.cpp 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* encoding: US-ASCII 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* tab size: 8 (not used) 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* indentation:4 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 2003aug08 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Markus W. Scherer 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* This tool takes an ICU data file and "swaps" it, that is, changes its 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* platform properties between big-/little-endianness and ASCII/EBCDIC charset 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* families. 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* The modified data file is written to a new file. 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Useful as an install-time tool for shipping only one flavor of ICU data 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* and preparing data files for the target platform. 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Will not work with data DLLs (shared libraries). 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uinvchar.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uarrsort.h" 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucmndata.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "udataswp.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "swapimpl.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "toolutil.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uoptions.h" 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h> 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h> 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* definitions */ 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DEFAULT_PADDING_LENGTH 15 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UOption options[]={ 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UOPTION_HELP_H, 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UOPTION_HELP_QUESTION_MARK, 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UOPTION_DEF("type", 't', UOPT_REQUIRES_ARG) 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OPT_HELP_H, 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OPT_HELP_QUESTION_MARK, 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OPT_OUT_TYPE 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufileSize(FILE *f) { 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t size; 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fseek(f, 0, SEEK_END); 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size=(int32_t)ftell(f); 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fseek(f, 0, SEEK_SET); 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return size; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Swap an ICU .dat package, including swapping of enclosed items. 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC int32_t U_CALLCONV 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_swapPackage(const char *inFilename, const char *outFilename, 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataSwapper *ds, 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode); 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruprintError(void *context, const char *fmt, va_list args) { 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru vfprintf((FILE *)context, fmt, args); 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruprintUsage(const char *pname, UBool ishelp) { 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "%csage: %s [ -h, -?, --help ] -tl|-tb|-te|--type=b|... infilename outfilename\n", 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ishelp ? 'U' : 'u', pname); 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ishelp) { 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "\nOptions: -h, -?, --help print this message and exit\n" 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " Read the input file, swap its platform properties according\n" 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " to the -t or --type option, and write the result to the output file.\n" 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " -tl change to little-endian/ASCII charset family\n" 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " -tb change to big-endian/ASCII charset family\n" 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " -te change to big-endian/EBCDIC charset family\n"); 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return !ishelp; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruextern int 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumain(int argc, char *argv[]) { 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FILE *in, *out; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *pname; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *data; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool ishelp; 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int rc; 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataSwapper *ds; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t outCharset; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool outIsBigEndian; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_MAIN_INIT_ARGS(argc, argv); 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 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"); 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the program basename */ 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname=strrchr(argv[0], U_FILE_SEP_CHAR); 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pname==NULL) { 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname=strrchr(argv[0], '/'); 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pname!=NULL) { 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++pname; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname=argv[0]; 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 132f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options); 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ishelp=options[OPT_HELP_H].doesOccur || options[OPT_HELP_QUESTION_MARK].doesOccur; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ishelp || argc!=3) { 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return printUsage(pname, ishelp); 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* parse the output type option */ 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data=(char *)options[OPT_OUT_TYPE].value; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data[0]==0 || data[1]!=0) { 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the type must be exactly one letter */ 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return printUsage(pname, FALSE); 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(data[0]) { 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 'l': 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outIsBigEndian=FALSE; 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outCharset=U_ASCII_FAMILY; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 'b': 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outIsBigEndian=TRUE; 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outCharset=U_ASCII_FAMILY; 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 'e': 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outIsBigEndian=TRUE; 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outCharset=U_EBCDIC_FAMILY; 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return printUsage(pname, FALSE); 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in=out=NULL; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data=NULL; 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* open the input file, get its length, allocate memory for it, read the file */ 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in=fopen(argv[1], "rb"); 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(in==NULL) { 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: unable to open input file \"%s\"\n", pname, argv[1]); 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=2; 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=fileSize(in); 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<DEFAULT_PADDING_LENGTH) { 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: empty input file \"%s\"\n", pname, argv[1]); 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=2; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * +15: udata_swapPackage() may need to add a few padding bytes to the 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * last item if charset swapping is done, 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * because the last item may be resorted into the middle and then needs 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * additional padding bytes 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data=(char *)malloc(length+DEFAULT_PADDING_LENGTH); 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data==NULL) { 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: error allocating memory for \"%s\"\n", pname, argv[1]); 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=2; 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the last 15 bytes to the usual padding byte, see udata_swapPackage() */ 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(data+length-DEFAULT_PADDING_LENGTH, 0xaa, DEFAULT_PADDING_LENGTH); 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length!=(int32_t)fread(data, 1, length, in)) { 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: error reading \"%s\"\n", pname, argv[1]); 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=3; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fclose(in); 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru in=NULL; 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the data in-place */ 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds=udata_openSwapperForInputData(data, length, outIsBigEndian, outCharset, &errorCode); 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: udata_openSwapperForInputData(\"%s\") failed - %s\n", 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname, argv[1], u_errorName(errorCode)); 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=4; 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->printError=printError; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->printErrorContext=stderr; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* speculative cast, protected by the following length check */ 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)data+4); 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( length>=20 && 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x43 && /* dataFormat="CmnD" */ 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6d && 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x6e && 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x44 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * swap the .dat package 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * udata_swapPackage() needs to rename ToC name entries from the old package 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * name to the new one. 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We pass it the filenames, and udata_swapPackage() will extract the 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * package names. 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_swapPackage(argv[1], argv[2], ds, data, length, data, &errorCode); 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_closeSwapper(ds); 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: udata_swapPackage(\"%s\") failed - %s\n", 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname, argv[1], u_errorName(errorCode)); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=4; 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the data, which is not a .dat package */ 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length=udata_swap(ds, data, length, data, &errorCode); 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_closeSwapper(ds); 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: udata_swap(\"%s\") failed - %s\n", 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pname, argv[1], u_errorName(errorCode)); 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=4; 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out=fopen(argv[2], "wb"); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(out==NULL) { 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: unable to open output file \"%s\"\n", pname, argv[2]); 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=5; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length!=(int32_t)fwrite(data, 1, length, out)) { 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s: error writing \"%s\"\n", pname, argv[2]); 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=6; 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto done; 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fclose(out); 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru out=NULL; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* all done */ 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rc=0; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudone: 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(in!=NULL) { 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fclose(in); 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(out!=NULL) { 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fclose(out); 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(data!=NULL) { 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru free(data); 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rc; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* swap .dat package files -------------------------------------------------- */ 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruextractPackageName(const UDataSwapper *ds, const char *filename, 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char pkg[], int32_t capacity, 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *basename; 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len; 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru basename=findBasename(filename); 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru len=(int32_t)uprv_strlen(basename)-4; /* -4: subtract the length of ".dat" */ 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(len<=0 || 0!=uprv_strcmp(basename+len, ".dat")) { 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): \"%s\" is not recognized as a package filename (must end with .dat)\n", 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru basename); 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(len>=capacity) { 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): the package name \"%s\" is too long (>=%ld)\n", 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (long)capacity); 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(pkg, basename, len); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pkg[len]=0; 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return len; 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct ToCEntry { 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t nameOffset, inOffset, outOffset, length; 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerucompareToCEntries(const void *context, const void *left, const void *right) { 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *chars=(const char *)context; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int32_t)uprv_strcmp(chars+((const ToCEntry *)left)->nameOffset, 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru chars+((const ToCEntry *)right)->nameOffset); 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC int32_t U_CALLCONV 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_swapPackage(const char *inFilename, const char *outFilename, 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataSwapper *ds, 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataInfo *pInfo; 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t headerSize; 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint8_t *inBytes; 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint8_t *outBytes; 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t itemCount, offset, i; 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t itemLength; 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UDataOffsetTOCEntry *inEntries; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataOffsetTOCEntry *outEntries; 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ToCEntry *table; 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char inPkgName[32], outPkgName[32]; 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t inPkgNameLength, outPkgNameLength; 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check data format and format version */ 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!( 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0]==0x43 && /* dataFormat="CmnD" */ 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[1]==0x6d && 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2]==0x6e && 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[3]==0x44 && 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]==1 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru )) { 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as an ICU .dat package\n", 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pInfo->formatVersion[0]); 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We need to change the ToC name entries so that they have the correct 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * package name prefix. 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Extract the package names from the in/out filenames. 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inPkgNameLength=extractPackageName( 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds, inFilename, 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inPkgName, (int32_t)sizeof(inPkgName), 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outPkgNameLength=extractPackageName( 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds, outFilename, 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outPkgName, (int32_t)sizeof(outPkgName), 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pErrorCode); 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It is possible to work with inPkgNameLength!=outPkgNameLength, 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * but then the length of the data file would change more significantly, 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * which we are not currently prepared for. 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inPkgNameLength!=outPkgNameLength) { 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): the package names \"%s\" and \"%s\" must have the same length\n", 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inPkgName, outPkgName); 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inBytes=(const uint8_t *)inData+headerSize; 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inEntries=(const UDataOffsetTOCEntry *)(inBytes+4); 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<0) { 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* preflighting */ 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemCount=ds->readUInt32(*(const uint32_t *)inBytes); 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(itemCount==0) { 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no items: count only the item count and return */ 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+4; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the last item's offset and preflight it */ 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=ds->readUInt32(inEntries[itemCount-1].dataOffset); 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemLength=udata_swap(ds, inBytes+offset, -1, NULL, pErrorCode); 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*pErrorCode)) { 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+offset+(uint32_t)itemLength; 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check that the itemCount fits, then the ToC table, then at least the header of the last item */ 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length-=headerSize; 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length<4) { 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* itemCount does not fit */ 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=0xffffffff; 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemCount=0; /* make compilers happy */ 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemCount=ds->readUInt32(*(const uint32_t *)inBytes); 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(itemCount==0) { 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=4; 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if((uint32_t)length<(4+8*itemCount)) { 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* ToC table does not fit */ 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=0xffffffff; 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* offset of the last item plus at least 20 bytes for its header */ 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=20+ds->readUInt32(inEntries[itemCount-1].dataOffset); 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((uint32_t)length<offset) { 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): too few bytes (%d after header) for a .dat package\n", 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length); 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes=(uint8_t *)outData+headerSize; 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the item count */ 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray32(ds, inBytes, 4, outBytes, pErrorCode); 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(itemCount==0) { 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no items: just return now */ 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+4; 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the item name strings */ 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=4+8*itemCount; 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemLength=(int32_t)(ds->readUInt32(inEntries[0].dataOffset)-offset); 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_swapInvStringBlock(ds, inBytes+offset, itemLength, outBytes+offset, pErrorCode); 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage() failed to swap the data item name strings\n"); 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* keep offset and itemLength in case we allocate and copy the strings below */ 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the package names into the output charset */ 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->outCharset!=U_CHARSET_FAMILY) { 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataSwapper *ds2; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds2=udata_openSwapper(TRUE, U_CHARSET_FAMILY, TRUE, ds->outCharset, pErrorCode); 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds2->swapInvChars(ds2, inPkgName, inPkgNameLength, inPkgName, pErrorCode); 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds2->swapInvChars(ds2, outPkgName, outPkgNameLength, outPkgName, pErrorCode); 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_closeSwapper(ds2); 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage() failed to swap the input/output package names\n"); 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* change the prefix of each ToC entry name from the old to the new package name */ 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *entryName; 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru entryName=(char *)inBytes+ds->readUInt32(inEntries[i].nameOffset); 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(0==uprv_memcmp(entryName, inPkgName, inPkgNameLength)) { 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(entryName, outPkgName, inPkgNameLength); 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage() failed: ToC item %ld does not have the input package name as a prefix\n", 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (long)i); 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INVALID_FORMAT_ERROR; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Allocate the ToC table and, if necessary, a temporary buffer for 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * pseudo-in-place swapping. 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We cannot swap in-place because: 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1. If the swapping of an item fails mid-way, then in-place swapping 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * has destroyed its data. 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Out-of-place swapping allows us to then copy its original data. 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 2. If swapping changes the charset family, then we must resort 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * not only the ToC table but also the data items themselves. 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This requires a permutation and is best done with separate in/out 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * buffers. 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We swapped the strings above to avoid the malloc below if string swapping fails. 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inData==outData) { 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* +15: prepare for extra padding of a newly-last item */ 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table=(ToCEntry *)uprv_malloc(itemCount*sizeof(ToCEntry)+length+DEFAULT_PADDING_LENGTH); 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(table!=NULL) { 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes=(uint8_t *)(table+itemCount); 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the item count and the swapped strings */ 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes, inBytes, 4); 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes+offset, inBytes+offset, itemLength); 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table=(ToCEntry *)uprv_malloc(itemCount*sizeof(ToCEntry)); 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(table==NULL) { 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapPackage(): out of memory allocating %d bytes\n", 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inData==outData ? 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemCount*sizeof(ToCEntry)+length+DEFAULT_PADDING_LENGTH : 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itemCount*sizeof(ToCEntry)); 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outEntries=(UDataOffsetTOCEntry *)(outBytes+4); 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* read the ToC table */ 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].nameOffset=ds->readUInt32(inEntries[i].nameOffset); 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].inOffset=ds->readUInt32(inEntries[i].dataOffset); 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(i>0) { 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i-1].length=table[i].inOffset-table[i-1].inOffset; 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[itemCount-1].length=(uint32_t)length-table[itemCount-1].inOffset; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->inCharset==ds->outCharset) { 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* no charset swapping, no resorting: keep item offsets the same */ 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].outOffset=table[i].inOffset; 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* charset swapping: resort items by their swapped names */ 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Before the actual sorting, we need to make sure that each item 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * has a length that is a multiple of 16 bytes so that all items 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * are 16-aligned. 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Only the old last item may be missing up to 15 padding bytes. 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Add padding bytes for it. 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Since the icuswap main() function has already allocated enough 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * input buffer space and set the last 15 bytes there to 0xaa, 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * we only need to increase the total data length and the length 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of the last item here. 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((length&0xf)!=0) { 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t delta=16-(length&0xf); 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru length+=delta; 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[itemCount-1].length+=(uint32_t)delta; 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Save the offset before we sort the TOC. */ 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset=table[0].inOffset; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* sort the TOC entries */ 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_sortArray(table, (int32_t)itemCount, (int32_t)sizeof(ToCEntry), 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru compareToCEntries, outBytes, FALSE, pErrorCode); 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Note: Before sorting, the inOffset values were in order. 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Now the outOffset values are in order. 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* assign outOffset values */ 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].outOffset=offset; 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset+=table[i].length; 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* write the output ToC table */ 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->writeUInt32(&outEntries[i].nameOffset, table[i].nameOffset); 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->writeUInt32(&outEntries[i].dataOffset, table[i].outOffset); 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap each data item */ 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=0; i<itemCount; ++i) { 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* first copy the item bytes to make sure that unreachable bytes are copied */ 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes+table[i].outOffset, inBytes+table[i].inOffset, table[i].length); 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the item */ 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_swap(ds, inBytes+table[i].inOffset, (int32_t)table[i].length, 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outBytes+table[i].outOffset, pErrorCode); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->outCharset==U_CHARSET_FAMILY) { 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "warning: udata_swapPackage() failed to swap item \"%s\"\n" 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " at inOffset 0x%x length 0x%x - %s\n" 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " the data item will be copied, not swapped\n\n", 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (char *)outBytes+table[i].nameOffset, 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].inOffset, table[i].length, u_errorName(*pErrorCode)); 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "warning: udata_swapPackage() failed to swap an item\n" 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " at inOffset 0x%x length 0x%x - %s\n" 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " the data item will be copied, not swapped\n\n", 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru table[i].inOffset, table[i].length, u_errorName(*pErrorCode)); 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reset the error code, copy the data item, and continue */ 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ZERO_ERROR; 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outBytes+table[i].outOffset, inBytes+table[i].inOffset, table[i].length); 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inData==outData) { 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the data from the temporary buffer to the in-place buffer */ 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy((uint8_t *)outData+headerSize, outBytes, length); 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(table); 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize+length; 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Hey, Emacs, please set the following: 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Local Variables: 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * indent-tabs-mode: nil 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * End: 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 648