UnicodeString& RelativeDateFormat::format( Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const { UErrorCode status = U_ZERO_ERROR; UChar emptyStr = 0; UnicodeString dateString(&emptyStr); // calculate the difference, in days, between 'cal' and now. int dayDiff = dayDifference(cal, status); // look up string int32_t len = 0; const UChar *theString = getStringForDay(dayDiff, len, status); if(U_SUCCESS(status) && (theString!=NULL)) { // found a relative string dateString.setTo(theString, len); } if(fTimeFormat == NULL || fCombinedFormat == 0) { if (dateString.length() > 0) { appendTo.append(dateString); } else if(fDateFormat != NULL) { fDateFormat->format(cal,appendTo,pos); } } else { if (dateString.length() == 0 && fDateFormat != NULL) { fDateFormat->format(cal,dateString,pos); } UnicodeString timeString(&emptyStr); FieldPosition timepos = pos; fTimeFormat->format(cal,timeString,timepos); Formattable timeDateStrings[] = { timeString, dateString }; fCombinedFormat->format(timeDateStrings, 2, appendTo, pos, status); // pos is ignored by this int32_t offset; if (pos.getEndIndex() > 0 && (offset = appendTo.indexOf(dateString)) >= 0) { // pos.field was found in dateString, offset start & end based on final position of dateString pos.setBeginIndex( pos.getBeginIndex() + offset ); pos.setEndIndex( pos.getEndIndex() + offset ); } else if (timepos.getEndIndex() > 0 && (offset = appendTo.indexOf(timeString)) >= 0) { // pos.field was found in timeString, offset start & end based on final position of timeString pos.setBeginIndex( timepos.getBeginIndex() + offset ); pos.setEndIndex( timepos.getEndIndex() + offset ); } } return appendTo; }
U_CAPI int32_t U_EXPORT2 udat_format( const UDateFormat* format, UDate dateToFormat, UChar* result, int32_t resultLength, UFieldPosition* position, UErrorCode* status) { if(U_FAILURE(*status)) return -1; UnicodeString res; if(!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if(position != 0) fp.setField(position->field); ((DateFormat*)format)->format(dateToFormat, res, fp); if(position != 0) { position->beginIndex = fp.getBeginIndex(); position->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 unum_formatDouble( const UNumberFormat* fmt, double number, UChar* result, int32_t resultLength, UFieldPosition *pos, /* 0 if ignore */ UErrorCode* status) { if(U_FAILURE(*status)) return -1; UnicodeString res; if(!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if(pos != 0) fp.setField(pos->field); ((const NumberFormat*)fmt)->format(number, res, fp); if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
U_INTERNAL int32_t U_EXPORT2 unum_formatUFormattable(const UNumberFormat* fmt, const UFormattable *number, UChar *result, int32_t resultLength, UFieldPosition *pos, /* ignored if 0 */ UErrorCode *status) { if (U_FAILURE(*status)) { return 0; } if (fmt == NULL || number==NULL || (result==NULL ? resultLength!=0 : resultLength<0)) { *status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } UnicodeString res(result, 0, resultLength); FieldPosition fp; if(pos != 0) fp.setField(pos->field); ((const NumberFormat*)fmt)->format(*(Formattable::fromUFormattable(number)), res, fp, *status); if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
static jcharArray formatResult(JNIEnv* env, const UnicodeString& s, FieldPositionIterator* fpi, jobject javaFieldPositionIterator) { static jmethodID gFPI_setData = env->GetMethodID(JniConstants::fieldPositionIteratorClass, "setData", "([I)V"); if (fpi != NULL) { std::vector<int32_t> data; FieldPosition fp; while (fpi->next(fp)) { data.push_back(fp.getField()); data.push_back(fp.getBeginIndex()); data.push_back(fp.getEndIndex()); } jintArray javaData = NULL; if (!data.empty()) { javaData = env->NewIntArray(data.size()); if (javaData == NULL) { return NULL; } ScopedIntArrayRW ints(env, javaData); if (ints.get() == NULL) { return NULL; } memcpy(ints.get(), &data[0], data.size() * sizeof(int32_t)); } env->CallVoidMethod(javaFieldPositionIterator, gFPI_setData, javaData); } jcharArray result = env->NewCharArray(s.length()); if (result != NULL) { env->SetCharArrayRegion(result, 0, s.length(), s.getBuffer()); } return result; }
bool NumberStringBuilder::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const { int32_t rawField = fp.getField(); if (rawField == FieldPosition::DONT_CARE) { return FALSE; } if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) { status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } auto field = static_cast<Field>(rawField); bool seenStart = false; int32_t fractionStart = -1; int32_t startIndex = fp.getEndIndex(); for (int i = fZero + startIndex; i <= fZero + fLength; i++) { Field _field = UNUM_FIELD_COUNT; if (i < fZero + fLength) { _field = getFieldPtr()[i]; } if (seenStart && field != _field) { // Special case: GROUPING_SEPARATOR counts as an INTEGER. if (field == UNUM_INTEGER_FIELD && _field == UNUM_GROUPING_SEPARATOR_FIELD) { continue; } fp.setEndIndex(i - fZero); break; } else if (!seenStart && field == _field) { fp.setBeginIndex(i - fZero); seenStart = true; } if (_field == UNUM_INTEGER_FIELD || _field == UNUM_DECIMAL_SEPARATOR_FIELD) { fractionStart = i - fZero + 1; } } // Backwards compatibility: FRACTION needs to start after INTEGER if empty. // Do not return that a field was found, though, since there is not actually a fraction part. if (field == UNUM_FRACTION_FIELD && !seenStart && fractionStart != -1) { fp.setBeginIndex(fractionStart); fp.setEndIndex(fractionStart); } return seenStart; }
U_CAPI int32_t U_EXPORT2 unum_formatDecimal(const UNumberFormat* fmt, const char * number, int32_t length, UChar* result, int32_t resultLength, UFieldPosition *pos, /* 0 if ignore */ UErrorCode* status) { if(U_FAILURE(*status)) { return -1; } if ((result == NULL && resultLength != 0) || resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } FieldPosition fp; if(pos != 0) { fp.setField(pos->field); } if (length < 0) { length = uprv_strlen(number); } StringPiece numSP(number, length); Formattable numFmtbl(numSP, *status); UnicodeString resultStr; if (resultLength > 0) { // Alias the destination buffer. resultStr.setTo(result, 0, resultLength); } ((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status); if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return resultStr.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 unum_formatDoubleCurrency(const UNumberFormat* fmt, double number, UChar* currency, UChar* result, int32_t resultLength, UFieldPosition* pos, /* ignored if 0 */ UErrorCode* status) { if (U_FAILURE(*status)) return -1; UnicodeString res; if (!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if (pos != 0) { fp.setField(pos->field); } CurrencyAmount *tempCurrAmnt = new CurrencyAmount(number, currency, *status); // Check for null pointer. if (tempCurrAmnt == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return -1; } Formattable n(tempCurrAmnt); ((const NumberFormat*)fmt)->format(n, res, fp, *status); if (pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 udat_formatCalendar(const UDateFormat* format, UCalendar* calendar, UChar* result, int32_t resultLength, UFieldPosition* position, UErrorCode* status) { if(U_FAILURE(*status)) { return -1; } if (result == NULL ? resultLength != 0 : resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } UnicodeString res; if (result != NULL) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if(position != 0) fp.setField(position->field); ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp); if(position != 0) { position->beginIndex = fp.getBeginIndex(); position->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }