/* assemble the target item name from the item's parent item name */ staticvoid
checkParent(constchar *itemName, CheckDependency check, void *context,
UErrorCode *pErrorCode) { constchar *itemID, *parent, *parentLimit, *suffix;
int32_t parentLength;
// get the item basename
itemID=strrchr(itemName, '/'); if(itemID!=nullptr) {
++itemID;
} else {
itemID=itemName;
}
// get the item suffix
suffix=strrchr(itemID, '.'); if(suffix==nullptr) { // empty suffix, point to the end of the string
suffix=strrchr(itemID, 0);
}
// get the position of the last '_' for(parentLimit=suffix; parentLimit>itemID && *--parentLimit!='_';) {}
if(parentLimit!=itemID) { // get the parent item name by truncating the last part of this item's name */
parent=itemID;
parentLength = static_cast<int32_t>(parentLimit - itemID);
} else { // no '_' in the item name: the parent is the root bundle
parent="root";
parentLength=4; if((suffix-itemID)==parentLength && 0==memcmp(itemID, parent, parentLength)) { // the item itself is "root", which does not depend on a parent return;
}
}
checkIDSuffix(itemName, parent, parentLength, suffix, check, context, pErrorCode);
}
// get dependencies from resource bundles ---------------------------------- ***
staticconst char16_t SLASH=0x2f;
/* * Check for the alias from the string or alias resource res.
*/ staticvoid
checkAlias(constchar *itemName,
Resource res, const char16_t *alias, int32_t length, UBool useResSuffix,
CheckDependency check, void *context, UErrorCode *pErrorCode) {
int32_t i;
// extract the locale ID from alias strings like // locale_ID/key1/key2/key3 // locale_ID
// search for the first slash for(i=0; i<length && alias[i]!=SLASH; ++i) {}
if(res_getPublicType(res)==URES_ALIAS) { // ignore aliases with an initial slash: // /ICUDATA/... and /pkgname/... go to a different package // /LOCALE/... are for dynamic sideways fallbacks and don't go to a fixed bundle if(i==0) { return; // initial slash ('/')
}
// ignore the intra-bundle path starting from the first slash ('/')
length=i;
} else/* URES_STRING */ { // the whole string should only consist of a locale ID if(i!=length) {
fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) %%ALIAS contains a '/'\n",
itemName, res);
*pErrorCode=U_UNSUPPORTED_ERROR; return;
}
}
// convert the Unicode string to char * char localeID[48]; if (length >= static_cast<int32_t>(sizeof(localeID))) {
fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias locale ID length %ld too long\n",
itemName, res, static_cast<long>(length));
*pErrorCode=U_BUFFER_OVERFLOW_ERROR; return;
}
u_UCharsToChars(alias, localeID, length);
localeID[length]=0;
/* * if the bundle attributes are present and the nofallback flag is not set, * then add the parent bundle as a dependency
*/ if(pInfo->formatVersion[0]>1 || (pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1)) { if(!resData.noFallback) { /* this bundle participates in locale fallback */
checkParent(itemName, check, context, pErrorCode);
}
}
}
// get dependencies from conversion tables --------------------------------- ***
/* check format version */ if(!(
pInfo->formatVersion[0]==6 &&
pInfo->formatVersion[1]>=2
)) {
fprintf(stderr, "icupkg/ucnv_enumDependencies(): .cnv format version %02x.%02x not supported\n",
pInfo->formatVersion[0], pInfo->formatVersion[1]); exit(U_UNSUPPORTED_ERROR);
}
/* read the initial UConverterStaticData structure after the UDataInfo header */
inStaticData = reinterpret_cast<const UConverterStaticData*>(inBytes);
if (length < static_cast<int32_t>(sizeof(UConverterStaticData)) || static_cast<uint32_t>(length) < (staticDataSize = ds->readUInt32(inStaticData->structSize))
) {
udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after header) for an ICU .cnv conversion table\n",
length);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; return;
}
if(outputType==MBCS_OUTPUT_EXT_ONLY) { /* * extension-only file, * contains a base name instead of normal base table data
*/ char baseName[32];
int32_t baseNameLength;
/* there is extension data after the base data, see ucnv_ext.h */ if(length<(extOffset+UCNV_EXT_INDEXES_MIN_LENGTH*4)) {
udata_printError(ds, "icupkg/ucnv_enumDependencies(): too few bytes (%d after headers) for an ICU MBCS .cnv conversion table with extension data\n",
length);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; return;
}
/* swap the base name, between the header and the extension data */ constchar* inBaseName = reinterpret_cast<constchar*>(inBytes) + mbcsHeaderLength * 4;
baseNameLength = static_cast<int32_t>(strlen(inBaseName)); if (baseNameLength >= static_cast<int32_t>(sizeof(baseName))) {
udata_printError(ds, "icupkg/ucnv_enumDependencies(%s): base name length %ld too long\n",
itemName, baseNameLength);
*pErrorCode=U_UNSUPPORTED_ERROR; return;
}
ds->swapInvChars(ds, inBaseName, baseNameLength+1, baseName, pErrorCode);
// find the data format and call the corresponding function, if any
int32_t format=getDataFormat(pInfo->dataFormat); if(format>=0) { switch(format) { case FMT_RES:
{ /* * Swap the resource bundle (if necessary) so that we can use * the normal runtime uresdata.c code to read it. * We do not want to duplicate that code, especially not together with on-the-fly swapping.
*/
NativeItem nrb(pItem, ures_swap);
ures_enumDependencies(pItem->name, nrb.getDataInfo(), nrb.getBytes(), nrb.getLength(), check, context, this, &errorCode); break;
} case FMT_CNV:
{ // TODO: share/cache swappers
UDataSwapper *ds=udata_openSwapper( static_cast<UBool>(pInfo->isBigEndian), pInfo->charsetFamily,
U_IS_BIG_ENDIAN, U_CHARSET_FAMILY,
&errorCode); if(U_FAILURE(errorCode)) {
fprintf(stderr, "icupkg: udata_openSwapper(\"%s\") failed - %s\n",
pItem->name, u_errorName(errorCode)); exit(errorCode);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.