public void InitCmpFlags(Dna memoryDna) { // compare the file to memory // this ptr should be the file data Debug.Assert(_names.Length != 0); // SDNA empty! _cmpFlags = new FileDnaFlags[_structs.Length]; for (int i = 0; i < _structs.Length; i++) { Dna.StructDecl oldStruct = _structs[i]; int oldLookup = GetReverseType(oldStruct.Type.Name); if (oldLookup == -1) { _cmpFlags[i] = FileDnaFlags.None; continue; } if (oldLookup < memoryDna._structs.Length) { Dna.StructDecl curStruct = memoryDna.GetStruct(oldLookup); _cmpFlags[i] = oldStruct.Equals(curStruct) ? FileDnaFlags.StructEqual : FileDnaFlags.StructNotEqual; } } // Recurse in for (int i = 0; i < _structs.Length; i++) { if (_cmpFlags[i] == FileDnaFlags.StructNotEqual) { InitRecurseCmpFlags(_structs[i]); } } }
protected void ParseStruct(BinaryWriter strc, BinaryReader data, Dna.StructDecl fileStruct, Dna.StructDecl memoryStruct, bool fixupPointers) { if (fileStruct == null) { return; } if (memoryStruct == null) { return; } long dataPtr = data.BaseStream.Position; long strcPtr = strc.BaseStream.Position; foreach (Dna.ElementDecl element in memoryStruct.Elements) { int memorySize = _memoryDna.GetElementSize(element); if (element.Type.Struct != null && element.Name.Name[0] != '*') { Dna.ElementDecl elementOld; long elementOffset = GetFileElement(fileStruct, element, dataPtr, out elementOld); if (elementOffset != 0) { Dna.StructDecl oldStruct = _fileDna.GetStruct(_fileDna.GetReverseType(element.Type.Name)); data.BaseStream.Position = elementOffset; int arrayLen = elementOld.Name.ArraySizeNew; if (arrayLen == 1) { strc.BaseStream.Position = strcPtr; ParseStruct(strc, data, oldStruct, element.Type.Struct, fixupPointers); strcPtr += memorySize; } else { int fileSize = _fileDna.GetElementSize(elementOld) / arrayLen; memorySize /= arrayLen; for (int i = 0; i < arrayLen; i++) { strc.BaseStream.Position = strcPtr; ParseStruct(strc, data, oldStruct, element.Type.Struct, fixupPointers); data.BaseStream.Position += fileSize; strcPtr += memorySize; } } } } else { strc.BaseStream.Position = strcPtr; GetMatchingFileDna(fileStruct, element, strc, dataPtr, fixupPointers); strcPtr += memorySize; } } }
private void ParseElement(BinaryWriter writer, Dna.StructDecl fileStruct, Dna.ElementDecl memoryElement, long structOffset) { long elementOffset; Dna.ElementDecl elementOld = GetFileElement(fileStruct, memoryElement, out elementOffset); if (elementOld != null) { Dna.StructDecl typeStructOld = _fileDna.GetStruct(memoryElement.Type.Name); int arrayLength = elementOld.NameInfo.ArrayLength; for (int i = 0; i < arrayLength; i++) { long subStructOffset = structOffset + i * typeStructOld.Type.Length + elementOffset; ParseStruct(writer, memoryElement.Type.Struct, typeStructOld, subStructOffset); } } }
protected Dna.ElementDecl GetFileElement(Dna.StructDecl fileStruct, Dna.ElementDecl lookupElement, out long elementOffset) { elementOffset = 0; foreach (Dna.ElementDecl element in fileStruct.Elements) { if (element.NameInfo.Equals(lookupElement.NameInfo)) { if (element.Type.Name.Equals(lookupElement.Type.Name)) { return(element); } break; } elementOffset += _fileDna.GetElementSize(element); } return(null); }
protected void ParseStruct(BinaryWriter writer, Dna.StructDecl memoryStruct, Dna.StructDecl fileStruct, long structOffset) { Debug.Assert(memoryStruct != null); Debug.Assert(fileStruct != null); foreach (Dna.ElementDecl element in memoryStruct.Elements) { if (element.Type.Struct != null && element.NameInfo.Name[0] != '*') { ParseElement(writer, fileStruct, element, structOffset); } else { WriteElement(writer, fileStruct, element, structOffset); } } }
// Structs containing non-equal structs are also non-equal private void InitRecurseCmpFlags(Dna.StructDecl iter) { for (int i = 0; i < _structs.Length; i++) { Dna.StructDecl curStruct = _structs[i]; if (curStruct != iter && _cmpFlags[i] == FileDnaFlags.StructEqual) { foreach (Dna.ElementDecl element in curStruct.Elements) { if (curStruct.Type == iter.Type && element.Name.IsPointer) { _cmpFlags[i] = FileDnaFlags.StructNotEqual; InitRecurseCmpFlags(curStruct); } } } } }
public void ResolvePointers(FileVerboseMode verboseMode) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; if (true) // && ((_flags & FileFlags.BitsVaries | FileFlags.VersionVaries) != 0)) { //ResolvePointersMismatch(); } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); Console.WriteLine("<bullet_physics version=\"{0}\" itemcount=\"{1}\">", Version, _chunks.Count); } foreach (ChunkInd dataChunk in _chunks) { if (_fileDna == null || fileDna.FlagEqual(dataChunk.DnaNR)) { Dna.StructDecl oldStruct = fileDna.GetStruct(dataChunk.DnaNR); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine(" <{0} pointer=\"{1}\">", oldStruct.Type.Name, dataChunk.OldPtr); } ResolvePointersChunk(dataChunk, verboseMode); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine(" </{0}>", oldStruct.Type.Name); } } else { //Console.WriteLine("skipping struct"); } } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { Console.WriteLine("</bullet_physics>"); } }
protected long GetFileElement(Dna.StructDecl firstStruct, Dna.ElementDecl lookupElement, long data, out Dna.ElementDecl found) { foreach (Dna.ElementDecl element in firstStruct.Elements) { if (element.Name.Equals(lookupElement.Name)) { if (element.Type.Name.Equals(lookupElement.Type.Name)) { found = element; return(data); } found = null; return(0); } data += _fileDna.GetElementSize(element); } found = null; return(0); }
protected void ResolvePointersChunk(ChunkInd dataChunk, FileVerboseMode verboseMode) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; Dna.StructDecl oldStruct = fileDna.GetStruct(dataChunk.DnaNR); int oldLen = oldStruct.Type.Length; byte[] cur = FindLibPointer(dataChunk.OldPtr); using (MemoryStream stream = new MemoryStream(cur, false)) { using (BinaryReader reader = new BinaryReader(stream)) { for (int block = 0; block < dataChunk.NR; block++) { long streamPosition = stream.Position; ResolvePointersStructRecursive(reader, dataChunk.DnaNR, verboseMode, 1); System.Diagnostics.Debug.Assert(stream.Position == streamPosition + oldLen); } } } }
public override void FinalizeChunk(Chunk chunk, string structType, DnaID chunkCode, IntPtr oldPtr) { if ((SerializationFlags & SerializationFlags.NoDuplicateAssert) == 0) { Debug.Assert(FindPointer(oldPtr) == IntPtr.Zero); } Dna.StructDecl structDecl = _dna.GetStruct(structType); for (int i = 0; i < _dna.NumStructs; i++) { if (_dna.GetStruct(i) == structDecl) { chunk.DnaNr = i; break; } } chunk.ChunkCode = (int)chunkCode; IntPtr uniquePtr = GetUniquePointer(oldPtr); _chunkP.Add(oldPtr, uniquePtr); //chunk->m_oldPtr); chunk.OldPtr = uniquePtr; //oldPtr; }
protected void WriteElement(BinaryWriter writer, Dna.StructDecl fileStruct, Dna.ElementDecl memoryElement, long structOffset) { bool brokenDna = (Flags & FileFlags.BrokenDna) != 0; int elementOffset; Dna.ElementDecl fileElement = fileStruct.FindElement(_fileDna, brokenDna, memoryElement.NameInfo, out elementOffset); ChunkReader.BaseStream.Position = structOffset + elementOffset; if (fileElement == null) { int elementLength = _memoryDna.GetElementSize(memoryElement); writer.BaseStream.Position += elementLength; } else if (fileElement.NameInfo.Name[0] == '*') { SafeSwapPtr(writer, ChunkReader); } else if (fileElement.Type.Name.Equals(memoryElement.Type.Name)) { int elementLength = _fileDna.GetElementSize(fileElement); if (elementLength != _memoryDna.GetElementSize(memoryElement)) { throw new InvalidDataException(); } byte[] mem = new byte[elementLength]; ChunkReader.Read(mem, 0, elementLength); writer.Write(mem); } else { throw new InvalidDataException(); //GetElement(arrayLen, lookupType, type, data, strcData); } }
protected unsafe void InitDna(byte[] bdnaOrg) { if (_dna != IntPtr.Zero) { return; } _dnaLength = bdnaOrg.Length; _dna = Marshal.AllocHGlobal(bdnaOrg.Length); Marshal.Copy(bdnaOrg, 0, _dna, _dnaLength); Stream stream = new UnmanagedMemoryStream((byte*)_dna.ToPointer(), _dnaLength); BinaryReader reader = new BinaryReader(stream); // SDNA byte[] code = reader.ReadBytes(8); string codes = ASCIIEncoding.ASCII.GetString(code); // NAME if (!codes.Equals("SDNANAME")) { throw new InvalidDataException(); } int dataLen = reader.ReadInt32(); _names = new Dna.NameInfo[dataLen]; for (int i = 0; i < dataLen; i++) { List<byte> name = new List<byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } _names[i] = new Dna.NameInfo(ASCIIEncoding.ASCII.GetString(name.ToArray())); } stream.Position = (stream.Position + 3) & ~3; // TYPE code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TYPE")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _types = new Dna.TypeDecl[dataLen]; for (int i = 0; i < dataLen; i++) { List<byte> name = new List<byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } string type = ASCIIEncoding.ASCII.GetString(name.ToArray()); _types[i] = new Dna.TypeDecl(type); } stream.Position = (stream.Position + 3) & ~3; // TLEN code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TLEN")) { throw new InvalidDataException(); } for (int i = 0; i < _types.Length; i++) { _types[i].Length = reader.ReadInt16(); } stream.Position = (stream.Position + 3) & ~3; // STRC code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("STRC")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _structs = new Dna.StructDecl[dataLen]; long shtPtr = stream.Position; for (int i = 0; i < dataLen; i++) { Dna.StructDecl structDecl = new Dna.StructDecl(); _structs[i] = structDecl; if (!BitConverter.IsLittleEndian) { throw new NotImplementedException(); } else { short typeNr = reader.ReadInt16(); structDecl.Type = _types[typeNr]; structDecl.Type.Struct = structDecl; int numElements = reader.ReadInt16(); structDecl.Elements = new Dna.ElementDecl[numElements]; for (int j = 0; j < numElements; j++) { typeNr = reader.ReadInt16(); short nameNr = reader.ReadInt16(); structDecl.Elements[j] = new Dna.ElementDecl(_types[typeNr], _names[nameNr]); } } } reader.Dispose(); stream.Dispose(); // build reverse lookups _structReverse = new Dictionary<string, Dna.StructDecl>(_structs.Length); foreach (Dna.StructDecl s in _structs) { _structReverse.Add(s.Type.Name, s); } }
protected int ResolvePointersStructRecursive(BinaryReader reader, int dnaNr, FileVerboseMode verboseMode, int recursion) { Dna fileDna = (_fileDna != null) ? _fileDna : _memoryDna; Dna.StructDecl oldStruct = fileDna.GetStruct(dnaNr); int totalSize = 0; foreach (Dna.ElementDecl element in oldStruct.Elements) { int size = fileDna.GetElementSize(element); int arrayLen = element.Name.ArraySizeNew; if (element.Name.Name[0] == '*') { if (arrayLen > 1) { throw new NotImplementedException(); } else { long ptr = (IntPtr.Size == 8) ? reader.ReadInt64() : reader.ReadInt32(); if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("<{0} type=\"pointer\"> {1} </{0}>", element.Name.Name.Substring(1), ptr); } byte[] ptrChunk = FindLibPointer(ptr); if (ptrChunk != null) { //throw new NotImplementedException(); } else { //Console.WriteLine("Cannot fixup pointer at {0} from {1} to {2}!", ptrptr, *ptrptr, ptr); } } } else { if (element.Type.Struct != null) { if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen > 1) { Console.WriteLine("<{0} type=\"{1}\" count={2}>", element.Name.CleanName, element.Type.Name, arrayLen); } else { Console.WriteLine("<{0} type=\"{1}\">", element.Name.CleanName, element.Type.Name); } } for (int i = 0; i < arrayLen; i++) { int revType = _fileDna.GetReverseType(element.Type.Name); ResolvePointersStructRecursive(reader, revType, verboseMode, recursion + 1); //throw new NotImplementedException(); } if ((verboseMode & FileVerboseMode.ExportXml) != 0) { for (int i = 0; i < recursion; i++) { Console.Write(" "); } Console.WriteLine("</{0}>", element.Name.CleanName); } } else { // export a simple type if ((verboseMode & FileVerboseMode.ExportXml) != 0) { if (arrayLen > MaxArrayLength) { Console.WriteLine("too long"); } else { bool isIntegerType; switch (element.Type.Name) { case "char": case "short": case "int": isIntegerType = true; break; default: isIntegerType = false; break; } if (isIntegerType) { throw new NotImplementedException(); /* * const char* newtype="int"; * int dbarray[MAX_ARRAY_LENGTH]; * int* dbPtr = 0; * char* tmp = elemPtr; * dbPtr = &dbarray[0]; * if (dbPtr) * { * char cleanName[MAX_STRLEN]; * getCleanName(memName,cleanName); * * int i; * getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); * for (i=0;i<recursion;i++) * printf(" "); * if (arrayLen==1) * printf("<%s type=\"%s\">",cleanName,memType); * else * printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); * for (i=0;i<arrayLen;i++) * printf(" %d ",dbPtr[i]); * printf("</%s>\n",cleanName); * }*/ } else { double[] dbArray = new double[arrayLen]; GetElement(reader, arrayLen, element.Type, dbArray); for (int i = 0; i < recursion; i++) { Console.Write(" "); } if (arrayLen == 1) { Console.Write("<{0} type=\"{1}\">", element.Name.Name, element.Type.Name); } else { Console.Write("<{0} type=\"{1}\" count=\"{2}\">", element.Name.CleanName, element.Type.Name, arrayLen); } for (int i = 0; i < arrayLen; i++) { Console.Write(" {0} ", dbArray[i].ToString(CultureInfo.InvariantCulture)); } Console.WriteLine("</{0}>", element.Name.CleanName); } } } reader.BaseStream.Position += size; } } totalSize += size; } return(totalSize); }
protected byte[] ReadChunkData(ChunkInd dataChunk, long chunkDataOffset) { //bool ignoreEndianFlag = false; if ((Flags & FileFlags.EndianSwap) != 0) { //swap(head, dataChunk, ignoreEndianFlag); } if (StructChanged(dataChunk.StructIndex)) { // Ouch! need to rebuild the struct Dna.StructDecl oldStruct = _fileDna.GetStruct(dataChunk.StructIndex); if ((Flags & FileFlags.BrokenDna) != 0) { if (oldStruct.Type.Name.Equals("btQuantizedBvhNodeData") && oldStruct.Type.Length == 28) { throw new NotImplementedException(); } if (oldStruct.Type.Name.Equals("btShortIntIndexData")) { throw new NotImplementedException(); } } // Don't try to convert Link block data, just memcpy it. Other data can be converted. if (oldStruct.Type.Name.Equals("Link")) { //Console.WriteLine("Link found"); } else { Dna.StructDecl curStruct = _memoryDna.GetStruct(oldStruct.Type.Name); if (curStruct != null) { byte[] structAlloc = new byte[dataChunk.NumBlocks * curStruct.Type.Length]; AddDataBlock(structAlloc); using (var stream = new MemoryStream(structAlloc)) { using (var writer = new BinaryWriter(stream)) { long structOffset = chunkDataOffset; for (int block = 0; block < dataChunk.NumBlocks; block++) { ParseStruct(writer, curStruct, oldStruct, structOffset); structOffset += oldStruct.Type.Length; } } } return(structAlloc); } } } else { #if DEBUG_EQUAL_STRUCTS #endif } byte[] dataAlloc = new byte[dataChunk.Length]; ChunkReader.Read(dataAlloc, 0, dataChunk.Length); return(dataAlloc); }
protected byte[] ReadStruct(BinaryReader head, ChunkInd dataChunk) { bool ignoreEndianFlag = false; if ((_flags & FileFlags.EndianSwap) == FileFlags.EndianSwap) { //swap(head, dataChunk, ignoreEndianFlag); } if (!_fileDna.FlagEqual(dataChunk.DnaNR)) { // Ouch! need to rebuild the struct Dna.StructDecl oldStruct = _fileDna.GetStruct(dataChunk.DnaNR); if ((_flags & FileFlags.BrokenDna) != 0) { if (oldStruct.Type.Name.Equals("btQuantizedBvhNodeData") && oldStruct.Type.Length == 28) { throw new NotImplementedException(); } if (oldStruct.Type.Name.Equals("btShortIntIndexData")) { throw new NotImplementedException(); } } // Don't try to convert Link block data, just memcpy it. Other data can be converted. if (oldStruct.Type.Name.Equals("Link")) { //Console.WriteLine("Link found"); } else { int reverseOld = _memoryDna.GetReverseType(oldStruct.Type.Name); if (reverseOld != -1) { Dna.StructDecl curStruct = _memoryDna.GetStruct(reverseOld); byte[] structAlloc = new byte[dataChunk.NR * curStruct.Type.Length]; AddDataBlock(structAlloc); using (MemoryStream stream = new MemoryStream(structAlloc)) { using (BinaryWriter writer = new BinaryWriter(stream)) { long headerPtr = head.BaseStream.Position; for (int block = 0; block < dataChunk.NR; block++) { head.BaseStream.Position = headerPtr; ParseStruct(writer, head, oldStruct, curStruct, true); headerPtr += oldStruct.Type.Length; //_libPointers.Add(old, cur); } } } return(structAlloc); } } } else { #if DEBUG_EQUAL_STRUCTS #endif } byte[] dataAlloc = new byte[dataChunk.Length]; head.Read(dataAlloc, 0, dataAlloc.Length); return(dataAlloc); }
protected void GetMatchingFileDna(Dna.StructDecl dna, Dna.ElementDecl lookupElement, BinaryWriter strcData, long data, bool fixupPointers) { // find the matching memory dna data // to the file being loaded. Fill the // memory with the file data... foreach (Dna.ElementDecl element in dna.Elements) { int eleLen = _fileDna.GetElementSize(element); if ((_flags & FileFlags.BrokenDna) != 0) { if (element.Type.Name.Equals("short") && element.Name.Name.Equals("int")) { eleLen = 0; } } if (lookupElement.Name.Equals(element.Name)) { int arrayLen = element.Name.ArraySizeNew; MemoryStream dataStream = new MemoryStream(_fileBuffer, false); dataStream.Position = data; BinaryReader dataReader = new BinaryReader(dataStream); if (element.Name.Name[0] == '*') { SafeSwapPtr(strcData, dataReader); if (fixupPointers) { if (arrayLen > 1) { throw new NotImplementedException(); } else { if (element.Name.Name[1] == '*') { throw new NotImplementedException(); } else { //_chunkPointerFixupArray.Add(strcData.BaseStream.Position); } } } else { //Console.WriteLine("skipped {0} {1} : {2:X}", element.Type.Name, element.Name.Name, strcData.BaseStream.Position); } } else if (element.Type.Name.Equals(lookupElement.Type.Name)) { byte[] mem = new byte[eleLen]; dataReader.Read(mem, 0, eleLen); strcData.Write(mem); } else { throw new NotImplementedException(); //GetElement(arrayLen, lookupType, type, data, strcData); } dataReader.Dispose(); dataStream.Dispose(); break; } data += eleLen; } }
protected unsafe void InitDna(byte[] bdnaOrg) { if (_dna != IntPtr.Zero) { return; } _dnaLength = bdnaOrg.Length; _dna = Marshal.AllocHGlobal(bdnaOrg.Length); Marshal.Copy(bdnaOrg, 0, _dna, _dnaLength); Stream stream = new UnmanagedMemoryStream((byte *)_dna.ToPointer(), _dnaLength); BinaryReader reader = new BinaryReader(stream); // SDNA byte[] code = reader.ReadBytes(8); string codes = ASCIIEncoding.ASCII.GetString(code); // NAME if (!codes.Equals("SDNANAME")) { throw new InvalidDataException(); } int dataLen = reader.ReadInt32(); _names = new Dna.NameInfo[dataLen]; for (int i = 0; i < dataLen; i++) { List <byte> name = new List <byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } _names[i] = new Dna.NameInfo(ASCIIEncoding.ASCII.GetString(name.ToArray())); } stream.Position = (stream.Position + 3) & ~3; // TYPE code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TYPE")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _types = new Dna.TypeDecl[dataLen]; for (int i = 0; i < dataLen; i++) { List <byte> name = new List <byte>(); byte ch = reader.ReadByte(); while (ch != 0) { name.Add(ch); ch = reader.ReadByte(); } string type = ASCIIEncoding.ASCII.GetString(name.ToArray()); _types[i] = new Dna.TypeDecl(type); } stream.Position = (stream.Position + 3) & ~3; // TLEN code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("TLEN")) { throw new InvalidDataException(); } for (int i = 0; i < _types.Length; i++) { _types[i].Length = reader.ReadInt16(); } stream.Position = (stream.Position + 3) & ~3; // STRC code = reader.ReadBytes(4); codes = ASCIIEncoding.ASCII.GetString(code); if (!codes.Equals("STRC")) { throw new InvalidDataException(); } dataLen = reader.ReadInt32(); _structs = new Dna.StructDecl[dataLen]; // NU long shtPtr = stream.Position; for (int i = 0; i < dataLen; i++) { Dna.StructDecl structDecl = new Dna.StructDecl(); _structs[i] = structDecl; if (!BitConverter.IsLittleEndian) { throw new NotImplementedException(); } else { short typeNr = reader.ReadInt16(); structDecl.Type = _types[typeNr]; structDecl.Type.Struct = structDecl; int numElements = reader.ReadInt16(); structDecl.Elements = new Dna.ElementDecl[numElements]; for (int j = 0; j < numElements; j++) { typeNr = reader.ReadInt16(); short nameNr = reader.ReadInt16(); structDecl.Elements[j] = new Dna.ElementDecl(_types[typeNr], _names[nameNr]); } } } reader.Dispose(); stream.Dispose(); // build reverse lookups _structReverse = new Dictionary <string, Dna.StructDecl>(_structs.Length); foreach (Dna.StructDecl s in _structs) { _structReverse.Add(s.Type.Name, s); } }