⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actionblockwriter.java

📁 java和flash混合编程
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/****************************************************************
 * Copyright (c) 2003, 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.writers;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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.OutStream;

/**
 * Implementation of SWFActionBlock that builds a byte array of the actions
 * it is passed.
 * 
 * @author nmain
 */
public class ActionBlockWriter implements SWFActionBlock, SWFActionCodes {

    /** Base for different types of fix-ups. */
    interface Fixer {
        public void fix( byte[] actionData );
    }
        
    private class OffsetFixer implements Fixer {
        
        private int mBaseOffset;
        private int mOffsetAddr;
        private String mTargetLabel;
        
        OffsetFixer( int baseOffset, int offsetAddr, String targetLabel ) {
            mBaseOffset  = baseOffset;
            mOffsetAddr  = offsetAddr;
            mTargetLabel = targetLabel;
        }
        
        public void fix( byte[] actionData ) {
            LabelInfo info = (LabelInfo) mLabelToInfo.get( mTargetLabel );
            int offset = info.offset - mBaseOffset;
            actionData[ mOffsetAddr   ] = (byte)(offset & 0xff);
            actionData[ mOffsetAddr+1 ] = (byte)((offset >> 8) & 0xff);
        }
    }
    
    private class SkipActionFixer implements Fixer {
        
        private int mSkipCountAddr;
        private int mBaseActionCount;
        private String mTargetLabel;
        
        SkipActionFixer( int baseActionCount, int skipCountAddr, String targetLabel ) {
            mBaseActionCount = baseActionCount;
            mSkipCountAddr   = skipCountAddr;
            mTargetLabel     = targetLabel;
        }
        
        public void fix( byte[] actionData ) {
            LabelInfo info = (LabelInfo) mLabelToInfo.get( mTargetLabel );
            int actionsToSkip = info.actionNumber - mBaseActionCount;
            actionData[ mSkipCountAddr ] = (byte) actionsToSkip;
        }        
    }
    
    private class BlockLengthFixer implements Fixer {
        
        private int mBlockLengthAddr;
        private int mBlockLength;
        
        BlockLengthFixer( int blockLengthAddr ) {
            mBlockLengthAddr = blockLengthAddr;
        }
        
        public void setBlockLength( int length ) {
            mBlockLength = length;
        }
        
        public void fix( byte[] actionData ) {
            actionData[ mBlockLengthAddr   ] = (byte)(mBlockLength & 0xff);
            actionData[ mBlockLengthAddr+1 ] = (byte)((mBlockLength >> 8) & 0xff);            
        }        
    }
    
    private class TryFlagsFixer implements Fixer {
        
        private int mFlagsAddr;
        private int mFlags = 0;
        
        TryFlagsFixer( int flagsAddr ) {
            mFlagsAddr = flagsAddr;
        }
        
        public void hasCatchBlock()   { mFlags |= SWFActionCodes.TRY_HAS_CATCH; }
        public void hasFinallyBlock() { mFlags |= SWFActionCodes.TRY_HAS_FINALLY; }
        public void catchInRegister() { mFlags |= SWFActionCodes.TRY_CATCH_IN_REGISTER; }
        
        public void fix( byte[] actionData ) {
            actionData[ mFlagsAddr ] = (byte)(mFlags & 0xff);
        }        
    }
    
    /** Info about a label. */
    private static class LabelInfo {
        public final String label;
        public final int    offset;
        public final int    actionNumber;
        
        public LabelInfo( String label, int offset, int actionNumber ) {
            this.label  = label;
            this.offset = offset;
            this.actionNumber = actionNumber;
        }
    }
    
    interface PushValue { public abstract void write( OutStream out ) throws IOException; }

    class PushUndefined  implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_UNDEFINED ); } }
    class PushStringVal  implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_STRING ); out.writeString( value, mStringEncoding ); } private String value; PushStringVal( String v ) { value = v; } }
    class PushBooleanVal implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_BOOLEAN ); out.writeUI8( value ? 1 : 0 ); } private boolean value; PushBooleanVal( boolean v ) { value = v; } }
    class PushIntegerVal implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_INTEGER ); out.writeSI32( value ); } private int value; PushIntegerVal( int v ) { value = v; } }
    class PushLookup     implements PushValue { public void write( OutStream out ) throws IOException { if( idx <=255 ) { out.writeUI8( PUSHTYPE_LOOKUP8 ); out.writeUI8( idx ); } else { out.writeUI8( PUSHTYPE_LOOKUP16 ); out.writeUI16( idx ); } } private int idx; PushLookup( int v ) { idx = v; } }
    class PushRegister   implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_REGISTER ); out.writeUI8( value ); } private int value; PushRegister( int v ) { value = v; } }
    class PushFloatVal   implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_FLOAT ); out.writeFloat( value ); } private float value; PushFloatVal( float v ) { value = v; } }
    class PushDoubleVal  implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_DOUBLE ); out.writeDouble( value ); } private double value; PushDoubleVal( double v ) { value = v; } }
    class PushNull       implements PushValue { public void write( OutStream out ) throws IOException { out.writeUI8( PUSHTYPE_NULL ); } }
    
    protected static class SubBlockWriter extends ActionBlockWriter {
        private BlockLengthFixer mLengthFixer;
        private int mInitOffset;
        
        SubBlockWriter( BlockLengthFixer fixer,
                        OutStream out,
		                ByteArrayOutputStream byteOut,
		                List  fixers,
		                Map   labelToInfo,
		                int[] actionCount,
		                int   flashVersion ) {
            super( out, byteOut, fixers, labelToInfo, actionCount, flashVersion );
            mLengthFixer = fixer;
            mInitOffset  = out.getCount();
        }
        
        public void end() throws IOException {
            int length = mOut.getCount() - mInitOffset;
            mLengthFixer.setBlockLength( length );
        }
    }
    
    protected OutStream             mOut;
    protected ByteArrayOutputStream mByteOut;
    protected List                  mFixers;
    protected Map                   mLabelToInfo;
    protected int[]                 mActionCount;
    protected List                  mPushValues = new ArrayList();
    protected int                 mFlashVersion;
    protected String              mStringEncoding;
    
    public ActionBlockWriter( int flashVersion ) {
        mByteOut = new ByteArrayOutputStream();
        mOut     = new OutStream( mByteOut );
        mFixers  = new ArrayList();
        mLabelToInfo = new HashMap();
        mActionCount = new int[] {0};
		setFlashVersion( flashVersion );
    }
    
    protected ActionBlockWriter( OutStream out,
            				     ByteArrayOutputStream byteOut,
            				     List  fixers,
            				     Map   labelToInfo,
            				     int[] actionCount,
 								 int   flashVersion ) {
        mByteOut      = byteOut;
        mOut          = out;
        mFixers       = fixers;
        mLabelToInfo  = labelToInfo;        
        mActionCount  = actionCount;
		setFlashVersion( flashVersion );
    }
    
	private void setFlashVersion( int flashVersion ) {
        mFlashVersion = flashVersion;
        mStringEncoding = ( flashVersion >= SWFConstants.FLASH_MX_VERSION ) ?
							 SWFConstants.STRING_ENCODING_MX :
							 SWFConstants.STRING_ENCODING_PRE_MX;	
	} 

	/** Close out the action data, fix up all labels and blocks and return the data. */
	public byte[] getActionData() throws IOException {
	    mOut.flush();
	    mOut.close();
	    byte[] data = mByteOut.toByteArray();
	    
	    for (Iterator i = mFixers.iterator(); i.hasNext();) {
            Fixer fixer = (Fixer) i.next();
            fixer.fix( data );
        }
	    
	    return data;
	}
	
    protected void writeCode( int code ) throws IOException {
        if( mPushValues.size() > 0 && code != PUSH ) flushPushValues();
        mOut.writeUI8( code );
        mActionCount[0]++;
    }
 
    public void end() throws IOException {
        writeCode( 0 );
    }
    
    /**
     * Pass through a blob of actions
     */
    public void blob( byte[] blob ) throws IOException
    {
        mOut.write( blob );
    }
    

    public void comment( String comment ) throws IOException
    {
        //ignore comments
    }    
 
    public void unknown( int code, byte[] data ) throws IOException
    {
        writeCode( code );
        
        int length = (data != null) ? data.length : 0;
        
        if( code >= 0x80 || length > 0 )
        {
            mOut.writeUI16( length );
        }
        
        if( length > 0 ) mOut.write( data );
    }
 
    public void initArray() throws IOException 
    {
        writeCode( INIT_ARRAY );
    }    
 
    public void jumpLabel( String label ) throws IOException {
        if( mPushValues.size() > 0 ) flushPushValues();
        
        int offset = (int) mOut.getCount();
        LabelInfo info = new LabelInfo( label, offset, mActionCount[0] );
        
        mLabelToInfo.put( label, info );
    }    
 
    public void gotoFrame( int frameNumber ) throws IOException
    {
        writeCode( GOTO_FRAME );
        mOut.writeUI16( 2 );
        mOut.writeUI16( frameNumber );
    }
 
    public void gotoFrame( String label ) throws IOException
    {
        writeCode( GOTO_LABEL );
        mOut.writeUI16  ( OutStream.getStringLength( label ) );
        mOut.writeString( label, mStringEncoding );
    }
 
    public void getURL( String url, String target ) throws IOException
    {
        writeCode( GET_URL );
        mOut.writeUI16  ( OutStream.getStringLength(url) + OutStream.getStringLength(target) );
        mOut.writeString( url, mStringEncoding );
        mOut.writeString( target, mStringEncoding );
    }
 
    public void nextFrame() throws IOException
    {
        writeCode( NEXT_FRAME );
    }
 
    public void prevFrame() throws IOException
    {
        writeCode( PREVIOUS_FRAME );
    }
 
    public void play() throws IOException
    {
        writeCode( PLAY );
    }
  
    public void stop() throws IOException
    {
        writeCode( STOP );
    }
 
    public void toggleQuality() throws IOException
    {
        writeCode( TOGGLE_QUALITY );
    }
 
    public void stopSounds() throws IOException
    {
        writeCode( STOP_SOUNDS );
    }
 
    public void setTarget( String target ) throws IOException
    {
        writeCode( SET_TARGET );
        mOut.writeUI16  ( OutStream.getStringLength( target ) );
        mOut.writeString( target, mStringEncoding );
    }

    protected void writeJump( String label, int code ) throws IOException {
        writeCode( code );
        mOut.writeUI16( 2 );
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -