/** * Unlocalized date-time pattern characters. For example: 'y', 'd', etc. All * locales use the same these unlocalized pattern characters.
*/ staticconst char16_t gPatternChars[] = { // if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR: // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB: // else: // GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB
/** * Map of each ASCII character to its corresponding index in the table above if * it is a pattern character and -1 otherwise.
*/ staticconst int8_t gLookupPatternChars[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ! " # $ % & ' ( ) * + , - . /
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, -1, -1, -1, -1, -1, #else // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, #endif // @ A B C D E F G H I J K L M N O
-1, 22, 36, -1, 10, 9, 11, 0, 5, -1, -1, 16, 26, 2, -1, 31, // P Q R S T U V W X Y Z [ \ ] ^ _
-1, 27, -1, 8, -1, 30, 29, 13, 32, 18, 23, -1, -1, -1, -1, -1, // ` a b c d e f g h i j k l m n o
-1, 14, 35, 25, 3, 19, -1, 21, 15, -1, -1, 4, -1, 6, -1, -1, // p q r s t u v w x y z { | } ~
-1, 28, 34, 7, -1, 20, 24, 12, 33, 1, 17, -1, -1, -1, -1, -1
};
//------------------------------------------------------ // Strings of last resort. These are only used if we have no resource // files. They aren't designed for actual use, just for backup.
// These are the weekday names and abbreviations of last resort. staticconst char16_t gLastResortDayNames[8][2] =
{
{0x0030, 0x0000}, /* "0" */
{0x0031, 0x0000}, /* "1" */
{0x0032, 0x0000}, /* "2" */
{0x0033, 0x0000}, /* "3" */
{0x0034, 0x0000}, /* "4" */
{0x0035, 0x0000}, /* "5" */
{0x0036, 0x0000}, /* "6" */
{0x0037, 0x0000} /* "7" */
};
// These are the quarter names and abbreviations of last resort. staticconst char16_t gLastResortQuarters[4][2] =
{
{0x0031, 0x0000}, /* "1" */
{0x0032, 0x0000}, /* "2" */
{0x0033, 0x0000}, /* "3" */
{0x0034, 0x0000}, /* "4" */
};
// These are the am/pm and BC/AD markers of last resort. staticconst char16_t gLastResortAmPmMarkers[2][3] =
{
{0x0041, 0x004D, 0x0000}, /* "AM" */
{0x0050, 0x004D, 0x0000} /* "PM" */
};
void
DateFormatSymbols::assignArray(UnicodeString*& dstArray,
int32_t& dstCount, const UnicodeString* srcArray,
int32_t srcCount)
{ // assignArray() is only called by copyData() and initializeData(), which in turn // implements the copy constructor and the assignment operator. // All strings in a DateFormatSymbols object are created in one of the following // three ways that all allow to safely use UnicodeString::fastCopyFrom(): // - readonly-aliases from resource bundles // - readonly-aliases or allocated strings from constants // - safely cloned strings (with owned buffers) from setXYZ() functions // // Note that this is true for as long as DateFormatSymbols can be constructed // only from a locale bundle or set via the cloning API, // *and* for as long as all the strings are in *private* fields, preventing // a subclass from creating these strings in an "unsafe" way (with respect to fastCopyFrom()). if(srcArray == nullptr) { // Do not attempt to copy bogus input (which will crash). // Note that this assignArray method already had the potential to return a null dstArray; // see handling below for "if(dstArray != nullptr)".
dstCount = 0;
dstArray = nullptr; return;
}
dstCount = srcCount;
dstArray = newUnicodeStringArray(srcCount); if(dstArray != nullptr) {
int32_t i; for(i=0; i<srcCount; ++i) {
dstArray[i].fastCopyFrom(srcArray[i]);
}
}
}
/** * Create a copy, in fZoneStrings, of the given zone strings array. The * member variables fZoneStringsRowCount and fZoneStringsColCount should * be set already by the caller.
*/ void
DateFormatSymbols::createZoneStrings(const UnicodeString *const * otherStrings)
{
int32_t row, col;
UBool failed = false;
fZoneStrings = static_cast<UnicodeString**>(uprv_malloc(fZoneStringsRowCount * sizeof(UnicodeString*))); if (fZoneStrings != nullptr) { for (row=0; row<fZoneStringsRowCount; ++row)
{
fZoneStrings[row] = newUnicodeStringArray(fZoneStringsColCount); if (fZoneStrings[row] == nullptr) {
failed = true; break;
} for (col=0; col<fZoneStringsColCount; ++col) { // fastCopyFrom() - see assignArray comments
fZoneStrings[row][col].fastCopyFrom(otherStrings[row][col]);
}
}
} // If memory allocation failed, roll back and delete fZoneStrings if (failed) { for (int i = row; i >= 0; i--) { delete[] fZoneStrings[i];
}
uprv_free(fZoneStrings);
fZoneStrings = nullptr;
}
}
} else {
fZoneStrings = nullptr;
fZoneStringsColCount = 0;
fZoneStringsRowCount = 0;
}
fZSFLocale = other.fZSFLocale; // Other zone strings data is created on demand
fLocaleZoneStrings = nullptr;
// fastCopyFrom() - see assignArray comments
fLocalPatternChars.fastCopyFrom(other.fLocalPatternChars);
void
DateFormatSymbols::setEras(const UnicodeString* erasArray, int32_t count)
{ // delete the old list if we own it delete[] fEras;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fEras = newUnicodeStringArray(count);
uprv_arrayCopy(erasArray,fEras, count);
fErasCount = count;
}
void
DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count)
{ // delete the old list if we own it delete[] fEraNames;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fEraNames = newUnicodeStringArray(count);
uprv_arrayCopy(eraNamesArray,fEraNames, count);
fEraNamesCount = count;
}
void
DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)
{ // delete the old list if we own it delete[] fNarrowEras;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fNarrowEras = newUnicodeStringArray(count);
uprv_arrayCopy(narrowErasArray,fNarrowEras, count);
fNarrowErasCount = count;
}
void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
{ // delete the old list if we own it delete[] fMonths;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fMonths = newUnicodeStringArray(count);
uprv_arrayCopy( monthsArray,fMonths,count);
fMonthsCount = count;
}
void
DateFormatSymbols::setShortMonths(const UnicodeString* shortMonthsArray, int32_t count)
{ // delete the old list if we own it delete[] fShortMonths;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fShortMonths = newUnicodeStringArray(count);
uprv_arrayCopy(shortMonthsArray,fShortMonths, count);
fShortMonthsCount = count;
}
void
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count, DtContextType context, DtWidthType width)
{ // delete the old list if we own it // we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
void DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count)
{ // delete the old list if we own it delete[] fWeekdays;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fWeekdays = newUnicodeStringArray(count);
uprv_arrayCopy(weekdaysArray,fWeekdays,count);
fWeekdaysCount = count;
}
void
DateFormatSymbols::setShortWeekdays(const UnicodeString* shortWeekdaysArray, int32_t count)
{ // delete the old list if we own it delete[] fShortWeekdays;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fShortWeekdays = newUnicodeStringArray(count);
uprv_arrayCopy(shortWeekdaysArray, fShortWeekdays, count);
fShortWeekdaysCount = count;
}
void
DateFormatSymbols::setWeekdays(const UnicodeString* weekdaysArray, int32_t count, DtContextType context, DtWidthType width)
{ // delete the old list if we own it // we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
void
DateFormatSymbols::setQuarters(const UnicodeString* quartersArray, int32_t count, DtContextType context, DtWidthType width)
{ // delete the old list if we own it // we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
void
DateFormatSymbols::setAmPmStrings(const UnicodeString* amPmsArray, int32_t count)
{ // delete the old list if we own it delete[] fAmPms;
// we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fAmPms = newUnicodeStringArray(count);
uprv_arrayCopy(amPmsArray,fAmPms,count);
fAmPmsCount = count;
}
umtx_lock(&LOCK); if (fZoneStrings == nullptr) { if (fLocaleZoneStrings == nullptr) { const_cast<DateFormatSymbols*>(this)->initZoneStringsArray();
}
result = (const UnicodeString**)fLocaleZoneStrings;
} else {
result = (const UnicodeString**)fZoneStrings;
}
rowCount = fZoneStringsRowCount;
columnCount = fZoneStringsColCount;
umtx_unlock(&LOCK);
return result;
}
// For now, we include all zones #define ZONE_SET UCAL_ZONE_TYPE_ANY
// This code must be called within a synchronized block void
DateFormatSymbols::initZoneStringsArray() { if (fZoneStrings != nullptr || fLocaleZoneStrings != nullptr) { return;
}
if (U_FAILURE(status)) { if (zarray) { for (int32_t i = 0; i < rows; i++) { if (zarray[i]) { delete[] zarray[i];
}
}
uprv_free(zarray);
zarray = nullptr;
}
}
void
DateFormatSymbols::setZoneStrings(const UnicodeString* const *strings, int32_t rowCount, int32_t columnCount)
{ // since deleting a 2-d array is a pain in the butt, we offload that task to // a separate function
disposeZoneStrings(); // we always own the new list, which we create here (we duplicate rather // than adopting the list passed in)
fZoneStringsRowCount = rowCount;
fZoneStringsColCount = columnCount;
createZoneStrings(const_cast<const UnicodeString**>(strings));
}
staticconst uint64_t kNumericFieldsAlways =
(static_cast<uint64_t>(1) << UDAT_YEAR_FIELD) | // y
(static_cast<uint64_t>(1) << UDAT_DATE_FIELD) | // d
(static_cast<uint64_t>(1) << UDAT_HOUR_OF_DAY1_FIELD) | // k
(static_cast<uint64_t>(1) << UDAT_HOUR_OF_DAY0_FIELD) | // H
(static_cast<uint64_t>(1) << UDAT_MINUTE_FIELD) | // m
(static_cast<uint64_t>(1) << UDAT_SECOND_FIELD) | // s
(static_cast<uint64_t>(1) << UDAT_FRACTIONAL_SECOND_FIELD) | // S
(static_cast<uint64_t>(1) << UDAT_DAY_OF_YEAR_FIELD) | // D
(static_cast<uint64_t>(1) << UDAT_DAY_OF_WEEK_IN_MONTH_FIELD) | // F
(static_cast<uint64_t>(1) << UDAT_WEEK_OF_YEAR_FIELD) | // w
(static_cast<uint64_t>(1) << UDAT_WEEK_OF_MONTH_FIELD) | // W
(static_cast<uint64_t>(1) << UDAT_HOUR1_FIELD) | // h
(static_cast<uint64_t>(1) << UDAT_HOUR0_FIELD) | // K
(static_cast<uint64_t>(1) << UDAT_YEAR_WOY_FIELD) | // Y
(static_cast<uint64_t>(1) << UDAT_EXTENDED_YEAR_FIELD) | // u
(static_cast<uint64_t>(1) << UDAT_JULIAN_DAY_FIELD) | // g
(static_cast<uint64_t>(1) << UDAT_MILLISECONDS_IN_DAY_FIELD) | // A
(static_cast<uint64_t>(1) << UDAT_RELATED_YEAR_FIELD); // r
staticconst uint64_t kNumericFieldsForCount12 =
(static_cast<uint64_t>(1) << UDAT_MONTH_FIELD) | // M or MM
(static_cast<uint64_t>(1) << UDAT_DOW_LOCAL_FIELD) | // e or ee
(static_cast<uint64_t>(1) << UDAT_STANDALONE_DAY_FIELD) | // c or cc
(static_cast<uint64_t>(1) << UDAT_STANDALONE_MONTH_FIELD) | // L or LL
(static_cast<uint64_t>(1) << UDAT_QUARTER_FIELD) | // Q or QQ
(static_cast<uint64_t>(1) << UDAT_STANDALONE_QUARTER_FIELD); // q or qq
// ResourceSink to enumerate all calendar resources struct CalendarDataSink : public ResourceSink {
// Enum which specifies the type of alias received, or no alias enum AliasType {
SAME_CALENDAR,
DIFFERENT_CALENDAR,
GREGORIAN,
NONE
};
// Data structures to store resources from the current resource bundle
Hashtable arrays;
Hashtable arraySizes;
Hashtable maps; /** * Whenever there are aliases, the same object will be added twice to 'map'. * To avoid double deletion, 'maps' won't take ownership of the objects. Instead, * 'mapRefs' will own them and will delete them when CalendarDataSink is deleted.
*/
MemoryPool<Hashtable> mapRefs;
// Paths and the aliases they point to
UVector aliasPathPairs;
// Current and next calendar resource table which should be loaded
UnicodeString currentCalendarType;
UnicodeString nextCalendarType;
// Resources to visit when enumerating fallback calendars
LocalPointer<UVector> resourcesToVisit;
// Alias' relative path populated whenever an alias is read
UnicodeString aliasRelativePath;
// Stores the resources to visit on the next calendar.
LocalPointer<UVector> resourcesToVisitNext(nullptr);
ResourceTable calendarData = value.getTable(errorCode); if (U_FAILURE(errorCode)) { return; }
// Enumerate all resources for this calendar for (int i = 0; calendarData.getKeyAndValue(i, key, value); i++) {
UnicodeString keyUString(key, -1, US_INV);
// == Handle aliases ==
AliasType aliasType = processAliasFromValue(keyUString, value, errorCode); if (U_FAILURE(errorCode)) { return; } if (aliasType == GREGORIAN) { // Ignore aliases to the gregorian calendar, all of its resources will be loaded anyway. continue;
} elseif (aliasType == DIFFERENT_CALENDAR) { // Whenever an alias to the next calendar (except gregorian) is encountered, register the // calendar type it's pointing to if (resourcesToVisitNext.isNull()) {
resourcesToVisitNext
.adoptInsteadAndCheckErrorCode(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, errorCode),
errorCode); if (U_FAILURE(errorCode)) { return; }
}
LocalPointer<UnicodeString> aliasRelativePathCopy(aliasRelativePath.clone(), errorCode);
resourcesToVisitNext->adoptElement(aliasRelativePathCopy.orphan(), errorCode); if (U_FAILURE(errorCode)) { return; } continue;
// Only visit the resources that were referenced by an alias on the previous calendar // (AmPmMarkersAbbr is an exception). if (!resourcesToVisit.isNull() && !resourcesToVisit->isEmpty() && !resourcesToVisit->contains(&keyUString)
&& uprv_strcmp(key, gAmPmMarkersAbbrTag) != 0) { continue; }
// Iterate over all the elements of the table and add them to the map for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
UnicodeString keyUString(key, -1, US_INV);
// Ignore '%variant' keys if (keyUString.endsWith(kVariantTagUChar, UPRV_LENGTHOF(kVariantTagUChar))) { continue;
}
// == Handle String elements == if (value.getType() == URES_STRING) { // We are on a leaf, store the map elements into the stringMap if (i == 0) { // mapRefs will keep ownership of 'stringMap':
stringMap = mapRefs.create(false, errorCode); if (stringMap == nullptr) {
errorCode = U_MEMORY_ALLOCATION_ERROR; return;
}
maps.put(path, stringMap, errorCode); if (U_FAILURE(errorCode)) { return; }
stringMap->setValueDeleter(uprv_deleteUObject);
}
U_ASSERT(stringMap != nullptr);
int32_t valueStringSize; const char16_t *valueString = value.getString(valueStringSize, errorCode); if (U_FAILURE(errorCode)) { return; }
LocalPointer<UnicodeString> valueUString(new UnicodeString(true, valueString, valueStringSize), errorCode);
stringMap->put(keyUString, valueUString.orphan(), errorCode); if (U_FAILURE(errorCode)) { return; } continue;
}
U_ASSERT(stringMap == nullptr);
// Store the current path's length and append the current key to the path.
int32_t pathLength = path.length();
path.append(SOLIDUS).append(keyUString);
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.