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); }
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); }
/// <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)); }
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; } } }
/// <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)); }
/// <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())); }
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)); }
/// <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)); }
/// <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)); }
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); }
public static BlockHeaderEntity ReadValue(ReadValueContext context) { var value = BlendStructures.FileBlockHeader.ReadValue(context); return(new BlockHeaderEntity(value)); }