[commit] r1696 - in trunk: GME/Core GME/Interfaces GME/Mga GME/MgaUtil Tests/GPyUnit
GMESRC Repository Notifications
gme-commit at list.isis.vanderbilt.edu
Mon Nov 21 17:38:34 CST 2011
Author: ksmyth
Date: Mon Nov 21 17:38:34 2011
New Revision: 1696
Log:
Store regnodes in a hashmap. Uses an order of magnitude less memory
Added:
trunk/GME/Core/CoreDictionaryAttributeValue.cpp
trunk/GME/Core/CoreDictionaryAttributeValue.h
trunk/Tests/GPyUnit/test_registry.py
Modified:
trunk/GME/Core/Core.vcxproj
trunk/GME/Core/Core.vcxproj.filters
trunk/GME/Core/CoreAttribute.cpp
trunk/GME/Core/CoreAttribute.h
trunk/GME/Core/CoreBinFile.cpp
trunk/GME/Core/CoreBinFile.h
trunk/GME/Interfaces/Core.idl
trunk/GME/Mga/Mga.vcxproj
trunk/GME/Mga/MgaAttribute.cpp
trunk/GME/Mga/MgaAttribute.h
trunk/GME/Mga/MgaComplexOps.cpp
trunk/GME/Mga/MgaCoreObj.cpp
trunk/GME/Mga/MgaCoreObj.h
trunk/GME/Mga/MgaDeriveOps.cpp
trunk/GME/Mga/MgaFCO.cpp
trunk/GME/Mga/MgaFCO.h
trunk/GME/Mga/MgaFolder.cpp
trunk/GME/Mga/MgaGeneric.cpp
trunk/GME/Mga/MgaGeneric.h
trunk/GME/Mga/MgaLibOps.cpp
trunk/GME/Mga/MgaLibRefr.cpp
trunk/GME/Mga/MgaProject.h
trunk/GME/Mga/MgaTrukk.h
trunk/GME/MgaUtil/RegBrwNode.h
trunk/GME/MgaUtil/RegistryBrowserDlg.cpp
trunk/Tests/GPyUnit/__init__.py
Modified: trunk/GME/Core/Core.vcxproj
==============================================================================
--- trunk/GME/Core/Core.vcxproj Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/Core.vcxproj Mon Nov 21 17:38:34 2011 (r1696)
@@ -440,6 +440,7 @@
<ClCompile Include="Core.cpp" />
<ClCompile Include="CoreAttribute.cpp" />
<ClCompile Include="CoreBinFile.cpp" />
+ <ClCompile Include="CoreDictionaryAttributeValue.cpp" />
<ClCompile Include="CoreMetaAttribute.cpp" />
<ClCompile Include="CoreMetaObject.cpp" />
<ClCompile Include="CoreMetaProject.cpp" />
@@ -497,6 +498,7 @@
<ItemGroup>
<ClInclude Include="CoreAttribute.h" />
<ClInclude Include="CoreBinFile.h" />
+ <ClInclude Include="CoreDictionaryAttributeValue.h" />
<ClInclude Include="CoreMetaAttribute.h" />
<ClInclude Include="CoreMetaObject.h" />
<ClInclude Include="CoreMetaProject.h" />
Modified: trunk/GME/Core/Core.vcxproj.filters
==============================================================================
--- trunk/GME/Core/Core.vcxproj.filters Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/Core.vcxproj.filters Mon Nov 21 17:38:34 2011 (r1696)
@@ -58,6 +58,9 @@
<ClCompile Include="StdAfx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="CoreDictionaryAttributeValue.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CoreBinFile.rgs">
@@ -136,5 +139,8 @@
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="CoreDictionaryAttributeValue.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
Modified: trunk/GME/Core/CoreAttribute.cpp
==============================================================================
--- trunk/GME/Core/CoreAttribute.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/CoreAttribute.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -45,6 +45,7 @@
typedef CCoreDataAttribute<CCoreDataAttrBase<CComBstrObj>, VALTYPE_STRING> CCoreStringAttribute;
typedef CCoreDataAttribute<CCoreDataAttrBase<bindata>, VALTYPE_BINARY> CCoreBinaryAttribute;
typedef CCoreDataAttribute<CCoreDataAttrBase<double>, VALTYPE_REAL> CCoreRealAttribute;
+typedef CCoreDataAttribute<CCoreDataAttrBase<CComPtr<CCoreDictionaryAttributeValue>>, VALTYPE_DICT> CCoreDictAttribute;
void CCoreAttribute::Create(CCoreObject *object, CCoreMetaAttribute *metaattribute)
{
@@ -88,6 +89,17 @@
break;
}
+ case VALTYPE_DICT:
+ {
+ typedef CComPartObject< CCoreDictAttribute > COMTYPE;
+
+ COMTYPE *p = NULL;
+ COMTHROW( COMTYPE::CreateInstance(CastToUnknown(object), &p) );
+ attribute = p;
+
+ break;
+ }
+
case VALTYPE_STRING:
{
typedef CComPartObject< CCoreStringAttribute > COMTYPE;
@@ -819,13 +831,36 @@
CopyTo(v, values.front());
}
+template<>
+inline void CCoreDataAttrBase<CComPtr<CCoreDictionaryAttributeValue>>::ChangeFrontValue(VARIANT &v)
+{
+ ASSERT( values.size() >= 2 );
+}
+
+
+template<class DATA>
+DATA CCoreDataAttrBase<DATA>::CreateValue()
+{
+ return value_type();
+}
+
+template<>
+CComPtr<CCoreDictionaryAttributeValue> CCoreDataAttrBase<CComPtr<CCoreDictionaryAttributeValue>>::CreateValue()
+{
+ CCoreDictionaryAttributeValue *val = NULL;
+ typedef CComObject< CCoreDictionaryAttributeValue > COMTYPE;
+ // FIXME: is this necessary?
+ COMTHROW( COMTYPE::CreateInstance((COMTYPE **)&val) );
+ return CComPtr<CCoreDictionaryAttributeValue>(val);
+}
+
template<class DATA>
void CCoreDataAttrBase<DATA>::InsertFrontValue(VARIANT &v)
{
if( limited_size(values, 2) == 1 )
{
LockSelfTry();
- values.push_front(value_type());
+ values.push_front(CreateValue());
try
{
CopyTo(v, values.front());
@@ -840,7 +875,7 @@
}
else
{
- values.push_front(value_type());
+ values.push_front(CreateValue());
try
{
CopyTo(v, values.front());
Modified: trunk/GME/Core/CoreAttribute.h
==============================================================================
--- trunk/GME/Core/CoreAttribute.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/CoreAttribute.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -7,6 +7,7 @@
#include "CoreTransactionItem.h"
#include "CoreMetaAttribute.h"
#include "CoreObject.h"
+#include "CoreDictionaryAttributeValue.h"
#include <list>
#include <set>
@@ -252,6 +253,7 @@
public:
void ChangeFrontValue(VARIANT &v);
+ DATA CreateValue();
void InsertFrontValue(VARIANT &v);
void SpliceValue(values_iterator before, values_iterator pos) NOTHROW;
Modified: trunk/GME/Core/CoreBinFile.cpp
==============================================================================
--- trunk/GME/Core/CoreBinFile.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/CoreBinFile.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -44,6 +44,9 @@
binattr = new ((void*)(&attr)) BinAttr<VALTYPE_COLLECTION>;
break;
+ case VALTYPE_DICT:
+ binattr = new ((void*)(&attr)) BinAttr<VALTYPE_DICT>;
+ break;
case VALTYPE_REAL:
binattr = new ((void*)(&attr)) BinAttr<VALTYPE_REAL>;
break;
@@ -79,7 +82,70 @@
*p_l4 = (((((t_guid.Data4[4] << 8) + t_guid.Data4[5]) << 8) + t_guid.Data4[6]) << 8) + t_guid.Data4[7];
}
-bool BinObject::HasGuidAndStatAttributes( bool* p_guidFound, bool* p_statusFound)
+void WalkRegistry(CCoreDictionaryAttributeValue::map_type& map, CComBSTR& path, CCoreBinFile* p_bf, BinObject& node)
+{
+ binattrs_iterator i = node.binattrs.begin();
+ binattrs_iterator e = node.binattrs.end();
+ while( i != e)
+ {
+ if( i->attrid == ATTRID_REGNOWNER + ATTRID_COLLECTION) {
+ // Copy, since we're going to remove from it
+ std::vector<objects_iterator> a = ((BinAttr<VALTYPE_COLLECTION>*)(void*)&(*i))->a;
+ for (auto it = a.begin(); it != a.end(); it++)
+ {
+ objects_type::iterator regnode = p_bf->objects.find((*it)->first);
+ if (regnode == p_bf->objects.end())
+ throw E_BINFILE;
+
+ CComVariant name;
+ regnode->second.Find(ATTRID_NAME)->Get(p_bf, &name);
+#define RFLAG_HASVALUE 1
+#define RFLAG_OPAQUE 2
+ CComVariant flag;
+ regnode->second.Find(ATTRID_REGFLAGS)->Get(p_bf, &flag);
+
+ CComBSTR newPath(path);
+ if (path != L"")
+ newPath += L"/";
+ newPath += name.bstrVal;
+ if (flag.intVal & RFLAG_HASVALUE) {
+ CComVariant value;
+ regnode->second.Find(ATTRID_REGNODEVALUE)->Get(p_bf, &value);
+ map[newPath] = CComBSTR(value.bstrVal);
+ }
+ WalkRegistry(map, newPath, p_bf, regnode->second);
+ p_bf->opened_object = regnode;
+ regnode->second.Find(ATTRID_REGNOWNER)->Set(p_bf, CComVariant());
+ }
+ return;
+ }
+ ++i;
+ }
+}
+
+void BinObject::UpgradeRegistryIfNecessary(CCoreBinFile* p_bf)
+{
+ binattrs_iterator i = binattrs.begin();
+ binattrs_iterator e = binattrs.end();
+ while( i != e)
+ {
+ if( i->attrid == ATTRID_REGNOWNER + ATTRID_COLLECTION) {
+ CCoreDictionaryAttributeValue::map_type map;
+
+ WalkRegistry(map, CComBSTR(), p_bf, *this);
+
+ BinAttrBase::Create(*i, VALTYPE_DICT);
+ i->attrid = ATTRID_REGNODE;
+ CComVariant dict;
+ i->Get(p_bf, &dict);
+ ((CCoreDictionaryAttributeValue*)dict.pdispVal)->m_dict = map;
+ return;
+ }
+ ++i;
+ }
+}
+
+bool BinObject::HasGuidAndStatAttributes( bool* p_guidFound, bool* p_statusFound, bool* p_oldRegFound)
{
int a1( 0), a2( 0), a3( 0), a4( 0);
@@ -94,6 +160,8 @@
case ATTRID_GUID3: ++a3;break;
case ATTRID_GUID4: ++a4;break;
case ATTRID_FILESTATUS: *p_statusFound = true; break;
+ case ATTRID_REGNOWNER + ATTRID_COLLECTION:
+ *p_oldRegFound = true; break;
};
++i;
@@ -232,6 +300,7 @@
{ int len; binfile->read(len); binfile->cifs += len; } // FIXME maybe cifs > cifs_eof
break;
+ case VALTYPE_DICT:
case VALTYPE_BINARY:
{ int len; binfile->read(len); binfile->cifs += len; } // FIXME maybe cifs > cifs_eof
break;
@@ -965,6 +1034,7 @@
HR_THROW(E_PROJECT_MISMATCH);
ASSERT( resolvelist.empty() );
+ bool oldReg_found = false;
for(;;)
{
@@ -1001,7 +1071,7 @@
{
bool stat_found( false), guid_found( false);
- opened_object->second.HasGuidAndStatAttributes( &guid_found, &stat_found);
+ opened_object->second.HasGuidAndStatAttributes( &guid_found, &stat_found, &oldReg_found);
if( !guid_found) // we will create guid attributes for it
opened_object->second.CreateGuidAttributes( this);
@@ -1037,6 +1107,23 @@
isEmpty = true;
resolvelist.clear();
+ if (oldReg_found) {
+ for (auto it = objects.begin(); it != objects.end(); it++)
+ {
+ if (it->first.metaid >= DTID_MODEL && it->first.metaid <= DTID_FOLDER) // 101 .. 106
+ {
+ it->second.UpgradeRegistryIfNecessary(this);
+ }
+ }
+ for (auto it = objects.begin(); it != objects.end(); )
+ {
+ if (it->first.metaid == DTID_REGNODE)
+ objects.erase(it++);
+ else
+ it++;
+ }
+ }
+
ofs.clear();
// FIXME: set read_only correctly
read_only = false;
Modified: trunk/GME/Core/CoreBinFile.h
==============================================================================
--- trunk/GME/Core/CoreBinFile.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Core/CoreBinFile.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -2,6 +2,8 @@
#ifndef MGA_COREBINFILE_H
#define MGA_COREBINFILE_H
+#include "CoreDictionaryAttributeValue.h"
+
#include <fstream>//fstream.h
#include <list>//slist
#include <map>
@@ -143,9 +145,10 @@
binattrs_type binattrs;
bool deleted;
- bool HasGuidAndStatAttributes( bool* p_guidFound, bool* p_statusFound);
+ bool HasGuidAndStatAttributes( bool* p_guidFound, bool* p_statusFound, bool* p_oldRegFound);
void CreateGuidAttributes( CCoreBinFile* p_bf);
void CreateStatusAttribute( CCoreBinFile* p_bf);
+ void UpgradeRegistryIfNecessary(CCoreBinFile* binFile);
BinAttrBase *Find(attrid_type attrid)
{
@@ -266,6 +269,9 @@
void write(const CComBstrObj &a);
void write(const bindata &a);
void write(const unsigned char* a, int len);
+ void write(const wchar_t* a, int len) {
+ write((const unsigned char*)a, len * sizeof(wchar_t));
+ }
void writestring(const char* pos);
// ------- Attribute
@@ -522,6 +528,107 @@
}
};
+// --------------------------- BinAttr<VALTYPE_DICT>
+
+template<>
+class BinAttr<VALTYPE_DICT> : public BinAttrBase
+{
+public:
+ BinAttr() : data(0) {
+ CCoreDictionaryAttributeValue *val = NULL;
+ typedef CComObject< CCoreDictionaryAttributeValue > COMTYPE;
+ HRESULT hr = COMTYPE::CreateInstance((COMTYPE **)&val);
+ COMTHROW(hr);
+ dict = val;
+ }
+ virtual ~BinAttr() { }
+
+ char* data;
+ // memcpy: if lazy read, data is not guaranteed to be properly aligned for int*
+ int read_len(char*& offset) const { int ret; memcpy(&ret, offset, sizeof(int)); offset += sizeof(int); return ret; }
+
+ CComPtr<ICoreDictionaryAttributeValue> dict;
+
+ virtual valtype_type GetValType() const NOTHROW { return VALTYPE_DICT; }
+ virtual void Set(CCoreBinFile *binfile, VARIANT v)
+ {
+ ASSERT( binfile != NULL );
+ ASSERT(v.vt = VT_DISPATCH);
+ binfile->modified = true;
+ dict = 0;
+ v.pdispVal->QueryInterface(&dict);
+ }
+
+ virtual void Get(CCoreBinFile *binfile, VARIANT *p) const {
+ if (dict == 0) {
+ // lazy read
+ CCoreDictionaryAttributeValue* val = NULL;
+ typedef CComObject< CCoreDictionaryAttributeValue > COMTYPE;
+ HRESULT hr = COMTYPE::CreateInstance((COMTYPE **)&val);
+ COMTHROW(hr);
+
+ char* data = this->data;
+ int size = read_len(data);
+ while (data < this->data + size)
+ {
+ int keysize = read_len(data);
+ CComBSTR key(keysize / sizeof(wchar_t));
+ memcpy(key.m_str, data, keysize);
+ data += keysize;
+ int valuesize = read_len(data);
+ CComBSTR value(valuesize / sizeof(wchar_t));
+ memcpy(value.m_str, data, valuesize);
+ data += valuesize;
+ val->m_dict.emplace(
+ std::unordered_map<CComBSTR, CComBSTR, CComBSTR_Length>::value_type(std::move(key), std::move(value)));
+ }
+
+ BinAttr<VALTYPE_DICT>* _this = const_cast<BinAttr<VALTYPE_DICT>*>(this);
+ _this->dict = val;
+ _this->data = 0;
+ }
+ CComVariant ret = dict;
+ COMTHROW(ret.Detach(p));
+ }
+ virtual void Write(CCoreBinFile *binfile) const {
+ int size = 0;
+
+ if (dict == NULL)
+ {
+ // need to read before write
+ // TODO: could just blit it
+ CComVariant p;
+ Get(binfile, &p);
+ }
+
+ const CCoreDictionaryAttributeValue* cdict = (const CCoreDictionaryAttributeValue*)(const ICoreDictionaryAttributeValue*)dict;
+ for (auto it = cdict->m_dict.begin(); it != cdict->m_dict.end(); it++) {
+ size += sizeof(int);
+ size += it->first.Length() * sizeof(wchar_t);
+ size += sizeof(int);
+ size += it->second.Length() * sizeof(wchar_t);
+ }
+ binfile->write(size);
+
+ for (auto it = cdict->m_dict.begin(); it != cdict->m_dict.end(); it++) {
+ // binfile->write((int)it->first.Length());
+ binfile->write(it->first, it->first.Length());
+ // binfile->write((int)it->second.Length());
+ binfile->write(it->second, it->second.Length());
+ }
+ }
+ virtual void Read(CCoreBinFile *binfile) {
+ dict = 0;
+ data = (char*)binfile->cifs;
+ int len = read_len(binfile->cifs);
+ binfile->cifs += len;
+ }
+ BinAttr(BinAttr<VALTYPE_DICT>&& that) : BinAttrBase(that.attrid), data(that.data), dict(std::move(that.dict)) { }
+ virtual void move(BinAttrUnion&& dest) {
+ new (&dest) BinAttr<VALTYPE_DICT>(std::move(*this));
+ }
+};
+
// --------------------------- BinAttr<VALTYPE_LOCK>
template<>
Added: trunk/GME/Core/CoreDictionaryAttributeValue.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/GME/Core/CoreDictionaryAttributeValue.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -0,0 +1,29 @@
+#include "StdAfx.h"
+
+#include "CoreDictionaryAttributeValue.h"
+
+STDMETHODIMP CCoreDictionaryAttributeValue::put_Value(BSTR Key, BSTR Value)
+{
+COMTRY {
+ m_dict[CComBSTR(Key)] = CComBSTR(Value);
+} COMCATCH(;)
+}
+STDMETHODIMP CCoreDictionaryAttributeValue::get_Value(BSTR Key, BSTR* Value)
+{
+COMTRY {
+ CComBSTR _key;
+ _key.Attach(Key);
+ auto ent = m_dict.find(_key);
+ _key.Detach();
+ if (ent == m_dict.end())
+ return E_NOTFOUND;
+ *Value = CComBSTR(ent->second).Detach();
+} COMCATCH(;)
+}
+
+STDMETHODIMP CCoreDictionaryAttributeValue::get_Keys(VARIANT* Keys)
+{
+COMTRY {
+ return E_NOTIMPL;
+} COMCATCH(;)
+}
Added: trunk/GME/Core/CoreDictionaryAttributeValue.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/GME/Core/CoreDictionaryAttributeValue.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "StdAfx.h"
+
+#include <unordered_map>
+
+struct CComBSTR_Length {
+ ::std::size_t operator ()(const CComBSTR& bstr) const {
+ return bstr.Length();
+ }
+};
+
+class ATL_NO_VTABLE CCoreDictionaryAttributeValue :
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IDispatchImpl<ICoreDictionaryAttributeValue, &IID_ICoreDictionaryAttributeValue, &LIBID_MGACoreLib>
+{
+public:
+ CCoreDictionaryAttributeValue() {}
+ ~CCoreDictionaryAttributeValue() {}
+
+//DECLARE_REGISTRY_RESOURCEID(IDR_)
+//DECLARE_PROTECT_FINAL_CONSTRUCT()
+// DECLARE_INTERFACE
+
+BEGIN_COM_MAP(CCoreDictionaryAttributeValue)
+ COM_INTERFACE_ENTRY(ICoreDictionaryAttributeValue)
+ COM_INTERFACE_ENTRY(IDispatch)
+END_COM_MAP()
+
+public:
+ STDMETHOD(put_Value)(BSTR Key, BSTR Value);
+ STDMETHOD(get_Value)(BSTR Key, BSTR* Value);
+ STDMETHOD(get_Keys)(VARIANT* Keys);
+ STDMETHOD(get_Map)(VARIANT* Map) {
+ Map->vt = VT_I8;
+ Map->llVal = (size_t)(void*)&m_dict;
+ return S_OK;
+ }
+
+ STDMETHOD(put_Map)(VARIANT Map) {
+ m_dict = std::move(*(map_type*)(void*)(size_t)Map.llVal);
+ return S_OK;
+ }
+
+ STDMETHOD(Clone)(ICoreDictionaryAttributeValue** Clone)
+ {
+ CCoreDictionaryAttributeValue* out;
+ typedef CComObject< CCoreDictionaryAttributeValue > COMTYPE;
+ HRESULT hr = COMTYPE::CreateInstance((COMTYPE **)&out);
+ if (SUCCEEDED(hr))
+ {
+ out->AddRef();
+ out->m_dict = this->m_dict;
+ *Clone = out;
+ }
+ return hr;
+ }
+
+ typedef std::unordered_map<CComBSTR, CComBSTR, CComBSTR_Length> map_type;
+ map_type m_dict;
+};
+
+static void CopyTo(const VARIANT& from, CComPtr<CCoreDictionaryAttributeValue>& to)
+{
+ if (from.vt == VT_DISPATCH) {
+ to = 0;
+ CComPtr<ICoreDictionaryAttributeValue> fro;
+ COMTHROW(from.pdispVal->QueryInterface(&fro));
+ COMTHROW(fro->Clone((ICoreDictionaryAttributeValue**)&to));
+ }
+}
Modified: trunk/GME/Interfaces/Core.idl
==============================================================================
--- trunk/GME/Interfaces/Core.idl Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Interfaces/Core.idl Mon Nov 21 17:38:34 2011 (r1696)
@@ -85,8 +85,9 @@
[helpstring("Real (double precision)")]
VALTYPE_REAL = 7,
+ VALTYPE_DICT = 8,
[helpstring("Last value type")]
- VALTYPE_MAX = 7
+ VALTYPE_MAX = 8,
} valtype_enum;
typedef enum transtype_enum
@@ -597,4 +598,30 @@
HRESULT version([out, retval] GMEInterfaceVersion_enum *pVal);
};
+[
+ object,
+ uuid(FAB8C11E-747A-45A5-BF05-1A8FB353B03B),
+ dual,
+ pointer_default(unique)
+]
+interface ICoreDictionaryAttributeValue : IDispatch
+{
+ [propget, id(DISPID_VALUE)]
+ HRESULT Value([in] BSTR Key, [out, retval] BSTR *Value);
+
+ [propput, id(DISPID_VALUE)]
+ HRESULT Value([in] BSTR Key, [in] BSTR Value);
+
+ [propget]
+ HRESULT Keys([out, retval] VARIANT *Keys);
+
+ [propget]
+ HRESULT Map([out, retval] VARIANT* Map);
+
+ [propput]
+ HRESULT Map([in] VARIANT Map);
+
+ HRESULT Clone([out] ICoreDictionaryAttributeValue** Clone);
+};
+
//-------------------------------------------------------------------------------
\ No newline at end of file
Modified: trunk/GME/Mga/Mga.vcxproj
==============================================================================
--- trunk/GME/Mga/Mga.vcxproj Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/Mga.vcxproj Mon Nov 21 17:38:34 2011 (r1696)
@@ -176,7 +176,7 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
+ <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
Modified: trunk/GME/Mga/MgaAttribute.cpp
==============================================================================
--- trunk/GME/Mga/MgaAttribute.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaAttribute.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -3,6 +3,12 @@
#include "MgaAttribute.h"
#include "MgaFCO.h"
+#include "atlsafe.h"
+
+#include <unordered_map>
+
+#include "Core.h"
+
/////////////////////////////////////////////////////////////////////////////
// CMgaAttribute
@@ -456,20 +462,6 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////
-#define RFLAG_HASVALUE 1
-#define RFLAG_OPAQUE 2
-
-
-// THROWS!!!
-// RECURSIVE!!!
-void RegistryChildrenRemove(CoreObj &t) {
- CoreObjs children = CoreObj(t)[ATTRID_REGNOWNER + ATTRID_COLLECTION];
- ITERATE_THROUGH(children) {
- RegistryChildrenRemove(ITER);
- COMTHROW(ITER->Delete());
- }
-}
-
// THROWS!!!
// RECURSIVE!!!
@@ -479,77 +471,40 @@
// If dst node is opaque, src is not copied and recursion also stops.
void MergeRegs(const CoreObj &src, CoreObj &dst) {
- CoreObjs dstcoll = dst[ATTRID_REGNOWNER+ATTRID_COLLECTION];
- ITERATE_THROUGH(src[ATTRID_REGNOWNER+ATTRID_COLLECTION]) {
- CoreObj &srcn = ITER;
- CoreObj dstn;
- CComBSTR srcname = srcn[ATTRID_NAME];
- long dstflags, srcflags = ITER[ATTRID_REGFLAGS];
- ITERATE_THROUGH(dstcoll) {
- if(srcname == CComBSTR(ITER[ATTRID_NAME])) {
- dstn = ITER;
- break;
- }
- }
- if(!dstn) {
- CComPtr<ICoreProject> p;
- COMTHROW(dst->get_Project(&p));
- COMTHROW(p->CreateObject(DTID_REGNODE, &dstn.ComPtr()));
- dstn[ATTRID_NAME] = srcn[ATTRID_NAME];
- dstn[ATTRID_REGNOWNER] = dst;
- dstflags = 0;
- }
- else dstflags = ITER[ATTRID_REGFLAGS];
- if(!(dstflags & RFLAG_OPAQUE)) {
- if(!(dstflags & RFLAG_HASVALUE) && (srcflags & RFLAG_HASVALUE)) {
- dstn[ATTRID_REGNODEVALUE] = srcn[ATTRID_REGNODEVALUE];
- dstn[ATTRID_XREF] = srcn[ATTRID_XREF];
- }
- dstn[ATTRID_REGFLAGS] = dstflags | srcflags;
- MergeRegs(srcn, dstn);
- }
+ {
+ // KMS: need to set ATTRID_REGNODE for write ops
+ CComVariant attr = dst[ATTRID_REGNODE];
+ dst[ATTRID_REGNODE] = attr;
}
-}
+ CComVariant attr = dst[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> dictval;
+ COMTHROW(attr.pdispVal->QueryInterface(&dictval));
+ VARIANT vmap;
+ COMTHROW(dictval->get_Map(&vmap));
+ CMgaRegNode::map_type* map = (CMgaRegNode::map_type*)(void*)vmap.llVal;
+
+ CoreObj s = src;
+ do {
+ CComVariant sattr = s[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> sdictval;
+ COMTHROW(sattr.pdispVal->QueryInterface(&sdictval));
+ VARIANT svmap;
+ COMTHROW(sdictval->get_Map(&svmap));
+ CMgaRegNode::map_type* smap = (CMgaRegNode::map_type*)(void*)svmap.llVal;
-// throws
-CoreObj findregvalueobj(CoreObj &cur, LPOLESTR bstrObname, long &opacity, bool create) { //returns NULL if not found
- wchar_t* obname = bstrObname;
- if (obname == NULL) obname = L"";
- ASSERT(*obname != '/');
- LPOLESTR endstr = wcschr(obname,'/');
- size_t len = endstr ? endstr - obname : wcslen(obname);
- CoreObjs snodes = cur[ATTRID_REGNOWNER+ATTRID_COLLECTION];
- ITERATE_THROUGH(snodes) {
- CComBSTR nm = ITER[ATTRID_NAME];
- if(nm.Length()==len && wcsncmp(nm,obname, len) == 0) {
- opacity |= (long)ITER[ATTRID_REGFLAGS];
- if(!endstr) {
- return ITER;
- }
- return findregvalueobj(ITER, endstr +1, opacity, create);
- }
- }
- if(create) {
- CComPtr<ICoreProject> p;
- COMTHROW(cur->get_Project(&p));
- CoreObj nob;
- COMTHROW(p->CreateObject(DTID_REGNODE, &nob.ComPtr()));
+ for (auto it = smap->begin(); it != smap->end(); it++)
{
- LPOLESTR z = new OLECHAR[len+1];
- wcsncpy(z, obname, len);
- z[len] = '\0';
- nob[ATTRID_NAME] = z;
- delete[] z;
+ if (map->find(it->first) == map->end())
+ {
+ map->insert(CMgaRegNode::map_type::value_type(it->first, it->second));
+ }
}
- nob[ATTRID_REGFLAGS] = 0;
- nob[ATTRID_REGNOWNER] = cur;
- if(!endstr) return nob;
- return findregvalueobj(nob, endstr +1, opacity, create);
- }
- return NULLCOREOBJ;
-}
+ if (!s.IsFCO())
+ break;
+ } while (s = s[ATTRID_DERIVED]);
+}
class regnotifytask : public DeriveTreeTask {
bool Do(CoreObj self, std::vector<CoreObj> *peers = NULL) {
@@ -559,6 +514,66 @@
};
+template<class F>
+void CMgaRegNode::WalkKeyValues(CoreObj& obj, F& f, long status, bool& continue_)
+{
+ CComVariant attr = obj[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> oldval;
+ COMTHROW(attr.pdispVal->QueryInterface(&oldval));
+ VARIANT vmap;
+ COMTHROW(oldval->get_Map(&vmap));
+ map_type* map = (map_type*)(void*)vmap.llVal;
+
+ for (auto it = map->begin(); it != map->end(); it++)
+ {
+ f(*map, it, status, continue_);
+ }
+}
+
+template<class F>
+void CMgaRegNode::WalkKeyValuesInher(F& f)
+{
+ bool continue_ = true;
+ CoreObj s = fco->self;
+ long status = ATTSTATUS_HERE;
+ do {
+ WalkKeyValues(s, f, status, continue_);
+ status = min(ATTSTATUS_IN_ARCHETYPE4, status + 1);
+ if (!continue_)
+ break;
+ if (!s.IsFCO())
+ break;
+ } while (s = s[ATTRID_DERIVED]);
+}
+
+void CMgaRegNode::SetValue(const wchar_t* path, const wchar_t* value)
+{
+ {
+ // KMS: need to set ATTRID_REGNODE for write ops
+ CComVariant attr = fco->self[ATTRID_REGNODE];
+ fco->self[ATTRID_REGNODE] = attr;
+ }
+
+ CComVariant attr = fco->self[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> oldval;
+ COMTHROW(attr.pdispVal->QueryInterface(&oldval));
+
+ CComPtr<ICoreDictionaryAttributeValue> newval = oldval;
+ //COMTHROW(oldval->Clone(&newval));
+ VARIANT vmap;
+ COMTHROW(newval->get_Map(&vmap));
+ map_type* map = (map_type*)(void*)vmap.llVal;
+
+ if (value == NULL_SENTINEL) {
+ auto ent = map->find(CComBSTR(path));
+ if (ent != map->end())
+ map->erase(ent);
+ } else
+ (*map)[CComBSTR(path)] = CComBSTR(value);
+}
+
+const wchar_t* CMgaRegNode::NULL_SENTINEL = (const wchar_t*) "\0xFF\0xFE\0";
+
void CMgaRegNode::markchg() {
regnotifytask().DoWithDeriveds(fco->self);
@@ -569,7 +584,7 @@
STDMETHODIMP CMgaRegNode::get_Object( IMgaObject **pVal) {
- COMTRY {
+ COMTRY {
CHECK_OUTPTRPAR(pVal);
IMgaFCO *p;
fco->getinterface(&p);
@@ -582,11 +597,45 @@
fco->CheckRead();
CHECK_OUTPAR(status);
- if(load_status == ATTSTATUS_INVALID) {
- CComBSTR v;
- COMTHROW(get_Value(&v));
+ *status = ATTSTATUS_UNDEFINED;
+ CoreObj s = fco->self;
+ long _status = ATTSTATUS_HERE;
+ do {
+ CComVariant attr = s[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> oldval;
+ COMTHROW(attr.pdispVal->QueryInterface(&oldval));
+
+ CComPtr<ICoreDictionaryAttributeValue> newval = oldval;
+ VARIANT vmap;
+ COMTHROW(newval->get_Map(&vmap));
+ map_type* map = (map_type*)(void*)vmap.llVal;
+ if (map->find(mypath) != map->end())
+ {
+ *status = _status;
+ return S_OK;
+ }
+
+ _status = min(ATTSTATUS_IN_ARCHETYPE4, _status + 1);
+ if (!s.IsFCO())
+ break;
+ } while (s = s[ATTRID_DERIVED]);
+
+ metaref_type mref = fco->self[ATTRID_META];
+ if(mref) {
+ CComQIPtr<IMgaMetaBase> m(mgaproject->FindMetaRef(mref));
+ CComPtr<IMgaMetaRegNode> rn;
+ HRESULT hr = m->get_RegistryNode(mypath, &rn);
+ if (hr == E_NOTFOUND) {
+ *status = ATTSTATUS_UNDEFINED;
+ }
+ else if (SUCCEEDED(hr)) {
+ *status = ATTSTATUS_METADEFAULT;
+ }
+ else if(hr != E_NOTFOUND)
+ COMTHROW(hr);
}
- *status = load_status;
+
+ return S_OK;
} COMCATCH(;)
}
@@ -594,55 +643,38 @@
STDMETHODIMP CMgaRegNode::get_Value(BSTR *pVal) {
COMTRY {
CHECK_OUTVARIANTPAR(pVal);
- fco->CheckRead();
- CComVariant var;
- long opacity = 0;
- if(load_status == ATTSTATUS_INVALID) {
- long ls = ATTSTATUS_HERE;
- CoreObj cur = fco->self;
- valueobj = NULL;
- while(cur) {
- valueobj <<= findregvalueobj(cur, mypath, opacity, false);
- if(valueobj != NULL) {
- long flags = valueobj[ATTRID_REGFLAGS];
- if(flags & RFLAG_HASVALUE) {
- load_status = ls;
- break; // breaks here with >= HERE
- }
- }
- if((opacity & RFLAG_OPAQUE) != 0) { // opaque node hit.
- load_status = ATTSTATUS_UNDEFINED;
- break;
- }
- CComPtr<ICoreMetaObject> mo;
- if(GetMetaID(cur) == DTID_FOLDER) break; // folders do not inherit
- cur = cur[ATTRID_DERIVED];
- ls++;
- }
- }
- if(load_status >= ATTSTATUS_HERE) {
- *pVal = CComBSTR(valueobj[ATTRID_REGNODEVALUE]).Detach();
- }
- else if(load_status != ATTSTATUS_UNDEFINED) { // INVALID || INMETA
- load_status = ATTSTATUS_UNDEFINED;
- metaref_type mref = fco->self[ATTRID_META];
- if(mref) {
- CComQIPtr<IMgaMetaBase> m(mgaproject->FindMetaRef(mref));
- CComPtr<IMgaMetaRegNode> rn;
- HRESULT hr = m->get_RegistryNode(mypath, &rn);
- if(hr == S_OK) {
- load_status = ATTSTATUS_METADEFAULT;
- COMTHROW(rn->get_Value( pVal));
- }
- else if(hr != E_NOTFOUND) COMTHROW(hr);
+ CoreObj s = fco->self;
+ do {
+ CComVariant attr = s[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> dict;
+ COMTHROW(attr.pdispVal->QueryInterface(&dict));
+ VARIANT vmap;
+ COMTHROW(dict->get_Map(&vmap));
+ map_type* map = (map_type*)(void*)vmap.llVal;
+
+ map_type::iterator it = map->find(mypath);
+ if (it != map->end()) {
+ *pVal = CComBSTR(it->second).Detach();
+ return S_OK;
+ }
+ if (!s.IsFCO())
+ break;
+ } while (s = s[ATTRID_DERIVED]);
+
+ metaref_type mref = fco->self[ATTRID_META];
+ if(mref) {
+ CComQIPtr<IMgaMetaBase> m(mgaproject->FindMetaRef(mref));
+ CComPtr<IMgaMetaRegNode> rn;
+ HRESULT hr = m->get_RegistryNode(mypath, &rn);
+ if(hr == S_OK) {
+ COMTHROW(rn->get_Value(pVal));
+ return S_OK;
}
+ else if(hr != E_NOTFOUND)
+ COMTHROW(hr);
}
- if(load_status == ATTSTATUS_UNDEFINED) {
- // n.b. this is a fancy way of saying *pVal = NULL;
- // FIXME: *pVal is NULL here and we return S_OK
- CComBSTR x; *pVal = x.Detach();
- }
+ *pVal = NULL;
} COMCATCH(;)
}
@@ -652,16 +684,7 @@
fco->CheckRead();
CHECK_OUTPTRPAR(pVal);
- if(load_status == ATTSTATUS_INVALID) {
- CComBSTR v;
- COMTHROW(get_Value(&v));
- }
- if(load_status >= ATTSTATUS_HERE) {
- CoreObj v = valueobj[ATTRID_XREF];
- if(v) {
- ObjForCore(v)->getinterface(pVal);
- }
- }
+ fco->getinterface(pVal);
} COMCATCH(;)
}
@@ -670,61 +693,33 @@
fco->CheckRead();
CHECK_OUTPAR(pVal)
*pVal = VARIANT_FALSE;
- long opa;
- CoreObj vobj;
- vobj <<= findregvalueobj(fco->self, mypath, opa, false);
- if(vobj) {
- long flags = vobj[ATTRID_REGFLAGS];
- if(flags & ~RFLAG_OPAQUE)
- *pVal = VARIANT_TRUE;
- }
} COMCATCH(;);
}
STDMETHODIMP CMgaRegNode::put_Opacity( VARIANT_BOOL newVal) {
+ return S_OK;
+ return E_NOTIMPL;
COMTRY_IN_TRANSACTION {
fco->CheckWrite();
CHECK_INPAR(newVal);
- long opa;
- CoreObj vobj;
- vobj <<= findregvalueobj(fco->self, mypath, opa, true);
- long newmask = newVal ? RFLAG_OPAQUE : 0;
- long flags = vobj[ATTRID_REGFLAGS];
- if((flags & RFLAG_OPAQUE) != newmask) {
- vobj[ATTRID_REGFLAGS] = (flags & ~RFLAG_OPAQUE) | newmask;
- if(load_status != ATTSTATUS_HERE) load_status = ATTSTATUS_INVALID;
- markchg();
- }
} COMCATCH_IN_TRANSACTION(;);
}
STDMETHODIMP CMgaRegNode::put_Value(BSTR newVal) {
- COMTRY_IN_TRANSACTION_MAYBE {
+ COMTRY {
CHECK_INSTRPAR(newVal);
fco->CheckWrite();
- long dummy;
- valueobj <<= findregvalueobj(fco->self, mypath, dummy, true);
- load_status = ATTSTATUS_HERE;
- valueobj[ATTRID_REGNODEVALUE] = newVal;
- valueobj[ATTRID_XREF] = NULLCOREOBJ;
- long flags = valueobj[ATTRID_REGFLAGS];
- if(!(flags & RFLAG_HASVALUE)) valueobj[ATTRID_REGFLAGS] = flags | RFLAG_HASVALUE;
+ SetValue(mypath, newVal);
markchg();
- } COMCATCH_IN_TRANSACTION_MAYBE(;)
+ } COMCATCH(;)
}
STDMETHODIMP CMgaRegNode::put_FCOValue(IMgaFCO *newVal) {
+ return E_NOTIMPL;
COMTRY_IN_TRANSACTION {
CHECK_MYINPTRPAR(newVal);
fco->CheckWrite();
- long dummy;
- valueobj <<= findregvalueobj(fco->self, mypath, dummy, true);
- load_status = ATTSTATUS_HERE;
- valueobj[ATTRID_REGNODEVALUE] = CComBSTR();
- valueobj[ATTRID_XREF] = CoreObj(newVal);
- long flags = valueobj[ATTRID_REGFLAGS];
- if(!(flags & RFLAG_HASVALUE)) valueobj[ATTRID_REGFLAGS] = flags | RFLAG_HASVALUE;
markchg();
} COMCATCH_IN_TRANSACTION(;)
}
@@ -733,50 +728,65 @@
COMTRY {
fco->CheckRead();
CHECK_OUTPTRPAR(pVal);
- long dummy;
- stdext::hash_set<CComBSTRNoAt, CComBSTR_hashfunc> match;
+
CoreObj s = fco->self;
- if(!s.IsFCO()) virtuals = VARIANT_FALSE;
+ if(!s.IsFCO())
+ virtuals = VARIANT_FALSE;
CREATEEXCOLLECTION_FOR(MgaRegNode,q);
- do {
- CoreObj vobj;
- vobj <<= findregvalueobj(s, mypath, dummy, false);
- if(!vobj) continue;
- CoreObjs children = vobj[ATTRID_REGNOWNER+ATTRID_COLLECTION];
-
- ITERATE_THROUGH(children) {
- CComBSTR subpath(mypath);
- COMTHROW(subpath.Append(L"/"));
- CComBSTR path = ITER[ATTRID_NAME];
- COMTHROW(subpath.Append(path));
- if(virtuals) {
- if(match.find(path) != match.end()) continue;
- match.insert(path);
+ std::set<std::wstring> paths;
+ WalkKeyValuesInher([&](map_type& map, map_type::iterator& it, int inher, bool& continue_) {
+ if (virtuals == VARIANT_FALSE && inher != ATTSTATUS_HERE)
+ {
+ continue_ = false;
+ return;
+ }
+ if (wcsncmp(it->first, mypath, mypath.Length()) == 0)
+ {
+ std::wstring path = it->first;
+ if (path.length() > mypath.Length())
+ {
+ size_t end = path.find(L'/', mypath.Length() + 1);
+ if (end != std::wstring::npos)
+ path = path.substr(0, end);
+ paths.insert(std::move(path));
}
- q->Add(fco->rpool.getpoolobj(subpath, fco, mgaproject));
}
- } while(virtuals && (s = s[ATTRID_DERIVED]));
+ });
if(virtuals) {
metaref_type mref = fco->self[ATTRID_META];
if(mref) {
CComQIPtr<IMgaMetaBase> m(mgaproject->FindMetaRef(mref));
CComPtr<IMgaMetaRegNode> rn;
- HRESULT hr = m->get_RegistryNode(mypath, &rn);
+ HRESULT hr;
+ if (mypath == L"")
+ hr = S_OK;
+ else
+ hr = m->get_RegistryNode(mypath, &rn);
CComPtr<IMgaMetaRegNodes> rns;
if(hr == S_OK) {
- COMTHROW(hr = rn->get_RegistryNodes(&rns));
+ if (mypath == L"")
+ COMTHROW(m->get_RegistryNodes(&rns));
+ else
+ COMTHROW(rn->get_RegistryNodes(&rns));
MGACOLL_ITERATE(IMgaMetaRegNode, rns) {
CComBSTR path;
COMTHROW(MGACOLL_ITER->get_Name(&path));
- if(match.find(path) != match.end()) continue;
CComBSTR subpath(mypath);
- COMTHROW(subpath.Append("/"));
+ if (mypath != L"")
+ COMTHROW(subpath.Append("/"));
COMTHROW(subpath.Append(path));
- q->Add(fco->rpool.getpoolobj(subpath, fco, mgaproject));
+ paths.insert(subpath);
} MGACOLL_ITERATE_END;
}
}
}
+ for (std::set<std::wstring>::iterator pathsIt = paths.begin(); pathsIt != paths.end(); pathsIt++)
+ {
+ CComPtr<CMgaRegNode> regnode;
+ CreateComObject(regnode);
+ regnode->Initialize(CComBSTR(pathsIt->c_str()), fco, mgaproject);
+ q->Append(regnode.Detach());
+ }
*pVal = q.Detach();
} COMCATCH(;)
}
@@ -812,58 +822,45 @@
STDMETHODIMP CMgaRegNode::Clear() {
COMTRY_IN_TRANSACTION {
fco->CheckWrite();
-/* // old implementation: did not create object if it was not already there
- long l;
- COMTHROW(get_Status(&l));
- if(l == ATTSTATUS_HERE) {
- long flags = valueobj[ATTRID_REGFLAGS];
- valueobj[ATTRID_REGFLAGS] = flags & ~RFLAG_HASVALUE;
- load_status = ATTSTATUS_INVALID;
- markchg();
- }
-*/
- long dummy;
- valueobj <<= findregvalueobj(fco->self, mypath, dummy, true);
- valueobj[ATTRID_REGNODEVALUE] = CComBSTR();
- long flags = valueobj[ATTRID_REGFLAGS];
- valueobj[ATTRID_REGFLAGS] = flags & ~RFLAG_HASVALUE;
- load_status = ATTSTATUS_INVALID;
+ SetValue(mypath, NULL_SENTINEL);
+
markchg();
} COMCATCH_IN_TRANSACTION(;);
}
STDMETHODIMP CMgaRegNode::RemoveTree() {
- COMTRY_IN_TRANSACTION {
- fco->CheckWrite();
- long dummy;
- valueobj <<= findregvalueobj(fco->self, mypath, dummy, false);
- if(valueobj) {
- // lph: Pre-Notification PRE_STATUS (the registry node is being destroyed)
- CComBSTR desc = L"REGISTRY,";
- COMTHROW(desc.Append(mypath));
- COMTHROW(desc.Append(L",Removed"));
- fco->PreNotify(OBJEVENT_PRE_STATUS, CComVariant(desc));
- //--------------------------------------------------------------------------
- RegistryChildrenRemove(valueobj);
- COMTHROW(valueobj->Delete());
- load_status = ATTSTATUS_INVALID;
- markchg();
- }
- } COMCATCH_IN_TRANSACTION(;);
-}
-
-
-
-
-
-
-
-
-
-
+ COMTRY {
+ fco->CheckWrite();
+ // lph: Pre-Notification PRE_STATUS (the registry node is being destroyed)
+ CComBSTR desc = L"REGISTRY,";
+ COMTHROW(desc.Append(mypath));
+ COMTHROW(desc.Append(L",Removed"));
+ fco->PreNotify(OBJEVENT_PRE_STATUS, CComVariant(desc));
+ {
+ // KMS: need to set ATTRID_REGNODE for write ops
+ CComVariant attr = fco->self[ATTRID_REGNODE];
+ fco->self[ATTRID_REGNODE] = attr;
+ }
+ CComVariant attr = fco->self[ATTRID_REGNODE];
+ CComPtr<ICoreDictionaryAttributeValue> oldval;
+ COMTHROW(attr.pdispVal->QueryInterface(&oldval));
+ VARIANT vmap;
+ COMTHROW(oldval->get_Map(&vmap));
+ map_type* map = (map_type*)(void*)vmap.llVal;
+ for (auto it = map->begin(); it != map->end(); it++)
+ {
+ if (wcsncmp(it->first, mypath, mypath.Length()) == 0)
+ {
+ map->erase(it);
+ }
+ }
+ // TODO
+ markchg();
+ } COMCATCH(;);
+}
Modified: trunk/GME/Mga/MgaAttribute.h
==============================================================================
--- trunk/GME/Mga/MgaAttribute.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaAttribute.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -5,7 +5,15 @@
#include "resource.h" // main symbols
+#include "MgaProject.h"
+#include <unordered_map>
+
+struct CComBSTR_Length {
+ ::std::size_t operator ()(const CComBSTR& bstr) const {
+ return bstr.Length();
+ }
+};
/////////////////////////////////////////////////////////////////////////////
// CMgaAttribute
@@ -146,11 +154,11 @@
// IMgaRegNode
void markchg();
public:
- STDMETHOD(get_Name)( BSTR *pVal) {
+ STDMETHOD(get_Name)(BSTR *pVal) {
COMTRY {
CHECK_OUTPAR(pVal);
LPCOLESTR p = (mypath == NULL ? NULL : wcsrchr(mypath, '/'));
- if(p) p += 1; // skip '/'
+ if (p) p += 1; // skip '/'
else p = mypath;
CComBSTR rval(p);
*pVal = rval.Detach();
@@ -179,72 +187,32 @@
STDMETHOD(Clear)();
STDMETHOD(RemoveTree)();
- typedef CMgaRegNode *hashobp;
- hashobp *prevptr, next;
- CMgaRegNode() : prevptr(NULL), next(NULL), load_status(ATTSTATUS_INVALID) { }
- ~CMgaRegNode() { // remove object from hash
- if(next) next->prevptr = prevptr;
- *prevptr = next;
- }
- void Initialize(BSTR path, FCO *o, CMgaProject *p) { // Throws!!!
- mypath = path;
+ CMgaRegNode() { }
+ ~CMgaRegNode() { }
+
+ void Initialize(BSTR path, FCO *o, CMgaProject* mgaproject) {
+ mypath = path;
fco = o;
- mgaproject = p;
+ this->mgaproject = mgaproject;
}
- long load_status;
- CoreObj valueobj;
- FCOPtr fco;
- CComBSTR mypath;
- CMgaProject *mgaproject;
-};
-
+ template<class F>
+ void WalkKeyValues(CoreObj& obj, F& f, long status, bool& continue_);
-#define RPOOL_HASHSIZE 8
+ template<class F>
+ void WalkKeyValuesInher(F& f);
+ void SetValue(const wchar_t* path, const wchar_t* value);
+ const static wchar_t* NULL_SENTINEL;
-class regnpool {
- CMgaRegNode::hashobp pool[RPOOL_HASHSIZE];
-public:
- regnpool() {
- int i;
- for(i = 0; i < RPOOL_HASHSIZE;i++) pool[i] = NULL;
- }
-
- ~regnpool() {
- int i;
- for(i = 0; i < RPOOL_HASHSIZE;i++) ASSERT(pool[i] == NULL);
- }
-
- int rpool_hash(BSTR nam) {
- int i = SysStringLen(nam);
- int hash = i;
- while(i) hash ^= nam[--i];
- return hash % RPOOL_HASHSIZE;
- }
-
- // Throws (allocates)!!!!
- CComPtr<IMgaRegNode> getpoolobj(BSTR nam, FCO *o, CMgaProject *pr) {
- CMgaRegNode::hashobp &k = pool[rpool_hash(nam)], *kk;
- for(kk = &k; *kk != NULL; kk = &((*kk)->next)) {
- if((*kk)->mypath == nam) {
- return (*kk);
- }
- }
- CComPtr<CMgaRegNode > s;
- CreateComObject(s);
- s->prevptr = &k; // Insert to the front
- s->next = k;
- if(k) k->prevptr = &(s->next);
- k = s;
+ FCOPtr fco;
+ CComBSTR mypath;
+ CMgaProject* mgaproject;
- s->Initialize(nam, o, pr);
- CComPtr<IMgaRegNode> retval = s;
- return retval;
- }
+ typedef std::unordered_map<CComBSTR, CComBSTR, CComBSTR_Length> map_type;
};
-void RegistryChildrenRemove(CoreObj &t);
+
void MergeRegs(const CoreObj &src, CoreObj &dst);
Modified: trunk/GME/Mga/MgaComplexOps.cpp
==============================================================================
--- trunk/GME/Mga/MgaComplexOps.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaComplexOps.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -122,11 +122,6 @@
ITER[ATTRID_XREF] = nil;
CoreObjMark(ITER[ATTRID_ATTRPARENT], OBJEVENT_ATTR);
break;
- case DTID_REGNODE:
-// registry REF attribute: set it to NIL
- ITER[ATTRID_XREF] = nil;
- CoreObjMark(ITER[ATTRID_REGNOWNER], OBJEVENT_REGISTRY);
- break;
default:
COMTHROW(E_MGA_META_INCOMPATIBILITY);
}
@@ -473,7 +468,7 @@
}
else {
ai -= ATTRID_COLLECTION;
- if(LINKREF_ATTR(ai) && ai != ATTRID_ATTRPARENT && ai != ATTRID_REGNOWNER) {
+ if(LINKREF_ATTR(ai) && ai != ATTRID_ATTRPARENT) {
CoreObjs collmembers = origobj[ai + ATTRID_COLLECTION];
ITERATE_THROUGH(collmembers) {
CoreObj nchild;
@@ -1643,12 +1638,13 @@
case ATTRID_MASTEROBJ:
{
CoreObj nmas = nobj[ai];
- if( nobj.IsFCO() && nmas.IsFCO()) // save its master's guid into registry
+ if( nobj.IsFCO() && nmas && nmas.IsFCO()) // save its master's guid into registry
{
CComBSTR bstr;
ObjForCore( nmas)->GetGuidDisp( &bstr);
if( bstr) ObjForCore( nobj)->put_RegistryValue( CComBSTR( DETACHED_FROM), bstr);
}
+ MergeRegs(orig, nobj);
nobj[ai] = CComVariant( (IDispatch*) 0);//an empty value;
break;
}
@@ -1711,16 +1707,6 @@
ai -= ATTRID_COLLECTION;
switch( ai) {
- case ATTRID_REGNOWNER: // merge registry
- {
- CoreObjs collmembers = orig[ai + ATTRID_COLLECTION]; // copy the base's entries
- ITERATE_THROUGH(collmembers) {
- CoreObj nchild;
- ObjTreeCopy(mgaproject, ITER, nchild, crealist);
- nchild[ai] = nobj;
- }
- break;
- }
case ATTRID_ATTRPARENT: // copy the unfilled attributes
{
unsigned int owned_attrs(0), inherited_attrs(0), l3(0);
@@ -1871,7 +1857,6 @@
ai -= ATTRID_COLLECTION;
if(LINKREF_ATTR(ai)) {
if( ai == ATTRID_ATTRPARENT) { } // no need to copy attr values since the newobj already had its own
- else if( ai == ATTRID_REGNOWNER) { } // automatic
else if( ai == ATTRID_CONSTROWNER) { }
else if( ai == ATTRID_CONNROLE) { }
else if( ai == ATTRID_SETMEMBER) { }
Modified: trunk/GME/Mga/MgaCoreObj.cpp
==============================================================================
--- trunk/GME/Mga/MgaCoreObj.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaCoreObj.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -130,7 +130,6 @@
case DTID_CONNROLESEG: ai = ATTRID_CONNSEG; break;
case DTID_SETNODE: ai = ATTRID_SETMEMBER; break;
case DTID_CONSTRAINT: ai = ATTRID_CONSTROWNER; break;
- case DTID_REGNODE: ai = ATTRID_REGNOWNER; break;
default: ai = ATTRID_ATTRPARENT;
}
r = r[ai];
Modified: trunk/GME/Mga/MgaCoreObj.h
==============================================================================
--- trunk/GME/Mga/MgaCoreObj.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaCoreObj.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -2,6 +2,10 @@
////////////////////////////// COREOBJ COREOBJS & COREATTRIBUTE //////////////////
///////////////////////////////////////////////////////////////////////////////////
+#pragma once
+
+#include "MgaGeneric.h"
+
class CoreAttr; // defined below
class CoreObjs;
Modified: trunk/GME/Mga/MgaDeriveOps.cpp
==============================================================================
--- trunk/GME/Mga/MgaDeriveOps.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaDeriveOps.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -176,7 +176,6 @@
case DTID_CONNROLE: a = ATTRID_XREF; break;
case DTID_SETNODE: a = ATTRID_XREF; break;
case DTID_REFATTR: a = ATTRID_XREF; break;
- case DTID_REGNODE: a = ATTRID_XREF; break;
case DTID_CONNROLESEG: a = ATTRID_SEGREF; break;
default: COMTHROW(E_MGA_DATA_INCONSISTENCY);
}
Modified: trunk/GME/Mga/MgaFCO.cpp
==============================================================================
--- trunk/GME/Mga/MgaFCO.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaFCO.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -780,7 +780,15 @@
CheckRead();
CHECK_INSTRPAR(path);
CHECK_OUTPTRPAR(pVal);
- *pVal = rpool.getpoolobj(path, this, mgaproject).Detach();
+
+ CComPtr<CMgaRegNode> s;
+ CreateComObject(s);
+
+ s->Initialize(path, this, mgaproject);
+
+ CComPtr<IMgaRegNode> retval = s;
+
+ *pVal = s.Detach();
} COMCATCH(;)
}
@@ -792,36 +800,16 @@
COMTRY {
CheckRead();
CHECK_OUTPTRPAR(pVal);
- CREATEEXCOLLECTION_FOR(MgaRegNode,q);
- CoreObj s = self;
- if(!s.IsFCO()) virtuals = VARIANT_FALSE;
- stdext::hash_set<CComBSTRNoAt, CComBSTR_hashfunc> match;
- do {
- CoreObjs children = s[ATTRID_REGNOWNER+ATTRID_COLLECTION];
- ITERATE_THROUGH(children) {
- CComBSTR path;
- path = ITER[ATTRID_NAME];
- if(virtuals) {
- if(match.find(path) != match.end()) continue;
- match.insert(path);
- }
- q->Add(rpool.getpoolobj(path, this, mgaproject));
- }
- } while(virtuals && (s = s[ATTRID_DERIVED]));
- if(virtuals) {
- CComQIPtr<IMgaMetaBase> m;
- COMTHROW(get_MetaBase(&m));
- CComPtr<IMgaMetaRegNodes> rns;
- COMTHROW(m->get_RegistryNodes(&rns));
- MGACOLL_ITERATE(IMgaMetaRegNode, rns) {
- CComBSTR path;
- COMTHROW(MGACOLL_ITER->get_Name(&path));
- if(match.find(path) != match.end()) continue;
- q->Add(rpool.getpoolobj(path, this, mgaproject));
- } MGACOLL_ITERATE_END;
- }
- *pVal = q.Detach();
+ if(!self.IsFCO())
+ virtuals = VARIANT_FALSE;
+
+ CComPtr<CMgaRegNode> regnode;
+ CreateComObject(regnode);
+
+ regnode->Initialize(CComBSTR(L""), this, mgaproject);
+
+ COMTHROW(regnode->get_SubNodes(virtuals, pVal));
} COMCATCH(;);
}
HRESULT FCO::get_RegistryValue( BSTR path, BSTR *pVal) {
@@ -847,33 +835,14 @@
typedef std::vector<CComVariant> ModificationsVector;
void getRegistryModifications(CoreObj &cobj, CComBSTR &path, ModificationsVector &mv) {
- CComVariant current = cobj[ATTRID_REGNODEVALUE];
- CComVariant previous;
- COMTHROW(cobj->get_PreviousAttrValue(ATTRID_REGNODEVALUE, &previous));
- if (previous != current) {
- CComBSTR label = "REGISTRY:";
- COMTHROW(label.Append(path));
- CComVariant ident = label;
- mv.push_back(ident);
- mv.push_back(previous);
- }
- ITERATE_THROUGH(cobj[ATTRID_REGNOWNER+ATTRID_COLLECTION]) {
- CComBSTR cname = ITER[ATTRID_NAME];
- CComBSTR cpath = path;
- COMTHROW(cpath.Append("/"));
- COMTHROW(cpath.Append(cname));
- getRegistryModifications(ITER, cpath, mv);
- }
+ // TODO
}
HRESULT get_Modifications(FCO *fco, unsigned long changemask, CComVariant *mods) {
COMTRY {
ModificationsVector modifications;
if (changemask & OBJEVENT_REGISTRY) {
- ITERATE_THROUGH(fco->self[ATTRID_REGNOWNER+ATTRID_COLLECTION]) {
- CComBSTR path = ITER[ATTRID_NAME];
- getRegistryModifications(ITER, path, modifications);
- }
+ // TODO
}
if (changemask & OBJEVENT_ATTR) {
CComPtr<IMgaMetaFCO> mfco;
Modified: trunk/GME/Mga/MgaFCO.h
==============================================================================
--- trunk/GME/Mga/MgaFCO.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaFCO.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -355,7 +355,6 @@
bool simpleconn();
partpool ppool;
attrpool apool;
- regnpool rpool;
typedef stdext::hash_map<objid_type, CMgaConnPoint *, cp_hashfunc> cphash;
cphash connpointhash;
typedef stdext::hash_map<objid_type, CMgaConstraint *, cp_hashfunc> cshash;
Modified: trunk/GME/Mga/MgaFolder.cpp
==============================================================================
--- trunk/GME/Mga/MgaFolder.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaFolder.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -945,8 +945,7 @@
nnode[ATTRID_DERIVED] = NULL;
nnode[ATTRID_PERMISSIONS] = 0;
{ ITERATE_THROUGH(self[ATTRID_CONSTROWNER+ATTRID_COLLECTION]) ITER[ATTRID_CONSTROWNER] = nnode; }
- { ITERATE_THROUGH(self[ATTRID_REGNOWNER+ATTRID_COLLECTION]) ITER[ATTRID_REGNOWNER] = nnode; }
- { ITERATE_THROUGH(self[ATTRID_ATTRPARENT+ATTRID_COLLECTION]) ITER[ATTRID_ATTRPARENT] = nnode; }
+ // FIXME: should copy registry
{ ITERATE_THROUGH(self[ATTRID_XREF+ATTRID_COLLECTION]) ITER[ATTRID_XREF] = nnode; }
{ ITERATE_THROUGH(self[ATTRID_XREF+ATTRID_REFERENCE]) ITER[ATTRID_REFERENCE] = nnode; }
COMTHROW(self->Delete());
Modified: trunk/GME/Mga/MgaGeneric.cpp
==============================================================================
--- trunk/GME/Mga/MgaGeneric.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaGeneric.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -73,16 +73,17 @@
CREATE_ATTRIBUTE(ATTRID_CONSTRPRIORITY, "ConstrPriority", "Constraint Priority",VALTYPE_STRING);
CREATE_POINTER(ATTRID_CONSTROWNER, "ConstraintOf", "Owner Kind");
+// Old REGNODE format. Upgraded to new format in CoreBinFile
//REGNODE
- CREATE_OBJECT(DTID_REGNODE, "RegNode", "Template For Registry Node");
- COMMON_DEF
-
- CREATE_ATTRIBUTE(ATTRID_NAME, "Name", "RegNode Name", VALTYPE_STRING);
- CREATE_ATTRIBUTE(ATTRID_REGFLAGS, "RegistryFlags", "Registry Flags", VALTYPE_LONG);
- CREATE_POINTER(ATTRID_REGNOWNER, "RegNodeOf", "Parent Object/Regnode");
- CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");
- CREATE_ATTRIBUTE(ATTRID_REGNODEVALUE, "RegNodeValue", "RegNode Value",VALTYPE_STRING);
- CREATE_POINTER(ATTRID_XREF, "FCOref", "Referenced FCO");
+// CREATE_OBJECT(DTID_REGNODE, "RegNode", "Template For Registry Node");
+// COMMON_DEF
+//
+// CREATE_ATTRIBUTE(ATTRID_NAME, "Name", "RegNode Name", VALTYPE_STRING);
+// CREATE_ATTRIBUTE(ATTRID_REGFLAGS, "RegistryFlags", "Registry Flags", VALTYPE_LONG);
+// CREATE_POINTER(ATTRID_REGNOWNER, "RegNodeOf", "Parent Object/Regnode");
+// CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");
+// CREATE_ATTRIBUTE(ATTRID_REGNODEVALUE, "RegNodeValue", "RegNode Value",VALTYPE_STRING);
+// CREATE_POINTER(ATTRID_XREF, "FCOref", "Referenced FCO");
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// DATA ///////////////////////////////////////////////////
@@ -109,7 +110,8 @@
CREATE_POINTER(ATTRID_PARENT, "Parent", "Parent Object");
CREATE_COLLECTION(ATTRID_PARENT, "Children", "Child Objects");
CREATE_COLLECTION(ATTRID_CONSTROWNER, "Constraints", "Constraints");
- CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");
+ //CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");
+ CREATE_ATTRIBUTE(ATTRID_REGNODE, "RegNodes", "Registry Nodes", VALTYPE_DICT);
CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "Permissions", "Permissions", VALTYPE_LONG);
if( v2) GUID_ATTRS_DEFS;
@@ -125,13 +127,12 @@
CREATE_ATTRIBUTE(ATTRID_ROLEMETA, "RoleMeta", "Role Meta Identifier",VALTYPE_METAREF);\
CREATE_POINTER(ATTRID_FCOPARENT, "Parent", "Parent Object");\
CREATE_COLLECTION(ATTRID_CONSTROWNER, "Constraints", "Constraints");\
- CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");\
+ CREATE_ATTRIBUTE(ATTRID_REGNODE, "RegNodes", "Registry Nodes", VALTYPE_DICT); \
CREATE_COLLECTION(ATTRID_REFERENCE, "References", "Referenced by");\
CREATE_COLLECTION(ATTRID_XREF, "XReferences", "Cross refs");\
CREATE_COLLECTION(ATTRID_ATTRPARENT,"Attributes", "Attributes");\
CREATE_POINTER(ATTRID_DERIVED, "BaseType", "BaseType");\
CREATE_COLLECTION(ATTRID_DERIVED, "SubTypes", "SubTypes/Instances"); \
-/* CREATE_COLLECTION(ATTRID_REALOBJECT, "Aliases", "Aliases"); */ \
CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "Permissions", "Permissions", VALTYPE_LONG);
//MODEL
@@ -178,19 +179,6 @@
if( v2) GUID_ATTRS_DEFS;
CLSID_PUSH( CLSID_MgaO );
-/*
-//ALIAS
- CREATE_OBJECT(DTID_ALIASNODE, "AliasNode", "Template For Aliases");
- COMMON_DEF
-
- CREATE_ATTRIBUTE(ATTRID_ROLEMETA, "RoleMeta", "Role Meta Identifier",VALTYPE_METAREF);\
- CREATE_POINTER(ATTRID_FCOPARENT, "Parent", "Parent of FCO");\
- CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");\
- CREATE_POINTER(ATTRID_REALOBJECT, "RealObject", "Real Object");\
- CREATE_POINTER(ATTRID_DERIVED, "BaseType", "BaseType");\
- CREATE_COLLECTION(ATTRID_DERIVED, "SubTypes", "SubTypes/Instances"); \
- CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "IsInstance", "Is instance?", VALTYPE_LONG);
-*/
//SETNODE
CREATE_OBJECT(DTID_SETNODE, "SetNode", "Template For Set Member");
@@ -235,9 +223,7 @@
#define ATTR_DEF \
COMMON_DEF\
CREATE_ATTRIBUTE(ATTRID_META, "Meta", "Meta Identifier",VALTYPE_METAREF);\
- CREATE_POINTER(ATTRID_ATTRPARENT,"Owner", "Owner FCO");\
-// CREATE_COLLECTION(ATTRID_CONSTROWNER, "Constraints", "Constraints");\
-// CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");\
+ CREATE_POINTER(ATTRID_ATTRPARENT,"Owner", "Owner FCO");
//STRATTR
CREATE_OBJECT(DTID_STRATTR, "StrAttr", "String Attribute");
Modified: trunk/GME/Mga/MgaGeneric.h
==============================================================================
--- trunk/GME/Mga/MgaGeneric.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaGeneric.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -1,3 +1,4 @@
+#pragma once
void CreateCoreMetaProject(CComPtr<ICoreMetaProject> &project, bool v2 = false);
@@ -71,10 +72,10 @@
#define ATTRID_CONSTRPRIORITY 451
#define ATTRID_CONSTROWNER 652
-#define ATTRID_REGNOWNER 655
-#define ATTRID_REGNODENAME 456
-#define ATTRID_REGNODEVALUE 457
-#define ATTRID_REGFLAGS 458
+#define ATTRID_REGNOWNER 655 // <! deprecated
+#define ATTRID_REGNODEVALUE 457 // <! deprecated
+#define ATTRID_REGFLAGS 458 // <! deprecated
+#define ATTRID_REGNODE 457
// OBJECT ID'S
@@ -105,7 +106,7 @@
// contigious block ends
#define DTID_CONSTRAINT 120
-#define DTID_REGNODE 121
+#define DTID_REGNODE 121 // <! deprecated
#define DTID_SETNODE 122
Modified: trunk/GME/Mga/MgaLibOps.cpp
==============================================================================
--- trunk/GME/Mga/MgaLibOps.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaLibOps.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -280,9 +280,6 @@
metaid_type s;
COMTHROW( m_mgaproject->dataproject->CreateObject(s = orig.GetMetaID(), &nobj.ComPtr()));
- if( s != DTID_REGNODE ) // speedup, no references to regnodes
- m_fixup.identify(orig, nobj);
-
bool skip_this = false;
if(s >= DTID_MODEL && s <= DTID_FOLDER) {
setcheck( m_mgaproject, nobj, CHK_NEW);
@@ -701,7 +698,6 @@
if(oldnode.IsContainer()) {
newnode[ATTRID_LASTRELID] = oldnode[ATTRID_LASTRELID];
}
- steal(oldnode, newnode, ATTRID_REGNOWNER);
steal(oldnode, newnode, ATTRID_CONSTROWNER);
if(oldnode.IsFCO()) {
Modified: trunk/GME/Mga/MgaLibRefr.cpp
==============================================================================
--- trunk/GME/Mga/MgaLibRefr.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaLibRefr.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -205,7 +205,6 @@
COMTHROW(m_mgaproject->dataproject->CreateObject( GetMetaID(owner), &p_one_conn.saver.ComPtr()));
steal( owner, p_one_conn.saver, ATTRID_ATTRPARENT);
- steal( owner, p_one_conn.saver, ATTRID_REGNOWNER);
steal( owner, p_one_conn.saver, ATTRID_CONSTROWNER);
}
@@ -213,7 +212,6 @@
{
CoreObj inheritor( p_nConn);
steal( p_one_conn.saver, inheritor, ATTRID_ATTRPARENT);
- steal( p_one_conn.saver, inheritor, ATTRID_REGNOWNER);
steal( p_one_conn.saver, inheritor, ATTRID_CONSTROWNER);
SingleObjTreeDelete( p_one_conn.saver, true);
@@ -2164,7 +2162,6 @@
ai -= ATTRID_COLLECTION;
if(LINKREF_ATTR(ai)) {
if( ai == ATTRID_ATTRPARENT) { } // don't care
- else if( ai == ATTRID_REGNOWNER) { } // don't care
else if( ai == ATTRID_CONSTROWNER) { } // don't care
else if( ai == ATTRID_CONNROLE) { } // manually propagated, see collectFreshConnection below
else if( ai == ATTRID_SETMEMBER) { } // manually set, see SyncDerSets below
@@ -2481,7 +2478,6 @@
switch( ai) {
case ATTRID_CONSTROWNER: // the subobjects which are owned by p_derdObj
- case ATTRID_REGNOWNER: // will be preserved automatically
case ATTRID_ATTRPARENT: // p_baseObj's subobjects will be forgotten
break; // and when the new version is reattached
// then those will be propagated down to p_derdObj
@@ -2665,7 +2661,6 @@
ai -= ATTRID_COLLECTION;
if(LINKREF_ATTR(ai)) {
//if( ai == ATTRID_ATTRPARENT) { } // no need to copy these since the
- //else if( ai == ATTRID_REGNOWNER) { } // attachment provides the propagation
//else if( ai == ATTRID_CONSTROWNER) { } // automatically
if(ai == ATTRID_CONNROLE) {
// ConnRoles also depend on their base with ATTRID_MASTEROBJ
Modified: trunk/GME/Mga/MgaProject.h
==============================================================================
--- trunk/GME/Mga/MgaProject.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaProject.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -4,7 +4,7 @@
#define __MGAPROJECT_H_
#include "resource.h" // main symbols
-
+#include "MgaTrukk.h"
class CMgaTerritory;
class CMgaAddOn;
class CMgaClient;
Modified: trunk/GME/Mga/MgaTrukk.h
==============================================================================
--- trunk/GME/Mga/MgaTrukk.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/Mga/MgaTrukk.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -2,6 +2,9 @@
// Tricks, macros, definitions used throughout the Mga library
//
+#pragma once
+
+#include "MgaCoreObj.h"
#include "CommonMgaTrukk.h"
#define DIM(x) (sizeof(x)/ sizeof((x)[0]))
Modified: trunk/GME/MgaUtil/RegBrwNode.h
==============================================================================
--- trunk/GME/MgaUtil/RegBrwNode.h Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/MgaUtil/RegBrwNode.h Mon Nov 21 17:38:34 2011 (r1696)
@@ -13,7 +13,6 @@
class CRegBrwNode
{
public:
- bool opacity;
long status;
void* handle;
CRegBrwNode* parent;
Modified: trunk/GME/MgaUtil/RegistryBrowserDlg.cpp
==============================================================================
--- trunk/GME/MgaUtil/RegistryBrowserDlg.cpp Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/GME/MgaUtil/RegistryBrowserDlg.cpp Mon Nov 21 17:38:34 2011 (r1696)
@@ -250,10 +250,6 @@
COMTHROW(regNode->get_Status(&(brNode->status)));
- VARIANT_BOOL op;
- COMTHROW(regNode->get_Opacity(&op));
- brNode->opacity = (op == VARIANT_TRUE);
-
HTREEITEM hnd;
if (parent) {
hnd = m_wndRegistryTree.InsertItem(brNode->name, (HTREEITEM)(parent->handle));
Modified: trunk/Tests/GPyUnit/__init__.py
==============================================================================
--- trunk/Tests/GPyUnit/__init__.py Mon Nov 21 17:37:54 2011 (r1695)
+++ trunk/Tests/GPyUnit/__init__.py Mon Nov 21 17:38:34 2011 (r1696)
@@ -10,6 +10,7 @@
'test_registrar',
'test_gmeoleapp',
'test_parser',
+ 'test_registry',
'GME_297.suite',
'GME_310.suite',
'GME_371',
Added: trunk/Tests/GPyUnit/test_registry.py
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/Tests/GPyUnit/test_registry.py Mon Nov 21 17:38:34 2011 (r1696)
@@ -0,0 +1,159 @@
+
+import sys
+import os.path
+import unittest
+import win32com.client
+
+class TestRegistry(unittest.TestCase):
+ def __init__(self, name, **kwds):
+ super(TestRegistry, self).__init__(name, **kwds)
+ self.output_file = "TestRegistry-output.mga"
+
+ def test(self):
+ def _adjacent_file(file):
+ import os.path
+ return os.path.join(os.path.dirname(__file__), file)
+ from GPyUnit import util
+ util.register_xmp('MetaGME')
+ with util.disable_early_binding():
+ self.project = win32com.client.DispatchEx("Mga.MgaProject")
+ self.project.Create("MGA=" + _adjacent_file(self.output_file), "MetaGME")
+ self.project.BeginTransactionInNewTerr()
+
+ rootregs = self.project.RootFolder.GetRegistryDisp(True)
+ self.assertEqual(rootregs.Count, 0)
+ self.project.RootFolder.GetRegistryNodeDisp('test123').Value = 'xxx'
+ self.project.RootFolder.GetRegistryNodeDisp('test345').Value = 'yyy'
+
+ for i in range(1, self.project.RootMeta.RootFolder.DefinedFCOs.Count+1):
+ if self.project.RootMeta.RootFolder.DefinedFCOs.Item(i).Name == 'ParadigmSheet':
+ sheet_meta = self.project.RootMeta.RootFolder.DefinedFCOs.Item(i)
+ sheet = self.project.RootFolder.CreateRootObject(sheet_meta)
+ sheetregs = sheet.GetRegistryDisp(True)
+ self.assertEqual(sheetregs.Item(1).Name, 'namePosition')
+
+ namePosition = sheet.GetRegistryNodeDisp('namePosition')
+ self.assertEqual(namePosition.Name, 'namePosition')
+ self.assertEqual(namePosition.Value, '0')
+ self.assertEqual(namePosition.GetSubNodesDisp(True).Count, 0)
+ self.assertEqual(namePosition.GetSubNodesDisp(False).Count, 0)
+
+ def keytest():
+ newkey = sheet.GetRegistryNodeDisp('newkey')
+ newkey.Value = 'newvalue'
+ self.assertEqual(newkey.Value, 'newvalue')
+ keytest()
+ newkey = sheet.GetRegistryNodeDisp('newkey')
+ self.assertEqual(newkey.GetSubNodesDisp(True).Count, 0)
+
+ def subkeytest():
+ newsubkey = sheet.GetRegistryNodeDisp('newkey/subkey')
+ newsubkey.Value = 'subvalue'
+ self.assertEqual(newsubkey.Value, 'subvalue')
+ self.assertEqual(newsubkey.GetSubNodesDisp(True).Count, 0)
+ newkey = sheet.GetRegistryNodeDisp('newkey')
+ self.assertEqual(newkey.GetSubNodesDisp(False).Count, 1)
+ subkeytest()
+
+
+ #self.project.Save("MGA=" + _adjacent_file(self.output_file))
+ self.project.CommitTransaction()
+ terr = self.project.BeginTransactionInNewTerr()
+ sheet = terr.OpenObj(sheet)
+ keytest()
+ subkeytest()
+ self.project.CommitTransaction()
+
+ self.project.Undo()
+ self.project.Undo()
+ terr = self.project.BeginTransactionInNewTerr()
+ self.assertEqual(self.project.RootFolder.GetRegistryDisp(False).Count, 0)
+ self.project.CommitTransaction()
+
+ terr = self.project.BeginTransactionInNewTerr()
+ self.project.RootFolder.GetRegistryNodeDisp('xtest123').Value = 'xxx'
+ self.project.RootFolder.GetRegistryNodeDisp('ytest123').Value = 'yyy'
+ self.project.RootFolder.GetRegistryNodeDisp('xtest123/ztest').Value = 'zzz'
+ self.project.RootFolder.GetRegistryNodeDisp('xtest123/ztest/blank').Value = ''
+ self.project.CommitTransaction()
+
+ self.project.Save()
+ self.project.Close(True)
+
+ self.project.Open("MGA=" + _adjacent_file(self.output_file))
+ terr = self.project.BeginTransactionInNewTerr()
+ self.assertEqual(self.project.RootFolder.GetRegistryNodeDisp('xtest123').Value, 'xxx')
+ self.assertEqual(self.project.RootFolder.GetRegistryNodeDisp('ytest123').Value, 'yyy')
+ self.assertEqual(self.project.RootFolder.GetRegistryNodeDisp('xtest123/ztest').Value, 'zzz')
+ self.assertEqual(self.project.RootFolder.GetRegistryNodeDisp('xtest123/ztest/blank').Value, '')
+ ATTSTATUS_HERE = 0
+ self.assertEqual(self.project.RootFolder.GetRegistryNodeDisp('xtest123/ztest/blank').Status(), ATTSTATUS_HERE)
+ self.project.CommitTransaction()
+ self.project.Close(True)
+
+ def test_derived(self):
+ def _adjacent_file(file):
+ import os.path
+ return os.path.join(os.path.dirname(__file__), file)
+ from GPyUnit import util
+ util.register_xmp('MetaGME')
+ with util.disable_early_binding():
+ self.project = win32com.client.DispatchEx("Mga.MgaProject")
+ self.project.Create("MGA=" + _adjacent_file(self.output_file), "MetaGME")
+ self.project.BeginTransactionInNewTerr()
+
+ for i in range(1, self.project.RootMeta.RootFolder.DefinedFCOs.Count+1):
+ if self.project.RootMeta.RootFolder.DefinedFCOs.Item(i).Name == 'ParadigmSheet':
+ sheet_meta = self.project.RootMeta.RootFolder.DefinedFCOs.Item(i)
+ sheet = self.project.RootFolder.CreateRootObject(sheet_meta)
+ sheet2 = self.project.RootFolder.DeriveRootObject(sheet, False)
+ sheet3 = self.project.RootFolder.DeriveRootObject(sheet2, False)
+ sheet4 = self.project.RootFolder.DeriveRootObject(sheet3, False)
+
+ sheet.SetRegistryValueDisp('test123', 'test')
+ self.assertEqual(sheet4.GetRegistryValueDisp('test123'), 'test')
+ sheet3.DetachFromArcheType()
+ self.assertEqual(sheet4.GetRegistryValueDisp('test123'), 'test')
+ self.assertEqual(sheet2.GetRegistryDisp(False).Count, 0)
+ self.assertEqual(sheet4.GetRegistryDisp(False).Count, 0)
+ self.project.CommitTransaction()
+ self.project.Save()
+ self.project.Close()
+
+
+ def test_copy(self):
+ def _adjacent_file(file):
+ import os.path
+ return os.path.join(os.path.dirname(__file__), file)
+ from GPyUnit import util
+ util.register_xmp('MetaGME')
+ with util.disable_early_binding():
+ self.project = win32com.client.DispatchEx("Mga.MgaProject")
+ self.project.Create("MGA=" + _adjacent_file(self.output_file), "MetaGME")
+ self.project.BeginTransactionInNewTerr()
+
+ for i in range(1, self.project.RootMeta.RootFolder.DefinedFCOs.Count+1):
+ if self.project.RootMeta.RootFolder.DefinedFCOs.Item(i).Name == 'ParadigmSheet':
+ sheet_meta = self.project.RootMeta.RootFolder.DefinedFCOs.Item(i)
+ sheet = self.project.RootFolder.CreateRootObject(sheet_meta)
+ sheet.SetRegistryValueDisp('test123', 'test')
+ sheet2 = self.project.RootFolder.CopyFCOs(self.project.RootFolder.ChildFCOs).Item(1)
+ self.assertEqual(sheet2.GetRegistryValueDisp('test123'), 'test')
+ self.project.CommitTransaction()
+ self.project.Save()
+ self.project.Close()
+
+ def xxxtestupgrade(self):
+ def _adjacent_file(file):
+ import os.path
+ return os.path.join(os.path.dirname(__file__), file)
+ from GPyUnit import util
+ util.register_xmp('MetaGME')
+ with util.disable_early_binding():
+ self.project = win32com.client.DispatchEx("Mga.MgaProject")
+ self.project.Open("MGA=" + r"C:\Users\ksmyth\Documents\META\meta\CyPhyML\CyPhyML.mga")
+ self.project.BeginTransactionInNewTerr()
+ self.project.RootFolder.ChildFolders
+
+if __name__ == "__main__":
+ unittest.main()
More information about the gme-commit
mailing list