int32_t
UnicodeString::extract(int32_t start,
int32_t length, char *target,
uint32_t dstSize, constchar *codepage) const
{ // if the arguments are illegal, then do nothing if (/*dstSize < 0 || */(dstSize > 0 && target == nullptr)) { return 0;
}
// pin the indices to legal values
pinIndices(start, length);
// We need to cast dstSize to int32_t for all subsequent code. // I don't know why the API was defined with uint32_t but we are stuck with it. // Also, dstSize==0xffffffff means "unlimited" but if we use target+dstSize // as a limit in some functions, it may wrap around and yield a pointer // that compares less-than target.
int32_t capacity; if(dstSize < 0x7fffffff) { // Assume that the capacity is real and a limit pointer won't wrap around.
capacity = static_cast<int32_t>(dstSize);
} else { // Pin the capacity so that a limit pointer does not wrap around. char* targetLimit = static_cast<char*>(U_MAX_PTR(target)); // U_MAX_PTR(target) returns a targetLimit that is at most 0x7fffffff // greater than target and does not wrap around the top of the address space.
capacity = static_cast<int32_t>(targetLimit - target);
}
// create the converter
UConverter *converter;
UErrorCode status = U_ZERO_ERROR;
// just write the NUL if the string length is 0 if(length == 0) { return u_terminateChars(target, capacity, 0, &status);
}
// if the codepage is the default, use our cache // if it is an empty string, then use the "invariant character" conversion if (codepage == nullptr) { constchar *defaultName = ucnv_getDefaultName(); if(UCNV_FAST_IS_UTF8(defaultName)) { return toUTF8(start, length, target, capacity);
}
converter = u_getDefaultConverter(&status);
} elseif (*codepage == 0) { // use the "invariant characters" conversion
int32_t destLength; if(length <= capacity) {
destLength = length;
} else {
destLength = capacity;
}
u_UCharsToChars(getArrayStart() + start, target, destLength); return u_terminateChars(target, capacity, length, &status);
} else {
converter = ucnv_open(codepage, &status);
}
if(destCapacity==0) {
destLimit=dest=nullptr;
} elseif(destCapacity==-1) { // Pin the limit to U_MAX_PTR if the "magic" destCapacity is used.
destLimit = static_cast<char*>(U_MAX_PTR(dest)); // for NUL-termination, translate into highest int32_t
destCapacity=0x7fffffff;
} else {
destLimit=dest+destCapacity;
}
// set up the conversion parameters constchar *mySource = codepageData; constchar *mySourceEnd = mySource + dataLength;
char16_t *array, *myTarget;
// estimate the size needed:
int32_t arraySize; if(dataLength <= US_STACKBUF_SIZE) { // try to use the stack buffer
arraySize = US_STACKBUF_SIZE;
} else { // 1.25 char16_t's per source byte should cover most cases
arraySize = dataLength + (dataLength >> 2);
}
// we do not care about the current contents
UBool doCopyArray = false; for(;;) { if(!cloneArrayIfNeeded(arraySize, arraySize, doCopyArray)) {
setToBogus(); break;
}
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.