public int Read(out FieldValue[] values) { List <FieldValue> list = new List <FieldValue>(); int localOffset = 0; foreach (StructField field in _fields) { FieldValue value; // Perform alignment. localOffset = Offset.Increment(localOffset).Align(field.Alignment).Decrement(Offset).ToInt32(); // Resolve pointer, if needed. if (field.IsPointer) { IntPtr pointingTo = IOProvider.ReadBytes(Offset.Increment(localOffset), IntPtr.Size).ToIntPtr(); localOffset += IntPtr.Size; if (pointingTo == IntPtr.Zero) { value = new FieldValue() { Name = field.Name, FieldType = field.RawType, Value = null } } ; else { Read(field, pointingTo, out value); } value.PointerValue = pointingTo; } else { localOffset += Read(field, Offset.Increment(localOffset), out value); } if (field.SetsVarOn != null) { _fieldsByName[field.SetsVarOn].VarLength = field.SetsVarOnAdd + (int)(int.Parse(value.Value.ToString()) * (decimal)field.SetsVarOnMultiply); _fieldsByName[field.SetsVarOn].VarArrayLength = field.SetsVarOnAdd + (int)(int.Parse(value.Value.ToString()) * (decimal)field.SetsVarOnMultiply); } list.Add(value); } values = list.ToArray(); return(localOffset); }
public int Read(out FieldValue[] values) { List <FieldValue> list = new List <FieldValue>(); int localOffset = 0; foreach (StructField field in _fields) { FieldValue value; // resolve pointer if (field.IsPointer) { int pointingTo = Utils.ToInt32(IOProvider.ReadBytes(Offset.Increment(localOffset), 4), Utils.Endianness.Little); localOffset += 4; if (pointingTo == 0) { value = new FieldValue() { Name = field.Name, FieldType = field.RawType, Value = null } } ; else { Read(field, new IntPtr(pointingTo), out value); } value.PointerValue = pointingTo; } else { localOffset += Read(field, Offset.Increment(localOffset), out value); } if (field.SetsVarOn != null) { _fieldsByName[field.SetsVarOn].VarLength = field.SetsVarOnAdd + (int)(int.Parse(value.Value.ToString()) * (decimal)field.SetsVarOnMultiply); _fieldsByName[field.SetsVarOn].VarArrayLength = field.SetsVarOnAdd + (int)(int.Parse(value.Value.ToString()) * (decimal)field.SetsVarOnMultiply); } list.Add(value); } values = list.ToArray(); return(localOffset); }
private unsafe int ReadOnce(StructField field, IntPtr offset, out FieldValue valueOut) { FieldValue value = new FieldValue() { FieldType = field.Type, Name = field.Name }; int readSize = 0; switch (field.Type) { case FieldType.Bool32: value.Value = Utils.ToInt32(IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little) != 0; readSize = 4; break; case FieldType.Bool8: value.Value = IOProvider.ReadBytes(offset, 1)[0] != 0; readSize = 1; break; case FieldType.CharASCII: value.Value = (char)IOProvider.ReadBytes(offset, 1)[0]; readSize = 1; break; case FieldType.CharUTF16: value.Value = Encoding.Unicode.GetString(IOProvider.ReadBytes(offset, 2))[0]; readSize = 2; break; case FieldType.Double: { long data = Utils.ToInt64( IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little); value.Value = *(double *)&data; readSize = 8; } break; case FieldType.Int16: value.Value = (short)Utils.ToUInt16( IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little); readSize = 2; break; case FieldType.Int32: value.Value = Utils.ToInt32( IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little); readSize = 4; break; case FieldType.Int64: value.Value = Utils.ToInt64( IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little); readSize = 8; break; case FieldType.Int8: value.Value = (sbyte)IOProvider.ReadBytes(offset, 1)[0]; readSize = 1; break; case FieldType.PVoid: value.Value = IOProvider.ReadBytes(offset, IntPtr.Size).ToIntPtr(); readSize = IntPtr.Size; break; case FieldType.Single: { int data = Utils.ToInt32( IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little); value.Value = *(float *)&data; readSize = 4; } break; case FieldType.StringASCII: { StringBuilder str = new StringBuilder(); if (field.VarLength == -1) { int i; for (i = 0; ; i++) { byte b = IOProvider.ReadBytes(offset.Increment(i), 1)[0]; if (b == 0) { break; } str.Append((char)b); } readSize = i; } else { str.Append(Encoding.ASCII.GetString( IOProvider.ReadBytes(offset, field.VarLength))); readSize = field.VarLength; } value.Value = str.ToString(); } break; case FieldType.StringUTF16: { StringBuilder str = new StringBuilder(); if (field.VarLength == -1) { int i; for (i = 0; ; i += 2) { byte[] b = IOProvider.ReadBytes(offset.Increment(i), 2); if (Utils.IsEmpty(b)) { break; } str.Append(Encoding.Unicode.GetString(b)); } readSize = i; } else { str.Append(Encoding.Unicode.GetString( IOProvider.ReadBytes(offset, field.VarLength * 2))); // each char is 2 bytes readSize = field.VarLength; } value.Value = str.ToString(); } break; case FieldType.Struct: { FieldValue[] valuesOut; StructDef struc = Structs[field.StructName]; struc.IOProvider = this.IOProvider; struc.Offset = offset; struc.Structs = this.Structs; readSize = struc.Read(out valuesOut); value.Value = valuesOut; value.StructName = field.StructName; } break; case FieldType.UInt16: value.Value = Utils.ToUInt16( IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little); readSize = 2; break; case FieldType.UInt32: value.Value = Utils.ToUInt32( IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little); readSize = 4; break; case FieldType.UInt64: value.Value = (ulong)Utils.ToInt64( IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little); readSize = 8; break; case FieldType.UInt8: value.Value = IOProvider.ReadBytes(offset, 1)[0]; readSize = 1; break; default: readSize = 0; break; } valueOut = value; return(readSize); }