1fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius/* 2fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius****************************************************************************** 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* Copyright (C) 2014, International Business Machines Corporation and 4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* others. All Rights Reserved. 5fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius****************************************************************************** 6fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* 7fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* File RELDATEFMT.CPP 8fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius****************************************************************************** 9fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius*/ 10fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 11fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/reldatefmt.h" 12fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 13fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_FORMATTING 14fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 15fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/localpointer.h" 16fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "quantityformatter.h" 17fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/plurrule.h" 18fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/msgfmt.h" 19fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/decimfmt.h" 20fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/numfmt.h" 21fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "lrucache.h" 22fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "uresimp.h" 23fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/ures.h" 24fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "cstring.h" 25fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "ucln_in.h" 26fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "mutex.h" 27fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "charstr.h" 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 29fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "sharedptr.h" 30fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "sharedpluralrules.h" 31fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "sharednumberformat.h" 32fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 33fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Copied from uscript_props.cpp 34fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 35fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 36fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic icu::LRUCache *gCache = NULL; 37fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UMutex gCacheMutex = U_MUTEX_INITIALIZER; 38fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER; 39fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 40fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CDECL_BEGIN 41fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool U_CALLCONV reldatefmt_cleanup() { 42fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius gCacheInitOnce.reset(); 43fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (gCache) { 44fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete gCache; 45fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius gCache = NULL; 46fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 47fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 48fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 49fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CDECL_END 50fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 51fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_BEGIN 52fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 53fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// RelativeDateTimeFormatter specific data for a single locale 54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusclass RelativeDateTimeCacheData: public SharedObject { 55fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliuspublic: 56fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RelativeDateTimeCacheData() : combinedDateAndTime(NULL) { } 57fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius virtual ~RelativeDateTimeCacheData(); 58fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 59fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // no numbers: e.g Next Tuesday; Yesterday; etc. 60fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString absoluteUnits[UDAT_ABSOLUTE_UNIT_COUNT][UDAT_DIRECTION_COUNT]; 61fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 62fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // has numbers: e.g Next Tuesday; Yesterday; etc. For second index, 0 63fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // means past e.g 5 days ago; 1 means future e.g in 5 days. 64fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius QuantityFormatter relativeUnits[UDAT_RELATIVE_UNIT_COUNT][2]; 65fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 66fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius void adoptCombinedDateAndTime(MessageFormat *mfToAdopt) { 67fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete combinedDateAndTime; 68fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius combinedDateAndTime = mfToAdopt; 69fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 70fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const MessageFormat *getCombinedDateAndTime() const { 71fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return combinedDateAndTime; 72fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 73fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusprivate: 74fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius MessageFormat *combinedDateAndTime; 75fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RelativeDateTimeCacheData(const RelativeDateTimeCacheData &other); 76fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RelativeDateTimeCacheData& operator=( 77fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RelativeDateTimeCacheData &other); 78fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}; 79fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 80fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeCacheData::~RelativeDateTimeCacheData() { 81fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete combinedDateAndTime; 82fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 83fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 84fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getStringWithFallback( 85fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 86fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *key, 87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString &result, 88fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 89fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t len = 0; 90fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UChar *resStr = ures_getStringByKeyWithFallback( 91fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, key, &len, &status); 92fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 94fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 95fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result.setTo(TRUE, resStr, len); 96fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 97fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 98fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 99fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getOptionalStringWithFallback( 100fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 101fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *key, 102fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString &result, 103fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 104fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 105fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 106fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 107fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t len = 0; 108fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UChar *resStr = ures_getStringByKey( 109fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, key, &len, &status); 110fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (status == U_MISSING_RESOURCE_ERROR) { 111fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result.remove(); 112fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_ZERO_ERROR; 113fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 115fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 116fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 117fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 118fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result.setTo(TRUE, resStr, len); 119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 122fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getString( 123fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 124fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString &result, 125fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 126fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t len = 0; 127fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UChar *resStr = ures_getString(resource, &len, &status); 128fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 131fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result.setTo(TRUE, resStr, len); 132fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 133fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 134fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 135fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getStringByIndex( 136fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 137fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t idx, 138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString &result, 139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 140fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t len = 0; 141fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UChar *resStr = ures_getStringByIndex( 142fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, idx, &len, &status); 143fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 144fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 145fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result.setTo(TRUE, resStr, len); 147fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 149fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 150fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void initAbsoluteUnit( 151fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 152fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UnicodeString &unitName, 153fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString *absoluteUnit, 154fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 155fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getStringWithFallback( 156fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 157fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "-1", 158fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_LAST], 159fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 160fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getStringWithFallback( 161fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 162fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "0", 163fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_THIS], 164fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 165fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getStringWithFallback( 166fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 167fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "1", 168fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_NEXT], 169fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 170fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getOptionalStringWithFallback( 171fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 172fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "-2", 173fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_LAST_2], 174fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 175fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getOptionalStringWithFallback( 176fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 177fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "2", 178fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_NEXT_2], 179fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 180fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit[UDAT_DIRECTION_PLAIN] = unitName; 181fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 182fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 183fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void initQuantityFormatter( 184fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 185fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius QuantityFormatter &formatter, 186fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 187fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 188fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 189fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t size = ures_getSize(resource); 191fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (int32_t i = 0; i < size; ++i) { 192fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer pluralBundle( 193fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByIndex(resource, i, NULL, &status)); 194fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 195fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 196fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 197fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString rawPattern; 198fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getString(pluralBundle.getAlias(), rawPattern, status)) { 199fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 200fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 201fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!formatter.add( 202fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getKey(pluralBundle.getAlias()), 203fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius rawPattern, 204fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status)) { 205fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 206fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 207fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 208fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 209fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 210fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void initRelativeUnit( 211fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius QuantityFormatter *relativeUnit, 213fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 214fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 215fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback( 216fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, "relativeTime", NULL, &status)); 217fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 218fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 219fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 220fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer futureBundle(ures_getByKeyWithFallback( 221fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), "future", NULL, &status)); 222fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 223fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 224fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 225fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initQuantityFormatter( 226fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius futureBundle.getAlias(), 227fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius relativeUnit[1], 228fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 229fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer pastBundle(ures_getByKeyWithFallback( 230fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), "past", NULL, &status)); 231fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 232fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 233fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 234fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initQuantityFormatter( 235fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pastBundle.getAlias(), 236fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius relativeUnit[0], 237fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 238fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 239fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 240fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void initRelativeUnit( 241fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 242fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *path, 243fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius QuantityFormatter *relativeUnit, 244fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 245fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 246fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback(resource, path, NULL, &status)); 247fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 248fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 249fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 250fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initRelativeUnit(topLevel.getAlias(), relativeUnit, status); 251fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void addTimeUnit( 254fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *path, 256fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius QuantityFormatter *relativeUnit, 257fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString *absoluteUnit, 258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 259fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 260fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback(resource, path, NULL, &status)); 261fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 262fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 263fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 264fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initRelativeUnit(topLevel.getAlias(), relativeUnit, status); 265fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString unitName; 266fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getStringWithFallback(topLevel.getAlias(), "dn", unitName, status)) { 267fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 268fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 269fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // TODO(Travis Keep): This is a hack to get around CLDR bug 6818. 270fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeId = ures_getLocaleByType( 271fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), ULOC_ACTUAL_LOCALE, &status); 272fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 273fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 274fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 275fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Locale locale(localeId); 276fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (uprv_strcmp("en", locale.getLanguage()) == 0) { 277fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius unitName.toLower(); 278fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 279fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // end hack 280fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback( 281fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), "relative", topLevel.getAlias(), &status); 282fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 283fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 284fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 285fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initAbsoluteUnit( 286fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), 287fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius unitName, 288fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnit, 289fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 290fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 291fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void readDaysOfWeek( 293fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *path, 295fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString *daysOfWeek, 296fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 297fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 298fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback(resource, path, NULL, &status)); 299fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 300fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 301fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 302fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t size = ures_getSize(topLevel.getAlias()); 303fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (size != 7) { 304fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_INTERNAL_PROGRAM_ERROR; 305fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 306fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 307fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (int32_t i = 0; i < size; ++i) { 308fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getStringByIndex(topLevel.getAlias(), i, daysOfWeek[i], status)) { 309fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 310fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 311fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 312fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 313fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 314fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void addWeekDay( 315fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 316fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *path, 317fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UnicodeString *daysOfWeek, 318fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDateAbsoluteUnit absoluteUnit, 319fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString absoluteUnits[][UDAT_DIRECTION_COUNT], 320fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 321fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 322fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback(resource, path, NULL, &status)); 323fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 324fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 325fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 326fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initAbsoluteUnit( 327fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), 328fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek[absoluteUnit - UDAT_ABSOLUTE_SUNDAY], 329fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius absoluteUnits[absoluteUnit], 330fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 331fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 332fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 333fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool loadUnitData( 334fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 335fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RelativeDateTimeCacheData &cacheData, 336fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 337fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addTimeUnit( 338fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 339fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/day", 340fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_DAYS], 341fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits[UDAT_ABSOLUTE_DAY], 342fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 343fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addTimeUnit( 344fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/week", 346fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_WEEKS], 347fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits[UDAT_ABSOLUTE_WEEK], 348fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 349fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addTimeUnit( 350fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 351fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/month", 352fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_MONTHS], 353fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits[UDAT_ABSOLUTE_MONTH], 354fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 355fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addTimeUnit( 356fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 357fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/year", 358fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_YEARS], 359fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits[UDAT_ABSOLUTE_YEAR], 360fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 361fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initRelativeUnit( 362fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 363fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/second", 364fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_SECONDS], 365fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 366fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initRelativeUnit( 367fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 368fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/minute", 369fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_MINUTES], 370fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 371fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initRelativeUnit( 372fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 373fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/hour", 374fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.relativeUnits[UDAT_RELATIVE_HOURS], 375fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 376fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getStringWithFallback( 377fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 378fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/second/relative/0", 379fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits[UDAT_ABSOLUTE_NOW][UDAT_DIRECTION_PLAIN], 380fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 381fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString daysOfWeek[7]; 382fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius readDaysOfWeek( 383fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 384fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "calendar/gregorian/dayNames/stand-alone/wide", 385fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 386fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 387fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 388fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 389fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/mon/relative", 390fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 391fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_MONDAY, 392fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 393fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 394fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 395fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 396fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/tue/relative", 397fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 398fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_TUESDAY, 399fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 400fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 401fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 402fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 403fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/wed/relative", 404fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 405fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_WEDNESDAY, 406fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 407fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 408fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 409fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 410fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/thu/relative", 411fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 412fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_THURSDAY, 413fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 414fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 415fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 416fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 417fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/fri/relative", 418fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 419fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_FRIDAY, 420fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 421fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 422fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 423fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 424fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/sat/relative", 425fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 426fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_SATURDAY, 427fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 428fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 429fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius addWeekDay( 430fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 431fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "fields/sun/relative", 432fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius daysOfWeek, 433fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDAT_ABSOLUTE_SUNDAY, 434fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cacheData.absoluteUnits, 435fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 436fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return U_SUCCESS(status); 437fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 438fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 439fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getDateTimePattern( 440fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UResourceBundle *resource, 441fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString &result, 442fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 443fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString defaultCalendarName; 444fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getStringWithFallback( 445fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, 446fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius "calendar/default", 447fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius defaultCalendarName, 448fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status)) { 449fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 450fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 451fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius CharString pathBuffer; 452fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pathBuffer.append("calendar/", status) 453fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius .appendInvariantChars(defaultCalendarName, status) 454fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius .append("/DateTimePatterns", status); 455fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel( 456fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_getByKeyWithFallback( 457fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resource, pathBuffer.data(), NULL, &status)); 458fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 459fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 460fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 461fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t size = ures_getSize(topLevel.getAlias()); 462fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (size <= 8) { 463fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Oops, size is to small to access the index that we want, fallback 464fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // to a hard-coded value. 465fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = UNICODE_STRING_SIMPLE("{1} {0}"); 466fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return TRUE; 467fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 468fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return getStringByIndex(topLevel.getAlias(), 8, result, status); 469fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 470fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 471fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Creates RelativeDateTimeFormatter specific data for a given locale 472fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic SharedObject *U_CALLCONV createData( 473fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeId, UErrorCode &status) { 474fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalUResourceBundlePointer topLevel(ures_open(NULL, localeId, &status)); 475fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 476fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 477fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 478fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalPointer<RelativeDateTimeCacheData> result( 479fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius new RelativeDateTimeCacheData()); 480fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (result.isNull()) { 481fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MEMORY_ALLOCATION_ERROR; 482fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 483fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 484fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!loadUnitData( 485fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius topLevel.getAlias(), 486fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *result, 487fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status)) { 488fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 489fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 490fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString dateTimePattern; 491fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getDateTimePattern(topLevel.getAlias(), dateTimePattern, status)) { 492fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 493fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 494fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result->adoptCombinedDateAndTime( 495fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius new MessageFormat(dateTimePattern, localeId, status)); 496fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 497fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 498fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 499fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result.orphan(); 500fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 501fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 502fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic void U_CALLCONV cacheInit(UErrorCode &status) { 503fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius U_ASSERT(gCache == NULL); 504fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ucln_i18n_registerCleanup(UCLN_I18N_RELDATEFMT, reldatefmt_cleanup); 505fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius gCache = new SimpleLRUCache(100, &createData, status); 506fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 507fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete gCache; 508fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius gCache = NULL; 509fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 510fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 511fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 512fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool getFromCache( 513fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *locale, 514fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RelativeDateTimeCacheData *&ptr, 515fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode &status) { 516fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius umtx_initOnce(gCacheInitOnce, &cacheInit, status); 517fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 518fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return FALSE; 519fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 520fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Mutex lock(&gCacheMutex); 521fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius gCache->get(locale, ptr, status); 522fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return U_SUCCESS(status); 523fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 524fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 525fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status) 526fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : cache(NULL), numberFormat(NULL), pluralRules(NULL) { 527fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius init(Locale::getDefault(), NULL, status); 528fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 529fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 530fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter::RelativeDateTimeFormatter( 531fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const Locale& locale, UErrorCode& status) 532fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : cache(NULL), numberFormat(NULL), pluralRules(NULL) { 533fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius init(locale, NULL, status); 534fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 535fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 536fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter::RelativeDateTimeFormatter( 537fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status) 538fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : cache(NULL), numberFormat(NULL), pluralRules(NULL) { 539fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius init(locale, nfToAdopt, status); 540fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 541fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 542fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter::RelativeDateTimeFormatter( 543fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RelativeDateTimeFormatter& other) 544fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius : cache(other.cache), 545fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius numberFormat(other.numberFormat), 546fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pluralRules(other.pluralRules) { 547fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cache->addRef(); 548fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius numberFormat->addRef(); 549fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pluralRules->addRef(); 550fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 551fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 552fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter& RelativeDateTimeFormatter::operator=( 553fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RelativeDateTimeFormatter& other) { 554fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (this != &other) { 555fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr(other.cache, cache); 556fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr(other.numberFormat, numberFormat); 557fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr(other.pluralRules, pluralRules); 558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return *this; 560fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 561fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 562fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRelativeDateTimeFormatter::~RelativeDateTimeFormatter() { 563fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (cache != NULL) { 564fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius cache->removeRef(); 565fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (numberFormat != NULL) { 567fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius numberFormat->removeRef(); 568fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 569fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (pluralRules != NULL) { 570fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pluralRules->removeRef(); 571fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 572fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 573fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 574fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusconst NumberFormat& RelativeDateTimeFormatter::getNumberFormat() const { 575fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return **numberFormat; 576fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 577fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 578fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusUnicodeString& RelativeDateTimeFormatter::format( 579fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius double quantity, UDateDirection direction, UDateRelativeUnit unit, 580fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString& appendTo, UErrorCode& status) const { 581fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 582fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return appendTo; 583fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 584fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (direction != UDAT_DIRECTION_LAST && direction != UDAT_DIRECTION_NEXT) { 585fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_ILLEGAL_ARGUMENT_ERROR; 586fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return appendTo; 587fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 588fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0; 589fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius FieldPosition pos(FieldPosition::DONT_CARE); 590fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return cache->relativeUnits[unit][bFuture].format( 591fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius quantity, 592fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius **numberFormat, 593fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius **pluralRules, 594fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius appendTo, 595fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pos, 596fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status); 597fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 598fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 599fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusUnicodeString& RelativeDateTimeFormatter::format( 600fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UDateDirection direction, UDateAbsoluteUnit unit, 601fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString& appendTo, UErrorCode& status) const { 602fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 603fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return appendTo; 604fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 605fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (unit == UDAT_ABSOLUTE_NOW && direction != UDAT_DIRECTION_PLAIN) { 606fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_ILLEGAL_ARGUMENT_ERROR; 607fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return appendTo; 608fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 609fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return appendTo.append(cache->absoluteUnits[unit][direction]); 610fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 611fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 612fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusUnicodeString& RelativeDateTimeFormatter::combineDateAndTime( 613fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UnicodeString& relativeDateString, const UnicodeString& timeString, 614fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString& appendTo, UErrorCode& status) const { 615fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Formattable args[2] = {timeString, relativeDateString}; 616fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius FieldPosition fpos(0); 617fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return cache->getCombinedDateAndTime()->format( 618fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius args, 2, appendTo, fpos, status); 619fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 620fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 621fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid RelativeDateTimeFormatter::init( 622fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const Locale &locale, NumberFormat *nfToAdopt, UErrorCode &status) { 623fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalPointer<NumberFormat> nf(nfToAdopt); 624fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!getFromCache(locale.getName(), cache, status)) { 625fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 626fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 627fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr( 628fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius PluralRules::createSharedInstance( 629fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius locale, UPLURAL_TYPE_CARDINAL, status), 630fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pluralRules); 631fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 632fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 633fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 634fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius pluralRules->removeRef(); 635fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (nf.isNull()) { 636fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr( 637fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius NumberFormat::createSharedInstance( 638fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius locale, UNUM_DECIMAL, status), 639fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius numberFormat); 640fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 641fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 642fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 643fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius numberFormat->removeRef(); 644fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 645fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedNumberFormat *shared = new SharedNumberFormat(nf.getAlias()); 646fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (shared == NULL) { 647fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius status = U_MEMORY_ALLOCATION_ERROR; 648fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 649fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 650fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius nf.orphan(); 651fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SharedObject::copyPtr(shared, numberFormat); 652fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 653fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 654fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 655fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 656fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_NAMESPACE_END 657fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 658fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif /* !UCONFIG_NO_FORMATTING */ 659fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 660