source: icXML/icXML-devel/src/xercesc/util/MsgLoaders/Win32/Win32MsgLoader.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 7 years ago

Original Xerces files with import mods for icxercesc

File size: 8.3 KB
RevLine 
[2722]1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: Win32MsgLoader.cpp 570552 2007-08-28 19:57:36Z amassari $
20 */
21
22
23// ---------------------------------------------------------------------------
24//  Includes
25// ---------------------------------------------------------------------------
26#include <windows.h>
27
28#include <icxercesc/util/PlatformUtils.hpp>
29#include <xercesc/util/XMLMsgLoader.hpp>
30#include <icxercesc/util/XMLString.hpp>
31#include <xercesc/util/XMLUni.hpp>
32#include "Win32MsgLoader.hpp"
33
34
35//      Function prototypes
36BOOL APIENTRY DllMain(HINSTANCE hModule,
37                             DWORD  ul_reason_for_call,
38                             LPVOID lpReserved);
39
40
41// ---------------------------------------------------------------------------
42//  Public Constructors and Destructor
43// ---------------------------------------------------------------------------
44HINSTANCE globalModuleHandle;
45
46BOOL APIENTRY DllMain(HINSTANCE hModule,
47                      DWORD  ul_reason_for_call,
48                      LPVOID /*lpReserved*/)
49{
50  switch (ul_reason_for_call) {
51  case DLL_PROCESS_ATTACH:
52    globalModuleHandle = hModule;
53    break;
54  case DLL_THREAD_ATTACH:
55    break;
56  case DLL_THREAD_DETACH:
57    break;
58  case DLL_PROCESS_DETACH:
59    break;
60  }
61  return TRUE;
62}
63
64XERCES_CPP_NAMESPACE_BEGIN
65
66// ---------------------------------------------------------------------------
67//  Global module handle
68// ---------------------------------------------------------------------------
69Win32MsgLoader::Win32MsgLoader(const XMLCh* const msgDomain) :
70
71    fDomainOfs(0)
72    , fModHandle(0)
73    , fMsgDomain(0)
74{
75    // Try to get the module handle
76    fModHandle = globalModuleHandle;
77    if (!fModHandle)
78    {
79        //
80        //  If we didn't find it, its probably because its a development
81        //  build which is built as separate DLLs, so lets look for the DLL
82        //  that we are part of.
83        //
84        static const char* const privDLLName = "IXUTIL";
85        fModHandle = ::GetModuleHandleA(privDLLName);
86
87        // If neither exists, then we give up
88        if (!fModHandle)
89        {
90            // Probably have to call panic here
91        }
92    }
93
94    // Store the domain name
95    fMsgDomain = XMLString::replicate(msgDomain, XMLPlatformUtils::fgMemoryManager);
96
97    // And precalc the id offset we use for this domain
98    if (XMLString::equals(fMsgDomain, XMLUni::fgXMLErrDomain))
99        fDomainOfs = 0;
100    else if (XMLString::equals(fMsgDomain, XMLUni::fgExceptDomain))
101        fDomainOfs = 0x2000;
102    else if (XMLString::equals(fMsgDomain, XMLUni::fgValidityDomain))
103        fDomainOfs = 0x4000;
104    else if (XMLString::equals(fMsgDomain, XMLUni::fgXMLDOMMsgDomain))
105        fDomainOfs = 0x6000;
106    else
107        XMLPlatformUtils::panic(PanicHandler::Panic_UnknownMsgDomain);
108}
109
110Win32MsgLoader::~Win32MsgLoader()
111{
112    XMLPlatformUtils::fgMemoryManager->deallocate(fMsgDomain);//delete [] fMsgDomain;
113}
114
115
116// ---------------------------------------------------------------------------
117//  Implementation of the virtual message loader API
118// ---------------------------------------------------------------------------
119
120//
121//  This is the method that actually does the work of loading a message from
122//  the attached resources. Note that we don't use LoadStringW here, since it
123//  won't work on Win98. So we go the next level down and do what LoadStringW
124//  would have done, since this will work on either platform.
125//
126bool Win32MsgLoader::loadMsg(const  XMLMsgLoader::XMLMsgId  msgToLoad
127                            ,       XMLCh* const            toFill
128                            , const XMLSize_t               maxChars)
129{
130    // In case we error return, and they don't check it...
131    toFill[0] = 0;
132
133    // Adjust the message id by the domain offset
134    const unsigned int theMsgId = msgToLoad + fDomainOfs;
135
136    //
137    //  Figure out the actual id the id, adjusting it by the domain offset.
138    //  Then first we calculate the particular 16 string block that this id
139    //  is in, and the offset within that block of the string in question.
140    //
141    const unsigned int theBlock = (theMsgId >> 4) + 1;
142    const unsigned int theOfs   = theMsgId & 0x000F;
143
144    // Try to find this resource. If we fail to find it, return false
145    HRSRC hMsgRsc = ::FindResourceEx
146    (
147        fModHandle
148        , RT_STRING
149        , MAKEINTRESOURCE(theBlock)
150        , MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
151    );
152    if (!hMsgRsc)
153        return false;
154
155    // We found it, so load the block. If this fails, also return a false
156    HGLOBAL hGbl = ::LoadResource(fModHandle, hMsgRsc);
157    if (!hGbl)
158        return false;
159
160    // Lock this resource into memory. Again, if it fails, just return false
161    const XMLCh* pBlock = (const XMLCh*)::LockResource(hGbl);
162    if (!pBlock)
163        return false;
164
165    //
166    //  Look through the block for our desired message. Its stored such that
167    //  the zeroth entry has the length minus the separator null.
168    //
169    for (unsigned int index = 0; index < theOfs; index++)
170        pBlock += *pBlock + 1;
171
172    // Calculate how many actual chars we will end up with
173    const XMLSize_t actualChars = ((maxChars < (XMLSize_t)*pBlock) ? maxChars : (XMLSize_t)*pBlock);
174
175    // Ok, finally now copy as much as we can into the caller's buffer
176    wcsncpy(toFill, pBlock + 1, actualChars);
177    toFill[actualChars] = 0;
178
179    return true;
180}
181
182
183bool Win32MsgLoader::loadMsg(const  XMLMsgLoader::XMLMsgId  msgToLoad
184                            ,       XMLCh* const            toFill
185                            , const XMLSize_t               maxChars
186                            , const XMLCh* const            repText1
187                            , const XMLCh* const            repText2
188                            , const XMLCh* const            repText3
189                            , const XMLCh* const            repText4
190                            , MemoryManager* const          manager)
191{
192    // Call the other version to load up the message
193    if (!loadMsg(msgToLoad, toFill, maxChars))
194        return false;
195
196    // And do the token replacement
197    XMLString::replaceTokens(toFill, maxChars, repText1, repText2, repText3, repText4, manager);
198    return true;
199}
200
201
202bool Win32MsgLoader::loadMsg(const  XMLMsgLoader::XMLMsgId  msgToLoad
203                            ,       XMLCh* const            toFill
204                            , const XMLSize_t               maxChars
205                            , const char* const             repText1
206                            , const char* const             repText2
207                            , const char* const             repText3
208                            , const char* const             repText4
209                            , MemoryManager* const          manager)
210{
211    //
212    //  Transcode the provided parameters and call the other version,
213    //  which will do the replacement work.
214    //
215    XMLCh* tmp1 = 0;
216    XMLCh* tmp2 = 0;
217    XMLCh* tmp3 = 0;
218    XMLCh* tmp4 = 0;
219
220    bool bRet = false;
221    if (repText1)
222        tmp1 = XMLString::transcode(repText1, manager);
223    if (repText2)
224        tmp2 = XMLString::transcode(repText2, manager);
225    if (repText3)
226        tmp3 = XMLString::transcode(repText3, manager);
227    if (repText4)
228        tmp4 = XMLString::transcode(repText4, manager);
229
230    bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4, manager);
231
232    if (tmp1)
233        manager->deallocate(tmp1);//delete [] tmp1;
234    if (tmp2)
235        manager->deallocate(tmp2);//delete [] tmp2;
236    if (tmp3)
237        manager->deallocate(tmp3);//delete [] tmp3;
238    if (tmp4)
239        manager->deallocate(tmp4);//delete [] tmp4;
240
241    return bRet;
242}
243
244XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.