//----------------------------------------------------------------------------- // // init(). Does most of the work of construction, shared between the // constructors. // //----------------------------------------------------------------------------- void RBBIDataWrapper::init0() {
fHeader = nullptr;
fForwardTable = nullptr;
fReverseTable = nullptr;
fRuleSource = nullptr;
fRuleStatusTable = nullptr;
fTrie = nullptr;
fUDataMem = nullptr;
fRefCount = 0;
fDontFreeData = true;
}
void RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) { if (U_FAILURE(status)) { return;
}
fHeader = data; if (fHeader->fMagic != 0xb1a0 || !isDataVersionAcceptable(fHeader->fFormatVersion)) {
status = U_INVALID_FORMAT_ERROR; return;
} // Note: in ICU version 3.2 and earlier, there was a formatVersion 1 // that is no longer supported. At that time fFormatVersion was // an int32_t field, rather than an array of 4 bytes.
//----------------------------------------------------------------------------- // // Operator == Consider two RBBIDataWrappers to be equal if they // refer to the same underlying data. Although // the data wrappers are normally shared between // iterator instances, it's possible to independently // open the same data twice, and get two instances, which // should still be ==. // //----------------------------------------------------------------------------- bool RBBIDataWrapper::operator ==(const RBBIDataWrapper &other) const { if (fHeader == other.fHeader) { returntrue;
} if (fHeader->fLength != other.fHeader->fLength) { returnfalse;
} if (uprv_memcmp(fHeader, other.fHeader, fHeader->fLength) == 0) { returntrue;
} returnfalse;
}
//----------------------------------------------------------------------------- // // Reference Counting. A single RBBIDataWrapper object is shared among // however many RulesBasedBreakIterator instances are // referencing the same data. // //----------------------------------------------------------------------------- void RBBIDataWrapper::removeReference() { if (umtx_atomic_dec(&fRefCount) == 0) { deletethis;
}
}
if (table == nullptr) {
RBBIDebugPrintf(" N U L L T A B L E\n\n"); return;
}
UBool use8Bits = table->fFlags & RBBI_8BITS_ROWS; for (s=0; s<table->fNumStates; s++) {
RBBIStateTableRow *row = (RBBIStateTableRow *)
(table->fTableData + (table->fRowLen * s)); if (use8Bits) {
RBBIDebugPrintf("%4d | %3d %3d %3d ", s, row->r8.fAccepting, row->r8.fLookAhead, row->r8.fTagsIdx); for (c=0; c<fHeader->fCatCount; c++) {
RBBIDebugPrintf("%3d ", row->r8.fNextState[c]);
}
} else {
RBBIDebugPrintf("%4d | %3d %3d %3d ", s, row->r16.fAccepting, row->r16.fLookAhead, row->r16.fTagsIdx); for (c=0; c<fHeader->fCatCount; c++) {
RBBIDebugPrintf("%3d ", row->r16.fNextState[c]);
}
}
RBBIDebugPrintf("\n");
}
RBBIDebugPrintf("\n");
} #endif
void RBBIDataWrapper::printData() { #ifdef RBBI_DEBUG
RBBIDebugPrintf("RBBI Data at %p\n", (void *)fHeader);
RBBIDebugPrintf(" Version = {%d %d %d %d}\n", fHeader->fFormatVersion[0], fHeader->fFormatVersion[1],
fHeader->fFormatVersion[2], fHeader->fFormatVersion[3]);
RBBIDebugPrintf(" total length of data = %d\n", fHeader->fLength);
RBBIDebugPrintf(" number of character categories = %d\n\n", fHeader->fCatCount);
printTable("Forward State Transition Table", fForwardTable);
printTable("Reverse State Transition Table", fReverseTable);
// // Check that the data header is for for break data. // (Header contents are defined in genbrk.cpp) // const UDataInfo *pInfo = (const UDataInfo *)((constchar *)inData+4); if(!( pInfo->dataFormat[0]==0x42 && /* dataFormat="Brk " */
pInfo->dataFormat[1]==0x72 &&
pInfo->dataFormat[2]==0x6b &&
pInfo->dataFormat[3]==0x20 &&
RBBIDataWrapper::isDataVersionAcceptable(pInfo->formatVersion) )) {
udata_printError(ds, "ubrk_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized\n",
pInfo->dataFormat[0], pInfo->dataFormat[1],
pInfo->dataFormat[2], pInfo->dataFormat[3],
pInfo->formatVersion[0]);
*status=U_UNSUPPORTED_ERROR; return 0;
}
// // Swap the data header. (This is the generic ICU Data Header, not the RBBI Specific // RBBIDataHeader). This swap also conveniently gets us // the size of the ICU d.h., which lets us locate the start // of the RBBI specific data. //
int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, status);
// // Get the RRBI Data Header, and check that it appears to be OK. // const uint8_t *inBytes =(const uint8_t *)inData+headerSize;
RBBIDataHeader *rbbiDH = (RBBIDataHeader *)inBytes; if (ds->readUInt32(rbbiDH->fMagic) != 0xb1a0 ||
!RBBIDataWrapper::isDataVersionAcceptable(rbbiDH->fFormatVersion) ||
ds->readUInt32(rbbiDH->fLength) < sizeof(RBBIDataHeader)) {
udata_printError(ds, "ubrk_swap(): RBBI Data header is invalid.\n");
*status=U_UNSUPPORTED_ERROR; return 0;
}
// // Prefight operation? Just return the size //
int32_t breakDataLength = ds->readUInt32(rbbiDH->fLength);
int32_t totalSize = headerSize + breakDataLength; if (length < 0) { return totalSize;
}
// // Check that length passed in is consistent with length from RBBI data header. // if (length < totalSize) {
udata_printError(ds, "ubrk_swap(): too few bytes (%d after ICU Data header) for break data.\n",
breakDataLength);
*status=U_INDEX_OUTOFBOUNDS_ERROR; return 0;
}
// // Swap the Data. Do the data itself first, then the RBBI Data Header, because // we need to reference the header to locate the data, and an // inplace swap of the header leaves it unusable. //
uint8_t *outBytes = (uint8_t *)outData + headerSize;
RBBIDataHeader *outputDH = (RBBIDataHeader *)outBytes;
int32_t tableStartOffset;
int32_t tableLength;
// // If not swapping in place, zero out the output buffer before starting. // Individual tables and other data items within are aligned to 8 byte boundaries // when originally created. Any unused space between items needs to be zero. // if (inBytes != outBytes) {
uprv_memset(outBytes, 0, breakDataLength);
}
// // Each state table begins with several 32 bit fields. Calculate the size // in bytes of these. //
int32_t topSize = offsetof(RBBIStateTable, fTableData);
// Forward state table.
tableStartOffset = ds->readUInt32(rbbiDH->fFTable);
tableLength = ds->readUInt32(rbbiDH->fFTableLen);
// Swap the state table if the table is in 16 bits. if (use8Bits) { if (outBytes != inBytes) {
uprv_memmove(outBytes+tableStartOffset+topSize,
inBytes+tableStartOffset+topSize,
tableLength-topSize);
}
} else {
ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
outBytes+tableStartOffset+topSize, status);
}
}
// Reverse state table. Same layout as forward table, above.
tableStartOffset = ds->readUInt32(rbbiDH->fRTable);
tableLength = ds->readUInt32(rbbiDH->fRTableLen);
// Swap the state table if the table is in 16 bits. if (use8Bits) { if (outBytes != inBytes) {
uprv_memmove(outBytes+tableStartOffset+topSize,
inBytes+tableStartOffset+topSize,
tableLength-topSize);
}
} else {
ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
outBytes+tableStartOffset+topSize, status);
}
}
// Trie table for character categories
ucptrie_swap(ds, inBytes+ds->readUInt32(rbbiDH->fTrie), ds->readUInt32(rbbiDH->fTrieLen),
outBytes+ds->readUInt32(rbbiDH->fTrie), status);
// Source Rules Text. It's UTF8 data if (outBytes != inBytes) {
uprv_memmove(outBytes+ds->readUInt32(rbbiDH->fRuleSource),
inBytes+ds->readUInt32(rbbiDH->fRuleSource),
ds->readUInt32(rbbiDH->fRuleSourceLen));
}
// Table of rule status values. It's all int_32 values
ds->swapArray32(ds, inBytes+ds->readUInt32(rbbiDH->fStatusTable), ds->readUInt32(rbbiDH->fStatusTableLen),
outBytes+ds->readUInt32(rbbiDH->fStatusTable), status);
// And, last, the header. // It is all int32_t values except for fFormataVersion, which is an array of four bytes. // Swap the whole thing as int32_t, then re-swap the one field. //
ds->swapArray32(ds, inBytes, sizeof(RBBIDataHeader), outBytes, status);
ds->swapArray32(ds, outputDH->fFormatVersion, 4, outputDH->fFormatVersion, status);
return totalSize;
}
#endif/* #if !UCONFIG_NO_BREAK_ITERATION */
Messung V0.5
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
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.