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