- /**
- * Sink to handle each skeleton table.
- */
- struct SkeletonSink : public ResourceTableSink {
- SkeletonSink(DateIntervalSink &sink) : outer(sink) {}
- virtual ~SkeletonSink();
-
- virtual ResourceTableSink *getOrCreateTableSink(
- const char *key, int32_t, UErrorCode &errorCode) {
- if (U_SUCCESS(errorCode)) {
- outer.currentSkeleton = key;
- return &outer.patternSink;
- }
- return NULL;
- }
-
- DateIntervalSink &outer;
- } skeletonSink;
-
- /**
- * Sink to store the date interval pattern for each skeleton pattern character.
- */
- struct PatternSink : public ResourceTableSink {
- PatternSink(DateIntervalSink &sink) : outer(sink) {}
- virtual ~PatternSink();
-
- virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
- if (U_FAILURE(errorCode)) { return; }
-
- // Process the key
- UCalendarDateFields calendarField = validateAndProcessPatternLetter(key);
-
- // If the calendar field has a valid value
- if (calendarField < UCAL_FIELD_COUNT) {
- // Set the interval pattern
- setIntervalPatternIfAbsent(calendarField, value, errorCode);
- } else {
- errorCode = U_INVALID_FORMAT_ERROR;
- }
- }
-
- UCalendarDateFields validateAndProcessPatternLetter(const char *patternLetter) {
- // Check that patternLetter is just one letter
- char c0;
- if ((c0 = patternLetter[0]) != 0 && patternLetter[1] == 0) {
- // Check that the pattern letter is accepted
- if (c0 == 'y') {
- return UCAL_YEAR;
- } else if (c0 == 'M') {
- return UCAL_MONTH;
- } else if (c0 == 'd') {
- return UCAL_DATE;
- } else if (c0 == 'a') {
- return UCAL_AM_PM;
- } else if (c0 == 'h' || c0 == 'H') {
- return UCAL_HOUR;
- } else if (c0 == 'm') {
- return UCAL_MINUTE;
- }// TODO(ticket:12190): Why icu4c doesn't accept the calendar field "s" but icu4j does?
- }
- return UCAL_FIELD_COUNT;
- }
-
- /**
- * Stores the interval pattern for the current skeleton in the internal data structure
- * if it's not present.
- */
- void setIntervalPatternIfAbsent(UCalendarDateFields lrgDiffCalUnit,
- const ResourceValue &value, UErrorCode &errorCode) {
- // Check if the pattern has already been stored on the data structure
- DateIntervalInfo::IntervalPatternIndex index =
- outer.dateIntervalInfo.calendarFieldToIntervalIndex(lrgDiffCalUnit, errorCode);
- if (U_FAILURE(errorCode)) { return; }
-
- UnicodeString skeleton(outer.currentSkeleton, -1, US_INV);
- UnicodeString* patternsOfOneSkeleton =
- (UnicodeString*)(outer.dateIntervalInfo.fIntervalPatterns->get(skeleton));
-
- if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) {
- UnicodeString pattern = value.getUnicodeString(errorCode);
- outer.dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit,
- pattern, errorCode);
- }
- }
-
- DateIntervalSink &outer;
- } patternSink;