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