⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfaccessorimpl.h

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 H
字号:
/****************************************************************************** * $Id: SFAccessorImpl.h,v 1.1 2002/08/09 21:36:17 warmerda Exp $ * * Project:  OpenGIS Simple Features Reference Implementation * Purpose:  IAccessor implementation that doesn't suffer IAccessorImpl's *           problem with confusion of accessor handle ids.  * Author:   Frank Warmerdam <warmerdam@pobox.com> * * This code is closely derived from the code in ATLDB.H for IAccessor. * ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: SFAccessorImpl.h,v $ * Revision 1.1  2002/08/09 21:36:17  warmerda * New * * Revision 1.2  2001/10/15 15:21:45  warmerda * switch to unix text mode * * Revision 1.1  2001/09/06 03:24:16  warmerda * New * */// It is assumed that ATLDB.H has already been included.// The following is intended to be exactly the same as the ATLDB.H IAccessor// except that IAccessor handles are strictly incrementing 32bit integers// instead of trying to use the pointers as the handle.  Using the pointer// causes problems when the accessor is "copied" into other rowsets (ie.// from the ICommand to the IRowset result) causing the handle and pointer// to get out of sync (since the handle has to be preserved but the pointer// changes as a copy of the structure is made).  This can be bad if the// old pointer (on the ICommand accessor) is deallocated and then gets reused// as an accessor on the IRowset resulting in two accessors with the same// handle on the Rowset. extern int g_nNextSFAccessorHandle;#ifdef SUPPORT_ATL_NET#  define SF_ATL_MAP CAtlMap#else#  define SF_ATL_MAP CSimpleMap#endif// SFAccessorImpltemplate <class T, class BindType = ATLBINDINGS,          class BindingVector = SF_ATL_MAP < int, BindType* > >class ATL_NO_VTABLE SFAccessorImpl : public IAccessorImplBase<BindType>{    public:    typedef BindType _BindType;    typedef BindingVector _BindingVector;    SFAccessorImpl()    {        m_bIsCommand = FALSE;        m_bHasParamaters = FALSE;        m_bIsChangeable = FALSE;    }    OUT_OF_LINE HRESULT InternalFinalConstruct(IUnknown* pUnkThis)    {        CComQIPtr<ICommand> spCommand = pUnkThis;        if (spCommand != NULL)        {            m_bIsCommand = TRUE;            CComQIPtr<ICommandWithParameters> spCommandParams = pUnkThis;            m_bHasParamaters =  spCommandParams != NULL;        }        else // its a Rowset        {            CComQIPtr<IRowsetChange> spRSChange = pUnkThis;            m_bIsChangeable = spRSChange != NULL;        }        return S_OK;    }    HRESULT FinalConstruct()    {        T* pT = (T*)this;        return InternalFinalConstruct(pT->GetUnknown());    }    void FinalRelease()    {#ifdef _DEBUG        if (m_rgBindings.GetSize())        ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::~SFAccessorImpl Bindings still in vector, removing\n");#endif //_DEBUG        while (m_rgBindings.GetSize())        ReleaseAccessor((HACCESSOR)m_rgBindings.GetKeyAt(0), NULL);    }    STDMETHOD(AddRefAccessor)(HACCESSOR hAccessor,                              ULONG *pcRefCount)    {        ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::AddRefAccessor\n");        if (hAccessor == NULL)        {            ATLTRACE2(atlTraceDBProvider, 0, _T("AddRefAccessor : Bad hAccessor\n"));            return E_INVALIDARG;        }        if (pcRefCount == NULL)        pcRefCount = (ULONG*)_alloca(sizeof(ULONG));        BindType* pBind = m_rgBindings.Lookup((int)hAccessor);        *pcRefCount = T::_ThreadModel::Increment((LONG*)&pBind->dwRef);        return S_OK;    }    OUT_OF_LINE ATLCOLUMNINFO* ValidateHelper(ULONG* pcCols, CComPtr<IDataConvert> & rspConvert)    {        T* pT = (T*)this;        rspConvert = pT->m_spConvert;        return pT->GetColumnInfo(pT, pcCols);    }    OUT_OF_LINE HRESULT ValidateBindingsFromMetaData(ULONG cBindings, const DBBINDING rgBindings[],                                                     DBBINDSTATUS rgStatus[], bool bHasBookmarks)    {        HRESULT hr = S_OK;        ULONG cCols;        CComPtr<IDataConvert> spConvert;        ATLCOLUMNINFO* pColInfo = ValidateHelper(&cCols, spConvert);        ATLASSERT(pColInfo != NULL);        for (ULONG iBinding = 0; iBinding < cBindings; iBinding++)        {            const DBBINDING& rBindCur = rgBindings[iBinding];            ULONG iOrdAdjusted;            if (bHasBookmarks)            iOrdAdjusted = rBindCur.iOrdinal;   // Bookmarks start with ordinal 0            else            iOrdAdjusted = rBindCur.iOrdinal - 1; // Non-bookmarks start w/ ordinal 1            if (rBindCur.iOrdinal > cCols)            {                hr = DB_E_ERRORSOCCURRED;                rgStatus[iBinding] = DBBINDSTATUS_BADORDINAL;                continue;            }            // If a binding specifies provider owned memory, and specifies type            // X | BYREF, and the provider's copy is not X or X | BYREF, return            // DBBINDSTATUS_BADBINDINFO            if (rBindCur.dwMemOwner == DBMEMOWNER_PROVIDEROWNED)            {                if ((rBindCur.wType & DBTYPE_BYREF) != 0)                {                    DBTYPE dbConsumerType = rBindCur.wType & 0xBFFF;                    DBTYPE dbProviderType = pColInfo[iOrdAdjusted].wType & 0xBFFF;                    if (dbConsumerType != dbProviderType)                    {                        hr = DB_E_ERRORSOCCURRED;                        rgStatus[iBinding] = DBBINDSTATUS_BADBINDINFO;                        continue;                    }                }            }            ATLASSERT(spConvert != NULL);            HRESULT hrConvert = spConvert->CanConvert(pColInfo[iOrdAdjusted].wType, rBindCur.wType);            if (FAILED(hrConvert) || hrConvert == S_FALSE)            {                hr = DB_E_ERRORSOCCURRED;                rgStatus[iBinding] = DBBINDSTATUS_UNSUPPORTEDCONVERSION;                continue;            }        }        return hr;    }    STDMETHOD(CreateAccessor)(DBACCESSORFLAGS dwAccessorFlags,                              ULONG cBindings,                              const DBBINDING rgBindings[],                              ULONG cbRowSize,                              HACCESSOR *phAccessor,                              DBBINDSTATUS rgStatus[])    {        ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::CreateAccessor\n");                                  T* pT = (T*)this;        T::ObjectLock cab(pT);        if (!phAccessor)        {            ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::CreateAccessor : Inavlid NULL Parameter for HACCESSOR*\n");            return E_INVALIDARG;        }        *phAccessor = NULL;        if (cBindings != 0 && rgBindings == NULL)        {            ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::CreateAccessor  : Bad Binding array\n");            return E_INVALIDARG;        }        if (dwAccessorFlags & DBACCESSOR_PASSBYREF)        {            CComVariant varByRef;            HRESULT hr = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_BYREFACCESSORS, &varByRef);            if (FAILED(hr) || varByRef.boolVal == VARIANT_FALSE)            return DB_E_BYREFACCESSORNOTSUPPORTED;        }        if (!m_bHasParamaters)        {            if (dwAccessorFlags & DBACCESSOR_PARAMETERDATA)            return DB_E_BADACCESSORFLAGS;        }        if (m_bIsCommand || !m_bIsChangeable)        {            if (cBindings == 0) // No NULL Accessors on the command            return DB_E_NULLACCESSORNOTSUPPORTED;        }        if (rgStatus == NULL && cBindings) // Create a fake status array        rgStatus = (DBBINDSTATUS*)_alloca(cBindings*sizeof(DBBINDSTATUS));        // Validate the Binding passed        HRESULT hr;        bool bHasBookmarks = false;        CComVariant varBookmarks;        HRESULT hrLocal = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_BOOKMARKS, &varBookmarks);        bHasBookmarks = (hrLocal == S_OK &&  varBookmarks.boolVal == VARIANT_TRUE);        hr = ValidateBindings(cBindings, rgBindings, rgStatus, bHasBookmarks);        if (FAILED(hr))        return hr;        if (!m_bIsCommand)        {            hr = ValidateBindingsFromMetaData(cBindings, rgBindings, rgStatus,                                              bHasBookmarks);            if (FAILED(hr))            return hr;        }        hr = IAccessorImplBase<BindType>::CreateAccessor(dwAccessorFlags, cBindings,                                                         rgBindings, cbRowSize, phAccessor,rgStatus);        if (SUCCEEDED(hr))        {            ATLASSERT(*phAccessor != NULL);            BindType* pBind = (BindType*)*phAccessor;            // NFW: Reset accessor handle!            *phAccessor = g_nNextSFAccessorHandle++;            hr = m_rgBindings.Add(*phAccessor, pBind) ? S_OK : E_OUTOFMEMORY;        }        return hr;    }    STDMETHOD(GetBindings)(HACCESSOR hAccessor,                           DBACCESSORFLAGS *pdwAccessorFlags,                           ULONG *pcBindings,                           DBBINDING **prgBindings)    {        ATLTRACE2(atlTraceDBProvider, 0, "SFAccessorImpl::GetBindings");        // Zero output parameters in case of failure        if (pdwAccessorFlags != NULL)        *pdwAccessorFlags = NULL;        if (pcBindings != NULL)        *pcBindings = NULL;        if (prgBindings != NULL)        *prgBindings = NULL;        // Check if any of the out params are NULL pointers        if ((pdwAccessorFlags && pcBindings && prgBindings) == NULL)        return E_INVALIDARG;        BindType* pBind = m_rgBindings.Lookup((int)hAccessor);        HRESULT hr = DB_E_BADACCESSORHANDLE;        if (pBind != NULL)        {            *pdwAccessorFlags = pBind->dwAccessorFlags;            *pcBindings = pBind->cBindings;            *prgBindings = (DBBINDING*)CoTaskMemAlloc(*pcBindings * sizeof(DBBINDING));            if (*prgBindings == NULL)            return E_OUTOFMEMORY;            memcpy(*prgBindings, pBind->pBindings, sizeof(DBBINDING) * (*pcBindings));            hr = S_OK;        }        return hr;    }    STDMETHOD(ReleaseAccessor)(HACCESSOR hAccessor,                               ULONG *pcRefCount)    {        ATLTRACE2(atlTraceDBProvider, 0, _T("SFAccessorImpl::ReleaseAccessor\n"));        BindType* pBind = m_rgBindings.Lookup((int)hAccessor);        if (pBind == NULL)        return DB_E_BADACCESSORHANDLE;        if (pcRefCount == NULL)        pcRefCount = (ULONG*)_alloca(sizeof(ULONG));        *pcRefCount = T::_ThreadModel::Decrement((LONG*)&pBind->dwRef);        if (!(*pcRefCount))        {            delete [] pBind->pBindings;            delete pBind;            return m_rgBindings.Remove((int)hAccessor) ? S_OK : DB_E_BADACCESSORHANDLE;        }        return S_OK;    }    BindingVector m_rgBindings;};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -