#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/udatpg.h"
#include "unicode/uenum.h"
#include "unicode/strenum.h"
#include "unicode/unistr.h"
#include "unicode/dtptngen.h"
#include "unicode/uchar.h"
#include "ustrenum.h"
#include "dtitv_impl.h"
U_NAMESPACE_USE
U_CAPI UDateTimePatternGenerator * U_EXPORT2
udatpg_open(const char *locale, UErrorCode *pErrorCode) {
if(locale==NULL) {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createInstance(*pErrorCode);
} else {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createInstance(Locale(locale), *pErrorCode);
}
}
U_CAPI UDateTimePatternGenerator * U_EXPORT2
udatpg_openEmpty(UErrorCode *pErrorCode) {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createEmptyInstance(*pErrorCode);
}
U_CAPI void U_EXPORT2
udatpg_close(UDateTimePatternGenerator *dtpg) {
delete (DateTimePatternGenerator *)dtpg;
}
U_CAPI UDateTimePatternGenerator * U_EXPORT2
udatpg_clone(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return NULL;
}
return (UDateTimePatternGenerator *)(((const DateTimePatternGenerator *)dtpg)->clone());
}
U_CAPI int32_t U_EXPORT2
udatpg_getBestPattern(UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t length,
UChar *bestPattern, int32_t capacity,
UErrorCode *pErrorCode) {
return udatpg_getBestPatternWithOptions(dtpg, skeleton, length,
UDATPG_MATCH_NO_OPTIONS,
bestPattern, capacity, pErrorCode);
}
U_CAPI int32_t U_EXPORT2
udatpg_getBestPatternWithOptions(UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t length,
UDateTimePatternMatchOptions options,
UChar *bestPattern, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(skeleton==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString skeletonString((UBool)(length<0), skeleton, length);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->getBestPattern(skeletonString, options, *pErrorCode);
return result.extract(bestPattern, capacity, *pErrorCode);
}
U_CAPI int32_t U_EXPORT2
udatpg_getSkeleton(UDateTimePatternGenerator * ,
const UChar *pattern, int32_t length,
UChar *skeleton, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(pattern==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(length<0), pattern, length);
UnicodeString result=DateTimePatternGenerator::staticGetSkeleton(
patternString, *pErrorCode);
return result.extract(skeleton, capacity, *pErrorCode);
}
U_CAPI int32_t U_EXPORT2
udatpg_getBaseSkeleton(UDateTimePatternGenerator * ,
const UChar *pattern, int32_t length,
UChar *skeleton, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(pattern==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(length<0), pattern, length);
UnicodeString result=DateTimePatternGenerator::staticGetBaseSkeleton(
patternString, *pErrorCode);
return result.extract(skeleton, capacity, *pErrorCode);
}
U_CAPI UDateTimePatternConflict U_EXPORT2
udatpg_addPattern(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
UBool override,
UChar *conflictingPattern, int32_t capacity, int32_t *pLength,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return UDATPG_NO_CONFLICT;
}
if(pattern==NULL && patternLength!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return UDATPG_NO_CONFLICT;
}
UnicodeString patternString((UBool)(patternLength<0), pattern, patternLength);
UnicodeString conflictingPatternString;
UDateTimePatternConflict result=((DateTimePatternGenerator *)dtpg)->
addPattern(patternString, override, conflictingPatternString, *pErrorCode);
int32_t length=conflictingPatternString.extract(conflictingPattern, capacity, *pErrorCode);
if(pLength!=NULL) {
*pLength=length;
}
return result;
}
U_CAPI void U_EXPORT2
udatpg_setAppendItemFormat(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length) {
UnicodeString valueString((UBool)(length<0), value, length);
((DateTimePatternGenerator *)dtpg)->setAppendItemFormat(field, valueString);
}
U_CAPI const UChar * U_EXPORT2
udatpg_getAppendItemFormat(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getAppendItemFormat(field);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_CAPI void U_EXPORT2
udatpg_setAppendItemName(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length) {
UnicodeString valueString((UBool)(length<0), value, length);
((DateTimePatternGenerator *)dtpg)->setAppendItemName(field, valueString);
}
U_CAPI const UChar * U_EXPORT2
udatpg_getAppendItemName(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getAppendItemName(field);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_CAPI int32_t U_EXPORT2
udatpg_getFieldDisplayName(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
UDateTimePGDisplayWidth width,
UChar *fieldName, int32_t capacity,
UErrorCode *pErrorCode) {
if (U_FAILURE(*pErrorCode))
return -1;
if (fieldName == NULL ? capacity != 0 : capacity < 0) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return -1;
}
UnicodeString result = ((const DateTimePatternGenerator *)dtpg)->getFieldDisplayName(field,width);
if (fieldName == NULL) {
return result.length();
}
return result.extract(fieldName, capacity, *pErrorCode);
}
U_CAPI void U_EXPORT2
udatpg_setDateTimeFormat(const UDateTimePatternGenerator *dtpg,
const UChar *dtFormat, int32_t length) {
UnicodeString dtFormatString((UBool)(length<0), dtFormat, length);
((DateTimePatternGenerator *)dtpg)->setDateTimeFormat(dtFormatString);
}
U_CAPI const UChar * U_EXPORT2
udatpg_getDateTimeFormat(const UDateTimePatternGenerator *dtpg,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getDateTimeFormat();
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_CAPI void U_EXPORT2
udatpg_setDecimal(UDateTimePatternGenerator *dtpg,
const UChar *decimal, int32_t length) {
UnicodeString decimalString((UBool)(length<0), decimal, length);
((DateTimePatternGenerator *)dtpg)->setDecimal(decimalString);
}
U_CAPI const UChar * U_EXPORT2
udatpg_getDecimal(const UDateTimePatternGenerator *dtpg,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getDecimal();
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_CAPI int32_t U_EXPORT2
udatpg_replaceFieldTypes(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
const UChar *skeleton, int32_t skeletonLength,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode) {
return udatpg_replaceFieldTypesWithOptions(dtpg, pattern, patternLength, skeleton, skeletonLength,
UDATPG_MATCH_NO_OPTIONS,
dest, destCapacity, pErrorCode);
}
U_CAPI int32_t U_EXPORT2
udatpg_replaceFieldTypesWithOptions(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
const UChar *skeleton, int32_t skeletonLength,
UDateTimePatternMatchOptions options,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if((pattern==NULL && patternLength!=0) || (skeleton==NULL && skeletonLength!=0)) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(patternLength<0), pattern, patternLength);
UnicodeString skeletonString((UBool)(skeletonLength<0), skeleton, skeletonLength);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->replaceFieldTypes(patternString, skeletonString, options, *pErrorCode);
return result.extract(dest, destCapacity, *pErrorCode);
}
U_CAPI UEnumeration * U_EXPORT2
udatpg_openSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
return uenum_openFromStringEnumeration(
((DateTimePatternGenerator *)dtpg)->getSkeletons(*pErrorCode),
pErrorCode);
}
U_CAPI UEnumeration * U_EXPORT2
udatpg_openBaseSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
return uenum_openFromStringEnumeration(
((DateTimePatternGenerator *)dtpg)->getBaseSkeletons(*pErrorCode),
pErrorCode);
}
U_CAPI const UChar * U_EXPORT2
udatpg_getPatternForSkeleton(const UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t skeletonLength,
int32_t *pLength) {
UnicodeString skeletonString((UBool)(skeletonLength<0), skeleton, skeletonLength);
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getPatternForSkeleton(skeletonString);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
static int32_t
_doReplaceAndReturnAdj( UDateTimePatternGenerator *dtpg, uint32_t options, UBool matchHourLen,
UnicodeString &patternString, const UnicodeString &skeleton, const UnicodeString &otherCycSkeleton,
int32_t timePatStart, int32_t timePatLimit, int32_t timeNonHourStart, int32_t timeNonHourLimit,
UErrorCode *pErrorCode) {
if (matchHourLen) {
options |= UDATPG_MATCH_HOUR_FIELD_LENGTH;
}
UnicodeString replacement=((DateTimePatternGenerator *)dtpg)->getBestPattern(otherCycSkeleton, (UDateTimePatternMatchOptions)options, *pErrorCode);
if (U_FAILURE(*pErrorCode)) {
return 0;
}
UnicodeString stringForOrigSkeleton=((DateTimePatternGenerator *)dtpg)->getBestPattern(skeleton, UDATPG_MATCH_ALL_FIELDS_LENGTH, *pErrorCode); if (U_SUCCESS(*pErrorCode)) {
int32_t index = patternString.indexOf(stringForOrigSkeleton);
if (index >= 0) {
int32_t stringForOrigSkelLen = stringForOrigSkeleton.length();
patternString.replace(index, stringForOrigSkelLen, replacement);
return replacement.length() - stringForOrigSkelLen;
}
} else {
*pErrorCode = U_ZERO_ERROR;
}
if (timeNonHourStart >= 0 && timeNonHourLimit > timeNonHourStart) {
UnicodeString nonHour;
patternString.extractBetween(timeNonHourStart, timeNonHourLimit, nonHour);
timeNonHourStart = -1;
timeNonHourLimit = 0;
UBool inQuoted = FALSE;
int32_t repPos, repLen = replacement.length();
for (repPos = 0; repPos < repLen; repPos++) {
UChar repChr = replacement.charAt(repPos);
if (repChr == 0x27 ) {
inQuoted = !inQuoted;
} else if (!inQuoted) {
if (repChr==LOW_H || repChr==CAP_H || repChr==CAP_K || repChr==LOW_K) { timeNonHourStart = repPos + 1;
} else if (timeNonHourStart < 0 && (repChr==LOW_M || repChr==LOW_S)) { timeNonHourStart = repPos;
}
if (!u_isWhitespace(repChr) && timeNonHourStart >= 0 && repChr!=LOW_A) { timeNonHourLimit = repPos + 1;
}
}
}
if (timeNonHourStart >= 0 && timeNonHourLimit > timeNonHourStart) {
replacement.replaceBetween(timeNonHourStart, timeNonHourLimit, nonHour);
}
}
patternString.replaceBetween(timePatStart, timePatLimit, replacement);
return replacement.length() - (timePatLimit - timePatStart); }
U_CAPI int32_t U_EXPORT2
uadatpg_remapPatternWithOptions(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
UDateTimePatternMatchOptions options,
UChar *newPattern, int32_t newPatternCapacity,
UErrorCode *pErrorCode) {
if (U_FAILURE(*pErrorCode)) {
return 0;
}
if ( pattern==NULL || ((newPattern==NULL)? newPatternCapacity!=0: newPatternCapacity<0) ) {
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((patternLength < 0), pattern, patternLength);
UBool force12 = ((options & UADATPG_FORCE_HOUR_CYCLE_MASK) == UADATPG_FORCE_12_HOUR_CYCLE);
UBool force24 = ((options & UADATPG_FORCE_HOUR_CYCLE_MASK) == UADATPG_FORCE_24_HOUR_CYCLE);
if (force12 || force24) {
UBool inQuoted = FALSE;
UBool inTimePat = FALSE;
UBool needReplacement = FALSE;
int32_t timePatStart = 0;
int32_t timePatLimit = 0;
int32_t timeNonHourStart = -1;
int32_t timeNonHourLimit = 0;
UnicodeString skeleton, otherCycSkeleton;
UnicodeString timePatChars("abBhHKkmsSzZOvVXx", -1, US_INV); int32_t numForcedH = 0;
int32_t patPos, patLen = patternString.length();
for (patPos = 0; patPos < patLen; patPos++) {
UChar patChr = patternString.charAt(patPos);
UChar otherCycPatChr = patChr;
if (patChr == 0x27 ) {
inQuoted = !inQuoted;
} else if (!inQuoted) {
if (timePatChars.indexOf(patChr) >= 0) {
if (!inTimePat) {
inTimePat = TRUE;
timePatStart = patPos;
timeNonHourStart = -1;
skeleton.remove();
otherCycSkeleton.remove();
numForcedH = 0;
}
if (patChr==LOW_H || patChr==CAP_K) { if (force24) {
otherCycPatChr = CAP_H; needReplacement = TRUE;
timeNonHourStart = patPos + 1;
numForcedH++;
}
} else if (patChr==CAP_H || patChr==LOW_K) { if (force12) {
otherCycPatChr = LOW_H; needReplacement = TRUE;
timeNonHourStart = patPos + 1;
}
} else if (timeNonHourStart < 0 && (patChr==LOW_M || patChr==LOW_S)) { timeNonHourStart = patPos;
}
skeleton.append(patChr);
otherCycSkeleton.append(otherCycPatChr);
} else if ((patChr >= 0x41 && patChr <= 0x5A) || (patChr >= 0x61 && patChr <= 0x7A)) {
if (inTimePat) {
inTimePat = FALSE;
if (needReplacement) {
needReplacement = FALSE;
int32_t posAdjust = _doReplaceAndReturnAdj(dtpg, options, numForcedH >= 2, patternString, skeleton, otherCycSkeleton,
timePatStart, timePatLimit, timeNonHourStart, timeNonHourLimit, pErrorCode);
patLen += posAdjust;
patPos += posAdjust;
}
}
}
if (inTimePat && !u_isWhitespace(patChr)) {
timePatLimit = patPos + 1;
if (timeNonHourStart >= 0 && patChr!=LOW_A && patChr!=LOW_B && patChr!=CAP_B) { timeNonHourLimit = timePatLimit;
}
}
}
}
if (needReplacement) {
_doReplaceAndReturnAdj(dtpg, options, numForcedH >= 2, patternString, skeleton, otherCycSkeleton,
timePatStart, timePatLimit, timeNonHourStart, timeNonHourLimit, pErrorCode);
}
}
return patternString.extract(newPattern, newPatternCapacity, *pErrorCode);
}
#endif