/* check the vicinity of the last-seen row (start searching with an unrolled loop) */
row=pv->v+prevRow*columns; if (rangeStart >= static_cast<UChar32>(row[0])) { if (rangeStart < static_cast<UChar32>(row[1])) { /* same row as last seen */ return row;
} elseif (rangeStart < static_cast<UChar32>((row += columns)[1])) { /* next row after the last one */
pv->prevRow=prevRow+1; return row;
} elseif (rangeStart < static_cast<UChar32>((row += columns)[1])) { /* second row after the last one */
pv->prevRow=prevRow+2; return row;
} elseif ((rangeStart - static_cast<UChar32>(row[1])) < 10) { /* we are close, continue looping */
prevRow+=2; do {
++prevRow;
row+=columns;
} while (rangeStart >= static_cast<UChar32>(row[1]));
pv->prevRow=prevRow; return row;
}
} elseif (rangeStart < static_cast<UChar32>(pv->v[1])) { /* the very first row */
pv->prevRow=0; return pv->v;
}
/* do a binary search for the start of the range */
start=0; while(start<limit-1) {
i=(start+limit)/2;
row=pv->v+i*columns; if (rangeStart < static_cast<UChar32>(row[0])) {
limit=i;
} elseif (rangeStart < static_cast<UChar32>(row[1])) {
pv->prevRow=i; return row;
} else {
start=i;
}
}
/* must be found because all ranges together always cover all of Unicode */
pv->prevRow=start; return pv->v+start*columns;
}
/* initialize */
columns=pv->columns;
column+=2; /* skip range start and limit columns */
value&=mask;
/* find the rows whose ranges overlap with the input range */
/* find the first and last rows, always successful */
firstRow=_findRow(pv, start);
lastRow=_findRow(pv, end);
/* * Rows need to be split if they partially overlap with the * input range (only possible for the first and last rows) * and if their value differs from the input value.
*/
splitFirstRow = start != static_cast<UChar32>(firstRow[0]) && value != (firstRow[column] & mask);
splitLastRow = limit != static_cast<UChar32>(lastRow[1]) && value != (lastRow[column] & mask);
/* count the number of row cells to move after the last row, and move them */
count = (int32_t)((pv->v+rows*columns)-(lastRow+columns)); if(count>0) {
uprv_memmove(
lastRow+(1+splitFirstRow+splitLastRow)*columns,
lastRow+columns,
count*4);
}
pv->rows=rows+splitFirstRow+splitLastRow;
/* split the first row, and move the firstRow pointer to the second part */ if(splitFirstRow) { /* copy all affected rows up one and move the lastRow pointer */
count = (int32_t)((lastRow-firstRow)+columns);
uprv_memmove(firstRow+columns, firstRow, (size_t)count*4);
lastRow+=columns;
/* split the range and move the firstRow pointer */
firstRow[1]=firstRow[columns]=(uint32_t)start;
firstRow+=columns;
}
/* split the last row */ if(splitLastRow) { /* copy the last row data */
uprv_memcpy(lastRow+columns, lastRow, (size_t)columns*4);
/* split the range and move the firstRow pointer */
lastRow[1]=lastRow[columns]=(uint32_t)limit;
}
}
/* set the "row last seen" to the last row for the range */
pv->prevRow=(int32_t)((lastRow-(pv->v))/columns);
/* set the input value in all remaining rows */
firstRow+=column;
lastRow+=column;
mask=~mask; for(;;) {
*firstRow=(*firstRow&mask)|value; if(firstRow==lastRow) { break;
}
firstRow+=columns;
}
}
count=columns=pv->columns; /* includes start/limit columns */
/* start comparing after start/limit but wrap around to them */
i=2; do { if(left[i]!=right[i]) { return left[i]<right[i] ? -1 : 1;
} if(++i==columns) {
i=0;
}
} while(--count>0);
/* * Find and set the special values. * This has to do almost the same work as the compaction below, * to find the indexes where the special-value rows will move.
*/
row=pv->v;
count=-valueColumns; for(i=0; i<rows; ++i) {
start=(UChar32)row[0];
/* count a new values vector if it is different from the current one */ if(count<0 || 0!=uprv_memcmp(row+2, row-valueColumns, valueColumns*4)) {
count+=valueColumns;
}
/* count is at the beginning of the last vector, add valueColumns to include that last vector */
count+=valueColumns;
/* Call the handler once more to signal the start of delivering real values. */
handler(context, UPVEC_START_REAL_VALUES_CP, UPVEC_START_REAL_VALUES_CP,
count, row-valueColumns, valueColumns, pErrorCode); if(U_FAILURE(*pErrorCode)) { return;
}
/* * Move vector contents up to a contiguous array with only unique * vector values, and call the handler function for each vector. * * This destroys the Properties Vector structure and replaces it * with an array of just vector values.
*/
row=pv->v;
count=-valueColumns; for(i=0; i<rows; ++i) { /* fetch these first before memmove() may overwrite them */
start=(UChar32)row[0];
limit=(UChar32)row[1];
/* add a new values vector if it is different from the current one */ if(count<0 || 0!=uprv_memcmp(row+2, pv->v+count, valueColumns*4)) {
count+=valueColumns;
uprv_memmove(pv->v+count, row+2, (size_t)valueColumns*4);
}
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.