source: trunk/Utilities/MaxMindGeoLite/Location.h @ 48

Last change on this file since 48 was 48, checked in by roman, 12 years ago
  • Property svn:keywords set to Id
File size: 17.5 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: Location.h 48 2012-02-11 22:26:24Z roman $
6
7#pragma once
8
9#include <atlenc.h>
10#include "rosockets.h"
11#include "MaxMindGeoLite_i.h"
12
13////////////////////////////////////////////////////////////
14// GeoLiteCity
15
16namespace GeoLiteCity
17{
18        ////////////////////////////////////////////////////////////
19        // CLocation
20
21        class CLocation
22        {
23        public:
24                INT m_nIdentifier;
25                CStringA m_sCountryCode;
26                CStringA m_sRegion;
27                CStringA m_sCity;
28                CStringA m_sPostalCode;
29                DOUBLE m_fLatitude;
30                DOUBLE m_fLongitude;
31                CStringA m_sMetroCode;
32                CStringA m_sAreaCode;
33
34        public:
35        // CLocation
36                CLocation() throw()
37                {
38                }
39                CLocation(LPCSTR pszString)
40                {
41                        Initialize(pszString);
42                }
43                VOID Initialize(LPCSTR pszString)
44                {
45                        CRoArrayT<CStringA> Array;
46                        __D(_StringHelper::GetCommaSeparatedItems(pszString, Array) >= 7, E_UNNAMED);
47                        __D(AtlStringToInteger(Array[0], m_nIdentifier), E_UNNAMED);
48                        m_sCountryCode = Array[1];
49                        m_sRegion = Array[2];
50                        m_sCity = Array[3];
51                        m_sPostalCode = Array[4];
52                        __D(AtlStringToDouble(Array[5], m_fLatitude), E_UNNAMED);
53                        __D(AtlStringToDouble(Array[6], m_fLongitude), E_UNNAMED);
54                        if(Array.GetCount() >= 8)
55                                m_sMetroCode = Array[7];
56                        if(Array.GetCount() >= 9)
57                                m_sAreaCode = Array[8];
58                }
59        };
60
61        ////////////////////////////////////////////////////////////
62        // CLocationArray
63
64        class CLocationArray :
65                protected CRoArrayT<CLocation>
66        {
67        public:
68        // CLocationArray
69                CLocationArray() throw()
70                {
71                }
72                CLocationArray(const CPath& sPath)
73                {
74                        Initialize(sPath);
75                }
76                VOID Initialize(const CPath& sPath)
77                {
78                        CAtlFile File;
79                        __C(File.Create(sPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING));
80                        ULONGLONG nSize;
81                        __C(File.GetSize(nSize));
82                        CHeapPtr<CHAR> pszData;
83                        __D(pszData.Allocate((SIZE_T) nSize + 1), E_OUTOFMEMORY);
84                        __C(File.Read(pszData, (DWORD) nSize));
85                        pszData[nSize] = 0;
86                        LPCSTR pszDataPointer = pszData;
87                        pszDataPointer = strchr(pszDataPointer, '\n') + 1; // Copyright line
88                        pszDataPointer = strchr(pszDataPointer, '\n') + 1; // Header line
89                        for(; *pszDataPointer; )
90                        {
91                                LPCSTR pszSeparator = strchr(pszDataPointer, '\n');
92                                if(!pszSeparator)
93                                        break;
94                                const SIZE_T nLength = pszSeparator - pszDataPointer;
95                                CTempBufferT<CHAR> pszLine(nLength + 1);
96                                strncpy_s(pszLine, nLength + 1, pszDataPointer, _TRUNCATE);
97                                const SIZE_T nIndex = Add();
98                                CLocation& Location = GetAt(nIndex);
99                                Location.Initialize(pszLine);
100                                __D(Location.m_nIdentifier == nIndex + 1, E_UNNAMED);
101                                pszDataPointer = pszSeparator + 1;
102                        }
103                }
104                BOOL Lookup(INT nIdentifier, const CLocation** ppLocation = NULL) const throw()
105                {
106                        if(nIdentifier < 1 || nIdentifier - 1 >= (INT) GetCount())
107                                return FALSE;
108                        const CLocation& Location = GetAt(nIdentifier - 1);
109                        _A(Location.m_nIdentifier == nIdentifier);
110                        if(ppLocation)
111                                *ppLocation = &Location;
112                        return TRUE;
113                }
114        };
115
116        ////////////////////////////////////////////////////////////
117        // CBlock
118
119        class CBlock
120        {
121        public:
122                ULONG m_nStartAddress;
123                ULONG m_nEndAddress;
124                INT m_nLocationIdentifier;
125
126        public:
127        // CBlock
128                CBlock() throw()
129                {
130                }
131                CBlock(LPCSTR pszString)
132                {
133                        Initialize(pszString);
134                }
135                VOID Initialize(LPCSTR pszString)
136                {
137                        CRoArrayT<CStringA> Array;
138                        __D(_StringHelper::GetCommaSeparatedItems(pszString, Array) >= 3, E_UNNAMED);
139                        LONGLONG nStartAddress, nEndAddress;
140                        __D(AtlStringToInteger(Array[0], nStartAddress), E_UNNAMED);
141                        __D(AtlStringToInteger(Array[1], nEndAddress), E_UNNAMED);
142                        m_nStartAddress = (ULONG) nStartAddress;
143                        m_nEndAddress = (ULONG) nEndAddress;
144                        __D(AtlStringToInteger(Array[2], m_nLocationIdentifier), E_UNNAMED);
145                }
146                BOOL Contains(ULONG nAddress) const throw()
147                {
148                        return nAddress >= m_nStartAddress && nAddress <= m_nEndAddress;
149                }
150        };
151
152        ////////////////////////////////////////////////////////////
153        // CBlockArray
154
155        class CBlockArray :
156                protected CRoArrayT<CBlock>
157        {
158        public:
159        // CBlockArray
160                CBlockArray() throw()
161                {
162                }
163                CBlockArray(const CPath& sPath)
164                {
165                        Initialize(sPath);
166                }
167                VOID Initialize(const CPath& sPath)
168                {
169                        CAtlFile File;
170                        __C(File.Create(sPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING));
171                        ULONGLONG nSize;
172                        __C(File.GetSize(nSize));
173                        CHeapPtr<CHAR> pszData;
174                        __D(pszData.Allocate((SIZE_T) nSize + 1), E_OUTOFMEMORY);
175                        __C(File.Read(pszData, (DWORD) nSize));
176                        pszData[nSize] = 0;
177                        LPCSTR pszDataPointer = pszData;
178                        pszDataPointer = strchr(pszDataPointer, '\n') + 1; // Copyright line
179                        pszDataPointer = strchr(pszDataPointer, '\n') + 1; // Header line
180                        ULONG nPreviousEndAddress = 0;
181                        for(; *pszDataPointer; )
182                        {
183                                LPCSTR pszSeparator = strchr(pszDataPointer, '\n');
184                                if(!pszSeparator)
185                                        break;
186                                const SIZE_T nLength = pszSeparator - pszDataPointer;
187                                CTempBufferT<CHAR> pszLine(nLength + 1);
188                                strncpy_s(pszLine, nLength + 1, pszDataPointer, _TRUNCATE);
189                                const SIZE_T nIndex = Add();
190                                CBlock& Block = GetAt(nIndex);
191                                Block.Initialize(pszLine);
192                                __D(Block.m_nStartAddress && Block.m_nStartAddress > nPreviousEndAddress, E_UNNAMED);
193                                nPreviousEndAddress = Block.m_nEndAddress;
194                                pszDataPointer = pszSeparator + 1;
195                        }
196                }
197                BOOL Lookup(ULONG nAddress, const CBlock** ppBlock = NULL) const throw()
198                {
199                        SIZE_T nLeftIndex = 0, nRightIndex = GetCount();
200                        if(!nRightIndex)
201                                return FALSE;
202                        if(nAddress < GetAt(0).m_nStartAddress || nAddress > GetAt(GetCount() - 1).m_nEndAddress)
203                                return FALSE;
204                        for(; nLeftIndex + 1 < nRightIndex; )
205                        {
206                                SIZE_T nIndex = (nLeftIndex + nRightIndex) / 2;
207                                const CBlock& Block = GetAt(nIndex);
208                                if(nAddress < Block.m_nStartAddress)
209                                {
210                                        nRightIndex = nIndex;
211                                } else
212                                if(nAddress > Block.m_nEndAddress)
213                                {
214                                        nLeftIndex = nIndex + 1;
215                                } else
216                                {
217                                        nLeftIndex = nIndex;
218                                        break;
219                                }
220                        }
221                        const CBlock& Block = GetAt(nLeftIndex);
222                        if(!Block.Contains(nAddress))
223                                return FALSE;
224                        if(ppBlock)
225                                *ppBlock = &Block;
226                        return TRUE;
227                }
228        };
229}
230
231////////////////////////////////////////////////////////////
232// CFreeThreadedMarshaler
233
234class CFreeThreadedMarshaler
235{
236private:
237        CComPtr<IUnknown> m_pMarshalerUnknown;
238        CComPtr<IMarshal> m_pMarshalerMarshal;
239
240public:
241// CFreeThreadedMarshaler
242        const CComPtr<IMarshal>& operator -> () const throw()
243        {
244                return GetMarshal();
245        }
246        VOID Initialize()
247        {
248                _A(!m_pMarshalerUnknown && !m_pMarshalerMarshal);
249                __C(CoCreateFreeThreadedMarshaler(NULL, &m_pMarshalerUnknown));
250                m_pMarshalerMarshal = m_pMarshalerUnknown;
251                __D(m_pMarshalerMarshal, E_NOINTERFACE);
252        }
253        VOID Terminate() throw()
254        {
255                m_pMarshalerMarshal = NULL;
256                m_pMarshalerUnknown = NULL;
257        }
258        const CComPtr<IMarshal>& GetMarshal() const throw()
259        {
260                return m_pMarshalerMarshal;
261        }
262};
263
264////////////////////////////////////////////////////////////
265// CLocations
266
267class ATL_NO_VTABLE CLocations : 
268        public CComObjectRootEx<CComMultiThreadModelNoCS>,
269        public CComCoClass<CLocations, &__uuidof(Locations)>,
270        public IDispatchImpl<ILocations>
271{
272public:
273        enum { IDR = IDR_LOCATIONS };
274
275//DECLARE_REGISTRY_RESOURCEID(IDR)
276
277DECLARE_CLASSFACTORY_SINGLETON(CLocations)
278
279DECLARE_PROTECT_FINAL_CONSTRUCT()
280
281BEGIN_COM_MAP(CLocations)
282        COM_INTERFACE_ENTRY(ILocations)
283        COM_INTERFACE_ENTRY(IDispatch)
284        COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IMarshal), m_FreeThreadedMarshaler)
285END_COM_MAP()
286
287public:
288
289        ////////////////////////////////////////////////////////
290        // CLocation
291
292        class ATL_NO_VTABLE CLocation : 
293                public CComObjectRootEx<CComMultiThreadModelNoCS>,
294                public CComCoClass<CLocation, &__uuidof(Location)>,
295                public IDispatchImpl<ILocation>
296        {
297        public:
298
299        DECLARE_NO_REGISTRY()
300
301        //DECLARE_PROTECT_FINAL_CONSTRUCT()
302
303        BEGIN_COM_MAP(CLocation)
304                COM_INTERFACE_ENTRY(ILocation)
305                COM_INTERFACE_ENTRY(IDispatch)
306        END_COM_MAP()
307
308        private:
309                GeoLiteCity::CLocation m_Location;
310
311        public:
312        // CLocation
313                CLocation() throw()
314                {
315                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
316                }
317                ~CLocation() throw()
318                {
319                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
320                }
321                VOID Initialize(const GeoLiteCity::CLocation& Location)
322                {
323                        m_Location = Location;
324                }
325
326        // ILocation
327                STDMETHOD(get_Country)(BSTR* psCountry) throw()
328                {
329                        _Z4(atlTraceCOM, 4, _T("...\n"));
330                        _ATLTRY
331                        {
332                                __D(psCountry, E_POINTER);
333                                ObjectLock Lock(this);
334                                *psCountry = CComBSTR(m_Location.m_sCountryCode).Detach();
335                        }
336                        _ATLCATCH(Exception)
337                        {
338                                _C(Exception);
339                        }
340                        return S_OK;
341                }
342                STDMETHOD(get_Region)(BSTR* psRegion) throw()
343                {
344                        _Z4(atlTraceCOM, 4, _T("...\n"));
345                        _ATLTRY
346                        {
347                                __D(psRegion, E_POINTER);
348                                ObjectLock Lock(this);
349                                *psRegion = CComBSTR(m_Location.m_sRegion).Detach();
350                        }
351                        _ATLCATCH(Exception)
352                        {
353                                _C(Exception);
354                        }
355                        return S_OK;
356                }
357                STDMETHOD(get_City)(BSTR* psCity) throw()
358                {
359                        _Z4(atlTraceCOM, 4, _T("...\n"));
360                        _ATLTRY
361                        {
362                                __D(psCity, E_POINTER);
363                                ObjectLock Lock(this);
364                                *psCity = CComBSTR(m_Location.m_sCity).Detach();
365                        }
366                        _ATLCATCH(Exception)
367                        {
368                                _C(Exception);
369                        }
370                        return S_OK;
371                }
372                STDMETHOD(get_PostalCode)(BSTR* psPostalCode) throw()
373                {
374                        _Z4(atlTraceCOM, 4, _T("...\n"));
375                        _ATLTRY
376                        {
377                                __D(psPostalCode, E_POINTER);
378                                ObjectLock Lock(this);
379                                *psPostalCode = CComBSTR(m_Location.m_sPostalCode).Detach();
380                        }
381                        _ATLCATCH(Exception)
382                        {
383                                _C(Exception);
384                        }
385                        return S_OK;
386                }
387                STDMETHOD(get_Latitude)(DOUBLE* pfLatitude) throw()
388                {
389                        _Z4(atlTraceCOM, 4, _T("...\n"));
390                        _ATLTRY
391                        {
392                                __D(pfLatitude, E_POINTER);
393                                ObjectLock Lock(this);
394                                *pfLatitude = m_Location.m_fLatitude;
395                        }
396                        _ATLCATCH(Exception)
397                        {
398                                _C(Exception);
399                        }
400                        return S_OK;
401                }
402                STDMETHOD(get_Longitude)(DOUBLE* pfLongitude) throw()
403                {
404                        _Z4(atlTraceCOM, 4, _T("...\n"));
405                        _ATLTRY
406                        {
407                                __D(pfLongitude, E_POINTER);
408                                ObjectLock Lock(this);
409                                *pfLongitude = m_Location.m_fLongitude;
410                        }
411                        _ATLCATCH(Exception)
412                        {
413                                _C(Exception);
414                        }
415                        return S_OK;
416                }
417                STDMETHOD(get_MetroCode)(BSTR* psMetroCode) throw()
418                {
419                        _Z4(atlTraceCOM, 4, _T("...\n"));
420                        _ATLTRY
421                        {
422                                __D(psMetroCode, E_POINTER);
423                                ObjectLock Lock(this);
424                                *psMetroCode = CComBSTR(m_Location.m_sMetroCode).Detach();
425                        }
426                        _ATLCATCH(Exception)
427                        {
428                                _C(Exception);
429                        }
430                        return S_OK;
431                }
432                STDMETHOD(get_AreaCode)(BSTR* psAreaCode) throw()
433                {
434                        _Z4(atlTraceCOM, 4, _T("...\n"));
435                        _ATLTRY
436                        {
437                                __D(psAreaCode, E_POINTER);
438                                ObjectLock Lock(this);
439                                *psAreaCode = CComBSTR(m_Location.m_sAreaCode).Detach();
440                        }
441                        _ATLCATCH(Exception)
442                        {
443                                _C(Exception);
444                        }
445                        return S_OK;
446                }
447        };
448
449private:
450        CWindowsSockets2 m_Sockets;
451        CFreeThreadedMarshaler m_FreeThreadedMarshaler;
452        //mutable CRoCriticalSection m_DataCriticalSection;
453        GeoLiteCity::CLocationArray m_LocationArray;
454        GeoLiteCity::CBlockArray m_BlockArray;
455
456public:
457// CLocations
458        static CString GetObjectFriendlyName()
459        {
460                return _StringHelper::GetLine(IDR, 2);
461        }
462        static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw()
463        {
464                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
465                _ATLTRY
466                {
467                        UpdateRegistryFromResource<CLocations>(bRegister);
468                }
469                _ATLCATCH(Exception)
470                {
471                        _C(Exception);
472                }
473                return S_OK;
474        }
475        CLocations() throw()
476        {
477                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
478        }
479        ~CLocations() throw()
480        {
481                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
482        }
483        HRESULT FinalConstruct() throw()
484        {
485                _ATLTRY
486                {
487                        __C(m_Sockets.GetStartupResult());
488                        m_FreeThreadedMarshaler.Initialize();
489                        Initialize();
490                }
491                _ATLCATCH(Exception)
492                {
493                        _C(Exception);
494                }
495                return S_OK;
496        }
497        VOID FinalRelease() throw()
498        {
499                m_FreeThreadedMarshaler.Terminate();
500        }
501        VOID Initialize()
502        {
503                TCHAR pszDirectory[MAX_PATH] = { 0 };
504                _W(GetModuleFileName(_AtlBaseModule.GetModuleInstance(), pszDirectory, DIM(pszDirectory)));
505                _W(RemoveFileSpec(pszDirectory));
506                CPath sLocationPath, sBlockPath;
507                sLocationPath.Combine(pszDirectory, _T("GeoLiteCity-Location.csv"));
508                sBlockPath.Combine(pszDirectory, _T("GeoLiteCity-Blocks.csv"));
509                //CRoCriticalSectionLock DataLock(m_DataCriticalSection);
510                m_LocationArray.Initialize(sLocationPath);
511                m_BlockArray.Initialize(sBlockPath);
512        }
513
514// ILocations
515        STDMETHOD(get_Item)(VARIANT vIndex, ILocation** ppLocation) throw()
516        {
517                _Z4(atlTraceCOM, 4, _T("vIndex.vt 0x%x\n"), vIndex.vt);
518                _ATLTRY
519                {
520                        __D(ppLocation, E_POINTER);
521                        __D(vIndex.vt == VT_BSTR, E_INVALIDARG);
522                        ULONG nAddress;
523                        nAddress = ntohl(inet_addr(CW2A(vIndex.bstrVal)));
524                        if(nAddress == INADDR_NONE)
525                        {
526                                SOCKADDR_IN Address;
527                                __E(CSocket::AddressFromHost(CW2CT(vIndex.bstrVal), 0, Address));
528                                nAddress = ntohl(Address.sin_addr.S_un.S_addr);
529                        }
530                        //ObjectLock Lock(this);
531                        //CRoCriticalSectionLock DataLock(m_DataCriticalSection);
532                        CObjectPtr<CLocation> pLocation;
533                        const GeoLiteCity::CBlock* pBlock;
534                        if(m_BlockArray.Lookup(nAddress, &pBlock))
535                        {
536                                const GeoLiteCity::CLocation* pInternalLocation;
537                                if(m_LocationArray.Lookup(pBlock->m_nLocationIdentifier, &pInternalLocation))
538                                        pLocation.Construct()->Initialize(*pInternalLocation);
539                                else
540                                        _A(FALSE);
541                        }
542                        *ppLocation = pLocation.Detach();
543                }
544                _ATLCATCH(Exception)
545                {
546                        _C(Exception);
547                }
548                return S_OK;
549        }
550};
551
552OBJECT_ENTRY_AUTO(__uuidof(Locations), CLocations)
553
554////////////////////////////////////////////////////////////
555// CLazyLocations
556
557class ATL_NO_VTABLE CLazyLocations : 
558        public CComObjectRootEx<CComMultiThreadModelNoCS>,
559        public CComCoClass<CLazyLocations, &__uuidof(LazyLocations)>,
560        public IDispatchImpl<ILazyLocations>
561{
562        typedef CThreadT<CLazyLocations> CThread;
563
564public:
565        enum { IDR = IDR_LAZYLOCATIONS };
566
567//DECLARE_REGISTRY_RESOURCEID(IDR)
568
569DECLARE_CLASSFACTORY_SINGLETON(CLazyLocations)
570
571DECLARE_PROTECT_FINAL_CONSTRUCT()
572
573BEGIN_COM_MAP(CLazyLocations)
574        COM_INTERFACE_ENTRY(ILazyLocations)
575        COM_INTERFACE_ENTRY_IID(__uuidof(IDispatch), ILazyLocations)
576        COM_INTERFACE_ENTRY(ILocations)
577        COM_INTERFACE_ENTRY_AGGREGATE(__uuidof(IMarshal), m_FreeThreadedMarshaler)
578END_COM_MAP()
579
580private:
581        CFreeThreadedMarshaler m_FreeThreadedMarshaler;
582        mutable CRoCriticalSection m_ThreadCriticalSection;
583        CObjectPtr<CThread> m_pThread;
584        mutable CRoCriticalSection m_DataCriticalSection;
585        CObjectPtr<CLocations> m_pLocations;
586
587        DWORD ThreadProc(CThread* pThread, CEvent& InitializationEvent, CEvent& TerminationEvent)
588        {
589                CMultiThreadedApartment MultiThreadedApartment;
590                _W(InitializationEvent.Set());
591                CComPtr<ILocations> pLocations;
592                __C(pLocations.CoCreateInstance(__uuidof(Locations)));
593                const CObjectPtr<CLocations> pNativeLocations = static_cast<CLocations*>((ILocations*) pLocations);
594                _A(pNativeLocations);
595                {
596                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
597                        _A(!m_pLocations);
598                        m_pLocations = pNativeLocations;
599                }
600                TerminationEvent;
601                CRoCriticalSectionLock ThreadLock(m_ThreadCriticalSection);
602                _A(m_pThread == pThread || !m_pThread && WaitForSingleObject(TerminationEvent, 0) == WAIT_OBJECT_0);
603                m_pThread.Release();
604                return 0;
605        }
606
607public:
608// CLazyLocations
609        static CString GetObjectFriendlyName()
610        {
611                return _StringHelper::GetLine(IDR, 2);
612        }
613        static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw()
614        {
615                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
616                _ATLTRY
617                {
618                        UpdateRegistryFromResource<CLazyLocations>(bRegister);
619                }
620                _ATLCATCH(Exception)
621                {
622                        _C(Exception);
623                }
624                return S_OK;
625        }
626        CLazyLocations() throw()
627        {
628                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
629        }
630        ~CLazyLocations() throw()
631        {
632                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
633        }
634        HRESULT FinalConstruct() throw()
635        {
636                _ATLTRY
637                {
638                        CRoCriticalSectionLock ThreadLock(m_ThreadCriticalSection);
639                        CObjectPtr<CThread> pThread;
640                        __E(pThread.Construct()->Initialize(this, &CLazyLocations::ThreadProc));
641                        m_pThread = pThread;
642                }
643                _ATLCATCH(Exception)
644                {
645                        _C(Exception);
646                }
647                return S_OK;
648        }
649        VOID FinalRelease() throw()
650        {
651                CObjectPtr<CThread> pThread;
652                {
653                        CRoCriticalSectionLock ThreadLock(m_ThreadCriticalSection);
654                        m_pThread.Swap(pThread);
655                }
656        }
657        CObjectPtr<CLocations> GetLocations() const throw()
658        {
659                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
660                return m_pLocations;
661        }
662
663// ILazyLocations
664        STDMETHOD(get_Initialized)(VARIANT_BOOL* pbInitialized) throw()
665        {
666                _Z4(atlTraceCOM, 4, _T("...\n"));
667                _ATLTRY
668                {
669                        __D(pbInitialized, E_POINTER);
670                        //ObjectLock Lock(this);
671                        //CRoCriticalSectionLock DataLock(m_DataCriticalSection);
672                        *pbInitialized = GetLocations() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
673                }
674                _ATLCATCH(Exception)
675                {
676                        _C(Exception);
677                }
678                return S_OK;
679        }
680
681// ILocations
682        STDMETHOD(get_Item)(VARIANT vIndex, ILocation** ppLocation) throw()
683        {
684                _Z4(atlTraceCOM, 4, _T("vIndex.vt 0x%x\n"), vIndex.vt);
685                _ATLTRY
686                {
687                        __D(ppLocation, E_POINTER);
688                        __D(vIndex.vt == VT_BSTR, E_INVALIDARG);
689                        //ObjectLock Lock(this);
690                        //CRoCriticalSectionLock DataLock(m_DataCriticalSection);
691                        CComPtr<ILocation> pLocation;
692                        const CObjectPtr<CLocations> pLocations = GetLocations();
693                        if(pLocations)
694                                __C(pLocations->get_Item(vIndex, &pLocation));
695                        *ppLocation = pLocation.Detach();
696                }
697                _ATLCATCH(Exception)
698                {
699                        _C(Exception);
700                }
701                return S_OK;
702        }
703};
704
705OBJECT_ENTRY_AUTO(__uuidof(LazyLocations), CLazyLocations)
Note: See TracBrowser for help on using the repository browser.