public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; int len; try { len = GetExpressionAttribute("len").EvaluateInt(instance); } catch (OverflowException) { throw new LoadDataException("Blob size is larger than Int32"); } if (offset + len > reader.BaseStream.Length) throw new LoadDataException("Blob size " + len + " exceeds stream length"); if (len < 0) throw new LoadDataException("Blob size " + len + " is negative"); var decodedSizeExpr = GetExpressionAttribute("decodedsize"); int decodedSize = decodedSizeExpr != null ? decodedSizeExpr.EvaluateInt(instance) : -1; string encoding = GetStringAttribute("encoding"); BlobDecoder blobDecoder = FindBlobEncoding(instance, encoding); BlobCell cell = new BlobCell(this, reader.BaseStream, offset, len, blobDecoder, decodedSize); instance.AddCell(cell, _hidden); instance.RegisterCellSize(cell, len); reader.BaseStream.Position += len; StructDef structDef = GetStructAttribute("struct"); if (structDef != null) instance.AddChildSeed(new BlobChildSeed(structDef, cell)); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int size = GetExpressionAttribute("size").EvaluateInt(instance); long baseOffset = reader.BaseStream.Position; uint baseValue; switch(size) { case 1: baseValue = reader.ReadByte(); break; case 2: baseValue = reader.ReadUInt16(); break; case 4: baseValue = reader.ReadUInt32(); break; default: throw new LoadDataException("Invalid bitfield size " + size); } BitfieldReader bitFieldReader = new BitfieldReader(baseValue, size, baseOffset); foreach(StructField field in ChildFields) { if (field is IntBasedField) { IntBasedField intBasedField = (IntBasedField) field; int? bit = intBasedField.GetIntAttribute("bit"); if (bit.HasValue) bitFieldReader.SetBits(bit.Value, bit.Value); else { int? fromBit = intBasedField.GetIntAttribute("frombit"); int? toBit = intBasedField.GetIntAttribute("tobit"); bitFieldReader.SetBits(fromBit.Value, toBit.Value); } } field.LoadData(bitFieldReader, instance); } }
protected IConvertible ReadIntValue(BinaryReader reader, StructInstance instance) { Expression expr = GetExpressionAttribute("value"); if (expr != null) { return expr.EvaluateInt(instance); } if (_structDef.IsReverseByteOrder()) reader = new ReverseByteOrderReader(reader.BaseStream); IConvertible value; switch (_size) { case 1: value = _unsigned ? (IConvertible)reader.ReadByte() : reader.ReadSByte(); break; case 2: value = _unsigned ? (IConvertible)reader.ReadUInt16() : reader.ReadInt16(); break; case 4: value = _unsigned ? (IConvertible)reader.ReadUInt32() : reader.ReadInt32(); break; case 8: value = _unsigned ? (IConvertible) reader.ReadUInt64() : reader.ReadInt64(); break; default: throw new Exception("Unsupported integer size " + _size); } return value; }
public override void LoadData(BinaryReader reader, StructInstance instance) { string text = GetStringAttribute("text"); if (_error) throw new LoadDataException(text); AddCell(instance, text, -1); }
public override void LoadData(BinaryReader reader, StructInstance instance) { var format = GetStringAttribute("format"); ImageDecoder decoder = FindImageDecoder(instance, format); var image = decoder.Decode(reader.BaseStream, instance); instance.AddCell(new ImageCell(this, image, (int)reader.BaseStream.Position), false); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; uint value = reader.ReadUInt32(); DateTime dt = new DateTime(1970, 1, 1).AddSeconds(value); AddCell(instance, dt, offset); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; string format = _hex ? "x" + (_size*2).ToString() : "d"; string displayValue; IConvertible value; value = ReadIntValue(reader, instance); switch(_size) { case 1: displayValue = _unsigned ? ((Byte)value).ToString(format) : ((SByte)value).ToString(format); break; case 2: displayValue = _unsigned ? ((UInt16)value).ToString(format) : ((Int16)value).ToString(format); break; case 4: displayValue = _unsigned ? ((UInt32)value).ToString(format) : ((Int32)value).ToString(format); break; case 8: displayValue = _unsigned ? ((UInt64) value).ToString(format) : ((Int64) value).ToString(format); break; case 0: displayValue = ((int)value).ToString(format); break; default: throw new Exception("Unsupported integer size " + _size); } if (_hex) displayValue = "0x" + displayValue; AddCell(instance, value, displayValue, offset); }
[Test] public void EvalEnumSymbol() { StructInstance instance = PrepareInstance( "enum e { a } struct A { enum8 q [enum=e]; if (q == a) { calc n [value=42]; } } ", new byte[] { 0 }); Assert.AreEqual("42", instance.Cells[1].Value); }
[Test] public void LookupLastCell() { StructInstance instance = PrepareInstance( "struct A { calc i [value=0]; [hidden] calc i [value=1]; calc j [value=i+1]; }", new byte[0]); Assert.AreEqual("2", instance.Cells[1].Value); }
[Test] public void InheritEnum() { StructInstance instance = PrepareInstance( "struct A { enum8 a [enum=F]; } enum E { h=2 } enum F [inherit=E] { f, g }", new byte[] { 2, 17, 37 }); Assert.AreEqual("h", instance.Cells[0].ToString()); }
[Test] public void Enum() { StructInstance instance = PrepareInstance( "struct A { enum8 a [enum=E]; } enum E { f, g, h }", new byte[] { 2, 17, 37 }); Assert.AreEqual("h", instance.Cells[0].ToString()); }
public void While() { StructInstance instance = PrepareInstance( "struct A { local x [value=0]; while(x<5) { u8 v; local x [value=x+v]; } }", new byte[] { 2, 2, 2, 2 }); Assert.AreEqual(3, instance.Cells.Count); }
[Test] public void LoadChildIfFalse() { StructInstance instance = PrepareInstance( "struct A { u8 a; if (a > 4) { child B [offset=a]; } } struct B { u8 value; } ", new byte[] { 2, 0, 17, 37 }); Assert.AreEqual(0, instance.Children.Count); }
[Test] public void FieldId() { StructInstance instance = PrepareInstance( "struct A { i8 \"Long nice name\" [id=q]; }", new byte[] { 17 }); Assert.AreEqual(17, instance.EvaluateSymbol("q")); }
[Test] public void Root() { StructInstance instance = PrepareInstance( "struct data { u8 value; child C2 [group=C, offset=1]; } struct C2 { calc q [value=root.value]; } ", new byte[] { 5, 17 }); Assert.AreEqual("5", instance.Children[0].Children[0].Cells[0].Value); }
[Test] public void Set() { StructInstance instance = PrepareInstance( "struct A { set8 a [enum=E]; } enum E { f, g, h }", new byte[] { 6 }); Assert.AreEqual("g, h", instance.Cells[0].Value); }
[Test] public void UnixTime() { StructInstance instance = PrepareInstance( "struct A { unixtime t; }", new byte[] { 0x42, 0xE8, 0xC5, 0x3D }); Assert.AreEqual(new DateTime(2002, 11, 4, 3, 23, 46), instance.Cells[0].GetValue()); }
[Test] public void ContextWithArgs() { StructInstance instance = PrepareInstance( "struct data { child C1 [offset=0]; child C2 [offset=1]; } struct C1 { i8 v; } struct C2 { calc q [value=parent.child(0).v]; } ", new byte[] { 5, 17 }); Assert.AreEqual("5", instance.Children[1].Cells[0].Value); }
public override void LoadData(BinaryReader reader, StructInstance instance) { var format = GetStringAttribute("format"); ImageDecoder decoder = FindImageDecoder(instance, format); var image = decoder.Decode(reader.BaseStream, instance); instance.AddCell(new ImageCell(this, image, (int)reader.BaseStream.Position), false); }
[Test] public void StrTrailingNull() { StructInstance instance = PrepareInstance( "struct A { str [len=4] a; }", new byte[] { (byte)'B', 0, (byte)'M', 0 }); Assert.AreEqual("B", instance.Cells[0].Value); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; uint value = reader.ReadUInt32(); DateTime dt = new DateTime(1970, 1, 1).AddSeconds(value); AddCell(instance, dt, offset); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; IConvertible iValue = ReadIntValue(reader, instance); ulong value = iValue.ToUInt64(CultureInfo.CurrentCulture); EnumDef enumDef = GetEnumAttribute("enum"); AddCell(instance, new SetValue((uint) value, enumDef, _size), offset); }
public void EvalSetSymbol() { StructInstance instance = PrepareInstance( "enum e { a, b, c } struct A { set8 q [enum=e]; if ((q & c) != 0) { calc n [value=42]; } } ", new byte[] { 4 }); Assert.AreEqual("42", instance.Cells[1].Value); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int)reader.BaseStream.Position; uint value = ReadIntValue(reader, instance).ToUInt32(CultureInfo.CurrentCulture); EnumDef enumDef = GetEnumAttribute("enum"); AddCell(instance, new EnumValue(value, enumDef), enumDef.ValueToString(value), offset); }
[Test] public void IncludeReplace() { StructInstance instance = PrepareInstance( "struct A { u8 x; include [replace] B; } struct B { u8 y; }", new byte[] { 17, 37 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("B", instance.NodeName); }
[Test] public void NullTerminatedWStr() { StructInstance instance = PrepareInstance( "struct A { wstr s; u8 a; }", new byte[] { (byte)'B', 0, (byte)'M', 0, 0, 0, 5 }); Assert.AreEqual("BM", instance.Cells[0].Value); Assert.AreEqual("5", instance.Cells[1].Value); }
[Test] public void ElIf() { StructInstance instance = PrepareInstance( "struct A { u8 a; if (a == 1) { x8 c; } elif (a == 2) { str [len=1] b; } else { u8 c; } }", new byte[] { 2, (byte)'B' }); Assert.AreEqual("B", instance.Cells[1].Value); Assert.AreEqual(2, instance.Cells.Count); }
[Test] public void ByteOrder() { StructInstance instance = PrepareInstance( "struct A [byteorder=motorola] { u16 x; i32 y;}", new byte[] { 0, 17, 0, 0, 0, 37 }); Assert.AreEqual("17", instance.Cells[0].Value); Assert.AreEqual("37", instance.Cells[1].Value); }
[Test] public void WeirdStrBytes() { StructInstance instance = PrepareInstance( "struct A { str [len=8] s; calc o [value=CurOffset]; }", new byte[] { 0, 0xFF, 0, 0, 0, 0xFF, 0, 0, (byte)'D', (byte)'O' }); Assert.AreEqual("", instance.Cells[0].Value); Assert.AreEqual("8", instance.Cells[1].Value); }
[Test] public void CompareX32() { StructInstance instance = PrepareInstance( "struct A { x32 x; if (x == -1) { u8 q; } }", new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 2 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("2", instance.Cells[1].Value); }
[Test] public void EvalGlobalMaskEnum() { StructInstance instance = PrepareInstance( "[globalmask] enum E { o, p, q } struct A { enum8 [enum=E] a; if (a == q) { u8 b; } }", new byte[] { 4, 17, 37 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("17", instance.Cells[1].Value); }
[Test] public void FollowSelfChildren() { StructInstance instance = PrepareInstance( "struct A { u8 q; child C [count=2, followchildren]; } struct C { u8 q; }", new byte[] { 2, 17, 37 }); Assert.AreEqual("17", instance.Children[0].Cells[0].Value); Assert.AreEqual("37", instance.Children[1].Cells[0].Value); }
public void Repeat() { StructInstance instance = PrepareInstance( "struct A { u8 a; repeat(a) { u8 c; } }", new byte[] { 2, 17, 37 }); Assert.AreEqual(3, instance.Cells.Count); Assert.AreEqual("37", instance.Cells[2].ToString()); }
[Test] public void SwitchOnString() { StructInstance instance = PrepareInstance( "struct A { str [len=1] a; switch(a) { case (\"b\") { u8 x; } default { u8 b; } } }", new byte[] { (byte)'b', 17 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("x", instance.Cells[1].Tag); }
[Test] public void EnumInBitField() { StructInstance instance = PrepareInstance( "struct A { bitfield(1) { enum8 e [enum=X, frombit=0, tobit=3]; } } enum X { q=12 }", new byte[] { 0xFC }); Assert.AreEqual(1, instance.Cells.Count); Assert.AreEqual("q", instance.Cells[0].Value); }
[Test] public void SwitchCaseDefault() { StructInstance instance = PrepareInstance( "struct A { u8 a; switch(a) { case 0 { u8 x; } case [default] { u8 b; } } }", new byte[] { 2, 17 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("b", instance.Cells[1].Tag); }
[Test] public void AssertFalse() { StructInstance instance = PrepareInstance( "struct A { u8 a; assert(a == 3); }", new byte[] { 2, 17, 37 }); Assert.AreEqual(2, instance.Cells.Count); Assert.IsInstanceOfType(typeof(ErrValue), instance.Cells[1].GetValue()); }
[Test] public void Include() { StructInstance instance = PrepareInstance( "struct A { u8 a; include B; } struct B { u8 value; } ", new byte[] { 2, 17, 37 }); Assert.AreEqual(2, instance.Cells.Count); Assert.AreEqual("17", instance.Cells[1].Value); }
public override void LoadData(BinaryReader reader, StructInstance instance) { long? offset = EvaluateOffset(instance); int count = EvaluateCount(instance); if (_isSibling) DoLoadChildren(instance, instance.Parent, reader.BaseStream, offset, count); else { instance.AddChildSeed(new ChildSeed(this, offset, count, _isSibling)); } }
private static ImageDecoder FindImageDecoder(StructInstance instance, string format) { if (format == "bmp") { return new DefaultImageDecoder(); } var decoders = instance.Def.StructFile.GetPluginExtensions<ImageDecoder>(); var result = decoders.Find(d => d.Name == format); if (result == null) throw new Exception("Couldn't find decoder for format " + format); return result; }
public override void LoadData(BinaryReader reader, StructInstance instance) { long offset = GetExpressionAttribute("offset").EvaluateLong(instance); if (_relative) reader.BaseStream.Seek(offset, SeekOrigin.Current); else { instance.MarkRewindOffset(reader.BaseStream.Position); reader.BaseStream.Position = offset; } }
public override void LoadData(BinaryReader reader, StructInstance instance) { var expression = GetExpressionAttribute("value"); if (IsEagerEval(expression)) { var value = expression.Evaluate(instance); AddCell(instance, value, -1); } else { AddCell(instance, expression); } }
public override void LoadData(BinaryReader reader, StructInstance instance) { while (GetExpressionAttribute("expr").EvaluateBool(instance)) { try { LoadChildFields(reader, instance); } catch (BreakRepeatException) { break; } } }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int) reader.BaseStream.Position; IConvertible value = ReadIntValue(reader, instance); ulong u = value.ToUInt64(CultureInfo.CurrentCulture); StringBuilder displayValue = new StringBuilder(_size * 8); for(int i=_size * 8 - 1; i >= 0; i--) { if ((u & (1ul << i)) != 0) displayValue.Append("1"); else displayValue.Append("0"); } AddCell(instance, value, displayValue.ToString(), offset); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int count = GetExpressionAttribute("count").EvaluateInt(instance); for(int i=0; i<count; i++) { try { LoadChildFields(reader, instance); } catch(BreakRepeatException) { break; } } }
private static BlobDecoder FindBlobEncoding(StructInstance instance, string encoding) { if (encoding == null) return null; if (encoding.ToLowerInvariant() == "zlib") { return new ZLibDecoder(); } if (encoding.ToLowerInvariant() == "minilzo") { return new MiniLZODecoder(); } var decoders = instance.Def.StructFile.GetPluginExtensions<BlobDecoder>(); var result = decoders.Find(d => d.Name == encoding); if (result == null) throw new Exception("Couldn't find decoder for encoding " + encoding); return result; }
private void DoLoadChildren(StructInstance instance, InstanceTreeNode parent, Stream stream, long? offset, int count) { StructInstance lastChild = instance.LastChild; string groupName = GetStringAttribute("group"); if (groupName != null) { GroupContainer container = new GroupContainer(parent, groupName); parent.AddChild(container); parent = container; } if (count == 0) return; StructDef childDef = GetStructAttribute("struct"); if (childDef == null) childDef = _structDef; StructInstance childInstance; bool followChildren = GetBoolAttribute("followchildren"); if (offset.HasValue) { childInstance = new StructInstance(childDef, parent, stream, offset.Value); } else { bool firstFollowChildren = followChildren && lastChild != parent; childInstance = new StructInstance(childDef, parent, stream, lastChild, firstFollowChildren); } parent.AddChild(childInstance); if (count > 1) { childInstance.SequenceIndex = 0; } for (int i = 1; i < count; i++) { var nextInstance = new StructInstance(childDef, parent, stream, childInstance, followChildren); parent.AddChild(nextInstance); nextInstance.SequenceIndex = i; childInstance = nextInstance; } }
public override void LoadData(BinaryReader reader, StructInstance instance) { IComparable switchValue = GetExpressionAttribute("expr").EvaluateComparable(instance); CaseField defaultField = null; foreach(CaseField field in ChildFields) { if (field.GetBoolAttribute("default")) defaultField = field; else { IComparable caseValue = field.GetExpressionAttribute("expr").EvaluateComparable(instance); if (switchValue.CompareTo(caseValue) == 0) { field.LoadData(reader, instance); defaultField = null; break; } } } if (defaultField != null) defaultField.LoadData(reader, instance); }
public override void LoadData(BinaryReader reader, StructInstance instance) { StructDef structDef = GetIncludedStruct(); if (structDef.FieldLike) instance.PushAddedCellHandler(cell => cell.Tag = Tag); bool oldHidden = instance.HideAddedCells(_hidden); try { structDef.LoadInstanceData(instance, reader.BaseStream); } finally { if (structDef.FieldLike) instance.PopAddedCellHandler(); instance.HideAddedCells(oldHidden); } if (GetBoolAttribute("replace")) instance.SetNodeName(structDef.Name); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int offset = (int) reader.BaseStream.Position; ushort dosDate, dosTime; if (GetBoolAttribute("timefirst")) { dosTime = reader.ReadUInt16(); dosDate = reader.ReadUInt16(); } else { dosDate = reader.ReadUInt16(); dosTime = reader.ReadUInt16(); } int day = dosDate & 0x1F; int month = (dosDate >> 5) & 0x0F; int year = 1980 + ((dosDate >> 9) & 0x7F); int second = (dosTime & 0x1F) * 2; int minute = (dosTime >> 5) & 0x3F; int hour = (dosTime >> 11) & 0x1F; AddCell(instance, new DateTime(year, month, day, hour, minute, second), offset); }
public override void LoadData(BinaryReader reader, StructInstance instance) { if (GetExpressionAttribute("expr").EvaluateBool(instance)) { LoadChildFields(reader, instance); } else if (_linkedFields != null) { foreach(StructField field in _linkedFields) { if (field is ElseIfField) { Expression expr = field.GetExpressionAttribute("expr"); bool result; try { result = expr.EvaluateBool(instance); } catch (Exception e) { throw new LoadDataException("Error evaluating if condition: " + e.Message); } if (result) { field.LoadData(reader, instance); break; } } else if (field is ElseField) { field.LoadData(reader, instance); break; } } } }
public override void LoadData(BinaryReader reader, StructInstance instance) { int result = GetExpressionAttribute("value").EvaluateInt(instance); instance.RegisterGlobal(Id, result); }
public override void LoadData(BinaryReader reader, StructInstance instance) { Expression valueExpr = GetExpressionAttribute("value"); if (valueExpr != null) { AddCell(instance, valueExpr); return; } int offset = (int)reader.BaseStream.Position; string value; int cellSize; int charSize = 1; if (_wide) charSize = 2; Expression lengthExpr = GetExpressionAttribute("len"); if (lengthExpr != null) { int length = lengthExpr.EvaluateInt(instance); if (length < 0) { throw new LoadDataException("Length expression " + lengthExpr + " has the result of " + length + " which is negative"); } cellSize = length * charSize; if (reader.BaseStream.Length - reader.BaseStream.Position < cellSize) { throw new LoadDataException("Length expression " + lengthExpr + " has the result of " + length + " and points outside the file"); } byte[] bytes = reader.ReadBytes(length * charSize); char[] chars = _wide ? Encoding.Unicode.GetChars(bytes) : Encoding.Default.GetChars(bytes); for (int i = 0; i < length; i++) { if (chars[i] == '\0') { length = i; break; } } value = new string(chars, 0, length); } else { StringBuilder valueBuilder = new StringBuilder(); BinaryReader charReader = _wide ? new BinaryReader(reader.BaseStream, Encoding.Unicode) : reader; while (true) { char c = charReader.ReadChar(); if (c == '\0') break; valueBuilder.Append(c); } value = valueBuilder.ToString(); cellSize = value.Length * charSize; } StructCell cell = AddCell(instance, value, offset); instance.RegisterCellSize(cell, cellSize); }
public Image Decode(Stream inputStream, StructInstance instance) { return Image.FromStream(inputStream); }
public abstract Image Decode(Stream inputStream, StructInstance instance);
static Value HashToStruct(VmApi api, Value[] args, int start, int length) { if (args [start].Kind != Value.Kinds.Struct) { api.RaiseShovelError ("First argument must be a struct."); } if (args [start + 1].Kind != Value.Kinds.Hash) { api.RaiseShovelError ("Second argument must be a hash."); } var ztruct = args [start].StructValue; var result = new StructInstance (); result.Struct = ztruct; result.Values = new Value[ztruct.Fields.Length]; var hash = args [start + 1].hashValue; var sizeIncrease = 1 + ztruct.Fields.Length; api.CellsIncrementHerald (sizeIncrease); for (int i = 0; i < ztruct.Fields.Length; i++) { var svKey = Value.Make (ztruct.Fields [i]); if (hash.ContainsKey (svKey)) { result.Values [i] = hash [svKey]; } } api.CellsIncrementer (sizeIncrease); return Value.Make (result); }
static Value InstantiateStruct(VmApi api, Value[] args, int start, int length) { if (length == 0) { api.RaiseShovelError ("Must provide at least one argument."); } if (args [start].Kind != Value.Kinds.Struct) { api.RaiseShovelError ("First argument must be a struct."); } var ztruct = args [start].StructValue; var sizeIncrease = 1 + ztruct.Fields.Length; api.CellsIncrementHerald (sizeIncrease); var result = new StructInstance (); result.Struct = ztruct; result.Values = new Value[ztruct.Fields.Length]; for (int i = 1; i < length; i++) { result.Values [i - 1] = args [start + i]; } api.CellsIncrementer (sizeIncrease); return Value.Make (result); }
public override void LoadData(BinaryReader reader, StructInstance instance) { int bytes = GetIntAttribute("bytes").Value; if (bytes > 1 && reader.BaseStream.Position % bytes != 0) reader.BaseStream.Position = ((reader.BaseStream.Position/bytes) + 1)*bytes; }
public override void LoadData(BinaryReader reader, StructInstance instance) { Expression expr = GetExpressionAttribute("expr"); if (!expr.EvaluateBool(instance)) throw new LoadDataException("Assertion failed: " + expr.ToString()); }
public override void LoadData(BinaryReader reader, StructInstance instance) { LoadChildFields(reader, instance); }