blob: 5a3a2bc0c610989881d72b17d0f3eef5c7231dd5 [file] [log] [blame]
/*
**********************************************************************
* Copyright (c) 2014, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/scientificformathelper.h"
#include "unicode/dcfmtsym.h"
#include "unicode/fpositer.h"
#include "unicode/utf16.h"
#include "unicode/uniset.h"
#include "decfmtst.h"
U_NAMESPACE_BEGIN
static const UChar kSuperscriptDigits[] = {0x2070, 0xB9, 0xB2, 0xB3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079};
static const UChar kSuperscriptPlusSign = 0x207A;
static const UChar kSuperscriptMinusSign = 0x207B;
ScientificFormatHelper::ScientificFormatHelper(
const DecimalFormatSymbols &dfs, UErrorCode &status)
: fPreExponent(), fStaticSets(NULL) {
if (U_FAILURE(status)) {
return;
}
fPreExponent.append(dfs.getConstSymbol(
DecimalFormatSymbols::kExponentMultiplicationSymbol));
fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kOneDigitSymbol));
fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol));
fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
}
ScientificFormatHelper::ScientificFormatHelper(
const ScientificFormatHelper &other)
: UObject(other),
fPreExponent(other.fPreExponent),
fStaticSets(other.fStaticSets) {
}
ScientificFormatHelper &ScientificFormatHelper::operator=(const ScientificFormatHelper &other) {
if (this == &other) {
return *this;
}
fPreExponent = other.fPreExponent;
fStaticSets = other.fStaticSets;
return *this;
}
ScientificFormatHelper::~ScientificFormatHelper() {
}
UnicodeString &ScientificFormatHelper::insertMarkup(
const UnicodeString &s,
FieldPositionIterator &fpi,
const UnicodeString &beginMarkup,
const UnicodeString &endMarkup,
UnicodeString &result,
UErrorCode &status) const {
if (U_FAILURE(status)) {
return result;
}
FieldPosition fp;
int32_t copyFromOffset = 0;
UBool exponentSymbolFieldPresent = FALSE;
UBool exponentFieldPresent = FALSE;
while (fpi.next(fp)) {
switch (fp.getField()) {
case UNUM_EXPONENT_SYMBOL_FIELD:
exponentSymbolFieldPresent = TRUE;
result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset);
copyFromOffset = fp.getEndIndex();
result.append(fPreExponent);
result.append(beginMarkup);
break;
case UNUM_EXPONENT_FIELD:
exponentFieldPresent = TRUE;
result.append(s, copyFromOffset, fp.getEndIndex() - copyFromOffset);
copyFromOffset = fp.getEndIndex();
result.append(endMarkup);
break;
default:
break;
}
}
if (!exponentSymbolFieldPresent || !exponentFieldPresent) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return result;
}
result.append(s, copyFromOffset, s.length() - copyFromOffset);
return result;
}
static UBool copyAsSuperscript(
const UnicodeString &s,
int32_t beginIndex,
int32_t endIndex,
UnicodeString &result,
UErrorCode &status) {
if (U_FAILURE(status)) {
return FALSE;
}
for (int32_t i = beginIndex; i < endIndex;) {
UChar32 c = s.char32At(i);
int32_t digit = u_charDigitValue(c);
if (digit < 0) {
status = U_INVALID_CHAR_FOUND;
return FALSE;
}
result.append(kSuperscriptDigits[digit]);
i += U16_LENGTH(c);
}
return TRUE;
}
UnicodeString &ScientificFormatHelper::toSuperscriptExponentDigits(
const UnicodeString &s,
FieldPositionIterator &fpi,
UnicodeString &result,
UErrorCode &status) const {
if (U_FAILURE(status)) {
return result;
}
FieldPosition fp;
int32_t copyFromOffset = 0;
UBool exponentSymbolFieldPresent = FALSE;
UBool exponentFieldPresent = FALSE;
while (fpi.next(fp)) {
switch (fp.getField()) {
case UNUM_EXPONENT_SYMBOL_FIELD:
exponentSymbolFieldPresent = TRUE;
result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset);
copyFromOffset = fp.getEndIndex();
result.append(fPreExponent);
break;
case UNUM_EXPONENT_SIGN_FIELD:
{
int32_t beginIndex = fp.getBeginIndex();
int32_t endIndex = fp.getEndIndex();
UChar32 aChar = s.char32At(beginIndex);
if (fStaticSets->fMinusSigns->contains(aChar)) {
result.append(s, copyFromOffset, beginIndex - copyFromOffset);
result.append(kSuperscriptMinusSign);
} else if (fStaticSets->fPlusSigns->contains(aChar)) {
result.append(s, copyFromOffset, beginIndex - copyFromOffset);
result.append(kSuperscriptPlusSign);
} else {
status = U_INVALID_CHAR_FOUND;
return result;
}
copyFromOffset = endIndex;
}
break;
case UNUM_EXPONENT_FIELD:
exponentFieldPresent = TRUE;
result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset);
if (!copyAsSuperscript(
s, fp.getBeginIndex(), fp.getEndIndex(), result, status)) {
return result;
}
copyFromOffset = fp.getEndIndex();
break;
default:
break;
}
}
if (!exponentSymbolFieldPresent || !exponentFieldPresent) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return result;
}
result.append(s, copyFromOffset, s.length() - copyFromOffset);
return result;
}
U_NAMESPACE_END
#endif /* !UCONFIG_NO_FORMATTING */