GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: Win32MsgLoader.cpp 570552 2007-08-28 19:57:36Z amassari $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <windows.h> 00027 00028 #include <xercesc/util/PlatformUtils.hpp> 00029 #include <xercesc/util/XMLMsgLoader.hpp> 00030 #include <xercesc/util/XMLString.hpp> 00031 #include <xercesc/util/XMLUni.hpp> 00032 #include "Win32MsgLoader.hpp" 00033 00034 00035 // Function prototypes 00036 BOOL APIENTRY DllMain(HINSTANCE hModule, 00037 DWORD ul_reason_for_call, 00038 LPVOID lpReserved); 00039 00040 00041 // --------------------------------------------------------------------------- 00042 // Public Constructors and Destructor 00043 // --------------------------------------------------------------------------- 00044 HINSTANCE globalModuleHandle; 00045 00046 BOOL APIENTRY DllMain(HINSTANCE hModule, 00047 DWORD ul_reason_for_call, 00048 LPVOID /*lpReserved*/) 00049 { 00050 switch (ul_reason_for_call) { 00051 case DLL_PROCESS_ATTACH: 00052 globalModuleHandle = hModule; 00053 break; 00054 case DLL_THREAD_ATTACH: 00055 break; 00056 case DLL_THREAD_DETACH: 00057 break; 00058 case DLL_PROCESS_DETACH: 00059 break; 00060 } 00061 return TRUE; 00062 } 00063 00064 XERCES_CPP_NAMESPACE_BEGIN 00065 00066 // --------------------------------------------------------------------------- 00067 // Global module handle 00068 // --------------------------------------------------------------------------- 00069 Win32MsgLoader::Win32MsgLoader(const XMLCh* const msgDomain) : 00070 00071 fDomainOfs(0) 00072 , fModHandle(0) 00073 , fMsgDomain(0) 00074 { 00075 // Try to get the module handle 00076 fModHandle = globalModuleHandle; 00077 if (!fModHandle) 00078 { 00079 // 00080 // If we didn't find it, its probably because its a development 00081 // build which is built as separate DLLs, so lets look for the DLL 00082 // that we are part of. 00083 // 00084 static const char* const privDLLName = "IXUTIL"; 00085 fModHandle = ::GetModuleHandleA(privDLLName); 00086 00087 // If neither exists, then we give up 00088 if (!fModHandle) 00089 { 00090 // Probably have to call panic here 00091 } 00092 } 00093 00094 // Store the domain name 00095 fMsgDomain = XMLString::replicate(msgDomain, XMLPlatformUtils::fgMemoryManager); 00096 00097 // And precalc the id offset we use for this domain 00098 if (XMLString::equals(fMsgDomain, XMLUni::fgXMLErrDomain)) 00099 fDomainOfs = 0; 00100 else if (XMLString::equals(fMsgDomain, XMLUni::fgExceptDomain)) 00101 fDomainOfs = 0x2000; 00102 else if (XMLString::equals(fMsgDomain, XMLUni::fgValidityDomain)) 00103 fDomainOfs = 0x4000; 00104 else if (XMLString::equals(fMsgDomain, XMLUni::fgXMLDOMMsgDomain)) 00105 fDomainOfs = 0x6000; 00106 else 00107 XMLPlatformUtils::panic(PanicHandler::Panic_UnknownMsgDomain); 00108 } 00109 00110 Win32MsgLoader::~Win32MsgLoader() 00111 { 00112 XMLPlatformUtils::fgMemoryManager->deallocate(fMsgDomain);//delete [] fMsgDomain; 00113 } 00114 00115 00116 // --------------------------------------------------------------------------- 00117 // Implementation of the virtual message loader API 00118 // --------------------------------------------------------------------------- 00119 00120 // 00121 // This is the method that actually does the work of loading a message from 00122 // the attached resources. Note that we don't use LoadStringW here, since it 00123 // won't work on Win98. So we go the next level down and do what LoadStringW 00124 // would have done, since this will work on either platform. 00125 // 00126 bool Win32MsgLoader::loadMsg(const XMLMsgLoader::XMLMsgId msgToLoad 00127 , XMLCh* const toFill 00128 , const XMLSize_t maxChars) 00129 { 00130 // In case we error return, and they don't check it... 00131 toFill[0] = 0; 00132 00133 // Adjust the message id by the domain offset 00134 const unsigned int theMsgId = msgToLoad + fDomainOfs; 00135 00136 // 00137 // Figure out the actual id the id, adjusting it by the domain offset. 00138 // Then first we calculate the particular 16 string block that this id 00139 // is in, and the offset within that block of the string in question. 00140 // 00141 const unsigned int theBlock = (theMsgId >> 4) + 1; 00142 const unsigned int theOfs = theMsgId & 0x000F; 00143 00144 // Try to find this resource. If we fail to find it, return false 00145 HRSRC hMsgRsc = ::FindResourceEx 00146 ( 00147 fModHandle 00148 , RT_STRING 00149 , MAKEINTRESOURCE(theBlock) 00150 , MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) 00151 ); 00152 if (!hMsgRsc) 00153 return false; 00154 00155 // We found it, so load the block. If this fails, also return a false 00156 HGLOBAL hGbl = ::LoadResource(fModHandle, hMsgRsc); 00157 if (!hGbl) 00158 return false; 00159 00160 // Lock this resource into memory. Again, if it fails, just return false 00161 const XMLCh* pBlock = (const XMLCh*)::LockResource(hGbl); 00162 if (!pBlock) 00163 return false; 00164 00165 // 00166 // Look through the block for our desired message. Its stored such that 00167 // the zeroth entry has the length minus the separator null. 00168 // 00169 for (unsigned int index = 0; index < theOfs; index++) 00170 pBlock += *pBlock + 1; 00171 00172 // Calculate how many actual chars we will end up with 00173 const XMLSize_t actualChars = ((maxChars < (XMLSize_t)*pBlock) ? maxChars : (XMLSize_t)*pBlock); 00174 00175 // Ok, finally now copy as much as we can into the caller's buffer 00176 wcsncpy(toFill, pBlock + 1, actualChars); 00177 toFill[actualChars] = 0; 00178 00179 return true; 00180 } 00181 00182 00183 bool Win32MsgLoader::loadMsg(const XMLMsgLoader::XMLMsgId msgToLoad 00184 , XMLCh* const toFill 00185 , const XMLSize_t maxChars 00186 , const XMLCh* const repText1 00187 , const XMLCh* const repText2 00188 , const XMLCh* const repText3 00189 , const XMLCh* const repText4 00190 , MemoryManager* const manager) 00191 { 00192 // Call the other version to load up the message 00193 if (!loadMsg(msgToLoad, toFill, maxChars)) 00194 return false; 00195 00196 // And do the token replacement 00197 XMLString::replaceTokens(toFill, maxChars, repText1, repText2, repText3, repText4, manager); 00198 return true; 00199 } 00200 00201 00202 bool Win32MsgLoader::loadMsg(const XMLMsgLoader::XMLMsgId msgToLoad 00203 , XMLCh* const toFill 00204 , const XMLSize_t maxChars 00205 , const char* const repText1 00206 , const char* const repText2 00207 , const char* const repText3 00208 , const char* const repText4 00209 , MemoryManager* const manager) 00210 { 00211 // 00212 // Transcode the provided parameters and call the other version, 00213 // which will do the replacement work. 00214 // 00215 XMLCh* tmp1 = 0; 00216 XMLCh* tmp2 = 0; 00217 XMLCh* tmp3 = 0; 00218 XMLCh* tmp4 = 0; 00219 00220 bool bRet = false; 00221 if (repText1) 00222 tmp1 = XMLString::transcode(repText1, manager); 00223 if (repText2) 00224 tmp2 = XMLString::transcode(repText2, manager); 00225 if (repText3) 00226 tmp3 = XMLString::transcode(repText3, manager); 00227 if (repText4) 00228 tmp4 = XMLString::transcode(repText4, manager); 00229 00230 bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4, manager); 00231 00232 if (tmp1) 00233 manager->deallocate(tmp1);//delete [] tmp1; 00234 if (tmp2) 00235 manager->deallocate(tmp2);//delete [] tmp2; 00236 if (tmp3) 00237 manager->deallocate(tmp3);//delete [] tmp3; 00238 if (tmp4) 00239 manager->deallocate(tmp4);//delete [] tmp4; 00240 00241 return bRet; 00242 } 00243 00244 XERCES_CPP_NAMESPACE_END