OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2009-2013, International Business Machines Corporation and | 3 * Copyright (C) 2009-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 * | 6 * |
7 * File PLURFMT.CPP | 7 * File PLURFMT.CPP |
8 ******************************************************************************* | 8 ******************************************************************************* |
9 */ | 9 */ |
10 | 10 |
11 #include "unicode/decimfmt.h" | 11 #include "unicode/decimfmt.h" |
12 #include "unicode/messagepattern.h" | 12 #include "unicode/messagepattern.h" |
13 #include "unicode/plurfmt.h" | 13 #include "unicode/plurfmt.h" |
14 #include "unicode/plurrule.h" | 14 #include "unicode/plurrule.h" |
15 #include "unicode/utypes.h" | 15 #include "unicode/utypes.h" |
16 #include "cmemory.h" | 16 #include "cmemory.h" |
17 #include "messageimpl.h" | 17 #include "messageimpl.h" |
| 18 #include "nfrule.h" |
18 #include "plurrule_impl.h" | 19 #include "plurrule_impl.h" |
19 #include "uassert.h" | 20 #include "uassert.h" |
20 #include "uhash.h" | 21 #include "uhash.h" |
21 | 22 |
22 #if !UCONFIG_NO_FORMATTING | 23 #if !UCONFIG_NO_FORMATTING |
23 | 24 |
24 U_NAMESPACE_BEGIN | 25 U_NAMESPACE_BEGIN |
25 | 26 |
26 static const UChar OTHER_STRING[] = { | 27 static const UChar OTHER_STRING[] = { |
27 0x6F, 0x74, 0x68, 0x65, 0x72, 0 // "other" | 28 0x6F, 0x74, 0x68, 0x65, 0x72, 0 // "other" |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 // Do not match this keyword again. | 475 // Do not match this keyword again. |
475 haveKeywordMatch=TRUE; | 476 haveKeywordMatch=TRUE; |
476 } | 477 } |
477 } | 478 } |
478 } | 479 } |
479 partIndex=pattern.getLimitPartIndex(partIndex); | 480 partIndex=pattern.getLimitPartIndex(partIndex); |
480 } while(++partIndex<count); | 481 } while(++partIndex<count); |
481 return msgStart; | 482 return msgStart; |
482 } | 483 } |
483 | 484 |
| 485 void PluralFormat::parseType(const UnicodeString& source, const NFRule *rbnfLeni
entScanner, Formattable& result, FieldPosition& pos) const { |
| 486 // If no pattern was applied, return null. |
| 487 if (msgPattern.countParts() == 0) { |
| 488 pos.setBeginIndex(-1); |
| 489 pos.setEndIndex(-1); |
| 490 return; |
| 491 } |
| 492 int partIndex = 0; |
| 493 int currMatchIndex; |
| 494 int count=msgPattern.countParts(); |
| 495 int startingAt = pos.getBeginIndex(); |
| 496 if (startingAt < 0) { |
| 497 startingAt = 0; |
| 498 } |
| 499 |
| 500 // The keyword is null until we need to match against a non-explicit, not-"o
ther" value. |
| 501 // Then we get the keyword from the selector. |
| 502 // (In other words, we never call the selector if we match against an explic
it value, |
| 503 // or if the only non-explicit keyword is "other".) |
| 504 UnicodeString keyword; |
| 505 UnicodeString matchedWord; |
| 506 const UnicodeString& pattern = msgPattern.getPatternString(); |
| 507 int matchedIndex = -1; |
| 508 // Iterate over (ARG_SELECTOR ARG_START message ARG_LIMIT) tuples |
| 509 // until the end of the plural-only pattern. |
| 510 while (partIndex < count) { |
| 511 const MessagePattern::Part* partSelector = &msgPattern.getPart(partIndex
++); |
| 512 if (partSelector->getType() != UMSGPAT_PART_TYPE_ARG_SELECTOR) { |
| 513 // Bad format |
| 514 continue; |
| 515 } |
| 516 |
| 517 const MessagePattern::Part* partStart = &msgPattern.getPart(partIndex++)
; |
| 518 if (partStart->getType() != UMSGPAT_PART_TYPE_MSG_START) { |
| 519 // Bad format |
| 520 continue; |
| 521 } |
| 522 |
| 523 const MessagePattern::Part* partLimit = &msgPattern.getPart(partIndex++)
; |
| 524 if (partLimit->getType() != UMSGPAT_PART_TYPE_MSG_LIMIT) { |
| 525 // Bad format |
| 526 continue; |
| 527 } |
| 528 |
| 529 UnicodeString currArg = pattern.tempSubString(partStart->getLimit(), par
tLimit->getIndex() - partStart->getLimit()); |
| 530 if (rbnfLenientScanner != NULL) { |
| 531 // If lenient parsing is turned ON, we've got some time consuming pa
rsing ahead of us. |
| 532 int32_t length = -1; |
| 533 currMatchIndex = rbnfLenientScanner->findTextLenient(source, currArg
, startingAt, &length); |
| 534 } |
| 535 else { |
| 536 currMatchIndex = source.indexOf(currArg); |
| 537 } |
| 538 if (currMatchIndex >= 0 && currMatchIndex >= matchedIndex && currArg.len
gth() > matchedWord.length()) { |
| 539 matchedIndex = currMatchIndex; |
| 540 matchedWord = currArg; |
| 541 keyword = pattern.tempSubString(partStart->getLimit(), partLimit->ge
tIndex() - partStart->getLimit()); |
| 542 } |
| 543 } |
| 544 if (matchedIndex >= 0) { |
| 545 pos.setBeginIndex(matchedIndex); |
| 546 pos.setEndIndex(matchedIndex + matchedWord.length()); |
| 547 result.setString(keyword); |
| 548 return; |
| 549 } |
| 550 |
| 551 // Not found! |
| 552 pos.setBeginIndex(-1); |
| 553 pos.setEndIndex(-1); |
| 554 } |
| 555 |
484 PluralFormat::PluralSelector::~PluralSelector() {} | 556 PluralFormat::PluralSelector::~PluralSelector() {} |
485 | 557 |
486 PluralFormat::PluralSelectorAdapter::~PluralSelectorAdapter() { | 558 PluralFormat::PluralSelectorAdapter::~PluralSelectorAdapter() { |
487 delete pluralRules; | 559 delete pluralRules; |
488 } | 560 } |
489 | 561 |
490 UnicodeString PluralFormat::PluralSelectorAdapter::select(void *context, double
number, | 562 UnicodeString PluralFormat::PluralSelectorAdapter::select(void *context, double
number, |
491 UErrorCode& /*ec*/) co
nst { | 563 UErrorCode& /*ec*/) co
nst { |
492 (void)number; // unused except in the assertion | 564 (void)number; // unused except in the assertion |
493 FixedDecimal *dec=static_cast<FixedDecimal *>(context); | 565 FixedDecimal *dec=static_cast<FixedDecimal *>(context); |
494 U_ASSERT(dec->source==number); | 566 U_ASSERT(dec->source==number); |
495 return pluralRules->select(*dec); | 567 return pluralRules->select(*dec); |
496 } | 568 } |
497 | 569 |
498 void PluralFormat::PluralSelectorAdapter::reset() { | 570 void PluralFormat::PluralSelectorAdapter::reset() { |
499 delete pluralRules; | 571 delete pluralRules; |
500 pluralRules = NULL; | 572 pluralRules = NULL; |
501 } | 573 } |
502 | 574 |
503 | 575 |
504 U_NAMESPACE_END | 576 U_NAMESPACE_END |
505 | 577 |
506 | 578 |
507 #endif /* #if !UCONFIG_NO_FORMATTING */ | 579 #endif /* #if !UCONFIG_NO_FORMATTING */ |
508 | 580 |
509 //eof | 581 //eof |
OLD | NEW |