Пример #1
0
        static DataArray parse_children(System.IO.Stream s, uint numChildren, DataType type = DataType.ARRAY, int version = 1)
        {
            DataArray ret = type == DataType.MACRO ? new DataMacroDefinition()
                            : type == DataType.COMMAND ? new DataCommand()
                            : new DataArray();

            while (numChildren-- > 0)
            {
                DataType t = (DataType)s.ReadInt32LE();
                switch (t)
                {
                case DataType.INT:
                    ret.AddNode(new DataAtom(s.ReadInt32LE()));
                    break;

                case DataType.FLOAT:
                    ret.AddNode(new DataAtom(s.ReadFloat()));
                    break;

                case DataType.VARIABLE:
                    ret.AddNode(DataVariable.Var(s.ReadLengthUTF8()));
                    break;

                case DataType.SYMBOL:
                    ret.AddNode(DataSymbol.Symbol(s.ReadLengthUTF8()));
                    break;

                case DataType.ARRAY:
                case DataType.COMMAND:
                case DataType.MACRO:
                    if (version == 2)
                    {
                        s.Position += 4;
                        uint   nC  = s.ReadUInt32LE();
                        ushort unk = s.ReadUInt16LE();
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    else if (version == 3)
                    {
                        s.Position += 4;
                        ushort nC = s.ReadUInt16LE();
                        s.Position += 2;
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    else
                    {
                        ushort nC = s.ReadUInt16LE(); // numChildren
                        s.Position += 4;              // id
                        ret.AddNode(parse_children(s, nC, t, version));
                    }
                    break;

                case DataType.STRING:
                    ret.AddNode(new DataAtom(s.ReadLengthUTF8()));
                    break;

                case DataType.EMPTY:
                    s.Position += 4;
                    break;

                case DataType.DEFINE:
                    var constant = s.ReadLengthUTF8();
                    numChildren--;
                    var definition = parse_children(s, 1, DataType.ARRAY, version).Array(0);
                    ret.AddNode(new DataDefine(constant, definition));
                    break;

                case DataType.IFDEF:
                    ret.AddNode(new DataIfDef(s.ReadLengthUTF8()));
                    break;

                case DataType.IFNDEF:
                    ret.AddNode(new DataIfNDef(s.ReadLengthUTF8()));
                    break;

                case DataType.ELSE:
                    s.Position += 4;
                    ret.AddNode(new DataElse());
                    break;

                case DataType.ENDIF:
                    s.Position += 4;
                    ret.AddNode(new DataEndIf());
                    break;

                case DataType.INCLUDE:
                    ret.AddNode(new DataInclude(s.ReadLengthUTF8()));
                    break;

                case DataType.MERGE:
                    ret.AddNode(new DataMerge(s.ReadLengthUTF8()));
                    break;

                case DataType.AUTORUN:
                    s.Position += 4;
                    ret.AddNode(new DataAutorun());
                    break;

                case DataType.UNDEF:
                    ret.AddNode(new DataUndef(s.ReadLengthUTF8()));
                    break;

                default:
                    throw new Exception("Unhandled DTB DataType " + Enum.GetName(typeof(DataType), t));
                }
            }
            return(ret);
        }