mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-20138 Adding FormattedValue helper implementation for FPI handlers.
- Changes FieldPositionIterator (FPI) to use tetrads in the UVector32.
This commit is contained in:
parent
9bb910b8d0
commit
1624176dd9
10 changed files with 187 additions and 6 deletions
|
@ -112,7 +112,7 @@ numparse_stringsegment.o numparse_parsednumber.o numparse_impl.o \
|
|||
numparse_symbols.o numparse_decimal.o numparse_scientific.o numparse_currency.o \
|
||||
numparse_affixes.o numparse_compositions.o numparse_validators.o \
|
||||
numrange_fluent.o numrange_impl.o \
|
||||
erarules.o formattedvalue.o
|
||||
erarules.o formattedvalue.o formattedval_iterimpl.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS = $(srcdir)/unicode/*.h
|
||||
|
|
55
icu4c/source/i18n/formattedval_impl.h
Normal file
55
icu4c/source/i18n/formattedval_impl.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
// © 2018 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#ifndef __FORMVAL_IMPL_H__
|
||||
#define __FORMVAL_IMPL_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
// This file contains compliant implementations of FormattedValue which can be
|
||||
// leveraged by ICU formatters.
|
||||
//
|
||||
// Each implementation is defined in its own cpp file in order to split
|
||||
// dependencies more modularly.
|
||||
|
||||
#include "unicode/formattedvalue.h"
|
||||
#include "fphdlimp.h"
|
||||
#include "uvectr32.h"
|
||||
#include "util.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
/** Implementation using FieldPositionHandler to accept fields. */
|
||||
class FormattedValueFieldPositionIteratorImpl : public UMemory, public FormattedValue {
|
||||
public:
|
||||
|
||||
/** @param initialFieldCapacity Initially allocate space for this many fields. */
|
||||
FormattedValueFieldPositionIteratorImpl(int32_t initialFieldCapacity, UErrorCode& status);
|
||||
|
||||
virtual ~FormattedValueFieldPositionIteratorImpl();
|
||||
|
||||
// Implementation of FormattedValue (const):
|
||||
|
||||
UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
|
||||
UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE;
|
||||
Appendable& appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE;
|
||||
UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
// Additional methods used during construction phase only (non-const):
|
||||
|
||||
FieldPositionIteratorHandler getHandler(UErrorCode& status);
|
||||
void appendString(UnicodeString string, UErrorCode& status);
|
||||
|
||||
private:
|
||||
// Final data:
|
||||
UnicodeString fString;
|
||||
UVector32 fFields;
|
||||
};
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
#endif // __FORMVAL_IMPL_H__
|
87
icu4c/source/i18n/formattedval_iterimpl.cpp
Normal file
87
icu4c/source/i18n/formattedval_iterimpl.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
// © 2018 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
// This file contains one implementation of FormattedValue.
|
||||
// Other independent implementations should go into their own cpp file for
|
||||
// better dependency modularization.
|
||||
|
||||
#include "formattedval_impl.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
FormattedValueFieldPositionIteratorImpl::FormattedValueFieldPositionIteratorImpl(
|
||||
int32_t initialFieldCapacity,
|
||||
UErrorCode& status)
|
||||
: fFields(initialFieldCapacity * 4, status) {
|
||||
}
|
||||
|
||||
FormattedValueFieldPositionIteratorImpl::~FormattedValueFieldPositionIteratorImpl() = default;
|
||||
|
||||
UnicodeString FormattedValueFieldPositionIteratorImpl::toString(
|
||||
UErrorCode&) const {
|
||||
return fString;
|
||||
}
|
||||
|
||||
UnicodeString FormattedValueFieldPositionIteratorImpl::toTempString(
|
||||
UErrorCode&) const {
|
||||
UnicodeString ret;
|
||||
ret.fastCopyFrom(fString);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Appendable& FormattedValueFieldPositionIteratorImpl::appendTo(
|
||||
Appendable& appendable,
|
||||
UErrorCode&) const {
|
||||
appendable.appendString(fString.getBuffer(), fString.length());
|
||||
return appendable;
|
||||
}
|
||||
|
||||
UBool FormattedValueFieldPositionIteratorImpl::nextPosition(
|
||||
ConstrainedFieldPosition& cfpos,
|
||||
UErrorCode&) const {
|
||||
U_ASSERT(fFields.size() % 4 == 0);
|
||||
int32_t numFields = fFields.size() / 4;
|
||||
int32_t i = cfpos.getInt64IterationContext();
|
||||
for (; i < numFields; i++) {
|
||||
UFieldCategory category = static_cast<UFieldCategory>(fFields.elementAti(i * 4));
|
||||
int32_t field = fFields.elementAti(i * 4 + 1);
|
||||
if (cfpos.matchesField(category, field)) {
|
||||
int32_t start = fFields.elementAti(i * 4 + 2);
|
||||
int32_t limit = fFields.elementAti(i * 4 + 3);
|
||||
cfpos.setState(category, field, start, limit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cfpos.setInt64IterationContext(i == numFields ? i : i + 1);
|
||||
return i < numFields;
|
||||
}
|
||||
|
||||
|
||||
FieldPositionIteratorHandler FormattedValueFieldPositionIteratorImpl::getHandler(
|
||||
UErrorCode& status) {
|
||||
return FieldPositionIteratorHandler(&fFields, status);
|
||||
}
|
||||
|
||||
void FormattedValueFieldPositionIteratorImpl::appendString(
|
||||
UnicodeString string,
|
||||
UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
fString.append(string);
|
||||
// Make the string NUL-terminated
|
||||
if (fString.getTerminatedBuffer() == nullptr) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
@ -62,12 +62,18 @@ FieldPositionOnlyHandler::isRecording(void) const {
|
|||
|
||||
FieldPositionIteratorHandler::FieldPositionIteratorHandler(FieldPositionIterator* posIter,
|
||||
UErrorCode& _status)
|
||||
: iter(posIter), vec(NULL), status(_status) {
|
||||
: iter(posIter), vec(NULL), status(_status), fCategory(UFIELD_CATEGORY_UNDEFINED) {
|
||||
if (iter && U_SUCCESS(status)) {
|
||||
vec = new UVector32(status);
|
||||
}
|
||||
}
|
||||
|
||||
FieldPositionIteratorHandler::FieldPositionIteratorHandler(
|
||||
UVector32* vec,
|
||||
UErrorCode& status)
|
||||
: iter(nullptr), vec(vec), status(status), fCategory(UFIELD_CATEGORY_UNDEFINED) {
|
||||
}
|
||||
|
||||
FieldPositionIteratorHandler::~FieldPositionIteratorHandler() {
|
||||
// setData adopts the vec regardless of status, so it's safe to null it
|
||||
if (iter) {
|
||||
|
@ -79,8 +85,9 @@ FieldPositionIteratorHandler::~FieldPositionIteratorHandler() {
|
|||
|
||||
void
|
||||
FieldPositionIteratorHandler::addAttribute(int32_t id, int32_t start, int32_t limit) {
|
||||
if (iter && U_SUCCESS(status) && start < limit) {
|
||||
if (vec && U_SUCCESS(status) && start < limit) {
|
||||
int32_t size = vec->size();
|
||||
vec->addElement(fCategory, status);
|
||||
vec->addElement(id, status);
|
||||
vec->addElement(start + fShift, status);
|
||||
vec->addElement(limit + fShift, status);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "unicode/fieldpos.h"
|
||||
#include "unicode/fpositer.h"
|
||||
#include "unicode/formattedvalue.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -57,6 +58,7 @@ class FieldPositionIteratorHandler : public FieldPositionHandler {
|
|||
FieldPositionIterator* iter; // can be NULL
|
||||
UVector32* vec;
|
||||
UErrorCode status;
|
||||
UFieldCategory fCategory;
|
||||
|
||||
// Note, we keep a reference to status, so if status is on the stack, we have
|
||||
// to be destroyed before status goes out of scope. Easiest thing is to
|
||||
|
@ -70,11 +72,24 @@ class FieldPositionIteratorHandler : public FieldPositionHandler {
|
|||
|
||||
public:
|
||||
FieldPositionIteratorHandler(FieldPositionIterator* posIter, UErrorCode& status);
|
||||
/** If using this constructor, you must call getError() when done formatting! */
|
||||
FieldPositionIteratorHandler(UVector32* vec, UErrorCode& status);
|
||||
~FieldPositionIteratorHandler();
|
||||
|
||||
void addAttribute(int32_t id, int32_t start, int32_t limit) U_OVERRIDE;
|
||||
void shiftLast(int32_t delta) U_OVERRIDE;
|
||||
UBool isRecording(void) const U_OVERRIDE;
|
||||
|
||||
/** Copies a failed error code into _status. */
|
||||
inline void getError(UErrorCode& _status) {
|
||||
if (U_SUCCESS(_status) && U_FAILURE(status)) {
|
||||
_status = status;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setCategory(UFieldCategory category) {
|
||||
fCategory = category;
|
||||
}
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -65,10 +65,10 @@ void FieldPositionIterator::setData(UVector32 *adopt, UErrorCode& status) {
|
|||
if (adopt->size() == 0) {
|
||||
delete adopt;
|
||||
adopt = NULL;
|
||||
} else if ((adopt->size() % 3) != 0) {
|
||||
} else if ((adopt->size() % 4) != 0) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
} else {
|
||||
for (int i = 1; i < adopt->size(); i += 3) {
|
||||
for (int i = 2; i < adopt->size(); i += 4) {
|
||||
if (adopt->elementAti(i) >= adopt->elementAti(i+1)) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
break;
|
||||
|
@ -95,6 +95,8 @@ UBool FieldPositionIterator::next(FieldPosition& fp) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// Ignore the first element of the tetrad: used for field category
|
||||
pos++;
|
||||
fp.setField(data->elementAti(pos++));
|
||||
fp.setBeginIndex(data->elementAti(pos++));
|
||||
fp.setEndIndex(data->elementAti(pos++));
|
||||
|
|
|
@ -238,6 +238,7 @@
|
|||
<ClCompile Include="fmtable.cpp" />
|
||||
<ClCompile Include="fmtable_cnv.cpp" />
|
||||
<ClCompile Include="format.cpp" />
|
||||
<ClCompile Include="formattedval_iterimpl.cpp" />
|
||||
<ClCompile Include="formattedvalue.cpp" />
|
||||
<ClCompile Include="fphdlimp.cpp" />
|
||||
<ClCompile Include="fpositer.cpp" />
|
||||
|
@ -559,6 +560,7 @@
|
|||
<ClInclude Include="numparse_types.h" />
|
||||
<ClInclude Include="numparse_utils.h" />
|
||||
<ClInclude Include="numrange_impl.h" />
|
||||
<ClInclude Include="formattedval_impl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="i18n.rc" />
|
||||
|
|
|
@ -156,6 +156,9 @@
|
|||
<ClCompile Include="format.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="formattedval_iterimpl.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="formattedvalue.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -794,6 +797,9 @@
|
|||
<ClInclude Include="ethpccal.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="formattedval_impl.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fphdlimp.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -345,6 +345,7 @@
|
|||
<ClCompile Include="fmtable.cpp" />
|
||||
<ClCompile Include="fmtable_cnv.cpp" />
|
||||
<ClCompile Include="format.cpp" />
|
||||
<ClCompile Include="formattedval_iterimpl.cpp" />
|
||||
<ClCompile Include="formattedvalue.cpp" />
|
||||
<ClCompile Include="fphdlimp.cpp" />
|
||||
<ClCompile Include="fpositer.cpp" />
|
||||
|
@ -664,6 +665,7 @@
|
|||
<ClInclude Include="numparse_types.h" />
|
||||
<ClInclude Include="numparse_utils.h" />
|
||||
<ClInclude Include="numrange_impl.h" />
|
||||
<ClInclude Include="formattedval_impl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="i18n.rc" />
|
||||
|
|
|
@ -916,7 +916,7 @@ group: dayperiodrules
|
|||
group: listformatter
|
||||
listformatter.o ulistformatter.o
|
||||
deps
|
||||
resourcebundle simpleformatter format uclean_i18n
|
||||
resourcebundle simpleformatter format uclean_i18n formatted_value_iterimpl
|
||||
|
||||
group: double_conversion
|
||||
double-conversion.o double-conversion-bignum.o double-conversion-bignum-dtoa.o
|
||||
|
@ -1046,6 +1046,11 @@ group: formatted_value
|
|||
deps
|
||||
platform
|
||||
|
||||
group: formatted_value_iterimpl
|
||||
formattedval_iterimpl.o
|
||||
deps
|
||||
formatted_value format uvector32
|
||||
|
||||
group: format
|
||||
format.o fphdlimp.o fpositer.o ufieldpositer.o
|
||||
deps
|
||||
|
|
Loading…
Add table
Reference in a new issue