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

📄 actionwriter.java

📁 java版本的flash文件(swf)播放器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/****************************************************************
 * 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.writers;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

import com.anotherbigidea.flash.SWFActionCodes;
import com.anotherbigidea.flash.SWFConstants;
import com.anotherbigidea.flash.interfaces.SWFActions;
import com.anotherbigidea.io.OutStream;

/**
 * A writer that implements the SWFActions interface and writes
 * action bytes to an OutStream
 */
public class ActionWriter implements SWFActions, SWFActionCodes 
{
    protected TagWriter tagWriter;
    protected OutStream out;
    protected ByteArrayOutputStream bout;
    protected int count;
    protected int flashVersion;
    protected String mStringEncoding;
    
    protected Vector pushValues;
    
    protected Hashtable labels;
    protected Vector jumps;
    protected Vector skips;
    
    //--for fixing up functions and WITH blocks..
    protected Vector blocks;
    protected Stack  blockStack;
    
    public ActionWriter( TagWriter tagWriter, int flashVersion )
    {
        this.flashVersion = flashVersion;
        this.tagWriter = tagWriter;
        
        mStringEncoding = ( flashVersion >= SWFConstants.FLASH_MX_VERSION ) ?
        						SWFConstants.STRING_ENCODING_MX :
								SWFConstants.STRING_ENCODING_PRE_MX;
    }
                            
    /**
     * @return the code count
     */
    protected int writeCode( int code ) throws IOException 
    {
        if( pushValues.size() > 0 ) flushPushValues();
        out.writeUI8( code );
        count++;
        return count;
    }
    
    /**
     * SWFActions interface
     */
    public void start( int conditions ) throws IOException
    {
        //ignore conditions
        
        count      = 0;
        bout       = new ByteArrayOutputStream();
        out        = new OutStream( bout );
        pushValues = new Vector();
        labels     = null;
        jumps      = null;
        skips      = null;
        blocks     = null;
        blockStack = null;        
    }    
    
    /**
     * SWFActions interface
     */
    public void end() throws IOException
    {
        writeCode( 0 );
        out.flush();
        byte[] bytes = bout.toByteArray();
     
        //--Fix up jumps and skips
        if( labels != null )
        {
            if( jumps != null ) fixupJumps(bytes);
            if( skips != null ) fixupSkips(bytes);
        }
        
        if( blocks != null ) fixupBlocks(bytes);

        writeBytes( bytes );
    }
    
    /**
     * Pass through a blob of actions
     */
    public void blob( byte[] blob ) throws IOException
    {
        writeBytes( blob );
    }
        
    protected void writeBytes( byte[] bytes ) throws IOException
    {
        tagWriter.getOutStream().write( bytes );                       
    }
    
    /**
     * SWFActions interface
     */
    public void done() throws IOException
    {
        tagWriter.completeTag();
    }
        
    protected void fixupBlocks( byte[] bytes )
    {
        for( Enumeration enum = blocks.elements(); enum.hasMoreElements(); )
        {
            int[] info = (int[])enum.nextElement();
            
            int codeSize = info[1];
            int offset   = info[0];
            byte[] sizeBytes = OutStream.sintTo2Bytes( codeSize );
            
            bytes[ offset     ] = sizeBytes[0];
            bytes[ offset + 1 ] = sizeBytes[1];
        }
    }
    
    protected void fixupJumps( byte[] bytes )
    {
        for( Enumeration enum = jumps.elements(); enum.hasMoreElements(); )
        {
            Object[] obja = (Object[])enum.nextElement();
            String label  = (String)obja[0];
            int    target = ((Integer)obja[1]).intValue();
            
            int[] labelInfo = (int[])labels.get( label );
            
            if( labelInfo == null )
            {
                System.out.println( "Missing label '" + label + "' in action code" );
                continue;
            }
            
            int absolute = labelInfo[0];  //offset of the label            
            int relative = absolute - ( target + 2 );  //relative jump
            
            byte[] val = OutStream.sintTo2Bytes( relative );
            bytes[target  ] = val[0];
            bytes[target+1] = val[1];
        }
    }
    
    protected void fixupSkips( byte[] bytes )
    {
        for( Enumeration enum = skips.elements(); enum.hasMoreElements(); )
        {
            Object[] obja = (Object[])enum.nextElement();
            String label  = (String)obja[0];
            
            int[] skipInfo  = (int[])obja[1];
            int   skipIndex = skipInfo[0];
            int   skipLoc   = skipInfo[1];            
            
            int[] labelInfo = (int[])labels.get( label );
            
            if( labelInfo == null )
            {
                System.out.println( "Missing label '" + label + "' in action code" );
                continue;
            }
            
            int labelIndex = labelInfo[1];  //index of the labelled action
            int skip = labelIndex - skipIndex - 1;

            byte val = OutStream.uintToByte( skip );
            bytes[skipLoc] = val;
        }
    }

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

    protected void writeJump( String label, int code ) throws IOException 
    {
        writeCode( code );
        out.writeUI16( 2 );
        
        int here = (int)out.getCount();
        out.writeUI16( 0 );   //will be fixed up later
        
        //--save jump info for later fix-up logic
        if( jumps == null ) jumps = new Vector();
        jumps.addElement( new Object[] { label, new Integer( here ) } );
    }
    
    /**
     * SWFActions interface
     */
    public void jump( String jumpLabel ) throws IOException
    {
        writeJump( jumpLabel, JUMP );
    }
    
    /**
     * SWFActions interface
     */
    public void ifJump( String jumpLabel ) throws IOException
    {
        writeJump( jumpLabel, IF );
    }
    
    /**
     * SWFActions interface
     */
    public void waitForFrame( int frameNumber, String jumpLabel ) throws IOException
    {
        writeCode( WAIT_FOR_FRAME );
        out.writeUI16( 3 );
        out.writeUI16( frameNumber );

        int here = (int)out.getCount();
        out.writeUI8 ( 0 ); //will be fixed up later
        
        //--save skip info for later fix-up logic
        if( skips == null ) skips = new Vector();
        skips.addElement( new Object[] { jumpLabel, new int[] { count, here }} );        
    }
    
    /**
     * SWFActions interface
     */
    public void waitForFrame( String jumpLabel ) throws IOException
    {
        writeCode( WAIT_FOR_FRAME_2 );
        out.writeUI16( 1 );

        int here = (int)out.getCount();
        out.writeUI8 ( 0 ); //will be fixed up later
        
        //--save skip info for later fix-up logic
        if( skips == null ) skips = new Vector();
        skips.addElement( new Object[] { jumpLabel, new int[] { count, here }} );        
    }
    
    /**
     * SWFActions interface
     */

⌨️ 快捷键说明

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