Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/writers/ActionWriter.java


1   /****************************************************************
2    * Copyright (c) 2001, David N. Main, All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or
5    * without modification, are permitted provided that the 
6    * following conditions are met:
7    *
8    * 1. Redistributions of source code must retain the above 
9    * copyright notice, this list of conditions and the following 
10   * disclaimer. 
11   * 
12   * 2. Redistributions in binary form must reproduce the above 
13   * copyright notice, this list of conditions and the following 
14   * disclaimer in the documentation and/or other materials 
15   * provided with the distribution.
16   * 
17   * 3. The name of the author may not be used to endorse or 
18   * promote products derived from this software without specific 
19   * prior written permission. 
20   * 
21   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 
22   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
23   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
24   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
25   * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
27   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
28   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
29   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
30   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
31   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
32   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************/
34  package com.anotherbigidea.flash.writers;
35  
36  import java.io.ByteArrayOutputStream;
37  import java.io.IOException;
38  import java.util.Enumeration;
39  import java.util.Hashtable;
40  import java.util.Stack;
41  import java.util.Vector;
42  
43  import com.anotherbigidea.flash.SWFActionCodes;
44  import com.anotherbigidea.flash.SWFConstants;
45  import com.anotherbigidea.flash.interfaces.SWFActions;
46  import com.anotherbigidea.io.OutStream;
47  
48  /**
49   * A writer that implements the SWFActions interface and writes
50   * action bytes to an OutStream
51   */
52  public class ActionWriter implements SWFActions, SWFActionCodes 
53  {
54      protected TagWriter tagWriter;
55      protected OutStream out;
56      protected ByteArrayOutputStream bout;
57      protected int count;
58      protected int flashVersion;
59      protected String mStringEncoding;
60      
61      protected Vector pushValues;
62      
63      protected Hashtable labels;
64      protected Vector jumps;
65      protected Vector skips;
66      
67      //--for fixing up functions and WITH blocks..
68      protected Vector blocks;
69      protected Stack  blockStack;
70      
71      public ActionWriter( TagWriter tagWriter, int flashVersion )
72      {
73          this.flashVersion = flashVersion;
74          this.tagWriter = tagWriter;
75          
76          mStringEncoding = ( flashVersion >= SWFConstants.FLASH_MX_VERSION ) ?
77                      SWFConstants.STRING_ENCODING_MX :
78                  SWFConstants.STRING_ENCODING_PRE_MX;
79      }
80                              
81      /**
82       * @return the code count
83       */
84      protected int writeCode( int code ) throws IOException 
85      {
86          if( pushValues.size() > 0 ) flushPushValues();
87          out.writeUI8( code );
88          count++;
89          return count;
90      }
91      
92      /**
93       * SWFActions interface
94       */
95      public void start( int conditions ) throws IOException
96      {
97          //ignore conditions
98          
99          count      = 0;
100         bout       = new ByteArrayOutputStream();
101         out        = new OutStream( bout );
102         pushValues = new Vector();
103         labels     = null;
104         jumps      = null;
105         skips      = null;
106         blocks     = null;
107         blockStack = null;        
108     }    
109     
110     /**
111      * SWFActions interface
112      */
113     public void end() throws IOException
114     {
115         writeCode( 0 );
116         out.flush();
117         byte[] bytes = bout.toByteArray();
118      
119         //--Fix up jumps and skips
120         if( labels != null )
121         {
122             if( jumps != null ) fixupJumps(bytes);
123             if( skips != null ) fixupSkips(bytes);
124         }
125         
126         if( blocks != null ) fixupBlocks(bytes);
127 
128         writeBytes( bytes );
129     }
130     
131     /**
132      * Pass through a blob of actions
133      */
134     public void blob( byte[] blob ) throws IOException
135     {
136         writeBytes( blob );
137     }
138         
139     protected void writeBytes( byte[] bytes ) throws IOException
140     {
141         tagWriter.getOutStream().write( bytes );                       
142     }
143     
144     /**
145      * SWFActions interface
146      */
147     public void done() throws IOException
148     {
149         tagWriter.completeTag();
150     }
151         
152     protected void fixupBlocks( byte[] bytes )
153     {
154         for( Enumeration enum = blocks.elements(); enum.hasMoreElements(); )
155         {
156             int[] info = (int[])enum.nextElement();
157             
158             int codeSize = info[1];
159             int offset   = info[0];
160             byte[] sizeBytes = OutStream.sintTo2Bytes( codeSize );
161             
162             bytes[ offset     ] = sizeBytes[0];
163             bytes[ offset + 1 ] = sizeBytes[1];
164         }
165     }
166     
167     protected void fixupJumps( byte[] bytes )
168     {
169         for( Enumeration enum = jumps.elements(); enum.hasMoreElements(); )
170         {
171             Object[] obja = (Object[])enum.nextElement();
172             String label  = (String)obja[0];
173             int    target = ((Integer)obja[1]).intValue();
174             
175             int[] labelInfo = (int[])labels.get( label );
176             
177             if( labelInfo == null )
178             {
179                 System.out.println( "Missing label '" + label + "' in action code" );
180                 continue;
181             }
182             
183             int absolute = labelInfo[0];  //offset of the label            
184             int relative = absolute - ( target + 2 );  //relative jump
185             
186             byte[] val = OutStream.sintTo2Bytes( relative );
187             bytes[target  ] = val[0];
188             bytes[target+1] = val[1];
189         }
190     }
191     
192     protected void fixupSkips( byte[] bytes )
193     {
194         for( Enumeration enum = skips.elements(); enum.hasMoreElements(); )
195         {
196             Object[] obja = (Object[])enum.nextElement();
197             String label  = (String)obja[0];
198             
199             int[] skipInfo  = (int[])obja[1];
200             int   skipIndex = skipInfo[0];
201             int   skipLoc   = skipInfo[1];            
202             
203             int[] labelInfo = (int[])labels.get( label );
204             
205             if( labelInfo == null )
206             {
207                 System.out.println( "Missing label '" + label + "' in action code" );
208                 continue;
209             }
210             
211             int labelIndex = labelInfo[1];  //index of the labelled action
212             int skip = labelIndex - skipIndex - 1;
213 
214             byte val = OutStream.uintToByte( skip );
215             bytes[skipLoc] = val;
216         }
217     }
218 
219     /**
220      * SWFActions interface
221      */
222     public void comment( String comment ) throws IOException
223     {
224         //ignore comments
225     }    
226     
227     /**
228      * SWFActions interface
229      */
230     public void unknown( int code, byte[] data ) throws IOException
231     {
232         writeCode( code );
233         
234         int length = (data != null) ? data.length : 0;
235         
236         if( code >= 0x80 || length > 0 )
237         {
238             out.writeUI16( length );
239         }
240         
241         if( length > 0 ) out.write( data );
242     }
243     
244     /**
245      * SWFActions interface
246      */
247     public void initArray() throws IOException 
248     {
249         writeCode( INIT_ARRAY );
250     }    
251         
252     /**
253      * SWFActions interface
254      */
255     public void jumpLabel( String label ) throws IOException
256     {
257         if( pushValues.size() > 0 ) flushPushValues();
258         
259         int offset = (int)out.getCount();
260         
261         if( labels == null ) labels = new Hashtable();        
262         labels.put( label, new int[] { offset, count + 1 } );
263     }    
264   
265     /**
266      * SWFActions interface
267      */
268     public void gotoFrame( int frameNumber ) throws IOException
269     {
270         writeCode( GOTO_FRAME );
271         out.writeUI16( 2 );
272         out.writeUI16( frameNumber );
273     }
274     
275     /**
276      * SWFActions interface
277      */
278     public void gotoFrame( String label ) throws IOException
279     {
280         writeCode( GOTO_LABEL );
281         out.writeUI16  ( OutStream.getStringLength( label ) );
282         out.writeString( label, mStringEncoding );
283     }
284     
285     /**
286      * SWFActions interface
287      */
288     public void getURL( String url, String target ) throws IOException
289     {
290         writeCode( GET_URL );
291         out.writeUI16  ( OutStream.getStringLength(url) + OutStream.getStringLength(target) );
292         out.writeString( url, mStringEncoding );
293         out.writeString( target, mStringEncoding );
294     }
295     
296     /**
297      * SWFActions interface
298      */
299     public void nextFrame() throws IOException
300     {
301         writeCode( NEXT_FRAME );
302     }
303     
304     /**
305      * SWFActions interface
306      */
307     public void prevFrame() throws IOException
308     {
309         writeCode( PREVIOUS_FRAME );
310     }
311     
312     /**
313      * SWFActions interface
314      */
315     public void play() throws IOException
316     {
317         writeCode( PLAY );
318     }
319     
320     /**
321      * SWFActions interface
322      */
323     public void stop() throws IOException
324     {
325         writeCode( STOP );
326     }
327     
328     /**
329      * SWFActions interface
330      */
331     public void toggleQuality() throws IOException
332     {
333         writeCode( TOGGLE_QUALITY );
334     }
335     
336     /**
337      * SWFActions interface
338      */
339     public void stopSounds() throws IOException
340     {
341         writeCode( STOP_SOUNDS );
342     }
343     
344     /**
345      * SWFActions interface
346      */
347     public void setTarget( String target ) throws IOException
348     {
349         writeCode( SET_TARGET );
350         out.writeUI16  ( OutStream.getStringLength( target ) );
351         out.writeString( target, mStringEncoding );
352     }
353 
354     protected void writeJump( String label, int code ) throws IOException 
355     {
356         writeCode( code );
357         out.writeUI16( 2 );
358         
359         int here = (int)out.getCount();
360         out.writeUI16( 0 );   //will be fixed up later
361         
362         //--save jump info for later fix-up logic
363         if( jumps == null ) jumps = new Vector();
364         jumps.addElement( new Object[] { label, new Integer( here ) } );
365     }
366     
367     /**
368      * SWFActions interface
369      */
370     public void jump( String jumpLabel ) throws IOException
371     {
372         writeJump( jumpLabel, JUMP );
373     }
374     
375     /**
376      * SWFActions interface
377      */
378     public void ifJump( String jumpLabel ) throws IOException
379     {
380         writeJump( jumpLabel, IF );
381     }
382     
383     /**
384      * SWFActions interface
385      */
386     public void waitForFrame( int frameNumber, String jumpLabel ) throws IOException
387     {
388         writeCode( WAIT_FOR_FRAME );
389         out.writeUI16( 3 );
390         out.writeUI16( frameNumber );
391 
392         int here = (int)out.getCount();
393         out.writeUI8 ( 0 ); //will be fixed up later
394         
395         //--save skip info for later fix-up logic
396         if( skips == null ) skips = new Vector();
397         skips.addElement( new Object[] { jumpLabel, new int[] { count, here }} );        
398     }
399     
400     /**
401      * SWFActions interface
402      */
403     public void waitForFrame( String jumpLabel ) throws IOException
404     {
405         writeCode( WAIT_FOR_FRAME_2 );
406         out.writeUI16( 1 );
407 
408         int here = (int)out.getCount();
409         out.writeUI8 ( 0 ); //will be fixed up later
410         
411         //--save skip info for later fix-up logic
412         if( skips == null ) skips = new Vector();
413         skips.addElement( new Object[] { jumpLabel, new int[] { count, here }} );        
414     }
415     
416     /**
417      * SWFActions interface
418      */
419     public void pop() throws IOException
420     {
421         writeCode( POP );
422     }
423     
424     /**
425      * SWFActions interface
426      */
427     public void add() throws IOException
428     {
429         writeCode( ADD );
430     }
431 
432     /**
433      * SWFActions interface
434      */
435     public void substract() throws IOException
436     {
437         writeCode( SUBTRACT );
438     }
439 
440     /**
441      * SWFActions interface
442      */
443     public void multiply() throws IOException
444     {
445         writeCode( MULTIPLY );
446     }
447 
448     /**
449      * SWFActions interface
450      */
451     public void divide() throws IOException
452     {
453         writeCode( DIVIDE );
454     }
455     
456     /**
457      * SWFActions interface
458      */
459     public void equals() throws IOException
460     {
461         writeCode( EQUALS );
462     }
463    
464     /**
465      * SWFActions interface
466      */
467     public void lessThan() throws IOException
468     {
469         writeCode( LESS );
470     }
471     
472     /**
473      * SWFActions interface
474      */
475     public void and() throws IOException
476     {
477         writeCode( AND );
478     }
479    
480     /**
481      * SWFActions interface
482      */
483     public void or() throws IOException
484     {
485         writeCode( OR );
486     }
487     
488     /**
489      * SWFActions interface
490      */
491     public void not() throws IOException
492     {
493         writeCode( NOT );
494     }
495     
496     /**
497      * SWFActions interface
498      */
499     public void stringEquals() throws IOException
500     {
501         writeCode( STRING_EQUALS );
502     }
503 
504     /**
505      * SWFActions interface
506      */
507     public void stringLength() throws IOException
508     {
509         writeCode( STRING_LENGTH );
510     }
511     
512     /**
513      * SWFActions interface
514      */
515     public void concat() throws IOException
516     {
517         writeCode( STRING_ADD );
518     }
519     
520     /**
521      * SWFActions interface
522      */
523     public void substring() throws IOException
524     {
525         writeCode( STRING_EXTRACT );
526     }
527     
528     /**
529      * SWFActions interface
530      */
531     public void stringLessThan() throws IOException
532     {
533         writeCode( STRING_LESS );
534     }
535     
536     /**
537      * SWFActions interface
538      */
539     public void stringLengthMB() throws IOException
540     {
541         writeCode( MB_STRING_LENGTH );
542     }
543 
544     /**
545      * SWFActions interface
546      */
547     public void substringMB() throws IOException
548     {
549         writeCode( MB_STRING_EXTRACT );
550     }    
551 
552     /**
553      * SWFActions interface
554      */
555     public void toInteger() throws IOException
556     {
557         writeCode( TO_INTEGER );
558     }
559 
560     /**
561      * SWFActions interface
562      */
563     public void charToAscii() throws IOException
564     {
565         writeCode( CHAR_TO_ASCII );
566     }
567 
568     /**
569      * SWFActions interface
570      */
571     public void asciiToChar() throws IOException
572     {
573         writeCode( ASCII_TO_CHAR );
574     }
575 
576     /**
577      * SWFActions interface
578      */
579     public void charMBToAscii() throws IOException
580     {
581         writeCode( MB_CHAR_TO_ASCII );
582     }
583 
584     /**
585      * SWFActions interface
586      */
587     public void asciiToCharMB() throws IOException
588     {
589         writeCode( MB_ASCII_TO_CHAR );
590     }
591     
592     /**
593      * SWFActions interface
594      */
595     public void call() throws IOException
596     {
597         writeCode( CALL );
598         out.writeUI16( 0 );   //SWF File Format anomaly
599     }
600 
601     /**
602      * SWFActions interface
603      */
604     public void getVariable() throws IOException
605     {
606         writeCode( GET_VARIABLE );
607     }
608 
609     /**
610      * SWFActions interface
611      */
612     public void setVariable() throws IOException
613     {
614         writeCode( SET_VARIABLE );
615     }
616     
617     /**
618      * SWFActions interface
619      */
620     public void getURL( int sendVars, int loadMode ) throws IOException
621     {
622         writeCode( GET_URL_2 );
623         out.writeUI16( 1 );
624 
625         int flags = 0;
626         
627         String sendVars_ = null;
628         switch( sendVars )
629         {
630             case GET_URL_SEND_VARS_GET:  flags = 1; break;
631             case GET_URL_SEND_VARS_POST: flags = 2; break;
632                                          
633             case GET_URL_SEND_VARS_NONE:
634             default: break;
635         }
636         
637         String mode = null;
638         switch( loadMode )
639         {
640             case GET_URL_MODE_LOAD_MOVIE_INTO_LEVEL:  break;                
641             case GET_URL_MODE_LOAD_MOVIE_INTO_SPRITE: flags |= 0x40; break;
642             case GET_URL_MODE_LOAD_VARS_INTO_LEVEL :  flags |= 0x80; break;
643             case GET_URL_MODE_LOAD_VARS_INTO_SPRITE:  flags |= 0xC0; break;
644             default: break;
645         }
646         
647         out.writeUI8( flags );        
648     }
649     
650     
651     /**
652      * SWFActions interface
653      */
654     public void gotoFrame( boolean play ) throws IOException
655     {
656         writeCode( GOTO_FRAME_2 );
657         out.writeUI16( 1 );
658         out.writeUI8( play ? 1 : 0 );
659     }
660     
661     /**
662      * SWFActions interface
663      */
664     public void setTarget() throws IOException
665     {
666         writeCode( SET_TARGET_2 );
667     }
668     
669     /**
670      * SWFActions interface
671      */
672     public void getProperty() throws IOException
673     {
674         writeCode( GET_PROPERTY );
675     }
676     
677     /**
678      * SWFActions interface
679      */
680     public void setProperty() throws IOException
681     {
682         writeCode( SET_PROPERTY );
683     }
684     
685     /**
686      * SWFActions interface
687      */
688     public void cloneSprite() throws IOException
689     {
690         writeCode( CLONE_SPRITE );
691     }
692     
693     /**
694      * SWFActions interface
695      */
696     public void removeSprite() throws IOException
697     {
698         writeCode( REMOVE_SPRITE );
699     }
700     
701     /**
702      * SWFActions interface
703      */
704     public void startDrag() throws IOException
705     {
706         writeCode( START_DRAG );
707     }
708     
709     /**
710      * SWFActions interface
711      */
712     public void endDrag() throws IOException
713     {
714         writeCode( END_DRAG );
715     }     
716     
717     /**
718      * SWFActions interface
719      */
720     public void trace() throws IOException
721     {
722         writeCode( TRACE );
723     }     
724     
725     /**
726      * SWFActions interface
727      */
728     public void getTime() throws IOException
729     {
730         writeCode( GET_TIME );
731     }     
732      
733     /**
734      * SWFActions interface
735      */
736     public void randomNumber() throws IOException
737     {
738         writeCode( RANDOM_NUMBER );
739     }         
740      
741     /**
742      * SWFActions interface
743      */
744     public void lookupTable( String[] values ) throws IOException
745     {
746         writeCode( LOOKUP_TABLE );
747         
748         ByteArrayOutputStream baout = new ByteArrayOutputStream();
749         OutStream bout = new OutStream( baout );
750         
751         bout.writeUI16( values.length );
752         
753         for( int i = 0; i < values.length; i++ )
754         {
755             bout.writeString( values[i], mStringEncoding );
756         }
757 
758         bout.flush();
759         byte[] data = baout.toByteArray();
760         out.writeUI16( data.length );
761         out.write( data );        
762     }
763      
764     /**
765      * SWFActions interface
766      */    
767     public void callFunction() throws IOException
768     {
769         writeCode( CALL_FUNCTION );
770     }         
771      
772     /**
773      * SWFActions interface
774      */                                      
775     public void callMethod() throws IOException
776     {
777         writeCode( CALL_METHOD );
778     }         
779      
780     /**
781      * SWFActions interface
782      */     
783     public void startFunction( String name, String[] paramNames ) throws IOException
784     {
785         if( blockStack == null ) blockStack = new Stack();
786         
787         writeCode( DEFINE_FUNCTION );        
788         
789         ByteArrayOutputStream baout = new ByteArrayOutputStream();
790         OutStream bout = new OutStream( baout );
791         
792         bout.writeString( name, mStringEncoding );
793         bout.writeUI16( paramNames.length );
794         
795         for( int i = 0; i < paramNames.length; i++ )
796         {
797             bout.writeString( paramNames[i], mStringEncoding );
798         }
799 
800         bout.writeUI16( 0 );  //code size - will be fixed up later
801         
802         bout.flush();
803         byte[] data = baout.toByteArray();
804         out.writeUI16( data.length );
805         out.write( data );
806         
807         blockStack.push( new int[]{ (int)out.getCount(), 0 } );
808     }    
809 
810     /**
811      * SWFActions interface
812      */     
813     public void endBlock() throws IOException 
814     {
815         if( blockStack == null || blockStack.isEmpty() ) return;  //nothing to do
816         int[] blockInfo = (int[])blockStack.pop();
817                 
818         if( blocks == null ) blocks = new Vector();
819         
820         int offset =  blockInfo[0];
821         int codeSize = ((int)out.getCount()) - offset;
822         
823         //--store this info for later fix-up
824         blockInfo[0] = offset - 2;
825         blockInfo[1] = codeSize;
826         blocks.addElement( blockInfo );
827     }
828     
829     /**
830      * SWFActions interface
831      */     
832     public void defineLocalValue() throws IOException
833     {
834         writeCode( DEFINE_LOCAL_VAL );
835     }
836 
837     /**
838      * SWFActions interface
839      */     
840     public void defineLocal() throws IOException
841     {
842         writeCode( DEFINE_LOCAL );
843     }   
844 
845     /**
846      * SWFActions interface
847      */     
848     public void deleteProperty() throws IOException
849     {
850         writeCode( DEL_VAR );
851     }   
852 
853     /**
854      * SWFActions interface
855      */     
856     public void deleteThreadVars() throws IOException
857     {
858         writeCode( DEL_THREAD_VARS );
859     }   
860 
861     /**
862      * SWFActions interface
863      */     
864     public void enumerate() throws IOException
865     {
866         writeCode( ENUMERATE );
867     }   
868 
869     /**
870      * SWFActions interface
871      */     
872     public void typedEquals() throws IOException
873     {
874         writeCode( TYPED_EQUALS );
875     }   
876 
877     /**
878      * SWFActions interface
879      */     
880     public void getMember() throws IOException
881     {
882         writeCode( GET_MEMBER );
883     }   
884 
885     /**
886      * SWFActions interface
887      */         
888     public void initObject() throws IOException
889     {
890         writeCode( INIT_OBJECT );
891     }   
892 
893     /**
894      * SWFActions interface
895      */     
896     public void newMethod() throws IOException
897     {
898         writeCode( CALL_NEW_METHOD );
899     }   
900 
901     /**
902      * SWFActions interface
903      */     
904     public void newObject() throws IOException
905     {
906         writeCode( NEW_OBJECT );
907     }   
908 
909     /**
910      * SWFActions interface
911      */     
912     public void setMember() throws IOException
913     {
914         writeCode( SET_MEMBER );
915     }   
916 
917     /**
918      * SWFActions interface
919      */     
920     public void getTargetPath() throws IOException
921     {
922         writeCode( GET_TARGET_PATH );
923     }   
924     
925     /**
926      * SWFActions interface
927      */ 
928     public void startWith() throws IOException
929     {
930         writeCode( WITH );
931         out.writeUI16( 2 );
932         out.writeUI16( 0 );  //codeSize - will be fixed up later
933         
934         //--push the block start info
935         if( blockStack == null ) blockStack = new Stack();
936         blockStack.push( new int[]{ (int)out.getCount(), 0 } );        
937     }   
938     
939     /**
940      * SWFActions interface
941      */ 
942     public void duplicate() throws IOException
943     {
944         writeCode( DUPLICATE );
945     }   
946     
947     /**
948      * SWFActions interface
949      */ 
950     public void returnValue() throws IOException
951     {
952         writeCode( RETURN );
953     }   
954     
955     /**
956      * SWFActions interface
957      */ 
958     public void swap() throws IOException
959     {
960         writeCode( SWAP );
961     }   
962     
963     /**
964      * SWFActions interface
965      */ 
966     public void storeInRegister( int registerNumber ) throws IOException
967     {
968         writeCode( REGISTER );
969         out.writeUI16( 1 );
970         out.writeUI8( registerNumber );
971     }   
972         
973     /**
974      * SWFActions interface
975      */ 
976     public void convertToNumber() throws IOException
977     {
978         writeCode( CONVERT_TO_NUMBER );
979     }   
980     
981     /**
982      * SWFActions interface
983      */ 
984     public void convertToString() throws IOException
985     {
986         writeCode( CONVERT_TO_STRING );
987     }   
988     
989     /**
990      * SWFActions interface
991      */ 
992     public void typeOf() throws IOException
993     {
994         writeCode( TYPEOF );
995     }   
996     
997     /**
998      * SWFActions interface
999      */ 
1000    public void typedAdd() throws IOException
1001    {
1002        writeCode( TYPED_ADD );
1003    }   
1004    
1005    /**
1006     * SWFActions interface
1007     */ 
1008    public void typedLessThan() throws IOException
1009    {
1010        writeCode( TYPED_LESS_THAN );
1011    }   
1012    
1013    /**
1014     * SWFActions interface
1015     */ 
1016    public void modulo() throws IOException
1017    {
1018        writeCode( MODULO );
1019    }   
1020        
1021    /**
1022     * SWFActions interface
1023     */ 
1024    public void bitAnd() throws IOException
1025    {
1026        writeCode( BIT_AND );
1027    }   
1028    
1029    /**
1030     * SWFActions interface
1031     */ 
1032    public void bitOr() throws IOException
1033    {
1034        writeCode( BIT_OR );
1035    }   
1036    
1037    /**
1038     * SWFActions interface
1039     */ 
1040    public void bitXor() throws IOException
1041    {
1042        writeCode( BIT_XOR );
1043    }   
1044    
1045    /**
1046     * SWFActions interface
1047     */ 
1048    public void shiftLeft() throws IOException
1049    {
1050        writeCode( SHIFT_LEFT );
1051    }   
1052    
1053    /**
1054     * SWFActions interface
1055     */ 
1056    public void shiftRight() throws IOException
1057    {
1058        writeCode( SHIFT_RIGHT );
1059    }   
1060    
1061    /**
1062     * SWFActions interface
1063     */ 
1064    public void shiftRightUnsigned() throws IOException
1065    {
1066        writeCode( SHIFT_UNSIGNED );
1067    }   
1068        
1069    /**
1070     * SWFActions interface
1071     */ 
1072    public void decrement() throws IOException
1073    {
1074        writeCode( DECREMENT );
1075    }   
1076    
1077    /**
1078     * SWFActions interface
1079     */ 
1080    public void increment() throws IOException
1081    {
1082        writeCode( INCREMENT );
1083    }   
1084    
1085    protected void flushPushValues() throws IOException
1086    {
1087        out.writeUI8( PUSH );
1088        count++;
1089        
1090        ByteArrayOutputStream baout = new ByteArrayOutputStream();
1091        OutStream bout = new OutStream( baout );
1092        
1093        for( Enumeration enum = pushValues.elements(); enum.hasMoreElements(); )
1094        {
1095            Object value = enum.nextElement();
1096            
1097            if( value instanceof String )
1098            {
1099                bout.writeUI8( PUSHTYPE_STRING );
1100                bout.writeString( value.toString(), mStringEncoding );
1101            }
1102            else if( value instanceof Boolean )
1103            {
1104                bout.writeUI8( PUSHTYPE_BOOLEAN );
1105                bout.writeUI8( ((Boolean)value).booleanValue() ? 1 : 0 );
1106            }
1107            else if( value instanceof Integer )
1108            {
1109                bout.writeUI8( PUSHTYPE_INTEGER );
1110                bout.writeSI32( ((Integer)value).intValue() );                
1111            }
1112            else if( value instanceof Short )
1113            {
1114                bout.writeUI8( PUSHTYPE_LOOKUP );
1115                bout.writeUI8( ((Short)value).intValue() );                
1116            }
1117            else if( value instanceof Byte )
1118            {
1119                bout.writeUI8( PUSHTYPE_REGISTER );
1120                bout.writeUI8( ((Byte)value).intValue() );                                   
1121            }
1122            else if( value instanceof Float )
1123            {
1124                bout.writeUI8( PUSHTYPE_FLOAT );
1125                bout.writeFloat( ((Float)value).floatValue() );                
1126            }
1127            else if( value instanceof Double )
1128            {
1129                bout.writeUI8( PUSHTYPE_DOUBLE );
1130                bout.writeDouble( ((Double)value).doubleValue() );
1131            }
1132            else
1133            {
1134                bout.writeUI8( PUSHTYPE_NULL );
1135            }
1136        }
1137
1138        pushValues.removeAllElements();
1139        
1140        bout.flush();
1141        byte[] data = baout.toByteArray();
1142        out.writeUI16( data.length );
1143        out.write( data );
1144    }
1145        
1146    /**
1147     * SWFActions interface
1148     */
1149    public void push( String value ) throws IOException
1150    {
1151        pushValues.addElement( value );
1152        if( flashVersion < 5 ) flushPushValues();
1153    }
1154    
1155    /**
1156     * SWFActions interface
1157     */
1158    public void push( float  value ) throws IOException
1159    {
1160        pushValues.addElement( new Float( value ) );
1161        if( flashVersion < 5 ) flushPushValues();
1162    }
1163    
1164    /**
1165     * SWFActions interface
1166     */
1167    public void push( double value ) throws IOException
1168    {
1169        pushValues.addElement( new Double( value ) );
1170        if( flashVersion < 5 ) flushPushValues();
1171    }
1172    
1173    /**
1174     * SWFActions interface
1175     */
1176    public void pushNull() throws IOException
1177    {
1178        pushValues.addElement( new Object() );
1179        if( flashVersion < 5 ) flushPushValues();
1180    }
1181    
1182    /**
1183     * SWFActions interface
1184     */
1185    public void pushRegister( int registerNumber ) throws IOException
1186    {
1187        pushValues.addElement( new Byte( (byte)registerNumber ) );
1188        if( flashVersion < 5 ) flushPushValues();
1189    }
1190    
1191    /**
1192     * SWFActions interface
1193     */
1194    public void push( boolean value ) throws IOException
1195    {
1196        pushValues.addElement( new Boolean( value ) );
1197        if( flashVersion < 5 ) flushPushValues();
1198    }
1199    
1200    /**
1201     * SWFActions interface
1202     */
1203    public void push( int value ) throws IOException
1204    {
1205        pushValues.addElement( new Integer( value ) );
1206        if( flashVersion < 5 ) flushPushValues();
1207    }
1208
1209    /**
1210     * SWFActions interface
1211     */
1212    public void lookup( int dictionaryIndex ) throws IOException
1213    {
1214        pushValues.addElement( new Short( (short)dictionaryIndex ) );
1215        if( flashVersion < 5 ) flushPushValues();
1216    }    
1217    
1218  /**
1219   * @see com.anotherbigidea.flash.interfaces.SWFActions#enumerateObject()
1220   */
1221  public void enumerateObject() throws IOException {
1222    writeCode( ENUMERATE_OBJECT );
1223  }
1224
1225  /**
1226   * @see com.anotherbigidea.flash.interfaces.SWFActions#greaterThan()
1227   */
1228  public void greaterThan() throws IOException {
1229    writeCode( GREATER );
1230  }
1231
1232  /**
1233   * @see com.anotherbigidea.flash.interfaces.SWFActions#instanceOf()
1234   */
1235  public void instanceOf() throws IOException {
1236    writeCode( INSTANCE_OF );
1237  }
1238
1239  /**
1240   * @see com.anotherbigidea.flash.interfaces.SWFActions#strictEquals()
1241   */
1242  public void strictEquals() throws IOException {
1243    writeCode( STRICT_EQUALS );
1244  }
1245
1246  /**
1247   * @see com.anotherbigidea.flash.interfaces.SWFActions#stringGreaterThan()
1248   */
1249  public void stringGreaterThan() throws IOException {
1250    writeCode( STRING_GREATER );
1251  }
1252
1253}