|
|
//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000 - 2000
//
// File: snapinpersistence.cpp
//
// Contents:
//
// Classes: CComponentPersistor, CDPersistor
//
//____________________________________________________________________________
#include "stdafx.h"
#include "mtnode.h"
#include "regutil.h"
/*+-------------------------------------------------------------------------*
* * struct less_component * * PURPOSE: implements viewID and CLSID based comparison for CComponent* pointers * This allows to sort components before pesisting *+-------------------------------------------------------------------------*/ struct less_component // define the struct to perform the comparison
{ typedef std::pair<int, CComponent*> comp_type;
bool operator ()(const comp_type& arg1, const comp_type& arg2) const { return arg1.first != arg2.first ? arg1.first < arg2.first : arg1.second->GetCLSID() < arg2.second->GetCLSID(); } };
/*+-------------------------------------------------------------------------*
* * struct less_compdata * * PURPOSE: implements CLSID based comparison for CComponentData* pointers * This allows to sort component data before pesisting *+-------------------------------------------------------------------------*/ struct less_compdata // define the struct to perform the comparison
{ bool operator ()(const CComponentData* pCD1, const CComponentData* pCD2) const { return pCD1->GetCLSID() < pCD2->GetCLSID(); } };
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage * * PURPOSE: gets CXML_IStorage for snapin. creates & inits one there is none * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * CXML_IStorage *& pXMLStorage [out] xml storage for the snapin * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage(int idView, const CLSID& clsid, CXML_IStorage *& pXMLStorage) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetXmlStorage"));
// init out parameter
pXMLStorage = NULL;
// try to find it first
bool bFound = false; sc = ScFindXmlStorage( idView, clsid, bFound, pXMLStorage ); if (sc) return sc;
if (bFound) { // recheck
sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc;
// return the ponter we found
return sc; }
// insert the new one
typedef std::map<key_t, CXML_IStorage> col_t; col_t::iterator it = m_XMLStorage.insert(col_t::value_type( key_t( idView, clsid ), CXML_IStorage())).first; pXMLStorage = &it->second;
// recheck
sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScFindXmlStorage * * PURPOSE: Finds the storage. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] whether data was found * CXML_IStorage *& pXMLStorage [out] pointer to found data * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages:: ScFindXmlStorage(int idView, const CLSID& clsid, bool& bFound, CXML_IStorage *& pXMLStorage) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScFindXmlStorage"));
// init out parameters
bFound = false; pXMLStorage = NULL;
typedef std::map<key_t, CXML_IStorage> col_t; col_t::iterator it = m_XMLStorage.find( key_t( idView, clsid ) );
// give a try to find it by the hash value
if ( it == m_XMLStorage.end() ) { bool bFoundInHash = false; sc = ScCheckForStreamsAndStoragesByHashValue( idView, clsid, bFoundInHash ); if (sc) return sc;
if ( !bFoundInHash ) // if not found - return
return sc;
// try again - it may be in the map by now
it = m_XMLStorage.find( key_t( idView, clsid ) );
if ( it == m_XMLStorage.end() ) // if still not found - return
return sc; }
// found!
bFound = true; pXMLStorage = &it->second;
#ifdef DBG // set the snapin name to identify the problems in debug
tstring strSnapin; GetSnapinNameFromCLSID( clsid, strSnapin ); pXMLStorage->m_dbg_Data.SetTraceInfo(TraceSnapinPersistenceError, true, strSnapin); #endif // #ifdef DBG
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScFindXmlStream * * PURPOSE: Finds the stream. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] whether data was found * CXML_IStream *& pXMLStream [out] pointer to found data * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages:: ScFindXmlStream(int idView, const CLSID& clsid, bool& bFound, CXML_IStream *& pXMLStream) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScFindXmlStream"));
// init out parameters
bFound = false; pXMLStream = NULL;
typedef std::map<key_t, CXML_IStream> col_t; col_t::iterator it = m_XMLStream.find( key_t( idView, clsid ) );
// give a try to find it by the hash value
if ( it == m_XMLStream.end() ) { bool bFoundInHash = false; sc = ScCheckForStreamsAndStoragesByHashValue( idView, clsid, bFoundInHash ); if (sc) return sc;
if ( !bFoundInHash ) // if not found - return
return sc;
// try again - it may be in the map by now
it = m_XMLStream.find( key_t( idView, clsid ) );
if ( it == m_XMLStream.end() ) // if still not found - return
return sc; }
// found!
bFound = true; pXMLStream = &it->second;
#ifdef DBG // set the snapin name to identify the problems in debug
tstring strSnapin; GetSnapinNameFromCLSID( clsid, strSnapin ); pXMLStream->m_dbg_Data.SetTraceInfo(TraceSnapinPersistenceError, true, strSnapin); #endif // #ifdef DBG
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetXmlStream * * PURPOSE: * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * CXML_IStream *& pXMLStream [out] xml stream for the snapin * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetXmlStream(int idView, const CLSID& clsid, CXML_IStream *& pXMLStream) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetXmlStream"));
// init out parameter
pXMLStream = NULL;
// try to find it first
bool bFound = false; sc = ScFindXmlStream( idView, clsid, bFound, pXMLStream ); if (sc) return sc;
if (bFound) { // recheck
sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc;
// return the ponter we found
return sc; }
// insert the new one
typedef std::map<key_t, CXML_IStream> col_t; col_t::iterator it = m_XMLStream.insert(col_t::value_type( key_t( idView, clsid ), CXML_IStream())).first; pXMLStream = &it->second;
// recheck
sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScInitIStorage * * PURPOSE: Initializes IStorage from the given source data * * PARAMETERS: * int idView [in] view number * LPCWSTR szHash [in] hash key (name of storage element) identifying the snapin * IStorage *pSource [in] source data for initialization * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScInitIStorage( int idView, LPCWSTR szHash, IStorage *pSource ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScInitIStorage"));
// parameter check;
sc = ScCheckPointers( pSource ); if (sc) return sc;
// insert the new one
typedef std::map<hash_t, CXML_IStorage> col_t; col_t::iterator it = m_StorageByHash.insert( col_t::value_type(hash_t(idView, szHash), CXML_IStorage())).first; CXML_IStorage *pXMLStorage = &it->second;
// recheck the pointer
sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc;
sc = pXMLStorage->ScInitializeFrom( pSource ); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScInitIStream * * PURPOSE: Initializes IStream from the given source data * * PARAMETERS: * int idView [in] view number * LPCWSTR szHash [in] hash key (name of storage element) identifying the snapin * IStream *pSource [in] source data for initialization * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScInitIStream ( int idView, LPCWSTR szHash, IStream *pSource ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScInitIStream"));
// parameter check;
sc = ScCheckPointers( pSource ); if (sc) return sc;
// insert the new one
typedef std::map<hash_t, CXML_IStream> col_t; col_t::iterator it = m_StreamByHash.insert( col_t::value_type(hash_t(idView, szHash), CXML_IStream())).first; CXML_IStream *pXMLStream = &it->second;
// recheck the pointer
sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc;
sc = pXMLStream->ScInitializeFrom( pSource ); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetIStorage * * PURPOSE: returns existing or creates a new IStorage for the component * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * IStorage **ppStorage [out] - storage for the component * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetIStorage( int idView, const CLSID& clsid, IStorage **ppStorage ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetIStorage"));
// paramter check
sc = ScCheckPointers( ppStorage ); if (sc) return sc;
// init an out parameter
*ppStorage = NULL;
CXML_IStorage *pXMLStorage = NULL; sc = ScGetXmlStorage( idView, clsid, pXMLStorage ); if (sc) return sc;
// recheck the pointer
sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) return sc;
// get the interface
sc = pXMLStorage->ScGetIStorage(ppStorage); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScGetIStream * * PURPOSE: returns existing or creates a new IStream for the component * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * IStream **ppStream [out] - stream fro the component * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScGetIStream ( int idView, const CLSID& clsid, IStream **ppStream ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScGetIStream"));
// paramter check
sc = ScCheckPointers( ppStream ); if (sc) return sc;
// init an out parameter
*ppStream = NULL;
CXML_IStream *pXMLStream = NULL; sc = ScGetXmlStream( idView, clsid, pXMLStream ); if (sc) return sc;
// recheck the pointer
sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) return sc;
// get the interface
sc = pXMLStream->ScGetIStream(ppStream); if (sc) return sc;
return sc; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::HasStream * * PURPOSE: Checks if snapins stream is available * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * * RETURNS: * bool - true == found * \***************************************************************************/ bool CMTSnapinNodeStreamsAndStorages::HasStream(int idView, const CLSID& clsid) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::HasStream"));
bool bFound = false; CXML_IStream * pUnused = NULL; sc = ScFindXmlStream( idView, clsid, bFound, pUnused ); if (sc) return false; // not found if error
return bFound; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::HasStorage * * PURPOSE: Checks if snapins storage is available * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * * RETURNS: * bool - true == found * \***************************************************************************/ bool CMTSnapinNodeStreamsAndStorages::HasStorage(int idView, const CLSID& clsid) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::HasStorage"));
bool bFound = false; CXML_IStorage * pUnused = NULL; sc = ScFindXmlStorage( idView, clsid, bFound, pUnused ); if (sc) return false; // not found if error
return bFound; }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue * * PURPOSE: Looks up streams and storages by a generated hash value. * if the streams/storages are found, they are moved to the * the list of 'recognized' storages - those identified by the CLSID. * This is a required step to recognize the streams and storages retrieved * from a structured storage based console, where they are identified by the * hash value. It is not possible to map from the hash value to the key * in unique way, so the collections of data are kept untill the request * comes and the hash can be mapped by matching with the one generated from * the key supplied by request. * * PARAMETERS: * int idView [in] view number * const CLSID& clsid [in] CLSID identifying the snapin * bool& bFound [out] - true if at least one matching hash value was found * * RETURNS: * SC - result code * \***************************************************************************/ SC CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue( int idView, const CLSID& clsid, bool& bFound ) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::ScCheckForStreamsAndStoragesByHashValue"));
bFound = false;
wchar_t buff[MAX_PATH]; std::wstring strHashValue = CMTNode::GetComponentStreamName( buff, clsid );
// process streams
{ typedef std::map<hash_t, CXML_IStream> col_t; col_t::iterator it = m_StreamByHash.begin(); while ( it != m_StreamByHash.end() ) { if ( it->first.second == strHashValue ) { bFound = true; // put to a 'recognized' list
int idView = it->first.first; m_XMLStream[key_t(idView, clsid)] = it->second; // for sanity: make sure it is not in the storage map!
ASSERT( m_StorageByHash.find(it->first) == m_StorageByHash.end() ); m_StorageByHash.erase( it->first );
// remove from hash table
it = m_StreamByHash.erase( it ); } else ++ it; }
if ( bFound ) return sc; }
// process storages
{ typedef std::map<hash_t, CXML_IStorage> col_t; col_t::iterator it = m_StorageByHash.begin(); while ( it != m_StorageByHash.end() ) { if ( it->first.second == strHashValue ) { bFound = true; // put to a 'recognized' list
int idView = it->first.first; m_XMLStorage[key_t(idView, clsid)] = it->second; // for sanity: make sure it is not in the stream map!
ASSERT( m_StreamByHash.find( it->first ) == m_StreamByHash.end() ); m_StreamByHash.erase( it->first );
// remove from hash table
it = m_StorageByHash.erase( it ); } else ++it; } }
return sc; }
/*+-------------------------------------------------------------------------*
* * CMTSnapinNodeStreamsAndStorages::RemoveView * * PURPOSE: removes information about one view * * PARAMETERS: * int idView [in] view number * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CMTSnapinNodeStreamsAndStorages::RemoveView(int nViewId) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::RemoveView"));
{ // remove streams
std::map<key_t, CXML_IStream>::iterator it_stream; for (it_stream = m_XMLStream.begin();it_stream != m_XMLStream.end();) { if (it_stream->first.first == nViewId) it_stream = m_XMLStream.erase(it_stream); else ++it_stream; } } { // remove storages
std::map<key_t, CXML_IStorage>::iterator it_storage; for (it_storage = m_XMLStorage.begin();it_storage != m_XMLStorage.end();) { if (it_storage->first.first == nViewId) it_storage = m_XMLStorage.erase(it_storage); else ++it_storage; } }
{ // remove streams by hash
std::map<hash_t, CXML_IStream>::iterator it_stream; for (it_stream = m_StreamByHash.begin();it_stream != m_StreamByHash.end();) { if (it_stream->first.first == nViewId) it_stream = m_StreamByHash.erase(it_stream); else ++it_stream; } } { // remove storages by hash
std::map<hash_t, CXML_IStorage>::iterator it_storage; for (it_storage = m_StorageByHash.begin();it_storage != m_StorageByHash.end();) { if (it_storage->first.first == nViewId) it_storage = m_StorageByHash.erase(it_storage); else ++it_storage; } } }
/***************************************************************************\
* * METHOD: CMTSnapinNodeStreamsAndStorages::Persist * * PURPOSE: persists stream and storage collections * * PARAMETERS: * CPersistor& persistor [in] peristor for the operation * bool bPersistViewId [in] whether to store view identifier * (ComponentDatas are saved with thi parameter set to false, * since the view id has no meaning for them) * * RETURNS: * SC - result code * \***************************************************************************/ void CMTSnapinNodeStreamsAndStorages::Persist(CPersistor& persistor, bool bPersistViewId) { DECLARE_SC(sc, TEXT("CMTSnapinNodeStreamsAndStorages::Persist"));
if (persistor.IsStoring()) { // define iterators for saving
std::map<key_t, CXML_IStorage>::iterator itStorages; std::map<key_t, CXML_IStream>::iterator itStreams; std::map<hash_t, CXML_IStorage>::iterator itStoragesByHash; std::map<hash_t, CXML_IStream>::iterator itStreamsByHash;
// init iterators to point to the start of the collections
itStorages = m_XMLStorage.begin(); itStreams = m_XMLStream.begin(); itStoragesByHash = m_StorageByHash.begin(); itStreamsByHash = m_StreamByHash.begin();
// we have 4 collections to save here.
// while saving them one by one would not change the functionality,
// console file is more readable when they are sorted by the snapin's clsid.
// following code does not do any explicit sorting, but persist in the
// certain order assurring the result is a sorted array of persisted data
// These 4 iterators represents 4 lines (queues) of sorted items, so
// in order to get the proper result we just need to merge them correctly.
// This is done by the following loop which splits the persistence in two steps:
// 1. Pick the right line (iterator) to persist it's first item.
// 2. Persist the selected item.
// There are 4 boolean variables indicating which item to save (only one can be 'true')
// thus the second part is strigth-forward - test variables and do the persisting.
// The iterator is picked by the following rules.
// 1.1 Only lines with items compete.
// 1.2 If there are items in lines key'ed by guids (in contrast to hash values)
// they are processed first, leaving hash values at the end.
// 1.3 If still there are 2 lines competing - their key's are compared and one
// with a smaller key is choosen
while ( 1 ) { // see what collection has data to save
bool bSaveStorage = ( itStorages != m_XMLStorage.end() ); bool bSaveStream = ( itStreams != m_XMLStream.end() ); bool bSaveStorageByHash = ( itStoragesByHash != m_StorageByHash.end() ); bool bSaveStreamByHash = ( itStreamsByHash != m_StreamByHash.end() );
// exit if nothind to tsave - assume we are done
if ( !( bSaveStorage || bSaveStream || bSaveStorageByHash || bSaveStreamByHash )) break;
// if both main collections are willing to save - let the smaller key win
if ( bSaveStorage && bSaveStream ) { bSaveStorage = ( itStorages->first < itStreams->first ); bSaveStream = !bSaveStorage; }
// if not done with a main collections - dont save by hash
if ( bSaveStorage || bSaveStream ) bSaveStorageByHash = bSaveStreamByHash = false;
// if both hash collections are willing to save - let the smaller key win
if ( bSaveStorageByHash && bSaveStreamByHash ) { bSaveStorageByHash = ( itStoragesByHash->first < itStreamsByHash->first ); bSaveStreamByHash = !bSaveStorageByHash; }
// only variable one can be set !
ASSERT ( 1 == ( (int)bSaveStorage + (int)bSaveStream + (int)bSaveStorageByHash + (int)bSaveStreamByHash) );
// add the tag for snapin entry
CPersistor persistorChild(persistor, GetItemXMLType());
// save one winning entry
if ( bSaveStorage ) { // persist a key
CLSID clsid = itStorages->first.second; int idView = itStorages->first.first;
persistorChild.Persist( clsid, XML_NAME_CLSID_SNAPIN );
if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView);
// persist data
persistorChild.Persist( itStorages->second ); // advance to the next entry
++itStorages; } else if (bSaveStream) { // persist a key
CLSID clsid = itStreams->first.second; int idView = itStreams->first.first;
persistorChild.Persist( clsid, XML_NAME_CLSID_SNAPIN );
if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView);
// persist data
persistorChild.Persist( itStreams->second );
// advance to the next entry
++itStreams; } else if ( bSaveStorageByHash ) { // persist a key
std::wstring hash = itStoragesByHash->first.second; int idView = itStoragesByHash->first.first; if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView);
CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash );
// persist data
persistorChild.Persist( itStoragesByHash->second ); // advance to the next entry
++itStoragesByHash; } else if (bSaveStreamByHash) { // persist a key
std::wstring hash = itStreamsByHash->first.second; int idView = itStreamsByHash->first.first;
if (bPersistViewId) persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView);
CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash );
// persist data
persistorChild.Persist( itStreamsByHash->second );
// advance to the next entry
++itStreamsByHash; } else { ASSERT( false ); // should not come here!
break; } }
} else { XMLListCollectionBase::Persist(persistor); } }
/*+-------------------------------------------------------------------------*
* * CMTSnapinNodeStreamsAndStorages::OnNewElement * * PURPOSE: called for each component data found loading XML doc * * PARAMETERS: * CPersistor& persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CMTSnapinNodeStreamsAndStorages::OnNewElement(CPersistor& persistor) { DECLARE_SC(sc, TEXT("CDPersistor::OnNewElement"));
// persistor is 'locked' on particular child element, so that
// a simple CPersistor constructor can be used to create child's peristor.
// Creating the child persistor is also necessary to release that 'lock'
CPersistor persistorChild(persistor, GetItemXMLType());
CLSID clsid; std::wstring hash; bool bByHash = false; ZeroMemory(&clsid,sizeof(clsid));
// look how entry is key'ed - by regular key of by a hash value
if ( persistorChild.HasElement( XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN ) ) { CPersistor persistorHash( persistorChild, XML_TAG_HASH_VALUE, XML_NAME_CLSID_SNAPIN); persistorHash.PersistContents( hash ); bByHash = true; } else persistorChild.Persist(clsid, XML_NAME_CLSID_SNAPIN);
// persist the view id - default to value used to store component data
int idView = VIEW_ID_DOCUMENT; persistorChild.PersistAttribute(XML_ATTR_ICOMPONENT_VIEW_ID, idView, attr_optional);
// now we should look what data do we have
// and persist if recognized
if (persistorChild.HasElement(CXML_IStream::_GetXMLType(),NULL)) { CXML_IStream *pXMLStream = NULL;
if (bByHash) { pXMLStream = &m_StreamByHash[ hash_t(idView, hash) ]; } else { sc = ScGetXmlStream( idView, clsid, pXMLStream ); if (sc) sc.Throw(); }
sc = ScCheckPointers( pXMLStream, E_UNEXPECTED ); if (sc) sc.Throw();
persistorChild.Persist( *pXMLStream ); } else if (persistorChild.HasElement(CXML_IStorage::_GetXMLType(),NULL)) { CXML_IStorage *pXMLStorage = NULL;
if (bByHash) { pXMLStorage = &m_StorageByHash[ hash_t(idView, hash) ]; } else { sc = ScGetXmlStorage( idView, clsid, pXMLStorage ); if (sc) sc.Throw(); }
sc = ScCheckPointers( pXMLStorage, E_UNEXPECTED ); if (sc) sc.Throw();
persistorChild.Persist( *pXMLStorage ); } }
/*+-------------------------------------------------------------------------*
*+-------------------------------------------------------------------------* *+-------------------------------------------------------------------------* *+-------------------------------------------------------------------------*/
/*+-------------------------------------------------------------------------*
* * CComponentPersistor::Persist * * PURPOSE: persists IComponent collection related to snapin ( and its extensions) * * PARAMETERS: * CPersistor &persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CComponentPersistor::Persist(CPersistor &persistor) { DECLARE_SC(sc, TEXT("CComponentPersistor::Persist"));
// let the base class do the job
BC::Persist( persistor, true /*bPersistViewId*/ ); }
/***************************************************************************\
* * METHOD: CComponentPersistor::ScReset * * PURPOSE: Restores component xml streams/storages into "Just loaded" state * * PARAMETERS: * * RETURNS: * SC - result code * \***************************************************************************/ SC CComponentPersistor::ScReset() { DECLARE_SC(sc, TEXT("CComponentPersistor::ScReset"));
// save contents to string
std::wstring strContents; sc = ScSaveToString(&strContents); if (sc) return sc;
// cleanup (anything not saved should go away)
m_XMLStorage.clear(); m_XMLStream.clear();
// load from string
sc = ScLoadFromString(strContents.c_str()); if (sc) return sc;
return sc; }
//############################################################################
//############################################################################
/*+-------------------------------------------------------------------------*
* * CDPersistor::Persist * * PURPOSE: persists collection of component datas * * PARAMETERS: * CPersistor& persistor : * * RETURNS: * void * *+-------------------------------------------------------------------------*/ void CDPersistor::Persist(CPersistor& persistor) { DECLARE_SC(sc, TEXT("CDPersistor::Persist"));
// let the base class do the job
BC::Persist( persistor, false /*bPersistViewId*/ ); }
/***************************************************************************\
* * METHOD: CDPersistor::ScReset * * PURPOSE: Restores component data xml streams/storages into "Just loaded" state * * PARAMETERS: * * RETURNS: * SC - result code * \***************************************************************************/ SC CDPersistor::ScReset() { DECLARE_SC(sc, TEXT("CDPersistor::ScReset"));
// save contents to string
std::wstring strContents; sc = ScSaveToString(&strContents); if (sc) return sc;
// cleanup (anything not saved should go away)
m_XMLStorage.clear(); m_XMLStream.clear();
// load from string
sc = ScLoadFromString(strContents.c_str()); if (sc) return sc;
return sc; }
|