/* get a const char* pointer to the key with the keyOffset byte offset from pRoot */ #define RES_GET_KEY16(pResData, keyOffset) \
((keyOffset)<(pResData)->localKeyLimit ? \
(constchar *)(pResData)->pRoot+(keyOffset) : \
(pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit)
/* get the root resource */
pResData->pRoot = static_cast<const int32_t*>(inBytes);
pResData->rootRes = static_cast<Resource>(*pResData->pRoot);
pResData->p16BitUnits=&gEmpty16;
/* formatVersion 1.1 must have a root item and at least 5 indexes */ if(length>=0 && (length/4)<((formatVersion[0]==1 && formatVersion[1]==0) ? 1 : 1+5)) {
*errorCode=U_INVALID_FORMAT_ERROR;
res_unload(pResData); return;
}
/* currently, we accept only resources that have a Table as their roots */
rootType = static_cast<UResType>(RES_GET_TYPE(pResData->rootRes)); if(!URES_IS_TABLE(rootType)) {
*errorCode=U_INVALID_FORMAT_ERROR;
res_unload(pResData); return;
}
if(formatVersion[0]==1 && formatVersion[1]==0) {
pResData->localKeyLimit=0x10000; /* greater than any 16-bit key string offset */
} else { /* bundles with formatVersion 1.1 and later contain an indexes[] array */ const int32_t *indexes=pResData->pRoot+1;
int32_t indexLength=indexes[URES_INDEX_LENGTH]&0xff; if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) {
*errorCode=U_INVALID_FORMAT_ERROR;
res_unload(pResData); return;
} if( length>=0 &&
(length<((1+indexLength)<<2) ||
length<(indexes[URES_INDEX_BUNDLE_TOP]<<2))
) {
*errorCode=U_INVALID_FORMAT_ERROR;
res_unload(pResData); return;
} if(indexes[URES_INDEX_KEYS_TOP]>(1+indexLength)) {
pResData->localKeyLimit=indexes[URES_INDEX_KEYS_TOP]<<2;
} if(formatVersion[0]>=3) { // In formatVersion 1, the indexLength took up this whole int. // In version 2, bits 31..8 were reserved and always 0. // In version 3, they contain bits 23..0 of the poolStringIndexLimit. // Bits 27..24 are in indexes[URES_INDEX_ATTRIBUTES] bits 15..12.
pResData->poolStringIndexLimit = static_cast<int32_t>(static_cast<uint32_t>(indexes[URES_INDEX_LENGTH]) >> 8);
} if(indexLength>URES_INDEX_ATTRIBUTES) {
int32_t att=indexes[URES_INDEX_ATTRIBUTES];
pResData->noFallback = static_cast<UBool>(att & URES_ATT_NO_FALLBACK);
pResData->isPoolBundle = static_cast<UBool>((att & URES_ATT_IS_POOL_BUNDLE) != 0);
pResData->usesPoolBundle = static_cast<UBool>((att & URES_ATT_USES_POOL_BUNDLE) != 0);
pResData->poolStringIndexLimit|=(att&0xf000)<<12; // bits 15..12 -> 27..24
pResData->poolStringIndex16Limit = static_cast<int32_t>(static_cast<uint32_t>(att) >> 16);
} if((pResData->isPoolBundle || pResData->usesPoolBundle) && indexLength<=URES_INDEX_POOL_CHECKSUM) {
*errorCode=U_INVALID_FORMAT_ERROR;
res_unload(pResData); return;
} if( indexLength>URES_INDEX_16BIT_TOP &&
indexes[URES_INDEX_16BIT_TOP]>indexes[URES_INDEX_KEYS_TOP]
) {
pResData->p16BitUnits = reinterpret_cast<const uint16_t*>(pResData->pRoot + indexes[URES_INDEX_KEYS_TOP]);
}
}
static Resource
makeResourceFrom16(const ResourceData *pResData, int32_t res16) { if(res16<pResData->poolStringIndex16Limit) { // Pool string, nothing to do.
} else { // Local string, adjust the 16-bit offset to a regular one, // with a larger pool string index limit.
res16=res16-pResData->poolStringIndex16Limit+pResData->poolStringIndexLimit;
} return URES_MAKE_RESOURCE(URES_STRING_V2, res16);
}
UBool icu::ResourceTable::getKeyAndValue(int32_t i, constchar *&key, icu::ResourceValue &value) const { if(0 <= i && i < length) {
icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value); if (keys16 != nullptr) {
key = RES_GET_KEY16(&rdValue.getData(), keys16[i]);
} else {
key = RES_GET_KEY32(&rdValue.getData(), keys32[i]);
}
Resource res; if (items16 != nullptr) {
res = makeResourceFrom16(&rdValue.getData(), items16[i]);
} else {
res = items32[i];
} // Note: the ResourceTracer keeps a reference to the field of this // ResourceTable. This is OK because the ResourceTable should remain // alive for the duration that fields are being read from it // (including nested fields).
rdValue.setResource(res, ResourceTracer(fTraceInfo, key)); returntrue;
} returnfalse;
}
UBool icu::ResourceTable::findValue(constchar *key, ResourceValue &value) const {
icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value); constchar *realKey = nullptr;
int32_t i; if (keys16 != nullptr) {
i = _res_findTableItem(&rdValue.getData(), keys16, length, key, &realKey);
} else {
i = _res_findTable32Item(&rdValue.getData(), keys32, length, key, &realKey);
} if (i >= 0) {
Resource res; if (items16 != nullptr) {
res = makeResourceFrom16(&rdValue.getData(), items16[i]);
} else {
res = items32[i];
} // Same note about lifetime as in getKeyAndValue().
rdValue.setResource(res, ResourceTracer(fTraceInfo, key)); returntrue;
} returnfalse;
}
UBool icu::ResourceArray::getValue(int32_t i, icu::ResourceValue &value) const { if(0 <= i && i < length) {
icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value); // Note: the ResourceTracer keeps a reference to the field of this // ResourceArray. This is OK because the ResourceArray should remain // alive for the duration that fields are being read from it // (including nested fields).
rdValue.setResource(
internalGetResource(&rdValue.getData(), i),
ResourceTracer(fTraceInfo, i)); returntrue;
} returnfalse;
}
switch(RES_GET_TYPE(res)) { case URES_TABLE16: case URES_STRING_V2: case URES_INT: case URES_ARRAY16: /* integer, or points to 16-bit units, nothing to do here */ return; default: break;
}
/* all other types use an offset to point to their data */
offset = static_cast<int32_t>(RES_GET_OFFSET(res)); if(offset==0) { /* special offset indicating an empty item */ return;
} if (pTempTable->resFlags[offset >> 5] & (static_cast<uint32_t>(1) << (offset & 0x1f))) { /* we already swapped this resource item */ return;
} else { /* mark it as swapped now */
pTempTable->resFlags[offset >> 5] |= static_cast<uint32_t>(1) << (offset & 0x1f);
}
p=inBundle+offset;
q=outBundle+offset;
switch(RES_GET_TYPE(res)) { case URES_ALIAS: /* physically same value layout as string, fall through */
U_FALLTHROUGH; case URES_STRING:
count = udata_readInt32(ds, static_cast<int32_t>(*p)); /* swap length */
ds->swapArray32(ds, p, 4, q, pErrorCode); /* swap each char16_t (the terminating NUL would not change) */
ds->swapArray16(ds, p+1, 2*count, q+1, pErrorCode); break; case URES_BINARY:
count = udata_readInt32(ds, static_cast<int32_t>(*p)); /* swap length */
ds->swapArray32(ds, p, 4, q, pErrorCode); /* no need to swap or copy bytes - ures_swap() copied them all */
/* swap known formats */ #if !UCONFIG_NO_COLLATION if( key!=nullptr && /* the binary is in a table */
(key!=gUnknownKey ? /* its table key string is "%%CollationBin" */ 0==ds->compareInvChars(ds, key, -1,
gCollationBinKey, UPRV_LENGTHOF(gCollationBinKey)-1) : /* its table key string is unknown but it looks like a collation binary */
ucol_looksLikeCollationBinary(ds, p+1, count))
) {
ucol_swap(ds, p+1, count, q+1, pErrorCode);
} #endif break; case URES_TABLE: case URES_TABLE32:
{ const uint16_t *pKey16;
uint16_t *qKey16;
/* check data format and format version */
pInfo=(const UDataInfo *)((constchar *)inData+4); if(!(
pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */
pInfo->dataFormat[1]==0x65 &&
pInfo->dataFormat[2]==0x73 &&
pInfo->dataFormat[3]==0x42 && /* formatVersion 1.1+ or 2.x or 3.x */
((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1) ||
pInfo->formatVersion[0]==2 || pInfo->formatVersion[0]==3)
)) {
udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not a resource bundle\n",
pInfo->dataFormat[0], pInfo->dataFormat[1],
pInfo->dataFormat[2], pInfo->dataFormat[3],
pInfo->formatVersion[0], pInfo->formatVersion[1]);
*pErrorCode=U_UNSUPPORTED_ERROR; return0;
}
tempTable.majorFormatVersion=pInfo->formatVersion[0];
/* a resource bundle must contain at least one resource item */ if(length<0) {
bundleLength=-1;
} else {
bundleLength=(length-headerSize)/4;
/* formatVersion 1.1 must have a root item and at least 5 indexes */ if(bundleLength<(1+5)) {
udata_printError(ds, "ures_swap(): too few bytes (%d after header) for a resource bundle\n",
length-headerSize);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; return0;
}
}
/* track which resources we have already swapped */
uint32_t stackResFlags[STACK_ROW_CAPACITY];
int32_t resFlagsLength;
/* *Weneedonebitper4resourcebundlebytessothatwecantrack *everypossibleResourceforwhetherwehaveswappeditalready. *MultipleResourcewordscanrefertothesamebundleoffsets *forsharingidenticalvalues. *Wecouldoptimizethisbyallocatingonlyforlocationsabove *whereResourcevaluesarestored(abovekeys&strings).
*/
resFlagsLength=(length+31)>>5; /* number of bytes needed */
resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint32_t */ if(resFlagsLength<=(int32_t)sizeof(stackResFlags)) {
tempTable.resFlags=stackResFlags;
} else {
tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength); if(tempTable.resFlags==nullptr) {
udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n");
*pErrorCode=U_MEMORY_ALLOCATION_ERROR; return0;
}
}
uprv_memset(tempTable.resFlags, 0, resFlagsLength);
/* copy the bundle for binary and inaccessible data */ if(inData!=outData) {
uprv_memcpy(outBundle, inBundle, 4*top);
}
/* swap the key strings, but not the padding bytes (0xaa) after the last string and its NUL */
udata_swapInvStringBlock(ds, inBundle+keysBottom, 4*(keysTop-keysBottom),
outBundle+keysBottom, pErrorCode); if(U_FAILURE(*pErrorCode)) {
udata_printError(ds, "ures_swap().udata_swapInvStringBlock(keys[%d]) failed\n", 4*(keysTop-keysBottom)); if(tempTable.resFlags!=stackResFlags) {
uprv_free(tempTable.resFlags);
} return0;
}
/* swap the root resource and indexes */
ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode);
}
return headerSize+4*top;
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.51Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
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.