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

📄 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:39 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:39  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;// SFAccessorImpltemplate <class T, class BindType = ATLBINDINGS, 			class BindingVector = CAtlMap < HACCESSOR, 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*/)	{		CComPtr<ICommand> spCommand;		CComPtr<ICommandWithParameters> spCommandWithParameters;		T* pT = (T*)this;		pT->_InternalQueryInterface(IID_ICommand,(void **) &spCommand);		if (spCommand !=NULL)  // It's a command		{			m_bIsCommand = TRUE;			pT->_InternalQueryInterface(IID_ICommandWithParameters, (void **) &spCommandWithParameters);			m_bHasParamaters =  spCommandWithParameters != NULL;		}		return S_OK;	}	HRESULT FinalConstruct()	{		T* pT = (T*)this;		return InternalFinalConstruct(pT->GetUnknown());	}	void FinalRelease()	{#ifdef _DEBUG		if (m_rgBindings.GetCount())			ATLTRACE(atlTraceDBProvider, 0, _T("SFAccessorImpl::~SFAccessorImpl Bindings still in vector, removing\n"));#endif //_DEBUG		while (m_rgBindings.GetCount()) 			ReleaseAccessor((HACCESSOR)m_rgBindings.GetKeyAt(m_rgBindings.GetStartPosition()), NULL);	}	STDMETHOD(AddRefAccessor)(HACCESSOR hAccessor,							  DBREFCOUNT *pcRefCount)	{		ATLTRACE(atlTraceDBProvider, 2, _T("SFAccessorImpl::AddRefAccessor\n"));		if (hAccessor == NULL)		{			ATLTRACE(atlTraceDBProvider, 0, _T("AddRefAccessor : Bad hAccessor\n"));			return DB_E_BADACCESSORHANDLE;		}		BindType* pBind;		if( ! m_rgBindings.Lookup(hAccessor, pBind ) )			return DB_E_BADACCESSORHANDLE;		ATLASSERT( pBind );		ULONG cRefCount = T::_ThreadModel::Increment((LONG*)&pBind->dwRef);		if (pcRefCount != NULL)			*pcRefCount = cRefCount;		return S_OK;	}	OUT_OF_LINE ATLCOLUMNINFO* ValidateHelper(DBORDINAL* pcCols, CComPtr<IDataConvert> & rspConvert)	{		T* pT = (T*)this;		rspConvert = pT->m_spConvert;		return T::GetColumnInfo(pT, pcCols);	}	OUT_OF_LINE HRESULT ValidateBindingsFromMetaData(DBCOUNTITEM cBindings, const DBBINDING rgBindings[], 				DBBINDSTATUS rgStatus[], bool bHasBookmarks)	{		HRESULT hr = S_OK;		DBORDINAL cCols;		CComPtr<IDataConvert> spConvert;		ATLCOLUMNINFO* pColInfo = ValidateHelper(&cCols, spConvert);		ATLASSERT(pColInfo != NULL);		for (DBCOUNTITEM iBinding = 0; iBinding < cBindings; iBinding++)		{			const DBBINDING& rBindCur = rgBindings[iBinding];			DBORDINAL 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 &&					((rBindCur.wType & (~DBTYPE_BYREF)) != 						(pColInfo[iOrdAdjusted].wType & (~DBTYPE_BYREF))))				{					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,							  DBCOUNTITEM cBindings,							  const DBBINDING rgBindings[],							  DBLENGTH cbRowSize,							  HACCESSOR *phAccessor,							  DBBINDSTATUS rgStatus[])	{		ATLTRACE(atlTraceDBProvider, 2, _T("SFAccessorImpl::CreateAccessor\n"));		T* pT = (T*)this;		T::ObjectLock cab(pT);		if (!phAccessor)		{			ATLTRACE(atlTraceDBProvider, 0, _T("SFAccessorImpl::CreateAccessor : Inavlid NULL Parameter for HACCESSOR*\n"));			return E_INVALIDARG;		}		*phAccessor = NULL;		if (cBindings != 0 && rgBindings == NULL)		{			ATLTRACE(atlTraceDBProvider, 0, _T("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 == ATL_VARIANT_FALSE)				return DB_E_BYREFACCESSORNOTSUPPORTED;		}		if (!m_bHasParamaters)		{			if (dwAccessorFlags & DBACCESSOR_PARAMETERDATA)				return DB_E_BADACCESSORFLAGS;		}		// since our accessor does not provide any further restrictions or optimizations based		// on the DBACCESSOR_OPTIMIZED flag, the flag will be ignored.  In particular we will 		// not be returning this flag in the call to IAccessor::GetBindings.  This way we will		// be complient with the OLEDB specifications and we will not have to prevent the 		// client from creating additional accessors after the first row is fetched.		DBACCESSORFLAGS dwMask = DBACCESSOR_OPTIMIZED;		dwAccessorFlags &= ~dwMask;		CComVariant varUpdate;		HRESULT hr = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_UPDATABILITY, &varUpdate);		m_bIsChangeable = (SUCCEEDED(hr) && (varUpdate.iVal & DBPROPVAL_UP_INSERT));		if (m_bIsCommand || !m_bIsChangeable)		{			if (cBindings == 0) // No NULL Accessors on the command				return DB_E_NULLACCESSORNOTSUPPORTED;		}		CTempBuffer<DBBINDSTATUS> tmpBuffer;		if (rgStatus == NULL && cBindings) // Create a fake status array 			rgStatus = tmpBuffer.Allocate(cBindings);		// Validate the Binding passed		bool bHasBookmarks = false;		CComVariant varBookmarks;		HRESULT hrLocal = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_BOOKMARKS, &varBookmarks);		bHasBookmarks = (hrLocal == S_OK &&  varBookmarks.boolVal != ATL_VARIANT_FALSE);		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;			//hr = m_rgBindings.SetAt((HACCESSOR)pBind, pBind) ? S_OK : E_OUTOFMEMORY;			_ATLTRY			{				m_rgBindings.SetAt((HACCESSOR)pBind, pBind);				hr = S_OK;			}			_ATLCATCH( e )			{				_ATLDELETEEXCEPTION( e );				hr = E_OUTOFMEMORY;			}		}		return hr;	}	STDMETHOD(GetBindings)(HACCESSOR hAccessor,						   DBACCESSORFLAGS *pdwAccessorFlags,						   DBCOUNTITEM *pcBindings,						   DBBINDING **prgBindings)	{		ATLTRACE(atlTraceDBProvider, 2, _T("SFAccessorImpl::GetBindings\n"));		// 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;		bool bFound = m_rgBindings.Lookup((INT_PTR)hAccessor, pBind);		HRESULT hr = DB_E_BADACCESSORHANDLE; 		if (bFound && pBind != NULL)		{			*pdwAccessorFlags = pBind->dwAccessorFlags;			*pcBindings = pBind->cBindings;			// Get NULL for NULL Accessor			*prgBindings = (pBind->cBindings) ? (DBBINDING*)CoTaskMemAlloc(*pcBindings * sizeof(DBBINDING)) : NULL;			if (*prgBindings == NULL && pBind->cBindings) // No Error if NULL Accessor				return E_OUTOFMEMORY;			memcpy(*prgBindings, pBind->pBindings, sizeof(DBBINDING) * (*pcBindings));			hr = S_OK;		}		return hr;	}	STDMETHOD(ReleaseAccessor)(HACCESSOR hAccessor,							   DBREFCOUNT *pcRefCount)	{		ATLTRACE(atlTraceDBProvider, 2, _T("SFAccessorImpl::ReleaseAccessor\n"));		T::ObjectLock cab((T*)this);		BindType* pBind;		bool bFound = m_rgBindings.Lookup((INT_PTR)hAccessor, pBind);		if (!bFound || pBind == NULL)			return DB_E_BADACCESSORHANDLE;		DBREFCOUNT cRefCount = T::_ThreadModel::Decrement((LONG*)&pBind->dwRef);		if (pcRefCount != NULL)			*pcRefCount = cRefCount;		if (cRefCount == 0)		{			delete [] pBind->pBindings;			delete pBind;			return m_rgBindings.RemoveKey(hAccessor) ? S_OK : DB_E_BADACCESSORHANDLE;		}		return S_OK;	}	BindingVector m_rgBindings;};

⌨️ 快捷键说明

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