예제 #1
0
        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]);
                }
            }
        }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
 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);
 }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
 // 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);
                 }
             }
         }
     }
 }
예제 #7
0
        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>");
            }
        }
예제 #8
0
 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);
 }
예제 #9
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);
                    }
                }
            }
        }
예제 #10
0
        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;
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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;
            }
        }
예제 #17
0
        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);
            }
        }