1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 2003-2011, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: pkgitems.cpp 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created on: 2005sep18 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created by: Markus W. Scherer 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Companion file to package.cpp. Deals with details of ICU data item formats. 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Used for item dependencies. 1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Contains adapted code from ucnv_bld.c (swapper code from 2003). 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uinvchar.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucmndata.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "udataswp.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "swapimpl.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "toolutil.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "package.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "pkg_imp.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdlib.h> 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h> 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* item formats in common */ 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresdata.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_bld.h" 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_io.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// general definitions ----------------------------------------------------- *** 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruprintError(void *context, const char *fmt, va_list args) { 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru vfprintf((FILE *)context, fmt, args); 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// a data item in native-platform form ------------------------------------- *** 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass NativeItem { 6250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho NativeItem() : pItem(NULL), pInfo(NULL), bytes(NULL), swapped(NULL), length(0) {} 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho NativeItem(const Item *item, UDataSwapFn *swap) : swapped(NULL) { 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setItem(item, swap); 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ~NativeItem() { 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete [] swapped; 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *getDataInfo() const { 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return pInfo; 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint8_t *getBytes() const { 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bytes; 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t getLength() const { 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return length; 7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void setItem(const Item *item, UDataSwapFn *swap) { 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pItem=item; 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t infoLength, itemHeaderLength; 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode errorCode=U_ZERO_ERROR; 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo=::getDataInfo(pItem->data, pItem->length, infoLength, itemHeaderLength, &errorCode); 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(errorCode)) { 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho exit(errorCode); // should succeed because readFile() checks headers 8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=pItem->length-itemHeaderLength; 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pInfo->isBigEndian==U_IS_BIG_ENDIAN && pInfo->charsetFamily==U_CHARSET_FAMILY) { 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bytes=pItem->data+itemHeaderLength; 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDataSwapper *ds=udata_openSwapper((UBool)pInfo->isBigEndian, pInfo->charsetFamily, U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode); 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(errorCode)) { 9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n", 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pItem->name, u_errorName(errorCode)); 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho exit(errorCode); 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->printError=printError; 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->printErrorContext=stderr; 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho swapped=new uint8_t[pItem->length]; 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(swapped==NULL) { 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: unable to allocate memory for swapping \"%s\"\n", pItem->name); 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho exit(U_MEMORY_ALLOCATION_ERROR); 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho swap(ds, pItem->data, pItem->length, swapped, &errorCode); 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo=::getDataInfo(swapped, pItem->length, infoLength, itemHeaderLength, &errorCode); 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bytes=swapped+itemHeaderLength; 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_closeSwapper(ds); 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprivate: 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const Item *pItem; 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *pInfo; 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint8_t *bytes; 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint8_t *swapped; 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// check a dependency ------------------------------------------------------ *** 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * assemble the target item name from the source item name, an ID 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and a suffix 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehomakeTargetName(const char *itemName, const char *id, int32_t idLength, const char *suffix, 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *target, int32_t capacity, 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *pErrorCode) { 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *itemID; 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t treeLength, suffixLength, targetLength; 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the item basename 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemID=strrchr(itemName, '/'); 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(itemID!=NULL) { 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++itemID; 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemID=itemName; 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // build the target string 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru treeLength=(int32_t)(itemID-itemName); 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(idLength<0) { 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idLength=(int32_t)strlen(id); 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru suffixLength=(int32_t)strlen(suffix); 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetLength=treeLength+idLength+suffixLength; 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(targetLength>=capacity) { 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/makeTargetName(%s) target item name length %ld too long\n", 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemName, (long)targetLength); 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru memcpy(target, itemName, treeLength); 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru memcpy(target+treeLength, id, idLength); 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru memcpy(target+treeLength+idLength, suffix, suffixLength+1); // +1 includes the terminating NUL 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocheckIDSuffix(const char *itemName, const char *id, int32_t idLength, const char *suffix, 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho CheckDependency check, void *context, 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *pErrorCode) { 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char target[200]; 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho makeTargetName(itemName, id, idLength, suffix, target, (int32_t)sizeof(target), pErrorCode); 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_SUCCESS(*pErrorCode)) { 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho check(context, itemName, target); 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* assemble the target item name from the item's parent item name */ 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucheckParent(const char *itemName, CheckDependency check, void *context, 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *itemID, *parent, *parentLimit, *suffix; 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t parentLength; 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the item basename 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemID=strrchr(itemName, '/'); 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(itemID!=NULL) { 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++itemID; 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemID=itemName; 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the item suffix 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru suffix=strrchr(itemID, '.'); 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(suffix==NULL) { 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // empty suffix, point to the end of the string 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru suffix=strrchr(itemID, 0); 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the position of the last '_' 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(parentLimit=suffix; parentLimit>itemID && *--parentLimit!='_';) {} 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(parentLimit!=itemID) { 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the parent item name by truncating the last part of this item's name */ 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parent=itemID; 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parentLength=(int32_t)(parentLimit-itemID); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no '_' in the item name: the parent is the root bundle 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parent="root"; 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parentLength=4; 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((suffix-itemID)==parentLength && 0==memcmp(itemID, parent, parentLength)) { 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the item itself is "root", which does not depend on a parent 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru checkIDSuffix(itemName, parent, parentLength, suffix, check, context, pErrorCode); 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// get dependencies from resource bundles ---------------------------------- *** 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const UChar SLASH=0x2f; 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Check for the alias from the string or alias resource res. 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocheckAlias(const char *itemName, 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Resource res, const UChar *alias, int32_t length, UBool useResSuffix, 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho CheckDependency check, void *context, UErrorCode *pErrorCode) { 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i; 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!uprv_isInvariantUString(alias, length)) { 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias string contains non-invariant characters\n", 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, res); 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_INVALID_CHAR_FOUND; 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // extract the locale ID from alias strings like 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // locale_ID/key1/key2/key3 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // locale_ID 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // search for the first slash 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for(i=0; i<length && alias[i]!=SLASH; ++i) {} 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(res_getPublicType(res)==URES_ALIAS) { 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // ignore aliases with an initial slash: 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // /ICUDATA/... and /pkgname/... go to a different package 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // /LOCALE/... are for dynamic sideways fallbacks and don't go to a fixed bundle 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(i==0) { 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; // initial slash ('/') 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // ignore the intra-bundle path starting from the first slash ('/') 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=i; 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else /* URES_STRING */ { 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the whole string should only consist of a locale ID 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(i!=length) { 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) %%ALIAS contains a '/'\n", 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, res); 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_UNSUPPORTED_ERROR; 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 259c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // convert the Unicode string to char * 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char localeID[32]; 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>=(int32_t)sizeof(localeID)) { 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias locale ID length %ld too long\n", 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, res, (long)length); 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho u_UCharsToChars(alias, localeID, length); 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho localeID[length]=0; 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho checkIDSuffix(itemName, localeID, -1, (useResSuffix ? ".res" : ""), check, context, pErrorCode); 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Enumerate one resource item and its children and extract dependencies from 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * aliases. 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoures_enumDependencies(const char *itemName, 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const ResourceData *pResData, 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Resource res, const char *inKey, const char *parentKey, int32_t depth, 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho CheckDependency check, void *context, 28527f654740f2a26ad62a5c155af9199af9e69b889claireho Package *pkg, 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *pErrorCode) { 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(res_getPublicType(res)) { 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool useResSuffix = TRUE; 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Check for %%ALIAS 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(depth==1 && inKey!=NULL) { 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(0!=strcmp(inKey, "%%ALIAS")) { 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Check for %%DEPENDENCY 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho else if(depth==2 && parentKey!=NULL) { 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(0!=strcmp(parentKey, "%%DEPENDENCY")) { 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho useResSuffix = FALSE; 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // we ignore all other strings 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *alias=res_getString(pResData, res, &length); 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho checkAlias(itemName, res, alias, length, useResSuffix, check, context, pErrorCode); 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ALIAS: 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *alias=res_getAlias(pResData, res, &length); 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho checkAlias(itemName, res, alias, length, TRUE, check, context, pErrorCode); 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE: 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t count=res_countArrayItems(pResData, res); 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for(int32_t i=0; i<count; ++i) { 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *itemKey; 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Resource item=res_getTableItemByIndex(pResData, res, i, &itemKey); 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_enumDependencies( 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, pResData, 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho item, itemKey, 329c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru inKey, depth+1, 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru check, context, 33127f654740f2a26ad62a5c155af9199af9e69b889claireho pkg, 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pErrorCode); 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/ures_enumDependencies(%s table res=%08x)[%d].recurse(%s: %08x) failed\n", 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, res, i, itemKey, item); 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ARRAY: 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t count=res_countArrayItems(pResData, res); 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for(int32_t i=0; i<count; ++i) { 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Resource item=res_getArrayItem(pResData, res, i); 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_enumDependencies( 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, pResData, 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho item, NULL, 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inKey, depth+1, 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru check, context, 35227f654740f2a26ad62a5c155af9199af9e69b889claireho pkg, 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pErrorCode); 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg/ures_enumDependencies(%s array res=%08x)[%d].recurse(%08x) failed\n", 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, res, i, item); 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoures_enumDependencies(const char *itemName, const UDataInfo *pInfo, 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inBytes, int32_t length, 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CheckDependency check, void *context, 37127f654740f2a26ad62a5c155af9199af9e69b889claireho Package *pkg, 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ResourceData resData; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_read(&resData, pInfo, inBytes, length, pErrorCode); 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*pErrorCode)) { 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: .res format version %02x.%02x not supported, or bundle malformed\n", 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo->formatVersion[0], pInfo->formatVersion[1]); 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(U_UNSUPPORTED_ERROR); 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * if the bundle attributes are present and the nofallback flag is not set, 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * then add the parent bundle as a dependency 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pInfo->formatVersion[0]>1 || (pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1)) { 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!resData.noFallback) { 38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* this bundle participates in locale fallback */ 38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho checkParent(itemName, check, context, pErrorCode); 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 39383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius icu::NativeItem nativePool; 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(resData.usesPoolBundle) { 39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char poolName[200]; 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho makeTargetName(itemName, "pool", 4, ".res", poolName, (int32_t)sizeof(poolName), pErrorCode); 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*pErrorCode)) { 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho check(context, itemName, poolName); 40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t index=pkg->findItem(poolName); 40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(index<0) { 40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // We cannot work with a bundle if its pool resource is missing. 40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // check() already printed a complaint. 40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: Cache the native version in the Item itself. 40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho nativePool.setItem(pkg->getItem(index), ures_swap); 41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *poolInfo=nativePool.getDataInfo(); 41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(poolInfo->formatVersion[0]<=1) { 41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: %s is not a pool bundle\n", poolName); 41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 41450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *poolIndexes=(const int32_t *)nativePool.getBytes()+1; 41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t poolIndexLength=poolIndexes[URES_INDEX_LENGTH]&0xff; 41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!(poolIndexLength>URES_INDEX_POOL_CHECKSUM && 41850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (poolIndexes[URES_INDEX_ATTRIBUTES]&URES_ATT_IS_POOL_BUNDLE)) 41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: %s is not a pool bundle\n", poolName); 42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(resData.pRoot[1+URES_INDEX_POOL_CHECKSUM]==poolIndexes[URES_INDEX_POOL_CHECKSUM]) { 42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resData.poolBundleKeys=(const char *)(poolIndexes+poolIndexLength); 42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: %s has mismatched checksum for %s\n", poolName, itemName); 42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_enumDependencies( 43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemName, &resData, 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resData.rootRes, NULL, NULL, 0, 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho check, context, 43527f654740f2a26ad62a5c155af9199af9e69b889claireho pkg, 43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pErrorCode); 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// get dependencies from conversion tables --------------------------------- *** 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* code adapted from ucnv_swap() */ 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucnv_enumDependencies(const UDataSwapper *ds, 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *itemName, const UDataInfo *pInfo, 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inBytes, int32_t length, 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CheckDependency check, void *context, 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t staticDataSize; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UConverterStaticData *inStaticData; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const _MBCSHeader *inMBCSHeader; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t outputType; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check format version */ 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!( 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0]==6 && 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[1]>=2 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )) { 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "icupkg/ucnv_enumDependencies(): .cnv format version %02x.%02x not supported\n", 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->formatVersion[0], pInfo->formatVersion[1]); 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(U_UNSUPPORTED_ERROR); 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the initial UConverterStaticData structure after the UDataInfo header */ 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inStaticData=(const UConverterStaticData *)inBytes; 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( length<(int32_t)sizeof(UConverterStaticData) || 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (uint32_t)length<(staticDataSize=ds->readUInt32(inStaticData->structSize)) 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after header) for an ICU .cnv conversion table\n", 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inBytes+=staticDataSize; 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length-=(int32_t)staticDataSize; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check for supported conversionType values */ 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(inStaticData->conversionType==UCNV_MBCS) { 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* MBCS data */ 483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint32_t mbcsHeaderLength, mbcsHeaderFlags, mbcsHeaderOptions; 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t extOffset; 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inMBCSHeader=(const _MBCSHeader *)inBytes; 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<(int32_t)sizeof(_MBCSHeader)) { 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(inMBCSHeader->version[0]==4 && inMBCSHeader->version[1]>=1) { 495c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru mbcsHeaderLength=MBCS_HEADER_V4_LENGTH; 496c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(inMBCSHeader->version[0]==5 && inMBCSHeader->version[1]>=3 && 497c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ((mbcsHeaderOptions=ds->readUInt32(inMBCSHeader->options))& 498c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK)==0 499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ) { 500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru mbcsHeaderLength=mbcsHeaderOptions&MBCS_OPT_LENGTH_MASK; 501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "icupkg/ucnv_enumDependencies(): unsupported _MBCSHeader.version %d.%d\n", 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inMBCSHeader->version[0], inMBCSHeader->version[1]); 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mbcsHeaderFlags=ds->readUInt32(inMBCSHeader->flags); 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru extOffset=(int32_t)(mbcsHeaderFlags>>8); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru outputType=(uint8_t)mbcsHeaderFlags; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outputType==MBCS_OUTPUT_EXT_ONLY) { 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * extension-only file, 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * contains a base name instead of normal base table data 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char baseName[32]; 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t baseNameLength; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* there is extension data after the base data, see ucnv_ext.h */ 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<(extOffset+UCNV_EXT_INDEXES_MIN_LENGTH*4)) { 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table with extension data\n", 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length); 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the base name, between the header and the extension data */ 529c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char *inBaseName=(const char *)inBytes+mbcsHeaderLength*4; 530c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru baseNameLength=(int32_t)strlen(inBaseName); 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(baseNameLength>=(int32_t)sizeof(baseName)) { 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "icupkg/ucnv_enumDependencies(%s): base name length %ld too long\n", 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru itemName, baseNameLength); 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 537c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ds->swapInvChars(ds, inBaseName, baseNameLength+1, baseName, pErrorCode); 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru checkIDSuffix(itemName, baseName, -1, ".cnv", check, context, pErrorCode); 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ICU data formats -------------------------------------------------------- *** 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const struct { 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t dataFormat[4]; 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} dataFormats[]={ 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { { 0x52, 0x65, 0x73, 0x42 } }, /* dataFormat="ResB" */ 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { { 0x63, 0x6e, 0x76, 0x74 } }, /* dataFormat="cnvt" */ 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { { 0x43, 0x76, 0x41, 0x6c } } /* dataFormat="CvAl" */ 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruenum { 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FMT_RES, 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FMT_CNV, 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FMT_ALIAS, 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FMT_COUNT 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetDataFormat(const uint8_t dataFormat[4]) { 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<FMT_COUNT; ++i) { 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(0==memcmp(dataFormats[i].dataFormat, dataFormat, 4)) { 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return i; 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// enumerate dependencies of a package item -------------------------------- *** 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruPackage::enumDependencies(Item *pItem, void *context, CheckDependency check) { 57750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t infoLength, itemHeaderLength; 57850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode errorCode=U_ZERO_ERROR; 57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *pInfo=getDataInfo(pItem->data, pItem->length, infoLength, itemHeaderLength, &errorCode); 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // should not occur because readFile() checks headers 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the data format and call the corresponding function, if any 58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t format=getDataFormat(pInfo->dataFormat); 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(format>=0) { 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(format) { 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case FMT_RES: 58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Swap the resource bundle (if necessary) so that we can use 59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the normal runtime uresdata.c code to read it. 59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We do not want to duplicate that code, especially not together with on-the-fly swapping. 59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho NativeItem nrb(pItem, ures_swap); 59627f654740f2a26ad62a5c155af9199af9e69b889claireho ures_enumDependencies(pItem->name, nrb.getDataInfo(), nrb.getBytes(), nrb.getLength(), check, context, this, &errorCode); 59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 59850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case FMT_CNV: 60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: share/cache swappers 60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDataSwapper *ds=udata_openSwapper( 60350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (UBool)pInfo->isBigEndian, pInfo->charsetFamily, 60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, 60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho &errorCode); 60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(errorCode)) { 60750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n", 60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pItem->name, u_errorName(errorCode)); 60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho exit(errorCode); 61050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->printError=printError; 61350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->printErrorContext=stderr; 61450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint8_t *inBytes=pItem->data+itemHeaderLength; 61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length=pItem->length-itemHeaderLength; 61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 61850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ucnv_enumDependencies(ds, pItem->name, pInfo, inBytes, length, check, context, &errorCode); 61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_closeSwapper(ds); 62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exit(errorCode); 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 63150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 633