1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2003-2010, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: pkgitems.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: 2005sep18 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Markus W. Scherer 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Companion file to package.cpp. Deals with details of ICU data item formats. 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Used for item dependencies. 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Contains adapted code from ucnv_bld.c (swapper code from 2003). 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ures.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/udata.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uinvchar.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucmndata.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "udataswp.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "swapimpl.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "toolutil.h" 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "package.h" 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "pkg_imp.h" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h> 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h> 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h> 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* item formats in common */ 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uresdata.h" 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_bld.h" 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_io.h" 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// general definitions ----------------------------------------------------- *** 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)printError(void *context, const char *fmt, va_list args) { 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) vfprintf((FILE *)context, fmt, args); 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// a data item in native-platform form ------------------------------------- *** 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class NativeItem { 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public: 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NativeItem() : pItem(NULL), pInfo(NULL), bytes(NULL), swapped(NULL), length(0) {} 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NativeItem(const Item *item, UDataSwapFn *swap) : swapped(NULL) { 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setItem(item, swap); 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ~NativeItem() { 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete [] swapped; 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UDataInfo *getDataInfo() const { 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return pInfo; 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *getBytes() const { 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return bytes; 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t getLength() const { 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void setItem(const Item *item, UDataSwapFn *swap) { 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pItem=item; 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t infoLength, itemHeaderLength; 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo=::getDataInfo(pItem->data, pItem->length, infoLength, itemHeaderLength, &errorCode); 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(errorCode); // should succeed because readFile() checks headers 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=pItem->length-itemHeaderLength; 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pInfo->isBigEndian==U_IS_BIG_ENDIAN && pInfo->charsetFamily==U_CHARSET_FAMILY) { 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytes=pItem->data+itemHeaderLength; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDataSwapper *ds=udata_openSwapper((UBool)pInfo->isBigEndian, pInfo->charsetFamily, U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode); 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n", 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pItem->name, u_errorName(errorCode)); 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(errorCode); 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ds->printError=printError; 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ds->printErrorContext=stderr; 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) swapped=new uint8_t[pItem->length]; 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(swapped==NULL) { 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: unable to allocate memory for swapping \"%s\"\n", pItem->name); 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(U_MEMORY_ALLOCATION_ERROR); 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) swap(ds, pItem->data, pItem->length, swapped, &errorCode); 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo=::getDataInfo(swapped, pItem->length, infoLength, itemHeaderLength, &errorCode); 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bytes=swapped+itemHeaderLength; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_closeSwapper(ds); 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private: 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const Item *pItem; 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UDataInfo *pInfo; 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *bytes; 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t *swapped; 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// check a dependency ------------------------------------------------------ *** 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * assemble the target item name from the source item name, an ID 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and a suffix 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)makeTargetName(const char *itemName, const char *id, int32_t idLength, const char *suffix, 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *target, int32_t capacity, 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *itemID; 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t treeLength, suffixLength, targetLength; 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get the item basename 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemID=strrchr(itemName, '/'); 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(itemID!=NULL) { 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++itemID; 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemID=itemName; 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // build the target string 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) treeLength=(int32_t)(itemID-itemName); 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(idLength<0) { 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idLength=(int32_t)strlen(id); 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) suffixLength=(int32_t)strlen(suffix); 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetLength=treeLength+idLength+suffixLength; 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(targetLength>=capacity) { 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/makeTargetName(%s) target item name length %ld too long\n", 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, (long)targetLength); 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memcpy(target, itemName, treeLength); 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memcpy(target+treeLength, id, idLength); 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memcpy(target+treeLength+idLength, suffix, suffixLength+1); // +1 includes the terminating NUL 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)checkIDSuffix(const char *itemName, const char *id, int32_t idLength, const char *suffix, 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CheckDependency check, void *context, 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char target[200]; 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) makeTargetName(itemName, id, idLength, suffix, target, (int32_t)sizeof(target), pErrorCode); 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*pErrorCode)) { 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) check(context, itemName, target); 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* assemble the target item name from the item's parent item name */ 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)checkParent(const char *itemName, CheckDependency check, void *context, 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *itemID, *parent, *parentLimit, *suffix; 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t parentLength; 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get the item basename 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemID=strrchr(itemName, '/'); 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(itemID!=NULL) { 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++itemID; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemID=itemName; 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get the item suffix 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) suffix=strrchr(itemID, '.'); 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(suffix==NULL) { 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // empty suffix, point to the end of the string 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) suffix=strrchr(itemID, 0); 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get the position of the last '_' 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(parentLimit=suffix; parentLimit>itemID && *--parentLimit!='_';) {} 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(parentLimit!=itemID) { 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get the parent item name by truncating the last part of this item's name */ 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parent=itemID; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parentLength=(int32_t)(parentLimit-itemID); 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // no '_' in the item name: the parent is the root bundle 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parent="root"; 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parentLength=4; 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((suffix-itemID)==parentLength && 0==memcmp(itemID, parent, parentLength)) { 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the item itself is "root", which does not depend on a parent 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkIDSuffix(itemName, parent, parentLength, suffix, check, context, pErrorCode); 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// get dependencies from resource bundles ---------------------------------- *** 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar SLASH=0x2f; 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Check for the alias from the string or alias resource res. 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)checkAlias(const char *itemName, 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Resource res, const UChar *alias, int32_t length, UBool useResSuffix, 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CheckDependency check, void *context, UErrorCode *pErrorCode) { 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!uprv_isInvariantUString(alias, length)) { 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias string contains non-invariant characters\n", 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, res); 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INVALID_CHAR_FOUND; 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // extract the locale ID from alias strings like 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // locale_ID/key1/key2/key3 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // locale_ID 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // search for the first slash 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<length && alias[i]!=SLASH; ++i) {} 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(res_getPublicType(res)==URES_ALIAS) { 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ignore aliases with an initial slash: 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // /ICUDATA/... and /pkgname/... go to a different package 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // /LOCALE/... are for dynamic sideways fallbacks and don't go to a fixed bundle 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i==0) { 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; // initial slash ('/') 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ignore the intra-bundle path starting from the first slash ('/') 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=i; 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else /* URES_STRING */ { 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the whole string should only consist of a locale ID 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i!=length) { 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) %%ALIAS contains a '/'\n", 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, res); 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_UNSUPPORTED_ERROR; 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert the Unicode string to char * 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char localeID[32]; 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length>=(int32_t)sizeof(localeID)) { 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias locale ID length %ld too long\n", 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, res, (long)length); 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_UCharsToChars(alias, localeID, length); 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) localeID[length]=0; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkIDSuffix(itemName, localeID, -1, (useResSuffix ? ".res" : ""), check, context, pErrorCode); 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Enumerate one resource item and its children and extract dependencies from 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * aliases. 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ures_enumDependencies(const char *itemName, 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const ResourceData *pResData, 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Resource res, const char *inKey, const char *parentKey, int32_t depth, 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CheckDependency check, void *context, 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Package *pkg, 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(res_getPublicType(res)) { 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case URES_STRING: 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool useResSuffix = TRUE; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check for %%ALIAS 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(depth==1 && inKey!=NULL) { 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0!=strcmp(inKey, "%%ALIAS")) { 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check for %%DEPENDENCY 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if(depth==2 && parentKey!=NULL) { 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0!=strcmp(parentKey, "%%DEPENDENCY")) { 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) useResSuffix = FALSE; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we ignore all other strings 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *alias=res_getString(pResData, res, &length); 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkAlias(itemName, res, alias, length, useResSuffix, check, context, pErrorCode); 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case URES_ALIAS: 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length; 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *alias=res_getAlias(pResData, res, &length); 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkAlias(itemName, res, alias, length, TRUE, check, context, pErrorCode); 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case URES_TABLE: 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* recurse */ 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t count=res_countArrayItems(pResData, res); 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int32_t i=0; i<count; ++i) { 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *itemKey; 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Resource item=res_getTableItemByIndex(pResData, res, i, &itemKey); 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_enumDependencies( 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, pResData, 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) item, itemKey, 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inKey, depth+1, 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) check, context, 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pkg, 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ures_enumDependencies(%s table res=%08x)[%d].recurse(%s: %08x) failed\n", 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, res, i, itemKey, item); 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case URES_ARRAY: 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* recurse */ 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t count=res_countArrayItems(pResData, res); 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int32_t i=0; i<count; ++i) { 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Resource item=res_getArrayItem(pResData, res, i); 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_enumDependencies( 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, pResData, 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) item, NULL, 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inKey, depth+1, 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) check, context, 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pkg, 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ures_enumDependencies(%s array res=%08x)[%d].recurse(%08x) failed\n", 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, res, i, item); 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ures_enumDependencies(const char *itemName, const UDataInfo *pInfo, 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *inBytes, int32_t length, 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CheckDependency check, void *context, 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Package *pkg, 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ResourceData resData; 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) res_read(&resData, pInfo, inBytes, length, pErrorCode); 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: .res format version %02x.%02x not supported, or bundle malformed\n", 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[0], pInfo->formatVersion[1]); 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(U_UNSUPPORTED_ERROR); 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if the bundle attributes are present and the nofallback flag is not set, 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * then add the parent bundle as a dependency 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pInfo->formatVersion[0]>1 || (pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1)) { 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!resData.noFallback) { 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* this bundle participates in locale fallback */ 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkParent(itemName, check, context, pErrorCode); 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_QUALIFIER NativeItem nativePool; 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(resData.usesPoolBundle) { 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char poolName[200]; 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) makeTargetName(itemName, "pool", 4, ".res", poolName, (int32_t)sizeof(poolName), pErrorCode); 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)) { 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) check(context, itemName, poolName); 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t index=pkg->findItem(poolName); 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(index<0) { 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We cannot work with a bundle if its pool resource is missing. 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check() already printed a complaint. 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO: Cache the native version in the Item itself. 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nativePool.setItem(pkg->getItem(index), ures_swap); 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UDataInfo *poolInfo=nativePool.getDataInfo(); 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(poolInfo->formatVersion[0]<=1) { 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: %s is not a pool bundle\n", poolName); 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const int32_t *poolIndexes=(const int32_t *)nativePool.getBytes()+1; 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t poolIndexLength=poolIndexes[URES_INDEX_LENGTH]&0xff; 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!(poolIndexLength>URES_INDEX_POOL_CHECKSUM && 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (poolIndexes[URES_INDEX_ATTRIBUTES]&URES_ATT_IS_POOL_BUNDLE)) 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: %s is not a pool bundle\n", poolName); 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(resData.pRoot[1+URES_INDEX_POOL_CHECKSUM]==poolIndexes[URES_INDEX_POOL_CHECKSUM]) { 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resData.poolBundleKeys=(const char *)(poolIndexes+poolIndexLength); 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: %s has mismatched checksum for %s\n", poolName, itemName); 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_enumDependencies( 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, &resData, 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resData.rootRes, NULL, NULL, 0, 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) check, context, 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pkg, 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pErrorCode); 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// get dependencies from conversion tables --------------------------------- *** 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* code adapted from ucnv_swap() */ 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucnv_enumDependencies(const UDataSwapper *ds, 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *itemName, const UDataInfo *pInfo, 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *inBytes, int32_t length, 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CheckDependency check, void *context, 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t staticDataSize; 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UConverterStaticData *inStaticData; 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const _MBCSHeader *inMBCSHeader; 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t outputType; 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check format version */ 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!( 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[0]==6 && 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[1]>=2 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) )) { 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg/ucnv_enumDependencies(): .cnv format version %02x.%02x not supported\n", 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[0], pInfo->formatVersion[1]); 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(U_UNSUPPORTED_ERROR); 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* read the initial UConverterStaticData structure after the UDataInfo header */ 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inStaticData=(const UConverterStaticData *)inBytes; 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( length<(int32_t)sizeof(UConverterStaticData) || 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (uint32_t)length<(staticDataSize=ds->readUInt32(inStaticData->structSize)) 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after header) for an ICU .cnv conversion table\n", 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length); 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inBytes+=staticDataSize; 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length-=(int32_t)staticDataSize; 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check for supported conversionType values */ 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(inStaticData->conversionType==UCNV_MBCS) { 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* MBCS data */ 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t mbcsHeaderLength, mbcsHeaderFlags, mbcsHeaderOptions; 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t extOffset; 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inMBCSHeader=(const _MBCSHeader *)inBytes; 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<(int32_t)sizeof(_MBCSHeader)) { 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table\n", 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length); 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(inMBCSHeader->version[0]==4 && inMBCSHeader->version[1]>=1) { 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mbcsHeaderLength=MBCS_HEADER_V4_LENGTH; 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(inMBCSHeader->version[0]==5 && inMBCSHeader->version[1]>=3 && 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((mbcsHeaderOptions=ds->readUInt32(inMBCSHeader->options))& 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MBCS_OPT_UNKNOWN_INCOMPATIBLE_MASK)==0 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mbcsHeaderLength=mbcsHeaderOptions&MBCS_OPT_LENGTH_MASK; 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_printError(ds, "icupkg/ucnv_enumDependencies(): unsupported _MBCSHeader.version %d.%d\n", 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) inMBCSHeader->version[0], inMBCSHeader->version[1]); 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_UNSUPPORTED_ERROR; 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) mbcsHeaderFlags=ds->readUInt32(inMBCSHeader->flags); 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) extOffset=(int32_t)(mbcsHeaderFlags>>8); 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) outputType=(uint8_t)mbcsHeaderFlags; 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(outputType==MBCS_OUTPUT_EXT_ONLY) { 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * extension-only file, 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * contains a base name instead of normal base table data 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char baseName[32]; 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t baseNameLength; 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* there is extension data after the base data, see ucnv_ext.h */ 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length<(extOffset+UCNV_EXT_INDEXES_MIN_LENGTH*4)) { 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table with extension data\n", 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length); 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* swap the base name, between the header and the extension data */ 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *inBaseName=(const char *)inBytes+mbcsHeaderLength*4; 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) baseNameLength=(int32_t)strlen(inBaseName); 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(baseNameLength>=(int32_t)sizeof(baseName)) { 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_printError(ds, "icupkg/ucnv_enumDependencies(%s): base name length %ld too long\n", 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) itemName, baseNameLength); 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_UNSUPPORTED_ERROR; 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ds->swapInvChars(ds, inBaseName, baseNameLength+1, baseName, pErrorCode); 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) checkIDSuffix(itemName, baseName, -1, ".cnv", check, context, pErrorCode); 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ICU data formats -------------------------------------------------------- *** 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const struct { 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t dataFormat[4]; 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} dataFormats[]={ 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { { 0x52, 0x65, 0x73, 0x42 } }, /* dataFormat="ResB" */ 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { { 0x63, 0x6e, 0x76, 0x74 } }, /* dataFormat="cnvt" */ 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { { 0x43, 0x76, 0x41, 0x6c } } /* dataFormat="CvAl" */ 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)enum { 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FMT_RES, 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FMT_CNV, 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FMT_ALIAS, 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FMT_COUNT 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getDataFormat(const uint8_t dataFormat[4]) { 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0; i<FMT_COUNT; ++i) { 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0==memcmp(dataFormats[i].dataFormat, dataFormat, 4)) { 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return i; 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// enumerate dependencies of a package item -------------------------------- *** 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Package::enumDependencies(Item *pItem, void *context, CheckDependency check) { 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t infoLength, itemHeaderLength; 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode=U_ZERO_ERROR; 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UDataInfo *pInfo=getDataInfo(pItem->data, pItem->length, infoLength, itemHeaderLength, &errorCode); 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; // should not occur because readFile() checks headers 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // find the data format and call the corresponding function, if any 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t format=getDataFormat(pInfo->dataFormat); 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(format>=0) { 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(format) { 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FMT_RES: 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Swap the resource bundle (if necessary) so that we can use 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the normal runtime uresdata.c code to read it. 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * We do not want to duplicate that code, especially not together with on-the-fly swapping. 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NativeItem nrb(pItem, ures_swap); 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_enumDependencies(pItem->name, nrb.getDataInfo(), nrb.getBytes(), nrb.getLength(), check, context, this, &errorCode); 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case FMT_CNV: 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO: share/cache swappers 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDataSwapper *ds=udata_openSwapper( 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (UBool)pInfo->isBigEndian, pInfo->charsetFamily, 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &errorCode); 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n", 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pItem->name, u_errorName(errorCode)); 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(errorCode); 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ds->printError=printError; 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ds->printErrorContext=stderr; 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *inBytes=pItem->data+itemHeaderLength; 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length=pItem->length-itemHeaderLength; 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_enumDependencies(ds, pItem->name, pInfo, inBytes, length, check, context, &errorCode); 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_closeSwapper(ds); 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) exit(errorCode); 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END 633