📄 messageloader.cpp
字号:
// possible errors, ex: message path incorrect // for now do nothing, let the while loop continue } status = U_ZERO_ERROR; // reset status } // now if we DIDN'T open a resource bundle, we want to enable ICU // fallback for the highest priority language if (acceptlanguages.size() > 0) { PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "No message was loaded, using ICU fallback behaviour."); languageTag = acceptlanguages.getLanguageTag(0);#ifdef PEGASUS_OS_OS400 CString cstr = languageTag.toString().getCString(); const char *atoe = cstr; AtoE((char*)atoe); uloc_getName(atoe, locale_ICU, size_locale_ICU, &status);#else uloc_getName( (const char*)(languageTag.toString()).getCString(), locale_ICU, size_locale_ICU, &status);#endif status = U_ZERO_ERROR; parms._resbundl = ures_open((const char*)resbundl_path_ICU, locale_ICU, &status); const char* _locale = NULL; if (U_SUCCESS(status)) { if (status == U_USING_DEFAULT_WARNING) { PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "PRIORITY ICU FALLBACK: using default resource bundle " "with "); PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, languageTag.toString()); status = U_ZERO_ERROR; // Reopen the bundle in the root locale ures_close(parms._resbundl); parms._resbundl = ures_open((const char*)resbundl_path_ICU, "", &status); if (U_SUCCESS(status)) { _locale = ures_getLocale(parms._resbundl,&status); } } else { _locale = ures_getLocale(parms._resbundl,&status); } String localeStr; if (_locale != NULL) {#ifdef PEGASUS_OS_OS400 char tmplcl[size_locale_ICU]; strcpy(tmplcl, _locale); EtoA(tmplcl); localeStr.assign(tmplcl);#else localeStr.assign(_locale);#endif } // The "root" locale indicates that an ICU message bundle is not present // for the current locale setting. if (localeStr != "root") { parms.contentlanguages.append(LanguageTag( LanguageParser::convertLocaleIdToLanguageTag( localeStr))); } if (_locale != NULL) { PEG_METHOD_EXIT(); return; } } } { // else if no message, load message from root bundle explicitly PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "EXHAUSTED ACCEPTLANGUAGES: using root bundle to extract message"); status = U_ZERO_ERROR; parms._resbundl = ures_open((const char*)resbundl_path_ICU, "", &status); if (U_SUCCESS(status)) { PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "EXHAUSTED ACCEPTLANGUAGES: opened root resource bundle"); } else { PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "EXHAUSTED ACCEPTLANGUAGES: could NOT open root resource " "bundle"); parms._resbundl = NO_ICU_MAGIC; } } PEG_METHOD_EXIT(); return;}String MessageLoader::extractICUMessage( UResourceBundle* resbundl, MessageLoaderParms& parms){ UErrorCode status = U_ZERO_ERROR; int32_t msgLen = 0;#ifdef PEGASUS_OS_OS400 CString cstr = parms.msg_id.getCString(); const char* atoe = cstr; AtoE((char*)atoe); const UChar* msg = ures_getStringByKey(resbundl, (const char*)atoe, &msgLen, &status);#else const UChar* msg = ures_getStringByKey( resbundl, (const char*)parms.msg_id.getCString(), &msgLen, &status);#endif if (U_FAILURE(status)) { return String::EMPTY; } return formatICUMessage(resbundl, msg, msgLen, parms);}String MessageLoader::uChar2String(UChar* uchar_str){ return String((const Char16 *)uchar_str);}String MessageLoader::uChar2String(UChar* uchar_str, int len){ return String((const Char16 *)uchar_str, len);}String MessageLoader::formatICUMessage( UResourceBundle* resbundl, const UChar* msg, int msg_len, MessageLoaderParms& parms){ // format the message UnicodeString msg_pattern(msg, msg_len); UnicodeString msg_formatted; UErrorCode status = U_ZERO_ERROR; const int arg_count = 10; const char *locale; if (resbundl == NULL) locale = ULOC_US; else locale = ures_getLocale(resbundl, &status); char lang[4]; char cc[4]; char var[arg_count]; uloc_getLanguage(locale, lang, 4, &status); uloc_getCountry(locale, cc, 4, &status); uloc_getVariant(locale, var, 10, &status); Locale localeID(lang,cc,var); status = U_ZERO_ERROR; MessageFormat formatter(msg_pattern, localeID, status); Formattable args[arg_count]; if (parms.arg0._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg0, args[0]); if (parms.arg1._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg1, args[1]); if (parms.arg2._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg2, args[2]); if (parms.arg3._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg3, args[3]); if (parms.arg4._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg4, args[4]); if (parms.arg5._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg5, args[5]); if (parms.arg6._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg6, args[6]); if (parms.arg7._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg7, args[7]); if (parms.arg8._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg8, args[8]); if (parms.arg9._type != Formatter::Arg::VOIDT) xferFormattable(parms.arg9, args[9]); Formattable args_obj(args,arg_count); status = U_ZERO_ERROR; msg_formatted = formatter.format(args_obj, msg_formatted, status); return uChar2String( const_cast<UChar*>(msg_formatted.getBuffer()), msg_formatted.length());}void MessageLoader::xferFormattable( Formatter::Arg &arg, Formattable& formattable){ //cout << "arg" << " = " << arg.toString() << endl; switch (arg._type) { case Formatter::Arg::INTEGER: formattable = (int32_t)arg._integer; break; case Formatter::Arg::UINTEGER: // Note: the ICU Formattable class doesn't support // unsigned 32. Cast to signed 64. formattable = (int64_t)arg._uinteger; break; case Formatter::Arg::BOOLEAN: // Note: the ICU formattable class doesn't support // boolean. Turn it into a string. if (!arg._boolean) formattable = Formattable("false"); else formattable = Formattable("true"); break; case Formatter::Arg::REAL: formattable = (double)arg._real; break; case Formatter::Arg::LINTEGER: // Note: this uses a Formattable constructor that is // labelled ICU 2.8 draft. Assumes that Pegasus uses // at least ICU 2.8. formattable = (int64_t)arg._lInteger; break; case Formatter::Arg::ULINTEGER: // Note: the ICU Formattable class doesn't support // unsigned 64. If the number is too big for signed 64 // then turn it into a string. This string will // not be formatted for the locale, but at least the number // will appear in the message. if (arg._lUInteger > PEGASUS_UINT64_LITERAL(0x7FFFFFFFFFFFFFFF)) { char buffer[32]; // Should need 21 chars max sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", arg._lUInteger); formattable = Formattable(buffer); } else { formattable = (int64_t)arg._lUInteger; } break; case Formatter::Arg::STRING: formattable = Formattable((UChar*)arg._string.getChar16Data()); break; case Formatter::Arg::VOIDT: default: formattable = ""; break; }}#endifString MessageLoader::formatDefaultMessage(MessageLoaderParms& parms){ PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::formatDefaultMessage"); // NOTE TO PROGRAMMERS: using native substitution functions // ie. calling Formatter::format() // can result in incorrect locale handling of substitutions // locale INSENSITIVE formatting code // this could have previously been set by ICU parms.contentlanguages.clear(); PEG_METHOD_EXIT(); return Formatter::format( parms.default_msg, parms.arg0, parms.arg1, parms.arg2, parms.arg3, parms.arg4, parms.arg5, parms.arg6, parms.arg7, parms.arg8, parms.arg9);}String MessageLoader::getQualifiedMsgPath(String path){ PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::getQualifiedMsgPath"); if (pegasus_MSG_HOME.size() == 0) initPegasusMsgHome(String::EMPTY); if (path.size() == 0) { PEG_METHOD_EXIT(); return pegasus_MSG_HOME + server_resbundl_name; } // NOTE TO PROGRAMMERS: WINDOWS and non-UNIX platforms should // redefine delim here Char16 delim = '/'; Uint32 i; if ((i = path.find(delim)) != PEG_NOT_FOUND && i == 0) { // fully qualified package name PEG_METHOD_EXIT(); return path; } PEG_METHOD_EXIT(); return pegasus_MSG_HOME + path; // relative path and package name}void MessageLoader::setPegasusMsgHome(String home){ PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::setPegasusMsgHome"); pegasus_MSG_HOME = home + "/"; // TODO: remove the next call once test cases are compatible with ICU // messages checkDefaultMsgLoading(); PEG_METHOD_EXIT();}void MessageLoader::setPegasusMsgHomeRelative(const String& argv0){#ifdef PEGASUS_HAS_MESSAGES try { String startingDir, pathDir;#ifdef PEGASUS_OS_TYPE_WINDOWS if (PEG_NOT_FOUND == argv0.find('\\')) { char exeDir[_MAX_PATH]; HMODULE module = GetModuleHandle(NULL); if (NULL != module ) { DWORD filename = GetModuleFileName(module,exeDir ,sizeof(exeDir)); if (0 != filename) { String path(exeDir); Uint32 command = path.reverseFind('\\'); startingDir = path.subString(0, command+1); } } } else { Uint32 command = argv0.reverseFind('\\'); startingDir = argv0.subString(0, command+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -