Rowset.Release( );
读操作也完成了,是不是仍然很简单呢?下面我们再来看看最麻烦的二进制数据(text、ntext、image等)的读写。要实现BLOB数据的读写,我们需要一个辅助的类,定义如下:
class CSequentialStream : public ISequentialStream // BLOB 数据访问类
{
public:
CSequentialStream( );
virtual ~CSequentialStream( );
virtual BOOL Seek( ULONG uPosition );
virtual BOOL Clear( );
virtual ULONG GetLength( ) { return m_uBufferUsed; };
virtual operator void* const( ) { return m_pBuffer; };
STDMETHODIMP_( ULONG ) AddRef( ) { return ++ m_uRefCount; };
STDMETHODIMP_( ULONG ) Release( ) { ASSERT( m_uRefCount != 0U ); -- m_uRefCount; if( m_uRefCount == 0U ) { delete this; } return m_uRefCount; };
STDMETHODIMP QueryInterface( REFIID riid, LPVOID* ppv );
STDMETHODIMP Read( void __RPC_FAR* pv, ULONG cb, ULONG __RPC_FAR* pcbRead );
STDMETHODIMP Write( const void __RPC_FAR* pv, ULONG cb, ULONG __RPC_FAR* pcbWritten );
void ResetPosition( ) { m_uPosition = 0U; };
HRESULT PreAllocBuffer( ULONG uSize );
private:
ULONG m_uRefCount; // reference count
void* m_pBuffer; // buffer
ULONG m_uBufferUsed; // buffer used
ULONG m_uBufferSize; // buffer size
ULONG m_uPosition; // current index position in the buffer
};
实现如下:
CSequentialStream::CSequentialStream( ) : m_uRefCount( 0U ), m_pBuffer( NULL ), m_uBufferUsed( 0U ), m_uBufferSize( 0U ), m_uPosition( 0U )
{
AddRef( );
}
CSequentialStream::~CSequentialStream( )
{
Clear( );
}
HRESULT CSequentialStream::QueryInterface( REFIID riid, void** ppv )
{
if( riid == IID_IUnknown || riid == IID_ISequentialStream )
{
* ppv = this;
( ( IUnknown* )*ppv )->AddRef( );
return S_OK;
}
* ppv = NULL;
return E_NOINTERFACE;
}
BOOL CSequentialStream::Seek( ULONG uPosition )
{
ASSERT( uPosition < m_uBufferUsed );
m_uPosition = uPosition;
return TRUE;
}
BOOL CSequentialStream::Clear( )
{
m_uBufferUsed = 0U;
m_uBufferSize = 0U;
m_uPosition = 0U;
( m_pBuffer != NULL ? CoTaskMemFree( m_pBuffer ) : 0 );
m_pB