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

📄 propset.cpp

📁 连接oracle
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		// Do a seek from the beginning of the property set.
		LISet32( li, ulSectionStart.LowPart + pido.dwOffset );
		pIStream->Seek( liPropSet, STREAM_SEEK_SET, NULL );
		pIStream->Seek( li, STREAM_SEEK_CUR, NULL );

		// Now pIStream is at the type/value pair
		if (pido.propertyID != 0)
		{
			pProp = new CProperty( pido.propertyID, NULL, 0 );
			pProp->ReadFromStream( pIStream );
			pProp->AssertValid();
			m_PropList.AddTail( pProp );
			m_PropList.AssertValid();
		}
		else
		{
			ReadNameDictFromStream( pIStream );
		}
	}

	pIStrPIDO->Release();

	return TRUE;
}

BOOL CPropertySection::GetID( LPCTSTR pszName, DWORD* pdwPropID )
{
	CString strName(pszName);
	strName.MakeLower();        // Dictionary stores all names in lowercase

	void* pvID;
	if (m_NameDict.Lookup(strName, pvID))
	{
		*pdwPropID = (DWORD)pvID;
		return TRUE;
	}

	// Failed to find entry in dictionary
	return FALSE;
}

BOOL CPropertySection::SetName( DWORD dwPropID, LPCTSTR pszName )
{
	BOOL bSuccess = TRUE;
	CString strName(pszName);
	strName.MakeLower();        // Dictionary stores all names in lowercase

	TRY
	{
		void* pDummy;
		BOOL bNameExists = m_NameDict.Lookup(strName, pDummy);

		ASSERT(! bNameExists);  // Property names must be unique.

		if (bNameExists)
			bSuccess = FALSE;
		else
			m_NameDict.SetAt(strName, (void*)dwPropID);
	}
	CATCH (CException, e)
	{
		TRACE0("Failed to add entry to dictionary.\n");
		bSuccess = FALSE;
	}
	END_CATCH

	return bSuccess;
}

struct DICTENTRYHEADER
{
	DWORD dwPropID;
	DWORD cb;
};

struct DICTENTRY
{
	DICTENTRYHEADER hdr;
	char sz[256];
};

BOOL CPropertySection::ReadNameDictFromStream( IStream* pIStream )
{
	ULONG cb;
	ULONG cbRead = 0;

	// Read dictionary header (count).
	ULONG cProperties = 0;
	pIStream->Read((LPVOID)&cProperties, sizeof(cProperties), &cb);
	if (sizeof(cProperties) != cb)
	{
		TRACE0("Read of dictionary header failed.\n");
		return FALSE;
	}

	ULONG iProp;
	DICTENTRY entry;

	for (iProp = 0; iProp < cProperties; iProp++)
	{
		// Read entry header (dwPropID, cch).
		if (FAILED(pIStream->Read((LPVOID)&entry, sizeof(DICTENTRYHEADER),
			&cbRead)) ||
			(sizeof(DICTENTRYHEADER) != cbRead))
		{
			TRACE0("Read of dictionary entry failed.\n");
			return FALSE;
		}

		// Read entry data (name).

		cb = entry.hdr.cb;

		if (FAILED(pIStream->Read((LPVOID)&entry.sz, cb, &cbRead)) ||
			(cbRead != cb))
		{
			TRACE0("Read of dictionary entry failed.\n");
			return FALSE;
		}

		LPTSTR pszName;

#ifdef _UNICODE
		// Persistent form is always ANSI/DBCS.  Convert to Unicode.
		WCHAR wszName[256];
		_mbstowcsz(wszName, entry.sz, 256);
		pszName = wszName;
#else // _UNICODE
		pszName = entry.sz;
#endif // _UNICODE

		// Section's "name" appears first in list and has dwPropID == 0.
		if ((iProp == 0) && (entry.hdr.dwPropID == 0))
			m_strSectionName = pszName;             // Section name
		else
			SetName(entry.hdr.dwPropID, pszName);   // Some other property
	}

	return TRUE;
}

static BOOL WriteNameDictEntry(IStream* pIStream, DWORD dwPropID, CString& strName)
{
	ULONG cb;
	ULONG cbWritten = 0;
	DICTENTRY entry;

	entry.hdr.dwPropID = dwPropID;
	entry.hdr.cb = min(strName.GetLength() + 1, 255);
#ifdef _UNICODE
	// Persistent form is always ANSI/DBCS.  Convert from Unicode.
	_wcstombsz(entry.sz, (LPCWSTR)strName, 256);
#else // _UNICODE
	memcpy(entry.sz, (LPCSTR)strName, (size_t)entry.hdr.cb);
#endif // _UNICODE

	cb = sizeof(DICTENTRYHEADER) + entry.hdr.cb;

	if (FAILED(pIStream->Write((LPVOID)&entry, cb, &cbWritten)) ||
		(cbWritten != cb))
	{
		TRACE0("Write of dictionary entry failed.\n");
		return FALSE;
	}

	return TRUE;
}

BOOL CPropertySection::WriteNameDictToStream( IStream* pIStream )
{
	ULONG cb;

	// Write dictionary header (count).
	ULONG cProperties = m_NameDict.GetCount() + 1;
	pIStream->Write((LPVOID)&cProperties, sizeof(cProperties), &cb);
	if (sizeof(cProperties) != cb)
	{
		TRACE0("Write of dictionary header failed.\n");
		return FALSE;
	}

	POSITION pos;
	CString strName;
	void* pvID;

	// Write out section's "name" with dwPropID == 0 first
	if (! WriteNameDictEntry(pIStream, 0, m_strSectionName))
		return FALSE;

	// Enumerate contents of dictionary and write out (dwPropID, cb, name).
	pos = m_NameDict.GetStartPosition();
	while (pos != NULL)
	{
		m_NameDict.GetNextAssoc( pos, strName, pvID );
		if (! WriteNameDictEntry(pIStream, (DWORD)pvID, strName))
			return FALSE;
	}

	return TRUE;
}

BOOL CPropertySection::SetSectionName( LPCTSTR pszName )
{
	m_strSectionName = pszName;
	return TRUE;
}

LPCTSTR CPropertySection::GetSectionName( void )
{
	return (LPCTSTR)m_strSectionName;
}


/////////////////////////////////////////////////////////////////////////////
// Implementation of the CPropertySet class

CPropertySet::CPropertySet( void )
{
	m_PH.wByteOrder = 0xFFFE;
	m_PH.wFormat = 0;
	m_PH.dwOSVer = (DWORD)MAKELONG( LOWORD(GetVersion()), 2 );
	m_PH.clsID =  GUID_NULL;
	m_PH.cSections = 0;

}

CPropertySet::CPropertySet( CLSID clsID )
{
	m_PH.wByteOrder = 0xFFFE;
	m_PH.wFormat = 0;
	m_PH.dwOSVer = (DWORD)MAKELONG( LOWORD(GetVersion()), 2 );
	m_PH.clsID = clsID;
	m_PH.cSections = 0;
}

CPropertySet::~CPropertySet()
{   RemoveAll();  }

BOOL CPropertySet::Set( CLSID FormatID, DWORD dwPropID, LPVOID pValue, DWORD dwType )
{
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect == NULL)
	{
		if ((pSect = new CPropertySection( FormatID )) != NULL)
			AddSection( pSect );
	}
	pSect->Set( dwPropID, pValue, dwType );
	return TRUE;
}

BOOL CPropertySet::Set( CLSID FormatID, DWORD dwPropID, LPVOID pValue )
{
	// Since there is no dwType, we have to assume that the property
	// already exists.  If it doesn't, fail.
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect != NULL)
		return pSect->Set( dwPropID, pValue );
	else
		return FALSE;
}

LPVOID CPropertySet::Get( CLSID FormatID, DWORD dwPropID, DWORD* pcb )
{
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect)
		return pSect->Get( dwPropID, pcb );
	else
		return NULL;
}

LPVOID CPropertySet::Get( CLSID FormatID, DWORD dwPropID )
{   return Get( FormatID, dwPropID, (DWORD*)NULL ); }

void CPropertySet::Remove( CLSID FormatID, DWORD dwPropID )
{
	CPropertySection*  pSect = GetSection( FormatID );
	if (pSect)
		pSect->Remove( dwPropID );
}

void CPropertySet::Remove( CLSID FormatID )
{
	CPropertySection* pSect;
	POSITION posRemove = m_SectionList.GetHeadPosition();
	POSITION pos = posRemove;
	while( posRemove != NULL )
	{
		pSect = (CPropertySection*)m_SectionList.GetNext( pos );
		if (IsEqualCLSID( pSect->m_FormatID, FormatID ))
		{
			m_SectionList.RemoveAt( posRemove );
			delete pSect;
			m_PH.cSections--;
			return;
		}
		posRemove = pos;
	}
}

void CPropertySet::RemoveAll( )
{
	POSITION pos = m_SectionList.GetHeadPosition();
	while( pos != NULL )
	{
		delete (CPropertySection*)m_SectionList.GetNext( pos );
	}
	m_SectionList.RemoveAll();
	m_PH.cSections = 0;
}

CPropertySection* CPropertySet::GetSection( CLSID FormatID )
{
	POSITION pos = m_SectionList.GetHeadPosition();
	CPropertySection* pSect;
	while (pos != NULL)
	{
		pSect = (CPropertySection*)m_SectionList.GetNext( pos );
		if (IsEqualCLSID( pSect->m_FormatID, FormatID ))
			return pSect;
	}
	return NULL;
}

CPropertySection* CPropertySet::AddSection( CLSID FormatID )
{
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect)
		return pSect;

	pSect = new CPropertySection( FormatID ) ;
	if (pSect)
		AddSection( pSect );
	return pSect;
}

void CPropertySet::AddSection( CPropertySection* pSect )
{
	m_SectionList.AddTail( pSect );
	m_PH.cSections++;
}

CProperty* CPropertySet::GetProperty( CLSID FormatID, DWORD dwPropID )
{
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect)
		return pSect->GetProperty( dwPropID );
	else
		return NULL;
}

void CPropertySet::AddProperty( CLSID FormatID, CProperty* pProp )
{
	CPropertySection* pSect = GetSection( FormatID );
	if (pSect)
		pSect->AddProperty( pProp );
}

WORD CPropertySet::GetByteOrder( void )
{   return m_PH.wByteOrder;  }

WORD CPropertySet::GetFormatVersion( void )
{   return m_PH.wFormat;  }

void CPropertySet::SetFormatVersion( WORD wFmtVersion )
{   m_PH.wFormat = wFmtVersion;  }

DWORD CPropertySet::GetOSVersion( void )
{   return m_PH.dwOSVer;  }

void CPropertySet::SetOSVersion( DWORD dwOSVer )
{   m_PH.dwOSVer = dwOSVer;  }

CLSID CPropertySet::GetClassID( void )
{   return m_PH.clsID;  }

void CPropertySet::SetClassID( CLSID clsID )
{   m_PH.clsID = clsID;  }

DWORD CPropertySet::GetCount( void )
{   return m_SectionList.GetCount();  }

CObList* CPropertySet::GetList( void )
{   return &m_SectionList;  }


BOOL CPropertySet::WriteToStream( IStream* pIStream )
{
	LPSTREAM        pIStrFIDO;
	FORMATIDOFFSET  fido;
	ULONG           cb;
	ULARGE_INTEGER  ulSeek;
	LARGE_INTEGER   li;

	// Write the Property List Header
	m_PH.cSections = m_SectionList.GetCount();
	pIStream->Write((LPVOID)&m_PH, sizeof(m_PH), &cb);
	if (sizeof(m_PH) != cb)
	{
		TRACE0("Write of Property Set Header failed.\n");
		return FALSE;
	}

	if (m_SectionList.IsEmpty())
	{
		TRACE0("Warning: Wrote empty property set.\n");
		return TRUE;
	}

	// After the header is the list of Format ID/Offset pairs
	// Since there is an ID/Offset pair for each section and we
	// need to write the ID/Offset pair as we write each section
	// we clone the stream and use the clone to access the
	// table of ID/offset pairs (FIDO)...
	//
	pIStream->Clone( &pIStrFIDO );

	// Now seek pIStream past the FIDO list
	//
	LISet32( li, m_PH.cSections * sizeof( FORMATIDOFFSET ) );
	pIStream->Seek( li, STREAM_SEEK_CUR, &ulSeek);

	// Write each section.
	CPropertySection*   pSect = NULL;
	POSITION            pos = m_SectionList.GetHeadPosition();
	while( pos != NULL )
	{
		// Get next element (note cast)
		pSect = (CPropertySection*)m_SectionList.GetNext( pos );

		// Write it
		if (!pSect->WriteToStream( pIStream ))
		{
			pIStrFIDO->Release();
			return FALSE;
		}

		// Using our cloned stream write the Format ID / Offset pair
		fido.formatID = pSect->m_FormatID;
		fido.dwOffset = ulSeek.LowPart;
		pIStrFIDO->Write((LPVOID)&fido, sizeof(fido), &cb);
		if (sizeof(fido) != cb)
		{
			TRACE0("Write of 'fido' failed.\n");
			pIStrFIDO->Release();
			return FALSE;
		}

		// Get the seek offset (for pIStream) after the write
		LISet32( li, 0 );
		pIStream->Seek( li, STREAM_SEEK_CUR, &ulSeek );
	}

	pIStrFIDO->Release();

	return TRUE;
}

BOOL CPropertySet::ReadFromStream( IStream* pIStream )
{
	ULONG               cb;
	FORMATIDOFFSET      fido;
	ULONG               cSections;
	LPSTREAM            pIStrFIDO;
	CPropertySection*   pSect;
	LARGE_INTEGER       li;
	LARGE_INTEGER       liPropSet;

	// Save the stream position at which the property set starts.
	LARGE_INTEGER liZero = {0,0};
	pIStream->Seek( liZero, STREAM_SEEK_CUR, (ULARGE_INTEGER*)&liPropSet );

	if (m_PH.cSections || !m_SectionList.IsEmpty())
		 RemoveAll();

	// The stream starts like this:
	//  wByteOrder   wFmtVer   dwOSVer   clsID  cSections
	// Which is nice, because our PROPHEADER is the same!
	pIStream->Read( (LPVOID)&m_PH, sizeof( m_PH ), &cb );
	if (cb != sizeof(m_PH))
		return FALSE;

	// Now we're pointing at the first of the FormatID/Offset pairs
	// (FIDOs).   To get to each section we use a cloned stream
	// to stay back and point at the FIDOs (pIStrFIDO).  We seek
	// pIStream to each of the sections, creating CProperitySection
	// and so forth as we go...
	//
	pIStream->Clone( &pIStrFIDO );

	cSections = m_PH.cSections;
	while (cSections--)
	{
		pIStrFIDO->Read( (LPVOID)&fido, sizeof( fido ), &cb );
		if (cb != sizeof(fido))
		{
			pIStrFIDO->Release();
			return FALSE;
		}

		// Do a seek from the beginning of the property set.
		LISet32( li, fido.dwOffset );
		pIStream->Seek( liPropSet, STREAM_SEEK_SET, NULL );
		pIStream->Seek( li, STREAM_SEEK_CUR, NULL );

		// Now pIStream is at the type/value pair
		pSect = new CPropertySection;
		pSect->SetFormatID( fido.formatID );
		pSect->ReadFromStream( pIStream, liPropSet );
		m_SectionList.AddTail( pSect );
	}

	pIStrFIDO->Release();
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

#endif // !defined(_MAC)

⌨️ 快捷键说明

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