Пример #1
0
        public List <BlendValueCapsule> DereferenceAll(IBlendType type)
        {
            if (!CanDereference(type))
            {
                return(null);
            }

            var result = new List <BlendValueCapsule>();

            try
            {
                int        offset = (int)m_address;
                IBlendType realType;
                using (var reader = new BinaryReader(m_mapper.GetStreamFromAddress(m_address, out realType)))
                {
                    type            = realType != null ? realType : type;         // if the given type is not equals to the real stored type, we belieave the real stored type.
                    result.Capacity = (int)reader.BaseStream.Length / type.SizeOf();
                    var context = new ReadValueContext()
                    {
                        reader = reader, mapper = m_mapper
                    };
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        var val = type.ReadValue(context);
                        result.Add(val);
                    }
                }
            }
            catch (Exception e)
            {
                throw new BlenderException("Failed to dereference {0} as {1}", AddressString, type.Name);
            }

            return(result);
        }
Пример #2
0
        public BlendValueCapsule DereferenceOne(IBlendType type)
        {
            if (!CanDereference(type))
            {
                return(null);
            }

            BlendValueCapsule result = null;

            try
            {
                int        offset = (int)m_address;
                IBlendType realType;
                using (var reader = new BinaryReader(m_mapper.GetStreamFromAddress(m_address, out realType)))
                {
                    var context = new ReadValueContext()
                    {
                        reader = reader, mapper = m_mapper
                    };
                    result = type.ReadValue(context);
                }
            }
            catch (Exception e)
            {
                throw new BlenderException("Failed to dereference {0} as {1}", AddressString, type.Name);
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Read value corresponded this type from binary
        /// </summary>
        /// <param name="context">variable for making a value</param>
        /// <returns>value</returns>
        /// <seealso cref="IBlendType.ReadValue"/>
        public BlendValueCapsule ReadValue(ReadValueContext context)
        {
            object obj = null;

            switch (m_type)
            {
            case BaseTypes.Char:
                obj = (char)context.reader.ReadByte();
                break;

            case BaseTypes.Short:
                obj = (short)context.reader.ReadInt16();
                break;

            case BaseTypes.Int:
                obj = (int)context.reader.ReadInt32();
                break;

            case BaseTypes.Float:
                obj = (float)context.reader.ReadSingle();
                break;

            default:
                Debug.Assert(false, "unsupported type " + m_toStringTable[(int)m_type]);
                break;
            }

            return(new BlendValueCapsule(this, obj));
        }
Пример #4
0
        private static List <BlockHeaderEntity> _CreateEntityList(ReadValueContext context, BlendTypeRepository repository)
        {
            var result = new List <BlockHeaderEntity>();

            BlendStructures.GlobalHeader.ReadValue(context);
            while (true)
            {
                var blockEntity = BlockHeaderEntity.ReadValue(context);
                switch (blockEntity.Code)
                {
                case "DNA1":
                    // skip
                    result.Add(blockEntity);
                    context.reader.ReadBytes(blockEntity.Size);
                    break;

                case "ENDB":
                    // end of file
                    result.Add(blockEntity);
                    return(result);

                case "REND":                         // RenderInfo
                case "TEST":                         // Preview Image
                    // skip
                    result.Add(blockEntity);
                    context.reader.ReadBytes(blockEntity.Size);
                    break;

                default:
                {
                    var type = repository.Find(blockEntity.SdnaIndex);

                    // register address mapping
                    int sdnaSize = blockEntity.Count * type.SizeOf();
                    context.mapper.AddEntry(blockEntity.OldAddress.Address, (int)context.reader.BaseStream.Position, blockEntity.Size, blockEntity.SdnaIndex, type);

                    if (blockEntity.Count == 1 && blockEntity.SdnaIndex == 0 && blockEntity.Size != type.SizeOf())
                    {
                        // Error? skip
                        result.Add(blockEntity);
                        context.reader.ReadBytes(blockEntity.Size);
                    }
                    else
                    {
                        Debug.Assert((type.SizeOf() * blockEntity.Count) == blockEntity.Size, "structure size unmatched");
                        for (int i = 0; i < blockEntity.Count; ++i)
                        {
                            var value = type.ReadValue(context);
                            blockEntity.Children.Add(new BlendEntityBase(value.Type.Name, value));
                        }

                        result.Add(blockEntity);
                    }
                }
                break;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Read value corresponded this type from binary
        /// </summary>
        /// <param name="context">variable for making a value</param>
        /// <returns>value</returns>
        /// <seealso cref="IBlendType.ReadValue"/>
        public BlendValueCapsule ReadValue(ReadValueContext context)
        {
            var rawValue = new _RawValue();

            foreach (var decl in m_decls)
            {
                var value = decl.Type.ReadValue(context);
                rawValue.Add(decl.Name, value);
            }

            return(new _BlendValueCapsule(this, rawValue));
        }
Пример #6
0
        /// <summary>
        /// Read value corresponded this type from binary
        /// </summary>
        /// <param name="context">variable for making a value</param>
        /// <returns>value</returns>
        /// <seealso cref="IBlendType.ReadValue"/>
        public BlendValueCapsule ReadValue(ReadValueContext context)
        {
            var sb = new StringBuilder("0x");

            for (int byteIndex = 0; byteIndex < m_size; ++byteIndex)
            {
                byte b = context.reader.ReadByte();
                sb.Append(b.ToString("x2"));
            }

            return(new BlendValueCapsule(this, sb.ToString()));
        }
Пример #7
0
        public List <BlockHeaderEntity> FromMemory(Stream stream)
        {
            var reader = new BinaryReader(stream);
            var mapper = new BlendAddressMapper(BinaryUtil.ReadBytesFromStream(stream));

            var context = new ReadValueContext()
            {
                reader = reader, mapper = mapper
            };
            var declList = _ReadDna1Block(context);

            //var sortedDeclList = _SortByTypeDependency(declList);

            // before create member type, register a parent type
            foreach (var decl in declList)
            {
                var parentType = BlendStructureType.CreateImperfect(decl.name, decl.sdnaIndex);
                m_repository.Add(parentType);
            }

            // build member decls and set to parent
            foreach (var decl in declList)
            {
                var parentType = (BlendStructureType)m_repository.Find(decl.name);

                int fieldCount  = decl.fieldNames.Length;
                var memberDecls = new BlendStructureType.MemberDecl[fieldCount];
                for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
                {
                    string type = decl.fieldTypes[fieldIndex];
                    string name = decl.fieldNames[fieldIndex];
                    int    tLen = decl.fieldLengths[fieldIndex];

                    var typeObj = m_repository.Find(type);
                    if (typeObj == null)
                    {
                        typeObj = new UnknownBlendType(type + " " + "name", tLen);
                    }

                    memberDecls[fieldIndex] = _ParseType(typeObj, name, tLen);
                }

                // set member decls
                parentType.SetMemberDecls(memberDecls);
            }

            stream.Seek(0, SeekOrigin.Begin);
            return(_CreateEntityList(context, m_repository));
        }
Пример #8
0
        /// <summary>
        /// Read value corresponded this type from binary
        /// </summary>
        /// <param name="context">variable for making a value</param>
        /// <returns>value</returns>
        /// <seealso cref="IBlendType.ReadValue"/>
        public BlendValueCapsule ReadValue(ReadValueContext context)
        {
            object obj = null;

            if (GetPointerSizeOf() == 4)
            {
                // 32bit
                obj = new BlendAddress(context.reader.ReadUInt32(), context.mapper);
            }
            else
            {
                // 64bit
                obj = new BlendAddress(context.reader.ReadUInt64(), context.mapper);
            }

            return(new BlendValueCapsule(this, obj));
        }
Пример #9
0
        /// <summary>
        /// Read value corresponded this type from binary
        /// </summary>
        /// <param name="context">variable for making a value</param>
        /// <returns>value</returns>
        /// <seealso cref="IBlendType.ReadValue"/>
        public virtual BlendValueCapsule ReadValue(ReadValueContext context)
        {
            object obj = null;

            switch (ArrayDimension)
            {
            case 1:
            {
                var objs = new BlendValueCapsule[m_dimCountArray[0]];
                for (int i = 0; i < m_dimCountArray[0]; ++i)
                {
                    objs[i] = m_baseType.ReadValue(context);
                }
                obj = objs;
            }
            break;

            case 2:
            {
                var objs = new object[m_dimCountArray[0]];

                for (int i = 0; i < m_dimCountArray[0]; ++i)
                {
                    var tmp = new BlendValueCapsule[m_dimCountArray[1]];
                    for (int j = 0; j < m_dimCountArray[1]; ++j)
                    {
                        tmp[j] = m_baseType.ReadValue(context);
                    }

                    objs[i] = tmp;
                }
                obj = objs;
            }
            break;
            }

            return(new _BlendValueCapsule(this, obj));
        }
Пример #10
0
        private static List <_StructureDecl> _ReadDna1Block(ReadValueContext context)
        {
            var declList = new List <_StructureDecl>();
            var header   = BlendStructures.GlobalHeader.ReadValue(context);

            if (header.GetMember("pointer_size").GetRawValue <char>() == '_')
            {
                throw new BlenderException("32bit pointer-size is unsupported");
            }

            if (header.GetMember("endianness").GetRawValue <char>() == 'V')
            {
                throw new BlenderException("big endian is unsupported");
            }

            while (true)
            {
                var fileBlock = BlendStructures.FileBlockHeader.ReadValue(context);
                var code      = fileBlock.GetMember("code").GetAllValueAsString();
                int size      = fileBlock.GetMember("size").GetRawValue <int>();

                if (code == "DNA1")
                {
                    context.reader.ReadBytes(4);                    // SDNA
                    context.reader.ReadBytes(4);                    // NAME

                    int nameCount     = context.reader.ReadInt32();
                    var names         = new string[nameCount];
                    int readByteCount = 0;
                    for (int index = 0; index < nameCount; ++index)
                    {
                        string s = BinaryUtil.ReadAsciiString(context.reader);
                        names[index]   = s;
                        readByteCount += (s.Length + 1);
                    }

                    context.reader.ReadBytes(readByteCount * 3 % 4); // align
                    context.reader.ReadBytes(4);                     // TYPE

                    int typeCount = context.reader.ReadInt32();
                    readByteCount = 0;
                    var types = new string[typeCount];
                    for (int index = 0; index < typeCount; ++index)
                    {
                        string s = BinaryUtil.ReadAsciiString(context.reader);
                        types[index]   = s;
                        readByteCount += (s.Length + 1);
                    }

                    context.reader.ReadBytes(readByteCount * 3 % 4); // align
                    context.reader.ReadBytes(4);                     // TLEN

                    readByteCount = 0;
                    var tLens = new int[typeCount];
                    for (int index = 0; index < typeCount; ++index)
                    {
                        int len = context.reader.ReadUInt16();
                        tLens[index]   = len;
                        readByteCount += 2;
                    }

                    context.reader.ReadBytes(readByteCount * 3 % 4); // align
                    context.reader.ReadBytes(4);                     // STRC

                    int structCount = context.reader.ReadInt32();
                    readByteCount = 0;
                    for (int index = 0; index < structCount; ++index)
                    {
                        var decl = new _StructureDecl();

                        int typeIndex = context.reader.ReadInt16();
                        decl.name      = types[typeIndex];
                        decl.sdnaIndex = index;
                        decl.size      = tLens[typeIndex];

                        int fieldCount = context.reader.ReadInt16();
                        decl.fieldTypes   = new string[fieldCount];
                        decl.fieldLengths = new int[fieldCount];
                        decl.fieldNames   = new string[fieldCount];
                        for (int fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
                        {
                            int fieldTypeIndex = context.reader.ReadInt16();
                            int fieldNameIndex = context.reader.ReadInt16();

                            decl.fieldTypes[fieldIndex]   = types[fieldTypeIndex];
                            decl.fieldLengths[fieldIndex] = tLens[fieldTypeIndex];
                            decl.fieldNames[fieldIndex]   = names[fieldNameIndex];
                        }

                        declList.Add(decl);
                    }
                }
                else if (code == "ENDB")
                {
                    // END
                    break;
                }
                else
                {
                    // Skip
                    context.reader.ReadBytes(size);
                }
            }

            return(declList);
        }
Пример #11
0
        public static BlockHeaderEntity ReadValue(ReadValueContext context)
        {
            var value = BlendStructures.FileBlockHeader.ReadValue(context);

            return(new BlockHeaderEntity(value));
        }