/// <summary> /// /// </summary> /// <param name="code"></param> /// <param name="instructionIndex"></param> /// <param name="mStack"></param> /// <returns></returns> public override bool Execute( AVM1Code code, int instructionIndex, CheckMachine.MachineStack mStack ) { AVM1DataElement e = new AVM1DataElement(); // check if we can resolve the argument within the basic block of the instruction if ( AVM1.Stack.Trace.TraceArgument( code, instructionIndex, null, _ArgumentNumber, out e ) ) { if ( e.DataType != AVM1DataTypes.AVM_String ) { return false; } else { CheckMachine.MachineStackEntry se = new CheckMachine.MachineStackEntry(); se.Type = CheckMachine.MachineStackType.String; se.Value = e.Value; mStack.Push( se ); return true; } } return false; }
/// <summary> /// Parses the arguments from a source stream (The documentation is misleading. /// The _length member does define the overall length of the action's arguments. /// Now, we have to track how much we used.) /// </summary> /// <param name="sourceStream">The source stream</param> /// <param name="sourceVersion">The version</param> protected override void Parse( System.IO.BinaryReader sourceStream, byte sourceVersion ) { _arguments = new List<AVM1DataElement>(); // // The documentation is misleading. The _length member does define the overall // length of the action's arguments. Now, we have to track how much we used. // long before = sourceStream.BaseStream.Position; while ( sourceStream.BaseStream.Position < ( before + _length ) ) { AVM1DataElement element = new AVM1DataElement(); element.DataType = ( AVM1DataTypes )sourceStream.ReadByte(); if ( ( element.DataType >= AVM1DataTypes.AVM_null ) && ( sourceVersion < 5 ) ) { throw new AVM1ExceptionVersion( "ActionPush with data type " + element.DataType.ToString() + " in Swf Version " + sourceVersion.ToString() ); } switch ( element.DataType ) { case AVM1DataTypes.AVM_String: element.Value = ( object )Helper.SwfStrings.SwfString( sourceVersion, sourceStream ); break; case AVM1DataTypes.AVM_float: element.Value = ( object )sourceStream.ReadSingle(); break; case AVM1DataTypes.AVM_null: element.Value = null; break; case AVM1DataTypes.AVM_undefined: element.Value = null; break; case AVM1DataTypes.AVM_register: element.Value = ( object )sourceStream.ReadByte(); break; case AVM1DataTypes.AVM_boolean: element.Value = ( object )sourceStream.ReadBoolean(); break; case AVM1DataTypes.AVM_double: element.Value = ( object )sourceStream.ReadDouble(); break; case AVM1DataTypes.AVM_integer: element.Value = ( object )sourceStream.ReadUInt32(); break; case AVM1DataTypes.AVM_constUInt8: element.Value = ( object )sourceStream.ReadByte(); break; case AVM1DataTypes.AVM_constUInt16: element.Value = ( object )sourceStream.ReadUInt16(); break; default: throw new AVM1ExceptionByteCodeFormat( "ActionPush with invalid data type 0x" + element.DataType.ToString( "X" ) ); } _arguments.Add( element ); } if ( sourceStream.BaseStream.Position != ( before + _length ) ) { throw new AVM1ExceptionByteCodeFormat( "ActionPush arguments consumed more than the Action's length (" + ( ( long )( sourceStream.BaseStream.Position - before ) ).ToString() + " consumed, " + _length.ToString() + " declared as length)" ); } }
/// <summary> /// Parses the action from a string array /// </summary> /// <param name="token">The action as string arry</param> /// <returns>True - If parsing was successful. False - If it was not</returns> protected override bool ParseFrom( params string[] token ) { _arguments = new List<AVM1DataElement>(); for ( int i = 0; i < token.Length; i++ ) { string arg = null; if ( token[ i ].Contains( ":" ) ) { arg = token[ i ].Substring( token[ i ].IndexOf( ":" ) + 1 ); } AVM1DataElement e = new AVM1DataElement(); if ( token[ i ].StartsWith( "Bool:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_boolean; e.Value = Boolean.Parse( arg ); } else if ( token[ i ].StartsWith( "Const16:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_constUInt16; e.Value = UInt16.Parse( arg, System.Globalization.NumberStyles.AllowHexSpecifier ); } else if ( token[ i ].StartsWith( "Const8:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_constUInt8; e.Value = Byte.Parse( arg, System.Globalization.NumberStyles.AllowHexSpecifier ); } else if ( token[ i ].StartsWith( "Double:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_double; e.Value = Double.Parse( arg ); } else if ( token[ i ].StartsWith( "Single:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_float; e.Value = float.Parse( arg ); } else if ( token[ i ].StartsWith( "UInt32:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_integer; e.Value = UInt32.Parse( arg, System.Globalization.NumberStyles.AllowHexSpecifier ); } else if ( token[ i ].StartsWith( "NULL", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_null; e.Value = null; } else if ( token[ i ].StartsWith( "Reg:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_register; e.Value = Byte.Parse( arg, System.Globalization.NumberStyles.AllowHexSpecifier ); } else if ( token[ i ].StartsWith( "String:", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_String; e.Value = arg; } else if ( token[ i ].StartsWith( "UNDEFINED", StringComparison.InvariantCulture ) ) { e.DataType = AVM1DataTypes.AVM_undefined; e.Value = null; } else { return false; } _arguments.Add( e ); } return true; }
/// <summary> /// /// </summary> public virtual Stack.AVM1Stack PerformStackOperations( Stack.AVM1Stack sourceStack ) { for ( int i = 0; i < _StackOps.Length; i++ ) { if ( _StackOps[ i ].Change < 0 ) { sourceStack.Pop(); } else if ( _StackOps[ i ].Change > 0 ) { AVM1DataElement e = new AVM1DataElement(); e.DataType = _StackOps[ i ].DataType; e.Value = null; sourceStack.Push( e ); } } return sourceStack; }