1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #if defined XALAN_ICU_MSG_LOADER
20
21
22 // Class header file.
23 #include "XalanICUMessageLoader.hpp"
24
25 #include "PlatformSupportInit.hpp"
26
27 #include "DOMStringHelper.hpp"
28
29 #include "unicode/uloc.h"
30
31 #include "unicode/udata.h"
32
33 #include <xercesc/util/XMLMsgLoader.hpp>
34
35 #include <xercesc/util/XMLString.hpp>
36
37 #include "xalanc/Include/XalanVersion.hpp"
38
39 #if defined(XALAN_WINDOWS)
40 #define XALAN_MESSAGES_NAME XalanMessages
41 #else
42 #define XALAN_MESSAGES_NAME xalanMsg
43 #endif
44
45 #define XALAN_MESSAGES_NAME_W_UNDERSCORE INVK_CAT2_RAW_NUMERIC(XALAN_MESSAGES_NAME,_)
46
47 #define MAKE_STRING(a) #a
48 #define INVK_MAKE_STRING(a) MAKE_STRING(a)
49
50 #if defined(XALAN_WINDOWS)
51
52 #if _MSC_VER >= 1400
53
54 #define ENTRY_POINT_SUFFIX _dat
55 #define PACKAGE_NAME_SUFFIX
56
57 #else
58 #ifdef NDEBUG_SYMBOLS // release with symbols
59
60 #define ENTRY_POINT_SUFFIX S_dat
61 #define PACKAGE_NAME_SUFFIX S
62
63 #elif NDEBUG // release
64
65 #define ENTRY_POINT_SUFFIX _dat
66 #define PACKAGE_NAME_SUFFIX
67
68 #elif _DEBUG // debug only
69
70 #define ENTRY_POINT_SUFFIX D_dat
71 #define PACKAGE_NAME_SUFFIX D
72
73 #endif // NDEBUG_SYMBOLS
74 #endif // _MSC_VER >= 1400
75
76 #define PACKAGE_NAME INVK_CAT3_RAW_NUMERIC(XALAN_MESSAGES_NAME_W_UNDERSCORE,\
77 INVK_CAT2_RAW_NUMERIC_SEP_UNDERSCORE(XALAN_VERSION_MAJOR,XALAN_VERSION_MINOR),\
78 PACKAGE_NAME_SUFFIX)
79
80 #define ICUDLL_ENTRYPOINT_NAME INVK_CAT3_RAW_NUMERIC(XALAN_MESSAGES_NAME_W_UNDERSCORE,\
81 INVK_CAT2_RAW_NUMERIC_SEP_UNDERSCORE(XALAN_VERSION_MAJOR,XALAN_VERSION_MINOR),\
82 ENTRY_POINT_SUFFIX)
83
84 #else // NON-WINDOWS systems
85
86 #define ICUDLL_ENTRYPOINT_NAME INVK_CAT2_RAW_NUMERIC(XALAN_MESSAGES_NAME_W_UNDERSCORE,dat)
87
88 #define PACKAGE_NAME XALAN_MESSAGES_NAME
89
90 #endif // XALAN_WINDOWS
91
92 static const char* const sPackageName=INVK_MAKE_STRING(PACKAGE_NAME);
93
94 extern "C" const char U_IMPORT ICUDLL_ENTRYPOINT_NAME [];
95
96
97 namespace XALAN_CPP_NAMESPACE {
98
99 using xercesc::XMLMsgLoader;
100
101 using xercesc::XMLString;
102
103
104
105 // ---------------------------------------------------------------------------
106 // Local static methods
107 // ---------------------------------------------------------------------------
108
109 /*
110 * Resource Data Reference.
111 *
112 * The data is packaged as a dll (or .so or whatever, depending on the platform) that exports a data symbol.
113 * The application (thic *.cpp) references that symbol here, and will pass the data address to ICU, which
114 * will then be able to fetch resources from the data.
115 */
116
117
118 static const char* domainName = INVK_MAKE_STRING(XALAN_PRODUCT);
119
120
121
XalanICUMessageLoader(MemoryManager & theManager)122 XalanICUMessageLoader::XalanICUMessageLoader(MemoryManager &theManager):
123 m_localeBundle(0),
124 m_domainBundle(0),
125 m_unknownMessage("The message was not found in the ICU resource bundle.", theManager)
126 {
127 UErrorCode err = U_ZERO_ERROR;
128
129 udata_setAppData(sPackageName, &ICUDLL_ENTRYPOINT_NAME, &err);
130
131 if (! U_SUCCESS(err))
132 {
133 assert( 0 );
134 }
135 const char* szLocal = XMLMsgLoader::getLocale();
136 if ( szLocal == 0 )
137 {
138 // We failed to get local from Xerces, let's try our own default.
139 szLocal="en_US";
140 }
141
142 m_localeBundle = ures_open(sPackageName, szLocal , &err);
143 if (!U_SUCCESS(err) || m_localeBundle == 0)
144 {
145 assert( 0 );
146 }
147
148 err = U_ZERO_ERROR;
149 m_domainBundle = ures_getByKey(m_localeBundle, domainName, 0, &err);
150 if (!U_SUCCESS(err) || m_domainBundle == 0)
151 {
152 assert( 0 );
153 }
154 }
155
156
157
~XalanICUMessageLoader()158 XalanICUMessageLoader::~XalanICUMessageLoader()
159 {
160 ures_close(m_domainBundle);
161 ures_close(m_localeBundle);
162 }
163
164
165
loadMsg(XalanMessages::Codes msgToLoad,XalanDOMChar * toFill,XalanSize_t maxChars)166 bool XalanICUMessageLoader::loadMsg(
167 XalanMessages::Codes msgToLoad,
168 XalanDOMChar* toFill,
169 XalanSize_t maxChars)
170 {
171 bool bResult = true;
172 UErrorCode err = U_ZERO_ERROR;
173 int32_t strLen = 0;
174
175 // Assuming array format
176 const UChar * const name = ures_getStringByIndex(m_domainBundle, (int32_t)msgToLoad+1, &strLen, &err);
177
178 if (!U_SUCCESS(err) || (name == 0))
179 {
180 XalanCopy(m_unknownMessage.c_str(), m_unknownMessage.c_str() + m_unknownMessage.length() + 1, toFill);
181
182 return false;
183 }
184
185 const XalanSize_t retStrLen =
186 static_cast<XalanSize_t>(strLen + 1 ) > maxChars ? maxChars : static_cast<XalanSize_t>(strLen + 1);
187
188 XalanCopy(name, name + retStrLen, toFill);
189
190 return bResult;
191 }
192
193 }
194
195 #endif // defined (XALAN_ICU_MSG_LOADER)
196
197
198
199