Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }