本文整理汇总了C++中Formattable类的典型用法代码示例。如果您正苦于以下问题:C++ Formattable类的具体用法?C++ Formattable怎么用?C++ Formattable使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Formattable类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ufmt_getDouble
U_DRAFT double U_EXPORT2
ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
Formattable *obj = Formattable::fromUFormattable(fmt);
return obj->getDouble(*status);
}
示例2: ufmt_getLong
U_DRAFT int32_t U_EXPORT2
ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
Formattable *obj = Formattable::fromUFormattable(fmt);
return obj->getLong(*status);
}
示例3: resultNumber
void
TimeUnitFormat::parseObject(const UnicodeString& source,
Formattable& result,
ParsePosition& pos) const {
Formattable resultNumber(0.0);
UBool withNumberFormat = false;
TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
int32_t oldPos = pos.getIndex();
int32_t newPos = -1;
int32_t longestParseDistance = 0;
UnicodeString* countOfLongestMatch = NULL;
#ifdef TMUTFMT_DEBUG
char res[1000];
source.extract(0, source.length(), res, "UTF-8");
std::cout << "parse source: " << res << "\n";
#endif
// parse by iterating through all available patterns
// and looking for the longest match.
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
i = (TimeUnit::UTimeUnitFields)(i+1)) {
Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
int32_t elemPos = UHASH_FIRST;
const UHashElement* elem = NULL;
while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
const UHashTok keyTok = elem->key;
UnicodeString* count = (UnicodeString*)keyTok.pointer;
#ifdef TMUTFMT_DEBUG
count->extract(0, count->length(), res, "UTF-8");
std::cout << "parse plural count: " << res << "\n";
#endif
const UHashTok valueTok = elem->value;
// the value is a pair of MessageFormat*
MessageFormat** patterns = (MessageFormat**)valueTok.pointer;
for (UTimeUnitFormatStyle style = UTMUTFMT_FULL_STYLE; style < UTMUTFMT_FORMAT_STYLE_COUNT;
style = (UTimeUnitFormatStyle)(style + 1)) {
MessageFormat* pattern = patterns[style];
pos.setErrorIndex(-1);
pos.setIndex(oldPos);
// see if we can parse
Formattable parsed;
pattern->parseObject(source, parsed, pos);
if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
continue;
}
#ifdef TMUTFMT_DEBUG
std::cout << "parsed.getType: " << parsed.getType() << "\n";
#endif
Formattable tmpNumber(0.0);
if (pattern->getArgTypeCount() != 0) {
Formattable& temp = parsed[0];
if (temp.getType() == Formattable::kString) {
UnicodeString tmpString;
UErrorCode pStatus = U_ZERO_ERROR;
getNumberFormat().parse(temp.getString(tmpString), tmpNumber, pStatus);
if (U_FAILURE(pStatus)) {
continue;
}
} else if (temp.isNumeric()) {
tmpNumber = temp;
} else {
continue;
}
}
int32_t parseDistance = pos.getIndex() - oldPos;
if (parseDistance > longestParseDistance) {
if (pattern->getArgTypeCount() != 0) {
resultNumber = tmpNumber;
withNumberFormat = true;
} else {
withNumberFormat = false;
}
resultTimeUnit = i;
newPos = pos.getIndex();
longestParseDistance = parseDistance;
countOfLongestMatch = count;
}
}
}
}
/* After find the longest match, parse the number.
* Result number could be null for the pattern without number pattern.
* such as unit pattern in Arabic.
* When result number is null, use plural rule to set the number.
*/
if (withNumberFormat == false && longestParseDistance != 0) {
// set the number using plurrual count
if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
resultNumber = Formattable(0.0);
} else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
resultNumber = Formattable(1.0);
} else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
resultNumber = Formattable(2.0);
} else {
// should not happen.
// TODO: how to handle?
resultNumber = Formattable(3.0);
}
}
if (longestParseDistance == 0) {
//.........这里部分代码省略.........
示例4: logln
void
NumberFormatRoundTripTest::test(NumberFormat *fmt, const Formattable& value)
{
fmt->setMaximumFractionDigits(999);
DecimalFormat *df = dynamic_cast<DecimalFormat *>(fmt);
if(df != NULL) {
df->setRoundingIncrement(0.0);
}
UErrorCode status = U_ZERO_ERROR;
UnicodeString s, s2, temp;
if(isDouble(value))
s = fmt->format(value.getDouble(), s);
else
s = fmt->format(value.getLong(), s);
Formattable n;
UBool show = verbose;
if(DEBUG_VAR)
logln(/*value.getString(temp) +*/ " F> " + escape(s));
fmt->parse(s, n, status);
failure(status, "fmt->parse");
if(DEBUG_VAR)
logln(escape(s) + " P> " /*+ n.getString(temp)*/);
if(isDouble(n))
s2 = fmt->format(n.getDouble(), s2);
else
s2 = fmt->format(n.getLong(), s2);
if(DEBUG_VAR)
logln(/*n.getString(temp) +*/ " F> " + escape(s2));
if(STRING_COMPARE) {
if (s != s2) {
errln("*** STRING ERROR \"" + escape(s) + "\" != \"" + escape(s2) + "\"");
show = TRUE;
}
}
if(EXACT_NUMERIC_COMPARE) {
if(value != n) {
errln("*** NUMERIC ERROR");
show = TRUE;
}
}
else {
// Compute proportional error
double error = proportionalError(value, n);
if(error > MAX_ERROR) {
errln(UnicodeString("*** NUMERIC ERROR ") + error);
show = TRUE;
}
if (error > max_numeric_error)
max_numeric_error = error;
if (error < min_numeric_error)
min_numeric_error = error;
}
if (show) {
errln(/*value.getString(temp) +*/ typeOf(value, temp) + " F> " +
escape(s) + " P> " + (n.getType() == Formattable::kDouble ? n.getDouble() : (double)n.getLong())
/*n.getString(temp) */ + typeOf(n, temp) + " F> " +
escape(s2));
}
}
示例5: UPRV_LENGTHOF
/**
* Test basic
*/
void TimeUnitTest::testBasic() {
const char* locales[] = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant", "pa"};
for ( unsigned int locIndex = 0;
locIndex < UPRV_LENGTHOF(locales);
++locIndex ) {
UErrorCode status = U_ZERO_ERROR;
Locale loc(locales[locIndex]);
TimeUnitFormat** formats = new TimeUnitFormat*[2];
formats[UTMUTFMT_FULL_STYLE] = new TimeUnitFormat(loc, status);
if (!assertSuccess("TimeUnitFormat(full)", status, TRUE)) return;
formats[UTMUTFMT_ABBREVIATED_STYLE] = new TimeUnitFormat(loc, UTMUTFMT_ABBREVIATED_STYLE, status);
if (!assertSuccess("TimeUnitFormat(short)", status)) return;
#ifdef TUFMTTS_DEBUG
std::cout << "locale: " << locales[locIndex] << "\n";
#endif
for (int style = UTMUTFMT_FULL_STYLE;
style <= UTMUTFMT_ABBREVIATED_STYLE;
++style) {
for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
j = (TimeUnit::UTimeUnitFields)(j+1)) {
#ifdef TUFMTTS_DEBUG
std::cout << "time unit: " << j << "\n";
#endif
double tests[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35};
for (unsigned int i = 0; i < UPRV_LENGTHOF(tests); ++i) {
#ifdef TUFMTTS_DEBUG
std::cout << "number: " << tests[i] << "\n";
#endif
TimeUnitAmount* source = new TimeUnitAmount(tests[i], j, status);
if (!assertSuccess("TimeUnitAmount()", status)) return;
UnicodeString formatted;
Formattable formattable;
formattable.adoptObject(source);
formatted = ((Format*)formats[style])->format(formattable, formatted, status);
if (!assertSuccess("format()", status)) return;
#ifdef TUFMTTS_DEBUG
char formatResult[1000];
formatted.extract(0, formatted.length(), formatResult, "UTF-8");
std::cout << "format result: " << formatResult << "\n";
#endif
Formattable result;
((Format*)formats[style])->parseObject(formatted, result, status);
if (!assertSuccess("parseObject()", status)) return;
if (!tmaEqual(*((TimeUnitAmount *)result.getObject()), *((TimeUnitAmount *) formattable.getObject()))) {
dataerrln("No round trip: ");
}
// other style parsing
Formattable result_1;
((Format*)formats[1-style])->parseObject(formatted, result_1, status);
if (!assertSuccess("parseObject()", status)) return;
if (!tmaEqual(*((TimeUnitAmount *)result_1.getObject()), *((TimeUnitAmount *) formattable.getObject()))) {
dataerrln("No round trip: ");
}
}
}
}
delete formats[UTMUTFMT_FULL_STYLE];
delete formats[UTMUTFMT_ABBREVIATED_STYLE];
delete[] formats;
}
}
示例6: fprintf
/**
* Parses a string using the rule set or DecimalFormat belonging
* to this substitution. If there's a match, a mathematical
* operation (the inverse of the one used in formatting) is
* performed on the result of the parse and the value passed in
* and returned as the result. The parse position is updated to
* point to the first unmatched character in the string.
* @param text The string to parse
* @param parsePosition On entry, ignored, but assumed to be 0.
* On exit, this is updated to point to the first unmatched
* character (or 0 if the substitution didn't match)
* @param baseValue A partial parse result that should be
* combined with the result of this parse
* @param upperBound When searching the rule set for a rule
* matching the string passed in, only rules with base values
* lower than this are considered
* @param lenientParse If true and matching against rules fails,
* the substitution will also try matching the text against
* numerals using a default-costructed NumberFormat. If false,
* no extra work is done. (This value is false whenever the
* formatter isn't in lenient-parse mode, but is also false
* under some conditions even when the formatter _is_ in
* lenient-parse mode.)
* @return If there's a match, this is the result of composing
* baseValue with whatever was returned from matching the
* characters. This will be either a Long or a Double. If there's
* no match this is new Long(0) (not null), and parsePosition
* is left unchanged.
*/
UBool
NFSubstitution::doParse(const UnicodeString& text,
ParsePosition& parsePosition,
double baseValue,
double upperBound,
UBool lenientParse,
Formattable& result) const
{
#ifdef RBNF_DEBUG
fprintf(stderr, "<nfsubs> %x bv: %g ub: %g\n", this, baseValue, upperBound);
#endif
// figure out the highest base value a rule can have and match
// the text being parsed (this varies according to the type of
// substitutions: multiplier, modulus, and numerator substitutions
// restrict the search to rules with base values lower than their
// own; same-value substitutions leave the upper bound wherever
// it was, and the others allow any rule to match
upperBound = calcUpperBound(upperBound);
// use our rule set to parse the text. If that fails and
// lenient parsing is enabled (this is always false if the
// formatter's lenient-parsing mode is off, but it may also
// be false even when the formatter's lenient-parse mode is
// on), then also try parsing the text using a default-
// constructed NumberFormat
if (ruleSet != NULL) {
ruleSet->parse(text, parsePosition, upperBound, result);
if (lenientParse && !ruleSet->isFractionRuleSet() && parsePosition.getIndex() == 0) {
UErrorCode status = U_ZERO_ERROR;
NumberFormat* fmt = NumberFormat::createInstance(status);
if (U_SUCCESS(status)) {
fmt->parse(text, result, parsePosition);
}
delete fmt;
}
// ...or use our DecimalFormat to parse the text
} else if (numberFormat != NULL) {
numberFormat->parse(text, result, parsePosition);
}
// if the parse was successful, we've already advanced the caller's
// parse position (this is the one function that doesn't have one
// of its own). Derive a parse result and return it as a Long,
// if possible, or a Double
if (parsePosition.getIndex() != 0) {
UErrorCode status = U_ZERO_ERROR;
double tempResult = result.getDouble(status);
// composeRuleValue() produces a full parse result from
// the partial parse result passed to this function from
// the caller (this is either the owning rule's base value
// or the partial result obtained from composing the
// owning rule's base value with its other substitution's
// parse result) and the partial parse result obtained by
// matching the substitution (which will be the same value
// the caller would get by parsing just this part of the
// text with RuleBasedNumberFormat.parse() ). How the two
// values are used to derive the full parse result depends
// on the types of substitutions: For a regular rule, the
// ultimate result is its multiplier substitution's result
// times the rule's divisor (or the rule's base value) plus
// the modulus substitution's result (which will actually
// supersede part of the rule's base value). For a negative-
// number rule, the result is the negative of its substitution's
// result. For a fraction rule, it's the sum of its two
// substitution results. For a rule in a fraction rule set,
// it's the numerator substitution's result divided by
// the rule's base value. Results from same-value substitutions
// propagate back upard, and null substitutions don't affect
// the result.
//.........这里部分代码省略.........
示例7: msg
void TestMessageFormat::testParse()
{
UErrorCode err = U_ZERO_ERROR;
int32_t count;
UnicodeString msgFormatString = "{0} =sep= {1}";
MessageFormat msg( msgFormatString, err);
UnicodeString source = "abc =sep= def";
UnicodeString tmp1, tmp2;
Formattable* fmt_arr = msg.parse( source, count, err );
if (U_FAILURE(err) || (!fmt_arr)) {
errln("*** MSG parse (ustring, count, err) error.");
}else{
logln("MSG parse -- count: %d", count);
if (count != 2) {
errln("*** MSG parse (ustring, count, err) count err.");
}else{
if ((fmt_arr[0].getType() == Formattable::kString)
&& (fmt_arr[1].getType() == Formattable::kString)
&& (fmt_arr[0].getString(tmp1) == "abc")
&& (fmt_arr[1].getString(tmp2) == "def")) {
logln("MSG parse (ustring, count, err) tested.");
}else{
errln("*** MSG parse (ustring, count, err) result err.");
}
}
}
delete[] fmt_arr;
ParsePosition pp(0);
fmt_arr = msg.parse( source, pp, count );
if ((pp == 0) || (!fmt_arr)) {
errln("*** MSG parse (ustring, parsepos., count) error.");
}else{
logln("MSG parse -- count: %d", count);
if (count != 2) {
errln("*** MSG parse (ustring, parsepos., count) count err.");
}else{
if ((fmt_arr[0].getType() == Formattable::kString)
&& (fmt_arr[1].getType() == Formattable::kString)
&& (fmt_arr[0].getString(tmp1) == "abc")
&& (fmt_arr[1].getString(tmp2) == "def")) {
logln("MSG parse (ustring, parsepos., count) tested.");
}else{
errln("*** MSG parse (ustring, parsepos., count) result err.");
}
}
}
delete[] fmt_arr;
pp = 0;
Formattable fmta;
msg.parseObject( source, fmta, pp );
if (pp == 0) {
errln("*** MSG parse (ustring, Formattable, parsepos ) error.");
}else{
logln("MSG parse -- count: %d", count);
fmta.getArray(count);
if (count != 2) {
errln("*** MSG parse (ustring, Formattable, parsepos ) count err.");
}else{
if ((fmta[0].getType() == Formattable::kString)
&& (fmta[1].getType() == Formattable::kString)
&& (fmta[0].getString(tmp1) == "abc")
&& (fmta[1].getString(tmp2) == "def")) {
logln("MSG parse (ustring, Formattable, parsepos ) tested.");
}else{
errln("*** MSG parse (ustring, Formattable, parsepos ) result err.");
}
}
}
}
示例8: workText
UBool
FractionalPartSubstitution::doParse(const UnicodeString& text,
ParsePosition& parsePosition,
double baseValue,
double /*upperBound*/,
UBool lenientParse,
Formattable& resVal) const
{
// if we're not in byDigits mode, we can just use the inherited
// doParse()
if (!byDigits) {
return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, resVal);
// if we ARE in byDigits mode, parse the text one digit at a time
// using this substitution's owning rule set (we do this by setting
// upperBound to 10 when calling doParse() ) until we reach
// nonmatching text
} else {
UnicodeString workText(text);
ParsePosition workPos(1);
double result = 0;
int32_t digit;
// double p10 = 0.1;
DigitList dl;
NumberFormat* fmt = NULL;
while (workText.length() > 0 && workPos.getIndex() != 0) {
workPos.setIndex(0);
Formattable temp;
getRuleSet()->parse(workText, workPos, 10, temp);
UErrorCode status = U_ZERO_ERROR;
digit = temp.getLong(status);
// digit = temp.getType() == Formattable::kLong ?
// temp.getLong() :
// (int32_t)temp.getDouble();
if (lenientParse && workPos.getIndex() == 0) {
if (!fmt) {
status = U_ZERO_ERROR;
fmt = NumberFormat::createInstance(status);
if (U_FAILURE(status)) {
delete fmt;
fmt = NULL;
}
}
if (fmt) {
fmt->parse(workText, temp, workPos);
digit = temp.getLong(status);
}
}
if (workPos.getIndex() != 0) {
dl.append((char)('0' + digit));
// result += digit * p10;
// p10 /= 10;
parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
workText.removeBetween(0, workPos.getIndex());
while (workText.length() > 0 && workText.charAt(0) == gSpace) {
workText.removeBetween(0, 1);
parsePosition.setIndex(parsePosition.getIndex() + 1);
}
}
}
delete fmt;
result = dl.fCount == 0 ? 0 : dl.getDouble();
result = composeRuleValue(result, baseValue);
resVal.setDouble(result);
return TRUE;
}
}
示例9: slog2f
std::string GlobalizationNDK::stringToNumber(const std::string& args)
{
if (args.empty()) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: no arguments provided!");
return errorInJson(PARSING_ERROR, "No arguments provided!");
}
Json::Reader reader;
Json::Value root;
bool parse = reader.parse(args, root);
if (!parse) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: invalid json data: %s",
args.c_str());
return errorInJson(PARSING_ERROR, "Invalid json data!");
}
Json::Value sv = root["numberString"];
if (sv.isNull()) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: no numberString provided!");
return errorInJson(FORMATTING_ERROR, "No numberString provided!");
}
if (!sv.isString()) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: invalid numberString type: %d!",
sv.type());
return errorInJson(FORMATTING_ERROR, "Invalid numberString type!");
}
std::string str = sv.asString();
if (str.empty()) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: empty numberString!");
return errorInJson(FORMATTING_ERROR, "Empty numberString!");
}
// This is the default value when no options provided.
ENumberType type = kNumberDecimal;
Json::Value options = root["options"];
std::string error;
if (!handleNumberOptions(options, type, error))
return errorInJson(PARSING_ERROR, error);
UErrorCode status = U_ZERO_ERROR;
NumberFormat* nf;
switch (type) {
case kNumberDecimal:
default:
nf = NumberFormat::createInstance(status);
break;
case kNumberCurrency:
nf = NumberFormat::createCurrencyInstance(status);
break;
case kNumberPercent:
nf = NumberFormat::createPercentInstance(status);
break;
}
if (!nf) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: failed to create NumberFormat instance for type %d: %d",
status, type);
return errorInJson(UNKNOWN_ERROR, "Failed to create NumberFormat instance!");
}
std::auto_ptr<NumberFormat> deleter(nf);
UnicodeString uStr = UnicodeString::fromUTF8(str);
Formattable value;
if (type == kNumberCurrency) {
ParsePosition pos;
CurrencyAmount* ca = nf->parseCurrency(uStr, pos);
if (ca)
value = ca->getNumber();
else
nf->parse(uStr, value, status);
} else
nf->parse(uStr, value, status);
if (status != U_ZERO_ERROR && status != U_ERROR_WARNING_START) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: failed (%d) to parse string: %s",
status, str.c_str());
return errorInJson(PARSING_ERROR, "Failed to parse string!");
}
if (!value.isNumeric()) {
slog2f(0, ID_G11N, SLOG2_ERROR, "GlobalizationNDK::stringToNumber: string is not numeric: %s",
str.c_str());
return errorInJson(FORMATTING_ERROR, "String is not numeric!");
}
return resultInJson(value.getDouble());
}
示例10: symbols
void DecimalFormatTest::execFormatTest(int32_t lineNum,
const UnicodeString &pattern, // Pattern
const UnicodeString &round, // rounding mode
const UnicodeString &input, // input decimal number
const UnicodeString &expected, // expected formatted result
UErrorCode &status) {
if (U_FAILURE(status)) {
return;
}
DecimalFormatSymbols symbols(Locale::getUS(), status);
// printf("Pattern = %s\n", UnicodeStringPiece(pattern).data());
DecimalFormat fmtr(pattern, symbols, status);
if (U_FAILURE(status)) {
dataerrln("file dcfmtest.txt, line %d: %s error creating the formatter.",
lineNum, u_errorName(status));
return;
}
if (round=="ceiling") {
fmtr.setRoundingMode(DecimalFormat::kRoundCeiling);
} else if (round=="floor") {
fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
} else if (round=="down") {
fmtr.setRoundingMode(DecimalFormat::kRoundDown);
} else if (round=="up") {
fmtr.setRoundingMode(DecimalFormat::kRoundUp);
} else if (round=="halfeven") {
fmtr.setRoundingMode(DecimalFormat::kRoundHalfEven);
} else if (round=="halfdown") {
fmtr.setRoundingMode(DecimalFormat::kRoundHalfDown);
} else if (round=="halfup") {
fmtr.setRoundingMode(DecimalFormat::kRoundHalfUp);
} else if (round=="default") {
// don't set any value.
} else if (round=="unnecessary") {
fmtr.setRoundingMode(DecimalFormat::kRoundUnnecessary);
} else {
fmtr.setRoundingMode(DecimalFormat::kRoundFloor);
errln("file dcfmtest.txt, line %d: Bad rounding mode \"%s\"",
lineNum, UnicodeStringPiece(round).data());
}
UnicodeString result;
UnicodeStringPiece spInput(input);
//fmtr.format(spInput, result, NULL, status);
Formattable fmtbl;
fmtbl.setDecimalNumber(spInput, status);
//NumberFormat &nfmtr = fmtr;
fmtr.format(fmtbl, result, NULL, status);
if ((status == U_FORMAT_INEXACT_ERROR) && (result == "") && (expected == "Inexact")) {
// Test succeeded.
status = U_ZERO_ERROR;
return;
}
if (U_FAILURE(status)) {
errln("file dcfmtest.txt, line %d: format() returned %s.",
lineNum, u_errorName(status));
status = U_ZERO_ERROR;
return;
}
if (result != expected) {
errln("file dcfmtest.txt, line %d: expected \"%s\", got \"%s\"",
lineNum, UnicodeStringPiece(expected).data(), UnicodeStringPiece(result).data());
}
}
示例11: fprintf
UBool
NFRuleSet::parse(const UnicodeString & text, ParsePosition & pos, double upperBound, Formattable & result) const
{
// try matching each rule in the rule set against the text being
// parsed. Whichever one matches the most characters is the one
// that determines the value we return.
result.setLong(0);
// dump out if there's no text to parse
if (text.length() == 0)
{
return 0;
}
ParsePosition highWaterMark;
ParsePosition workingPos = pos;
#ifdef RBNF_DEBUG
fprintf(stderr, "<nfrs> %x '", this);
dumpUS(stderr, name);
fprintf(stderr, "' text '");
dumpUS(stderr, text);
fprintf(stderr, "'\n");
fprintf(stderr, " parse negative: %d\n", this, negativeNumberRule != 0);
#endif
// start by trying the negative number rule (if there is one)
if (negativeNumberRule)
{
Formattable tempResult;
#ifdef RBNF_DEBUG
fprintf(stderr, " <nfrs before negative> %x ub: %g\n", negativeNumberRule, upperBound);
#endif
UBool success = negativeNumberRule->doParse(text, workingPos, 0, upperBound, tempResult);
#ifdef RBNF_DEBUG
fprintf(stderr, " <nfrs after negative> success: %d wpi: %d\n", success, workingPos.getIndex());
#endif
if (success && workingPos.getIndex() > highWaterMark.getIndex())
{
result = tempResult;
highWaterMark = workingPos;
}
workingPos = pos;
}
#ifdef RBNF_DEBUG
fprintf(stderr, "<nfrs> continue fractional with text '");
dumpUS(stderr, text);
fprintf(stderr, "' hwm: %d\n", highWaterMark.getIndex());
#endif
// then try each of the fraction rules
{
for (int i = 0; i < 3; i++)
{
if (fractionRules[i])
{
Formattable tempResult;
UBool success = fractionRules[i]->doParse(text, workingPos, 0, upperBound, tempResult);
if (success && (workingPos.getIndex() > highWaterMark.getIndex()))
{
result = tempResult;
highWaterMark = workingPos;
}
workingPos = pos;
}
}
}
#ifdef RBNF_DEBUG
fprintf(stderr, "<nfrs> continue other with text '");
dumpUS(stderr, text);
fprintf(stderr, "' hwm: %d\n", highWaterMark.getIndex());
#endif
// finally, go through the regular rules one at a time. We start
// at the end of the list because we want to try matching the most
// sigificant rule first (this helps ensure that we parse
// "five thousand three hundred six" as
// "(five thousand) (three hundred) (six)" rather than
// "((five thousand three) hundred) (six)"). Skip rules whose
// base values are higher than the upper bound (again, this helps
// limit ambiguity by making sure the rules that match a rule's
// are less significant than the rule containing the substitutions)/
{
int64_t ub = util64_fromDouble(upperBound);
#ifdef RBNF_DEBUG
{
char ubstr[64];
util64_toa(ub, ubstr, 64);
char ubstrhex[64];
util64_toa(ub, ubstrhex, 64, 16);
fprintf(stderr, "ub: %g, i64: %s (%s)\n", upperBound, ubstr, ubstrhex);
}
#endif
for (int32_t i = rules.size(); --i >= 0 && highWaterMark.getIndex() < text.length();)
{
if ((!fIsFractionRuleSet) && (rules[i]->getBaseValue() >= ub))
{
continue;
}
Formattable tempResult;
//.........这里部分代码省略.........
示例12: newRegionIDMap
//.........这里部分代码省略.........
}
} else {
LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName), status);
allRegions->addElement(newRegion.orphan(),status);
}
}
while ( ures_hasNext(regionUnknown.getAlias()) ) {
LocalPointer<UnicodeString> regionName (new UnicodeString(ures_getNextUnicodeString(regionUnknown.getAlias(),NULL,&status),status));
allRegions->addElement(regionName.orphan(),status);
}
while ( ures_hasNext(worldContainment.getAlias()) ) {
UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeString(worldContainment.getAlias(),NULL,&status));
continents->addElement(continentName,status);
}
while ( ures_hasNext(groupingContainment.getAlias()) ) {
UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeString(groupingContainment.getAlias(),NULL,&status));
groupings->addElement(groupingName,status);
}
for ( int32_t i = 0 ; i < allRegions->size() ; i++ ) {
LocalPointer<Region> r(new Region(), status);
if ( U_FAILURE(status) ) {
return;
}
UnicodeString *regionName = (UnicodeString *)allRegions->elementAt(i);
r->idStr = *regionName;
r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV);
r->type = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known.
Formattable result;
UErrorCode ps = U_ZERO_ERROR;
df->parse(r->idStr,result,ps);
if ( U_SUCCESS(ps) ) {
r->code = result.getLong(); // Convert string to number
uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)(r.getAlias()),&status);
r->type = URGN_SUBCONTINENT;
} else {
r->code = -1;
}
void* idStrAlias = (void*)&(r->idStr); // about to orphan 'r'. Save this off.
uhash_put(newRegionIDMap.getAlias(),idStrAlias,(void *)(r.orphan()),&status); // regionIDMap takes ownership
}
// Process the territory aliases
while ( ures_hasNext(territoryAlias.getAlias()) ) {
LocalUResourceBundlePointer res(ures_getNextResource(territoryAlias.getAlias(),NULL,&status));
const char *aliasFrom = ures_getKey(res.getAlias());
LocalPointer<UnicodeString> aliasFromStr(new UnicodeString(aliasFrom, -1, US_INV), status);
UnicodeString aliasTo = ures_getUnicodeStringByKey(res.getAlias(),"replacement",&status);
res.adoptInstead(NULL);
const Region *aliasToRegion = (Region *) uhash_get(newRegionIDMap.getAlias(),&aliasTo);
Region *aliasFromRegion = (Region *)uhash_get(newRegionIDMap.getAlias(),aliasFromStr.getAlias());
if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is just an alias from some string to a region
uhash_put(newRegionAliases.getAlias(),(void *)aliasFromStr.orphan(), (void *)aliasToRegion,&status);
} else {
if ( aliasFromRegion == NULL ) { // Deprecated region code not in the master codes list - so need to create a deprecated region for it.
LocalPointer<Region> newRgn(new Region, status);
if ( U_SUCCESS(status) ) {
aliasFromRegion = newRgn.orphan();
} else {
示例13: parseRBNFImpl
static jobject parseRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jstring text,
jobject position, jboolean lenient) {
// LOGI("ENTER parseRBNFImpl");
const char * parsePositionClassName = "java/text/ParsePosition";
const char * longClassName = "java/lang/Long";
const char * doubleClassName = "java/lang/Double";
UErrorCode status = U_ZERO_ERROR;
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
jchar *str = (UChar *)env->GetStringChars(text, NULL);
int strlength = env->GetStringLength(text);
jclass parsePositionClass = env->FindClass(parsePositionClassName);
jclass longClass = env->FindClass(longClassName);
jclass doubleClass = env->FindClass(doubleClassName);
jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass,
"getIndex", "()I");
jmethodID setIndexMethodID = env->GetMethodID(parsePositionClass,
"setIndex", "(I)V");
jmethodID setErrorIndexMethodID = env->GetMethodID(parsePositionClass,
"setErrorIndex", "(I)V");
jmethodID longInitMethodID = env->GetMethodID(longClass, "<init>", "(J)V");
jmethodID dblInitMethodID = env->GetMethodID(doubleClass, "<init>", "(D)V");
int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
// make sure the ParsePosition is valid. Actually icu4c would parse a number
// correctly even if the parsePosition is set to -1, but since the RI fails
// for that case we have to fail too
if(parsePos < 0 || parsePos > strlength) {
return NULL;
}
Formattable res;
const UnicodeString src((UChar*)str, strlength, strlength);
ParsePosition pp;
pp.setIndex(parsePos);
if(lenient) {
unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_TRUE);
}
((const NumberFormat*)fmt)->parse(src, res, pp);
if(lenient) {
unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_FALSE);
}
env->ReleaseStringChars(text, str);
if(pp.getErrorIndex() == -1) {
parsePos = pp.getIndex();
} else {
env->CallVoidMethod(position, setErrorIndexMethodID,
(jint) pp.getErrorIndex());
return NULL;
}
Formattable::Type numType;
numType = res.getType();
UErrorCode fmtStatus;
double resultDouble;
long resultLong;
int64_t resultInt64;
switch(numType) {
case Formattable::kDouble:
resultDouble = res.getDouble();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
return env->NewObject(doubleClass, dblInitMethodID,
(jdouble) resultDouble);
case Formattable::kLong:
resultLong = res.getLong();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
return env->NewObject(longClass, longInitMethodID,
(jlong) resultLong);
case Formattable::kInt64:
resultInt64 = res.getInt64();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
return env->NewObject(longClass, longInitMethodID,
(jlong) resultInt64);
default:
break;
}
return NULL;
}
示例14: test_Formattable
void test_Formattable( void )
{
UErrorCode status = U_ZERO_ERROR;
Formattable* ftp = new Formattable();
if (!ftp || !(ftp->getType() == Formattable::kLong) || !(ftp->getLong() == 0)) {
it_errln("*** Formattable constructor or getType or getLong");
}
delete ftp;
Formattable fta, ftb;
fta.setLong(1); ftb.setLong(2);
if ((fta != ftb) || !(fta == ftb)) {
it_logln("FT setLong, operator== and operator!= tested.");
status = U_ZERO_ERROR;
fta.getLong(&status);
if ( status == U_INVALID_FORMAT_ERROR){
it_errln("*** FT getLong(UErrorCode* status) failed on real Long");
} else {
it_logln("FT getLong(UErrorCode* status) tested.");
}
}else{
it_errln("*** Formattable setLong or operator== or !=");
}
fta = ftb;
if ((fta == ftb) || !(fta != ftb)) {
it_logln("FT operator= tested.");
}else{
it_errln("*** FT operator= or operator== or operator!=");
}
fta.setDouble( 3.0 );
if ((fta.getType() == Formattable::kDouble) && (fta.getDouble() == 3.0)) {
it_logln("FT set- and getDouble tested.");
}else{
it_errln("*** FT set- or getDouble");
}
fta.getDate(status = U_ZERO_ERROR);
if (status != U_INVALID_FORMAT_ERROR){
it_errln("*** FT getDate with status should fail on non-Date");
}
fta.setDate( 4.0 );
if ((fta.getType() == Formattable::kDate) && (fta.getDate() == 4.0)) {
it_logln("FT set- and getDate tested.");
status = U_ZERO_ERROR;
fta.getDate(status);
if ( status == U_INVALID_FORMAT_ERROR){
it_errln("*** FT getDate with status failed on real Date");
} else {
it_logln("FT getDate with status tested.");
}
}else{
it_errln("*** FT set- or getDate");
}
status = U_ZERO_ERROR;
fta.getLong(&status);
if (status != U_INVALID_FORMAT_ERROR){
it_errln("*** FT getLong(UErrorCode* status) should fail on non-Long");
}
fta.setString("abc");
const Formattable ftc(fta);
UnicodeString res;
{
UBool t;
t = (fta.getType() == Formattable::kString)
&& (fta.getString(res) == "abc")
&& (fta.getString() == "abc");
res = fta.getString(status = U_ZERO_ERROR);
t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
res = ftc.getString(status = U_ZERO_ERROR);
t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
ftc.getString(res,status = U_ZERO_ERROR);
t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
if (t) {
it_logln("FT set- and getString tested.");
}else{
it_errln("*** FT set- or getString");
}
}
UnicodeString ucs = "unicode-string";
UnicodeString* ucs_ptr = new UnicodeString("pointed-to-unicode-string");
const Formattable ftarray[] =
{
Formattable( 1.0, Formattable::kIsDate ),
2.0,
(int32_t)3,
ucs,
ucs_ptr
};
const int32_t ft_cnt = UPRV_LENGTHOF(ftarray);
Formattable ft_arr( ftarray, ft_cnt );
UnicodeString temp;
if ((ft_arr[0].getType() == Formattable::kDate) && (ft_arr[0].getDate() == 1.0)
&& (ft_arr[1].getType() == Formattable::kDouble) && (ft_arr[1].getDouble() == 2.0)
&& (ft_arr[2].getType() == Formattable::kLong) && (ft_arr[2].getLong() == (int32_t)3)
//.........这里部分代码省略.........
示例15: pattern1
void MessageFormatRegressionTest::Test4031438()
{
UErrorCode status = U_ZERO_ERROR;
UnicodeString pattern1("Impossible {1} has occurred -- status code is {0} and message is {2}.");
UnicodeString pattern2("Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.");
MessageFormat *messageFormatter = new MessageFormat("", status);
failure(status, "new MessageFormat");
const UBool possibleDataError = TRUE;
//try {
logln("Apply with pattern : " + pattern1);
messageFormatter->applyPattern(pattern1, status);
failure(status, "messageFormat->applyPattern");
//Object[] params = {new Integer(7)};
Formattable params []= {
Formattable((int32_t)7)
};
UnicodeString tempBuffer;
FieldPosition pos(FieldPosition::DONT_CARE);
tempBuffer = messageFormatter->format(params, 1, tempBuffer, pos, status);
if(tempBuffer != "Impossible {1} has occurred -- status code is 7 and message is {2}." || failure(status, "MessageFormat::format"))
dataerrln("Tests arguments < substitution failed");
logln("Formatted with 7 : " + tempBuffer);
ParsePosition pp(0);
int32_t count = 0;
Formattable *objs = messageFormatter->parse(tempBuffer, pp, count);
//if(objs[7/*params.length*/] != NULL)
// errln("Parse failed with more than expected arguments");
NumberFormat *fmt = 0;
UnicodeString temp, temp1;
for (int i = 0; i < count; i++) {
// convert to string if not already
Formattable obj = objs[i];
temp.remove();
if(obj.getType() == Formattable::kString)
temp = obj.getString(temp);
else {
fmt = NumberFormat::createInstance(status);
switch (obj.getType()) {
case Formattable::kLong: fmt->format(obj.getLong(), temp); break;
case Formattable::kInt64: fmt->format(obj.getInt64(), temp); break;
case Formattable::kDouble: fmt->format(obj.getDouble(), temp); break;
default: break;
}
}
// convert to string if not already
Formattable obj1 = params[i];
temp1.remove();
if(obj1.getType() == Formattable::kString)
temp1 = obj1.getString(temp1);
else {
fmt = NumberFormat::createInstance(status);
switch (obj1.getType()) {
case Formattable::kLong: fmt->format(obj1.getLong(), temp1); break;
case Formattable::kInt64: fmt->format(obj1.getInt64(), temp1); break;
case Formattable::kDouble: fmt->format(obj1.getDouble(), temp1); break;
default: break;
}
}
//if (objs[i] != NULL && objs[i].getString(temp1) != params[i].getString(temp2)) {
if (temp != temp1) {
errln("Parse failed on object " + objs[i].getString(temp1) + " at index : " + i);
}
}
delete fmt;
delete [] objs;
// {sfb} does this apply? no way to really pass a null Formattable,
// only a null array
/*tempBuffer = messageFormatter->format(null, tempBuffer, FieldPosition(FieldPosition::DONT_CARE), status);
if (tempBuffer != "Impossible {1} has occurred -- status code is {0} and message is {2}." || failure(status, "messageFormat->format"))
errln("Tests with no arguments failed");
logln("Formatted with null : " + tempBuffer);*/
logln("Apply with pattern : " + pattern2);
messageFormatter->applyPattern(pattern2, status);
failure(status, "messageFormatter->applyPattern", possibleDataError);
tempBuffer.remove();
tempBuffer = messageFormatter->format(params, 1, tempBuffer, pos, status);
if (tempBuffer != "Double ' Quotes 7 test and quoted {1} test plus other {2} stuff.")
dataerrln("quote format test (w/ params) failed. - %s", u_errorName(status));
logln("Formatted with params : " + tempBuffer);
/*tempBuffer = messageFormatter->format(null);
if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff."))
errln("quote format test (w/ null) failed.");
logln("Formatted with null : " + tempBuffer);
logln("toPattern : " + messageFormatter.toPattern());*/
/*} catch (Exception foo) {
errln("Exception when formatting in bug 4031438. "+foo.getMessage());
}*/
//.........这里部分代码省略.........