actionparser.java
来自「java和flash混合编程」· Java 代码 · 共 424 行 · 第 1/2 页
JAVA
424 行
/****************************************************************
* Copyright (c) 2001, David N. Main, All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name of the author may not be used to endorse or
* promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/
package com.anotherbigidea.flash.readers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.anotherbigidea.flash.SWFActionCodes;
import com.anotherbigidea.flash.SWFConstants;
import com.anotherbigidea.flash.interfaces.SWFActionBlock;
import com.anotherbigidea.flash.interfaces.SWFActions;
import com.anotherbigidea.io.InStream;
/**
* Parse action bytes and drive a SWFActions interface
*/
public class ActionParser implements SWFActionCodes
{
protected SWFActionBlock mBlock;
protected int mFlashVersion;
protected int mStartOffset;
public ActionParser( SWFActionBlock actions, int flashVersion )
{
mBlock = actions;
mFlashVersion = flashVersion;
}
public synchronized void parse( byte[] bytes ) throws IOException
{
parse( new InStream(bytes) );
}
public synchronized void parse( InStream in ) throws IOException
{
mStartOffset = (int) in.getBytesRead();
BlockParser parser = new BlockParser( mBlock, -1, in, mFlashVersion );
parser.parse();
}
private static class WaitForFrameTarget {
public int actionsToSkip;
public String targetLabel;
public WaitForFrameTarget( int skip, String label ) {
actionsToSkip = skip;
targetLabel = label;
}
}
private class BlockParser implements SWFActionCodes {
private SWFActionBlock mBlock;
private int mBlockSize;
private InStream mIn;
private int mInitBytesRead;
private int mFlashVersion;
protected String mStringEncoding = SWFConstants.STRING_ENCODING_MX;
private int mWaitForFrameIndex = 0;
private List mWaitForFrameTargets;
/** @return the target label for the Wait-for-frame action. */
private String newWaitForFrameTarget( int actionsToSkip ) {
if( mWaitForFrameTargets == null ) mWaitForFrameTargets = new ArrayList();
WaitForFrameTarget target = new WaitForFrameTarget( actionsToSkip, "w" + (mWaitForFrameIndex++) );
mWaitForFrameTargets.add( target );
return target.targetLabel;
}
BlockParser( SWFActionBlock block, int blockSize, InStream in, int flashVersion ) {
mBlock = block;
mBlockSize = blockSize;
mIn = in;
mInitBytesRead = (int) in.getBytesRead();
mFlashVersion = flashVersion;
if( flashVersion < SWFConstants.FLASH_MX_VERSION ) {
mStringEncoding = SWFConstants.STRING_ENCODING_PRE_MX;
}
}
private String makeLabel( int offset ) {
String label = Integer.toString( offset + mInitBytesRead - mStartOffset );
if( label.length() < 4 ) label = "0000".substring(0,4-label.length()) + label;
return label;
}
private void applyWaitForFrameTargets() throws IOException {
if( mWaitForFrameTargets == null || mWaitForFrameTargets.isEmpty() ) return;
for (Iterator i = mWaitForFrameTargets.iterator(); i.hasNext();) {
WaitForFrameTarget target = (WaitForFrameTarget) i.next();
if( target.actionsToSkip == 0 ) {
mBlock.jumpLabel( target.targetLabel );
i.remove();
continue;
}
target.actionsToSkip--;
}
}
void parse() throws IOException {
int offset = 0;
boolean foundEndAction = false;
end: while( ( offset = ((int) mIn.getBytesRead()) - mInitBytesRead ) < mBlockSize
|| mBlockSize < 0 //denotes termination by end rather than size
) {
int code = mIn.readUI8();
int dataLength = (code >= 0x80) ? mIn.readUI16() : 0;
applyWaitForFrameTargets();
mBlock.jumpLabel( makeLabel(offset) );
switch( code )
{
case 0: mBlock.end(); foundEndAction = true; break end;
//--Flash 3
case GOTO_FRAME : mBlock.gotoFrame( mIn.readUI16() ); break;
case GET_URL : mBlock.getURL( mIn.readString(mStringEncoding), mIn.readString(mStringEncoding) ); break;
case NEXT_FRAME : mBlock.nextFrame(); break;
case PREVIOUS_FRAME: mBlock.prevFrame(); break;
case PLAY : mBlock.play(); break;
case STOP : mBlock.stop(); break;
case TOGGLE_QUALITY: mBlock.toggleQuality(); break;
case STOP_SOUNDS : mBlock.stopSounds(); break;
case WAIT_FOR_FRAME: mBlock.waitForFrame( mIn.readUI16(), newWaitForFrameTarget( mIn.readUI8() ) ); break;
case SET_TARGET : mBlock.setTarget( mIn.readString(mStringEncoding) ); break;
case GOTO_LABEL : mBlock.gotoFrame( mIn.readString(mStringEncoding) ); break;
//--Flash 4
case IF : mBlock.ifJump( makeLabel( offset + 5 + mIn.readSI16() ) ); break;
case JUMP : mBlock.jump( makeLabel( offset + 5 + mIn.readSI16() ) ); break;
case WAIT_FOR_FRAME_2: mBlock.waitForFrame( newWaitForFrameTarget( mIn.readUI8() )); break;
case POP : mBlock.pop(); break;
case PUSH : parsePush( dataLength, mIn ); break;
case ADD : mBlock.add(); break;
case SUBTRACT : mBlock.substract(); break;
case MULTIPLY : mBlock.multiply(); break;
case DIVIDE : mBlock.divide(); break;
case EQUALS : mBlock.equals(); break;
case LESS : mBlock.lessThan(); break;
case AND : mBlock.and(); break;
case OR : mBlock.or(); break;
case NOT : mBlock.not(); break;
case STRING_EQUALS : mBlock.stringEquals(); break;
case STRING_LENGTH : mBlock.stringLength(); break;
case STRING_ADD : mBlock.concat(); break;
case STRING_EXTRACT : mBlock.substring(); break;
case STRING_LESS : mBlock.stringLessThan(); break;
case MB_STRING_EXTRACT : mBlock.substringMB(); break;
case MB_STRING_LENGTH : mBlock.stringLengthMB(); break;
case TO_INTEGER : mBlock.toInteger(); break;
case CHAR_TO_ASCII : mBlock.charToAscii(); break;
case ASCII_TO_CHAR : mBlock.asciiToChar(); break;
case MB_CHAR_TO_ASCII : mBlock.charMBToAscii(); break;
case MB_ASCII_TO_CHAR : mBlock.asciiToCharMB(); break;
case CALL : mBlock.call(); break;
case GET_VARIABLE : mBlock.getVariable(); break;
case SET_VARIABLE : mBlock.setVariable(); break;
case GET_URL_2 : parseGetURL2( mIn.readUI8() ); break;
case GOTO_FRAME_2 : mBlock.gotoFrame( mIn.readUI8() != 0 ); break;
case SET_TARGET_2 : mBlock.setTarget(); break;
case GET_PROPERTY : mBlock.getProperty(); break;
case SET_PROPERTY : mBlock.setProperty(); break;
case CLONE_SPRITE : mBlock.cloneSprite(); break;
case REMOVE_SPRITE : mBlock.removeSprite(); break;
case START_DRAG : mBlock.startDrag(); break;
case END_DRAG : mBlock.endDrag(); break;
case TRACE : mBlock.trace(); break;
case GET_TIME : mBlock.getTime(); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?