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: staticconst 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
// 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( constchar *locale, const char16_t *pattern,
int32_t patternLength, const char16_t *source,
int32_t sourceLength,
UErrorCode *status,
...)
{
va_list ap; //argument checking deferred 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);
}
UnicodeString res; if(!(result==nullptr && resultLength==0)) { // nullptr 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,
char16_t *result,
int32_t resultLength,
UErrorCode *status,
...)
{
va_list ap;
int32_t actLen; //argument checking deferred to last method call umsg_vformat which //saves time when arguments are valid and we don't care when arguments are not //since we return an error anyway
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) {
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, char16_t*); 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;
U_CAPI void
umsg_parse( const UMessageFormat *fmt, const char16_t *source,
int32_t sourceLength,
int32_t *count,
UErrorCode *status,
...)
{
va_list ap; //argument checking deferred to last method call umsg_vparse which //saves time when arguments are valid and we don't care when arguments are not //since we return an error anyway
case Formattable::kString:
aString = va_arg(ap, char16_t*); 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_EXIT;
// better not happen! case Formattable::kArray:
UPRV_UNREACHABLE_EXIT;
}
}
if (patternLength == -1) {
patternLength = u_strlen(pattern);
}
for (int i = 0; i < patternLength; ++i) {
char16_t 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);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.19Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.