diff options
author | neksard <neksard@yandex-team.ru> | 2022-02-10 16:45:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:23 +0300 |
commit | 8f7cf138264e0caa318144bf8a2c950e0b0a8593 (patch) | |
tree | 83bf5c8c8047c42d8475e6095df90ccdc3d1b57f /contrib/libs/icu/i18n/umsg.cpp | |
parent | d3a398281c6fd1d3672036cb2d63f842d2cb28c5 (diff) | |
download | ydb-8f7cf138264e0caa318144bf8a2c950e0b0a8593.tar.gz |
Restoring authorship annotation for <neksard@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/icu/i18n/umsg.cpp')
-rw-r--r-- | contrib/libs/icu/i18n/umsg.cpp | 1400 |
1 files changed, 700 insertions, 700 deletions
diff --git a/contrib/libs/icu/i18n/umsg.cpp b/contrib/libs/icu/i18n/umsg.cpp index 9a5344e019..da9be99dbd 100644 --- a/contrib/libs/icu/i18n/umsg.cpp +++ b/contrib/libs/icu/i18n/umsg.cpp @@ -1,708 +1,708 @@ // © 2016 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html -/* -******************************************************************************* -* -* Copyright (C) 1999-2012, International Business Machines -* Corporation and others. All Rights Reserved. -* -******************************************************************************* -* file name: umsg.cpp +// License & terms of use: http://www.unicode.org/copyright.html +/* +******************************************************************************* +* +* Copyright (C) 1999-2012, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: umsg.cpp * encoding: UTF-8 -* tab size: 8 (not used) -* indentation:4 -* -* This is a C wrapper to MessageFormat C++ API. -* -* Change history: -* -* 08/5/2001 Ram Added C wrappers for C++ API. Changed implementation of old API's -* Removed pattern parser. +* tab size: 8 (not used) +* indentation:4 +* +* This is a C wrapper to MessageFormat C++ API. +* +* Change history: * -*/ - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_FORMATTING - -#include "unicode/umsg.h" -#include "unicode/ustring.h" -#include "unicode/fmtable.h" -#include "unicode/msgfmt.h" -#include "unicode/unistr.h" -#include "cpputils.h" -#include "uassert.h" -#include "ustr_imp.h" - -U_NAMESPACE_BEGIN -/** - * This class isolates our access to private internal methods of - * MessageFormat. It is never instantiated; it exists only for C++ - * access management. - */ -class MessageFormatAdapter { -public: - static const Formattable::Type* getArgTypeList(const MessageFormat& m, - int32_t& count); - static UBool hasArgTypeConflicts(const MessageFormat& m) { - return m.hasArgTypeConflicts; - } -}; -const Formattable::Type* -MessageFormatAdapter::getArgTypeList(const MessageFormat& m, - int32_t& count) { - return m.getArgTypeList(count); -} -U_NAMESPACE_END - -U_NAMESPACE_USE - -U_CAPI int32_t -u_formatMessage(const char *locale, - const UChar *pattern, - int32_t patternLength, - UChar *result, - int32_t resultLength, - UErrorCode *status, - ...) -{ - va_list ap; - int32_t actLen; - //argument checking defered to subsequent method calls - // start vararg processing - va_start(ap, status); - - actLen = u_vformatMessage(locale,pattern,patternLength,result,resultLength,ap,status); - // end vararg processing - va_end(ap); - - return actLen; -} - -U_CAPI int32_t U_EXPORT2 -u_vformatMessage( const char *locale, - const UChar *pattern, - int32_t patternLength, - UChar *result, - int32_t resultLength, - va_list ap, - UErrorCode *status) - -{ - //argument checking defered to subsequent method calls - UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); - int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); - umsg_close(fmt); - return retVal; -} - -U_CAPI int32_t -u_formatMessageWithError(const char *locale, - const UChar *pattern, - int32_t patternLength, - UChar *result, - int32_t resultLength, - UParseError *parseError, - UErrorCode *status, - ...) -{ - va_list ap; - int32_t actLen; - //argument checking defered to subsequent method calls - // start vararg processing - va_start(ap, status); - - actLen = u_vformatMessageWithError(locale,pattern,patternLength,result,resultLength,parseError,ap,status); - - // end vararg processing - va_end(ap); - return actLen; -} - -U_CAPI int32_t U_EXPORT2 -u_vformatMessageWithError( const char *locale, - const UChar *pattern, - int32_t patternLength, - UChar *result, - int32_t resultLength, - UParseError *parseError, - va_list ap, - UErrorCode *status) - -{ - //argument checking defered to subsequent method calls - UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,parseError,status); - int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); - umsg_close(fmt); - return retVal; -} - - -// For parse, do the reverse of format: -// 1. Call through to the C++ APIs -// 2. Just assume the user passed in enough arguments. -// 3. Iterate through each formattable returned, and assign to the arguments -U_CAPI void -u_parseMessage( const char *locale, - const UChar *pattern, - int32_t patternLength, - const UChar *source, - int32_t sourceLength, - UErrorCode *status, - ...) -{ - va_list ap; - //argument checking defered to subsequent method calls - - // start vararg processing - va_start(ap, status); - - u_vparseMessage(locale,pattern,patternLength,source,sourceLength,ap,status); - // end vararg processing - va_end(ap); -} - -U_CAPI void U_EXPORT2 -u_vparseMessage(const char *locale, - const UChar *pattern, - int32_t patternLength, - const UChar *source, - int32_t sourceLength, - va_list ap, - UErrorCode *status) -{ - //argument checking defered to subsequent method calls - UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); - int32_t count = 0; - umsg_vparse(fmt,source,sourceLength,&count,ap,status); - umsg_close(fmt); -} - -U_CAPI void -u_parseMessageWithError(const char *locale, - const UChar *pattern, - int32_t patternLength, - const UChar *source, - int32_t sourceLength, - UParseError *error, - UErrorCode *status, - ...) -{ - va_list ap; - - //argument checking defered to subsequent method calls - - // start vararg processing - va_start(ap, status); - - u_vparseMessageWithError(locale,pattern,patternLength,source,sourceLength,ap,error,status); - // end vararg processing - va_end(ap); -} -U_CAPI void U_EXPORT2 -u_vparseMessageWithError(const char *locale, - const UChar *pattern, - int32_t patternLength, - const UChar *source, - int32_t sourceLength, - va_list ap, - UParseError *error, - UErrorCode* status) -{ - //argument checking defered to subsequent method calls - UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,error,status); - int32_t count = 0; - umsg_vparse(fmt,source,sourceLength,&count,ap,status); - umsg_close(fmt); -} -////////////////////////////////////////////////////////////////////////////////// -// -// Message format C API -// -///////////////////////////////////////////////////////////////////////////////// - - -U_CAPI UMessageFormat* U_EXPORT2 -umsg_open( const UChar *pattern, - int32_t patternLength, - const char *locale, - UParseError *parseError, - UErrorCode *status) -{ - //check arguments - if(status==NULL || U_FAILURE(*status)) - { - return 0; - } - if(pattern==NULL||patternLength<-1){ - *status=U_ILLEGAL_ARGUMENT_ERROR; - return 0; - } - - UParseError tErr; - if(parseError==NULL) - { - parseError = &tErr; - } - - int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength); - UnicodeString patString(patternLength == -1, pattern, len); - - MessageFormat* retVal = new MessageFormat(patString,Locale(locale),*parseError,*status); - if(retVal == NULL) { - *status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - if (U_SUCCESS(*status) && MessageFormatAdapter::hasArgTypeConflicts(*retVal)) { - *status = U_ARGUMENT_TYPE_MISMATCH; - } - return (UMessageFormat*)retVal; -} - -U_CAPI void U_EXPORT2 -umsg_close(UMessageFormat* format) -{ - //check arguments - if(format==NULL){ - return; - } - delete (MessageFormat*) format; -} - -U_CAPI UMessageFormat U_EXPORT2 -umsg_clone(const UMessageFormat *fmt, - UErrorCode *status) -{ - //check arguments - if(status==NULL || U_FAILURE(*status)){ - return NULL; - } - if(fmt==NULL){ - *status = U_ILLEGAL_ARGUMENT_ERROR; - return NULL; - } - UMessageFormat retVal = (UMessageFormat)((MessageFormat*)fmt)->clone(); - if(retVal == 0) { - *status = U_MEMORY_ALLOCATION_ERROR; - return 0; - } - return retVal; -} - -U_CAPI void U_EXPORT2 -umsg_setLocale(UMessageFormat *fmt, const char* locale) -{ - //check arguments - if(fmt==NULL){ - return; - } - ((MessageFormat*)fmt)->setLocale(Locale(locale)); -} - -U_CAPI const char* U_EXPORT2 -umsg_getLocale(const UMessageFormat *fmt) -{ - //check arguments - if(fmt==NULL){ - return ""; - } - return ((const MessageFormat*)fmt)->getLocale().getName(); -} - -U_CAPI void U_EXPORT2 -umsg_applyPattern(UMessageFormat *fmt, - const UChar* pattern, - int32_t patternLength, - UParseError* parseError, - UErrorCode* status) -{ - //check arguments - UParseError tErr; - if(status ==NULL||U_FAILURE(*status)){ - return ; - } +* 08/5/2001 Ram Added C wrappers for C++ API. Changed implementation of old API's +* Removed pattern parser. +* +*/ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "unicode/umsg.h" +#include "unicode/ustring.h" +#include "unicode/fmtable.h" +#include "unicode/msgfmt.h" +#include "unicode/unistr.h" +#include "cpputils.h" +#include "uassert.h" +#include "ustr_imp.h" + +U_NAMESPACE_BEGIN +/** + * This class isolates our access to private internal methods of + * MessageFormat. It is never instantiated; it exists only for C++ + * access management. + */ +class MessageFormatAdapter { +public: + static const Formattable::Type* getArgTypeList(const MessageFormat& m, + int32_t& count); + static UBool hasArgTypeConflicts(const MessageFormat& m) { + return m.hasArgTypeConflicts; + } +}; +const Formattable::Type* +MessageFormatAdapter::getArgTypeList(const MessageFormat& m, + int32_t& count) { + return m.getArgTypeList(count); +} +U_NAMESPACE_END + +U_NAMESPACE_USE + +U_CAPI int32_t +u_formatMessage(const char *locale, + const UChar *pattern, + int32_t patternLength, + UChar *result, + int32_t resultLength, + UErrorCode *status, + ...) +{ + va_list ap; + int32_t actLen; + //argument checking defered to subsequent method calls + // start vararg processing + va_start(ap, status); + + actLen = u_vformatMessage(locale,pattern,patternLength,result,resultLength,ap,status); + // end vararg processing + va_end(ap); + + return actLen; +} + +U_CAPI int32_t U_EXPORT2 +u_vformatMessage( const char *locale, + const UChar *pattern, + int32_t patternLength, + UChar *result, + int32_t resultLength, + va_list ap, + UErrorCode *status) + +{ + //argument checking defered to subsequent method calls + UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); + int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); + umsg_close(fmt); + return retVal; +} + +U_CAPI int32_t +u_formatMessageWithError(const char *locale, + const UChar *pattern, + int32_t patternLength, + UChar *result, + int32_t resultLength, + UParseError *parseError, + UErrorCode *status, + ...) +{ + va_list ap; + int32_t actLen; + //argument checking defered to subsequent method calls + // start vararg processing + va_start(ap, status); + + actLen = u_vformatMessageWithError(locale,pattern,patternLength,result,resultLength,parseError,ap,status); + + // end vararg processing + va_end(ap); + return actLen; +} + +U_CAPI int32_t U_EXPORT2 +u_vformatMessageWithError( const char *locale, + const UChar *pattern, + int32_t patternLength, + UChar *result, + int32_t resultLength, + UParseError *parseError, + va_list ap, + UErrorCode *status) + +{ + //argument checking defered to subsequent method calls + UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,parseError,status); + int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); + umsg_close(fmt); + return retVal; +} + + +// For parse, do the reverse of format: +// 1. Call through to the C++ APIs +// 2. Just assume the user passed in enough arguments. +// 3. Iterate through each formattable returned, and assign to the arguments +U_CAPI void +u_parseMessage( const char *locale, + const UChar *pattern, + int32_t patternLength, + const UChar *source, + int32_t sourceLength, + UErrorCode *status, + ...) +{ + va_list ap; + //argument checking defered to subsequent method calls + + // start vararg processing + va_start(ap, status); + + u_vparseMessage(locale,pattern,patternLength,source,sourceLength,ap,status); + // end vararg processing + va_end(ap); +} + +U_CAPI void U_EXPORT2 +u_vparseMessage(const char *locale, + const UChar *pattern, + int32_t patternLength, + const UChar *source, + int32_t sourceLength, + va_list ap, + UErrorCode *status) +{ + //argument checking defered to subsequent method calls + UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); + int32_t count = 0; + umsg_vparse(fmt,source,sourceLength,&count,ap,status); + umsg_close(fmt); +} + +U_CAPI void +u_parseMessageWithError(const char *locale, + const UChar *pattern, + int32_t patternLength, + const UChar *source, + int32_t sourceLength, + UParseError *error, + UErrorCode *status, + ...) +{ + va_list ap; + + //argument checking defered to subsequent method calls + + // start vararg processing + va_start(ap, status); + + u_vparseMessageWithError(locale,pattern,patternLength,source,sourceLength,ap,error,status); + // end vararg processing + va_end(ap); +} +U_CAPI void U_EXPORT2 +u_vparseMessageWithError(const char *locale, + const UChar *pattern, + int32_t patternLength, + const UChar *source, + int32_t sourceLength, + va_list ap, + UParseError *error, + UErrorCode* status) +{ + //argument checking defered to subsequent method calls + UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,error,status); + int32_t count = 0; + umsg_vparse(fmt,source,sourceLength,&count,ap,status); + umsg_close(fmt); +} +////////////////////////////////////////////////////////////////////////////////// +// +// Message format C API +// +///////////////////////////////////////////////////////////////////////////////// + + +U_CAPI UMessageFormat* U_EXPORT2 +umsg_open( const UChar *pattern, + int32_t patternLength, + const char *locale, + UParseError *parseError, + UErrorCode *status) +{ + //check arguments + if(status==NULL || U_FAILURE(*status)) + { + return 0; + } + if(pattern==NULL||patternLength<-1){ + *status=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + UParseError tErr; + if(parseError==NULL) + { + parseError = &tErr; + } + + int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength); + UnicodeString patString(patternLength == -1, pattern, len); + + MessageFormat* retVal = new MessageFormat(patString,Locale(locale),*parseError,*status); + if(retVal == NULL) { + *status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + if (U_SUCCESS(*status) && MessageFormatAdapter::hasArgTypeConflicts(*retVal)) { + *status = U_ARGUMENT_TYPE_MISMATCH; + } + return (UMessageFormat*)retVal; +} + +U_CAPI void U_EXPORT2 +umsg_close(UMessageFormat* format) +{ + //check arguments + if(format==NULL){ + return; + } + delete (MessageFormat*) format; +} + +U_CAPI UMessageFormat U_EXPORT2 +umsg_clone(const UMessageFormat *fmt, + UErrorCode *status) +{ + //check arguments + if(status==NULL || U_FAILURE(*status)){ + return NULL; + } + if(fmt==NULL){ + *status = U_ILLEGAL_ARGUMENT_ERROR; + return NULL; + } + UMessageFormat retVal = (UMessageFormat)((MessageFormat*)fmt)->clone(); + if(retVal == 0) { + *status = U_MEMORY_ALLOCATION_ERROR; + return 0; + } + return retVal; +} + +U_CAPI void U_EXPORT2 +umsg_setLocale(UMessageFormat *fmt, const char* locale) +{ + //check arguments + if(fmt==NULL){ + return; + } + ((MessageFormat*)fmt)->setLocale(Locale(locale)); +} + +U_CAPI const char* U_EXPORT2 +umsg_getLocale(const UMessageFormat *fmt) +{ + //check arguments + if(fmt==NULL){ + return ""; + } + return ((const MessageFormat*)fmt)->getLocale().getName(); +} + +U_CAPI void U_EXPORT2 +umsg_applyPattern(UMessageFormat *fmt, + const UChar* pattern, + int32_t patternLength, + UParseError* parseError, + UErrorCode* status) +{ + //check arguments + UParseError tErr; + if(status ==NULL||U_FAILURE(*status)){ + return ; + } if(fmt==NULL || (pattern==NULL && patternLength!=0) || patternLength<-1) { - *status=U_ILLEGAL_ARGUMENT_ERROR; - return ; - } - - if(parseError==NULL){ - parseError = &tErr; - } - + *status=U_ILLEGAL_ARGUMENT_ERROR; + return ; + } + + if(parseError==NULL){ + parseError = &tErr; + } + // UnicodeString(pattern, -1) calls u_strlen(). - ((MessageFormat*)fmt)->applyPattern(UnicodeString(pattern,patternLength),*parseError,*status); -} - -U_CAPI int32_t U_EXPORT2 -umsg_toPattern(const UMessageFormat *fmt, - UChar* result, - int32_t resultLength, - UErrorCode* status) -{ - //check arguments - if(status ==NULL||U_FAILURE(*status)){ - return -1; - } - if(fmt==NULL||resultLength<0 || (resultLength>0 && result==0)){ - *status=U_ILLEGAL_ARGUMENT_ERROR; - return -1; - } - - - UnicodeString res; - if(!(result==NULL && resultLength==0)) { - // NULL destination for pure preflighting: empty dummy string - // otherwise, alias the destination buffer - res.setTo(result, 0, resultLength); - } - ((const MessageFormat*)fmt)->toPattern(res); - return res.extract(result, resultLength, *status); -} - -U_CAPI int32_t -umsg_format( const UMessageFormat *fmt, - UChar *result, - int32_t resultLength, - UErrorCode *status, - ...) -{ - va_list ap; - int32_t actLen; - //argument checking defered to last method call umsg_vformat which - //saves time when arguments are valid and we dont care when arguments are not - //since we return an error anyway - - - // start vararg processing - va_start(ap, status); - - actLen = umsg_vformat(fmt,result,resultLength,ap,status); - - // end vararg processing - va_end(ap); - - return actLen; -} - -U_CAPI int32_t U_EXPORT2 -umsg_vformat( const UMessageFormat *fmt, - UChar *result, - int32_t resultLength, - va_list ap, - UErrorCode *status) -{ - //check arguments - if(status==0 || U_FAILURE(*status)) - { - return -1; - } - if(fmt==NULL||resultLength<0 || (resultLength>0 && result==0)) { - *status=U_ILLEGAL_ARGUMENT_ERROR; - return -1; - } - - int32_t count =0; - const Formattable::Type* argTypes = - MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, count); - // Allocate at least one element. Allocating an array of length - // zero causes problems on some platforms (e.g. Win32). - Formattable* args = new Formattable[count ? count : 1]; - - // iterate through the vararg list, and get the arguments out - for(int32_t i = 0; i < count; ++i) { - - UChar *stringVal; - double tDouble=0; - int32_t tInt =0; - int64_t tInt64 = 0; - UDate tempDate = 0; - switch(argTypes[i]) { - case Formattable::kDate: - tempDate = va_arg(ap, UDate); - args[i].setDate(tempDate); - break; - - case Formattable::kDouble: - tDouble =va_arg(ap, double); - args[i].setDouble(tDouble); - break; - - case Formattable::kLong: - tInt = va_arg(ap, int32_t); - args[i].setLong(tInt); - break; - - case Formattable::kInt64: - tInt64 = va_arg(ap, int64_t); - args[i].setInt64(tInt64); - break; - - case Formattable::kString: - // For some reason, a temporary is needed - stringVal = va_arg(ap, UChar*); - if(stringVal){ - args[i].setString(UnicodeString(stringVal)); - }else{ - *status=U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kArray: - // throw away this argument - // this is highly platform-dependent, and probably won't work - // so, if you try to skip arguments in the list (and not use them) - // you'll probably crash - va_arg(ap, int); - break; - - case Formattable::kObject: - // Unused argument number. Read and ignore a pointer argument. - va_arg(ap, void*); - break; - - default: - // Unknown/unsupported argument type. + ((MessageFormat*)fmt)->applyPattern(UnicodeString(pattern,patternLength),*parseError,*status); +} + +U_CAPI int32_t U_EXPORT2 +umsg_toPattern(const UMessageFormat *fmt, + UChar* result, + int32_t resultLength, + UErrorCode* status) +{ + //check arguments + if(status ==NULL||U_FAILURE(*status)){ + return -1; + } + if(fmt==NULL||resultLength<0 || (resultLength>0 && result==0)){ + *status=U_ILLEGAL_ARGUMENT_ERROR; + return -1; + } + + + UnicodeString res; + if(!(result==NULL && resultLength==0)) { + // NULL destination for pure preflighting: empty dummy string + // otherwise, alias the destination buffer + res.setTo(result, 0, resultLength); + } + ((const MessageFormat*)fmt)->toPattern(res); + return res.extract(result, resultLength, *status); +} + +U_CAPI int32_t +umsg_format( const UMessageFormat *fmt, + UChar *result, + int32_t resultLength, + UErrorCode *status, + ...) +{ + va_list ap; + int32_t actLen; + //argument checking defered to last method call umsg_vformat which + //saves time when arguments are valid and we dont care when arguments are not + //since we return an error anyway + + + // start vararg processing + va_start(ap, status); + + actLen = umsg_vformat(fmt,result,resultLength,ap,status); + + // end vararg processing + va_end(ap); + + return actLen; +} + +U_CAPI int32_t U_EXPORT2 +umsg_vformat( const UMessageFormat *fmt, + UChar *result, + int32_t resultLength, + va_list ap, + UErrorCode *status) +{ + //check arguments + if(status==0 || U_FAILURE(*status)) + { + return -1; + } + if(fmt==NULL||resultLength<0 || (resultLength>0 && result==0)) { + *status=U_ILLEGAL_ARGUMENT_ERROR; + return -1; + } + + int32_t count =0; + const Formattable::Type* argTypes = + MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, count); + // Allocate at least one element. Allocating an array of length + // zero causes problems on some platforms (e.g. Win32). + Formattable* args = new Formattable[count ? count : 1]; + + // iterate through the vararg list, and get the arguments out + for(int32_t i = 0; i < count; ++i) { + + UChar *stringVal; + double tDouble=0; + int32_t tInt =0; + int64_t tInt64 = 0; + UDate tempDate = 0; + switch(argTypes[i]) { + case Formattable::kDate: + tempDate = va_arg(ap, UDate); + args[i].setDate(tempDate); + break; + + case Formattable::kDouble: + tDouble =va_arg(ap, double); + args[i].setDouble(tDouble); + break; + + case Formattable::kLong: + tInt = va_arg(ap, int32_t); + args[i].setLong(tInt); + break; + + case Formattable::kInt64: + tInt64 = va_arg(ap, int64_t); + args[i].setInt64(tInt64); + break; + + case Formattable::kString: + // For some reason, a temporary is needed + stringVal = va_arg(ap, UChar*); + if(stringVal){ + args[i].setString(UnicodeString(stringVal)); + }else{ + *status=U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kArray: + // throw away this argument + // this is highly platform-dependent, and probably won't work + // so, if you try to skip arguments in the list (and not use them) + // you'll probably crash + va_arg(ap, int); + break; + + case Formattable::kObject: + // Unused argument number. Read and ignore a pointer argument. + va_arg(ap, void*); + break; + + default: + // Unknown/unsupported argument type. UPRV_UNREACHABLE; - } - } - UnicodeString resultStr; - FieldPosition fieldPosition(FieldPosition::DONT_CARE); - - /* format the message */ - ((const MessageFormat*)fmt)->format(args,count,resultStr,fieldPosition,*status); - - delete[] args; - - if(U_FAILURE(*status)){ - return -1; - } - - return resultStr.extract(result, resultLength, *status); -} - -U_CAPI void -umsg_parse( const UMessageFormat *fmt, - const UChar *source, - int32_t sourceLength, - int32_t *count, - UErrorCode *status, - ...) -{ - va_list ap; - //argument checking defered to last method call umsg_vparse which - //saves time when arguments are valid and we dont care when arguments are not - //since we return an error anyway - - // start vararg processing - va_start(ap, status); - - umsg_vparse(fmt,source,sourceLength,count,ap,status); - - // end vararg processing - va_end(ap); -} - -U_CAPI void U_EXPORT2 -umsg_vparse(const UMessageFormat *fmt, - const UChar *source, - int32_t sourceLength, - int32_t *count, - va_list ap, - UErrorCode *status) -{ - //check arguments - if(status==NULL||U_FAILURE(*status)) - { - return; - } - if(fmt==NULL||source==NULL || sourceLength<-1 || count==NULL){ - *status=U_ILLEGAL_ARGUMENT_ERROR; - return; - } - if(sourceLength==-1){ - sourceLength=u_strlen(source); - } - - UnicodeString srcString(source,sourceLength); - Formattable *args = ((const MessageFormat*)fmt)->parse(srcString,*count,*status); - UDate *aDate; - double *aDouble; - UChar *aString; - int32_t* aInt; - int64_t* aInt64; - UnicodeString temp; - int len =0; - // assign formattables to varargs - for(int32_t i = 0; i < *count; i++) { - switch(args[i].getType()) { - - case Formattable::kDate: - aDate = va_arg(ap, UDate*); - if(aDate){ - *aDate = args[i].getDate(); - }else{ - *status=U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kDouble: - aDouble = va_arg(ap, double*); - if(aDouble){ - *aDouble = args[i].getDouble(); - }else{ - *status=U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kLong: - aInt = va_arg(ap, int32_t*); - if(aInt){ - *aInt = (int32_t) args[i].getLong(); - }else{ - *status=U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kInt64: - aInt64 = va_arg(ap, int64_t*); - if(aInt64){ - *aInt64 = args[i].getInt64(); - }else{ - *status=U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kString: - aString = va_arg(ap, UChar*); - if(aString){ - args[i].getString(temp); - len = temp.length(); - temp.extract(0,len,aString); - aString[len]=0; - }else{ - *status= U_ILLEGAL_ARGUMENT_ERROR; - } - break; - - case Formattable::kObject: - // This will never happen because MessageFormat doesn't - // support kObject. When MessageFormat is changed to - // understand MeasureFormats, modify this code to do the - // right thing. [alan] + } + } + UnicodeString resultStr; + FieldPosition fieldPosition(FieldPosition::DONT_CARE); + + /* format the message */ + ((const MessageFormat*)fmt)->format(args,count,resultStr,fieldPosition,*status); + + delete[] args; + + if(U_FAILURE(*status)){ + return -1; + } + + return resultStr.extract(result, resultLength, *status); +} + +U_CAPI void +umsg_parse( const UMessageFormat *fmt, + const UChar *source, + int32_t sourceLength, + int32_t *count, + UErrorCode *status, + ...) +{ + va_list ap; + //argument checking defered to last method call umsg_vparse which + //saves time when arguments are valid and we dont care when arguments are not + //since we return an error anyway + + // start vararg processing + va_start(ap, status); + + umsg_vparse(fmt,source,sourceLength,count,ap,status); + + // end vararg processing + va_end(ap); +} + +U_CAPI void U_EXPORT2 +umsg_vparse(const UMessageFormat *fmt, + const UChar *source, + int32_t sourceLength, + int32_t *count, + va_list ap, + UErrorCode *status) +{ + //check arguments + if(status==NULL||U_FAILURE(*status)) + { + return; + } + if(fmt==NULL||source==NULL || sourceLength<-1 || count==NULL){ + *status=U_ILLEGAL_ARGUMENT_ERROR; + return; + } + if(sourceLength==-1){ + sourceLength=u_strlen(source); + } + + UnicodeString srcString(source,sourceLength); + Formattable *args = ((const MessageFormat*)fmt)->parse(srcString,*count,*status); + UDate *aDate; + double *aDouble; + UChar *aString; + int32_t* aInt; + int64_t* aInt64; + UnicodeString temp; + int len =0; + // assign formattables to varargs + for(int32_t i = 0; i < *count; i++) { + switch(args[i].getType()) { + + case Formattable::kDate: + aDate = va_arg(ap, UDate*); + if(aDate){ + *aDate = args[i].getDate(); + }else{ + *status=U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kDouble: + aDouble = va_arg(ap, double*); + if(aDouble){ + *aDouble = args[i].getDouble(); + }else{ + *status=U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kLong: + aInt = va_arg(ap, int32_t*); + if(aInt){ + *aInt = (int32_t) args[i].getLong(); + }else{ + *status=U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kInt64: + aInt64 = va_arg(ap, int64_t*); + if(aInt64){ + *aInt64 = args[i].getInt64(); + }else{ + *status=U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kString: + aString = va_arg(ap, UChar*); + if(aString){ + args[i].getString(temp); + len = temp.length(); + temp.extract(0,len,aString); + aString[len]=0; + }else{ + *status= U_ILLEGAL_ARGUMENT_ERROR; + } + break; + + case Formattable::kObject: + // This will never happen because MessageFormat doesn't + // support kObject. When MessageFormat is changed to + // understand MeasureFormats, modify this code to do the + // right thing. [alan] UPRV_UNREACHABLE; - - // better not happen! - case Formattable::kArray: + + // better not happen! + case Formattable::kArray: UPRV_UNREACHABLE; - } - } - - // clean up - delete [] args; -} - -#define SINGLE_QUOTE ((UChar)0x0027) -#define CURLY_BRACE_LEFT ((UChar)0x007B) -#define CURLY_BRACE_RIGHT ((UChar)0x007D) - -#define STATE_INITIAL 0 -#define STATE_SINGLE_QUOTE 1 -#define STATE_IN_QUOTE 2 -#define STATE_MSG_ELEMENT 3 - -#define MAppend(c) if (len < destCapacity) dest[len++] = c; else len++ - -int32_t umsg_autoQuoteApostrophe(const UChar* pattern, - int32_t patternLength, - UChar* dest, - int32_t destCapacity, - UErrorCode* ec) -{ - int32_t state = STATE_INITIAL; - int32_t braceCount = 0; - int32_t len = 0; - - if (ec == NULL || U_FAILURE(*ec)) { - return -1; - } - - if (pattern == NULL || patternLength < -1 || (dest == NULL && destCapacity > 0)) { - *ec = U_ILLEGAL_ARGUMENT_ERROR; - return -1; - } - U_ASSERT(destCapacity >= 0); - - if (patternLength == -1) { - patternLength = u_strlen(pattern); - } - - for (int i = 0; i < patternLength; ++i) { - UChar c = pattern[i]; - switch (state) { - case STATE_INITIAL: - switch (c) { - case SINGLE_QUOTE: - state = STATE_SINGLE_QUOTE; - break; - case CURLY_BRACE_LEFT: - state = STATE_MSG_ELEMENT; - ++braceCount; - break; - } - break; - - case STATE_SINGLE_QUOTE: - switch (c) { - case SINGLE_QUOTE: - state = STATE_INITIAL; - break; - case CURLY_BRACE_LEFT: - case CURLY_BRACE_RIGHT: - state = STATE_IN_QUOTE; - break; - default: - MAppend(SINGLE_QUOTE); - state = STATE_INITIAL; - break; - } - break; - - case STATE_IN_QUOTE: - switch (c) { - case SINGLE_QUOTE: - state = STATE_INITIAL; - break; - } - break; - - case STATE_MSG_ELEMENT: - switch (c) { - case CURLY_BRACE_LEFT: - ++braceCount; - break; - case CURLY_BRACE_RIGHT: - if (--braceCount == 0) { - state = STATE_INITIAL; - } - break; - } - break; - - default: // Never happens. - break; - } - - U_ASSERT(len >= 0); - MAppend(c); - } - - // End of scan - if (state == STATE_SINGLE_QUOTE || state == STATE_IN_QUOTE) { - MAppend(SINGLE_QUOTE); - } - - return u_terminateUChars(dest, destCapacity, len, ec); -} - -#endif /* #if !UCONFIG_NO_FORMATTING */ + } + } + + // clean up + delete [] args; +} + +#define SINGLE_QUOTE ((UChar)0x0027) +#define CURLY_BRACE_LEFT ((UChar)0x007B) +#define CURLY_BRACE_RIGHT ((UChar)0x007D) + +#define STATE_INITIAL 0 +#define STATE_SINGLE_QUOTE 1 +#define STATE_IN_QUOTE 2 +#define STATE_MSG_ELEMENT 3 + +#define MAppend(c) if (len < destCapacity) dest[len++] = c; else len++ + +int32_t umsg_autoQuoteApostrophe(const UChar* pattern, + int32_t patternLength, + UChar* dest, + int32_t destCapacity, + UErrorCode* ec) +{ + int32_t state = STATE_INITIAL; + int32_t braceCount = 0; + int32_t len = 0; + + if (ec == NULL || U_FAILURE(*ec)) { + return -1; + } + + if (pattern == NULL || patternLength < -1 || (dest == NULL && destCapacity > 0)) { + *ec = U_ILLEGAL_ARGUMENT_ERROR; + return -1; + } + U_ASSERT(destCapacity >= 0); + + if (patternLength == -1) { + patternLength = u_strlen(pattern); + } + + for (int i = 0; i < patternLength; ++i) { + UChar c = pattern[i]; + switch (state) { + case STATE_INITIAL: + switch (c) { + case SINGLE_QUOTE: + state = STATE_SINGLE_QUOTE; + break; + case CURLY_BRACE_LEFT: + state = STATE_MSG_ELEMENT; + ++braceCount; + break; + } + break; + + case STATE_SINGLE_QUOTE: + switch (c) { + case SINGLE_QUOTE: + state = STATE_INITIAL; + break; + case CURLY_BRACE_LEFT: + case CURLY_BRACE_RIGHT: + state = STATE_IN_QUOTE; + break; + default: + MAppend(SINGLE_QUOTE); + state = STATE_INITIAL; + break; + } + break; + + case STATE_IN_QUOTE: + switch (c) { + case SINGLE_QUOTE: + state = STATE_INITIAL; + break; + } + break; + + case STATE_MSG_ELEMENT: + switch (c) { + case CURLY_BRACE_LEFT: + ++braceCount; + break; + case CURLY_BRACE_RIGHT: + if (--braceCount == 0) { + state = STATE_INITIAL; + } + break; + } + break; + + default: // Never happens. + break; + } + + U_ASSERT(len >= 0); + MAppend(c); + } + + // End of scan + if (state == STATE_SINGLE_QUOTE || state == STATE_IN_QUOTE) { + MAppend(SINGLE_QUOTE); + } + + return u_terminateUChars(dest, destCapacity, len, ec); +} + +#endif /* #if !UCONFIG_NO_FORMATTING */ |