1 /* libsswf_actions.c++ -- written by Alexis WILKE for Made to Order Software Corp. (c) 2002-2008 */
2 
3 /*
4 
5 Copyright (c) 2002-2008 Made to Order Software Corp.
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 /** \file
35  *
36  * \brief The implementation of the sswf::Action and derived classes.
37  *
38  * This file declares the body of the functions which are not
39  * inline. It is part of the SSWF library.
40  */
41 
42 #include	"sswf/libsswf.h"
43 
44 using namespace sswf;
45 
46 
47 
48 /////////////////////////////////////////// Action
49 
50 /** \class sswf::Action
51  *
52  * \brief Holds an action.
53  *
54  * The Action class is used to hold ONE action. An array of actions
55  * can be used to generate an ActionScript.
56  *
57  * The Action class represents one SWF raw action (i.e. no JavaScript!)
58  *
59  * The organization of actions to create a valid script is described in my
60  * <a href="../SWFalexref.html#tag_doaction">Alexis' SWF Reference&mdash;Do Action</a>
61  * document.
62  *
63  * Actions are ItemBase objects which can thus be added in a Vectors
64  * array. Tags which support actions will usually expose the vector
65  * used to save actions in it. Also, some actions can have sub-actions.
66  * Similarly, you have the sswf::Action::SubList(void) function which
67  * can be used to retrieve the sub-actions of a given action.
68  *
69  * Note that newer action script code is much different from the old
70  * one. This applies to movies version 9 or better when setup to run
71  * ActionScript version 3 (see the
72  * <a href="../abcFormat.html">abcFormat.html</a> document.)
73  *
74  * \warning
75  * Most actions which support sub-actions are limited to about 64Kb
76  * of sub-action data (depending on the actions used, some actions
77  * save data in the action list and can use a lot more than 1 byte,
78  * especially the sswf::Action::ACTION_PUSH_DATA action!)
79  *
80  * \par
81  * The sswf::Action::ACTION_WAIT_FOR_FRAME and sswf::Action::ACTION_WAIT_FOR_FRAME2
82  * are limited to 255 bytes. Also, they branch as long as the frame
83  * is not reached which is somewhat the opposite of what we would
84  * usually need.
85  *
86  * \sa <a href="../SWFalexref.html#tag_doaction">Alexis' SWF Reference&mdash;Do Action</a>
87  */
88 
89 
90 
91 /** \enum sswf::Action::action_t
92  *
93  * \brief List all the actions supported by SSWF.
94  *
95  * These action enumeration variables are used whenever you create
96  * an action object. All the actions which do not require any data
97  * are created using the Action object. In this case you must specify
98  * the action enumeration variable.
99  *
100  * Actions which require some additional data will automatically
101  * receive a default (i.e. sswf::ActionBranch is set to ACTION_BRANCH_ALWAYS
102  * by default.) Some cannot actually be changed by you (i.e. sswf::ActionCallFrame).
103  * All of them can only receive a very few set of values. Trying to set
104  * another value will generate an error on creation.
105  */
106 
107 
108 /** \var sswf::Action::ACTION_UNKNOWN
109  *
110  * \brief The special unknown value.
111  *
112  * This special action number can be used to mark an entry as
113  * unknown. You cannot create and save an unknown action
114  * in an SWF file.
115  *
116  * <hr>
117  */
118 
119 
120 /** \var sswf::Action::ACTION_LABEL
121  *
122  * \brief A label to branch to.
123  *
124  * This special action repesents a label. A specific object
125  * must be created to use an ACTION_LABEL the sswf::ActionLabel
126  * object. You should name labels and then use their name with
127  * sswf::ActionBranch to jump to the
128  * instructions appearing after that label.
129  *
130  * It is legal to create multiple labels one after another
131  * without adding other instructions in between, in effect
132  * creating one label and aliases.
133  *
134  * \sa sswf::ActionBranch
135  * \sa sswf::ActionBranch::SetLabel(const char *label)
136  * \sa sswf::ActionLabel
137  * \sa sswf::ActionLabel::SetLabel(const char *label)
138  *
139  * <hr>
140  */
141 
142 
143 /** \var sswf::Action::ACTION_min
144  *
145  * \brief Very first valid action.
146  *
147  * The ACTION_min value represents the smallest valid action
148  * which can be saved in an SWF file.
149  *
150  * \sa sswf::Action::ACTION_max
151  *
152  * <hr>
153  */
154 
155 
156 /** \var sswf::Action::ACTION_END
157  *
158  * \brief End the current list of actions.
159  *
160  * The ACTION_END is for programs execution what the '\\0' is for
161  * C string: it represents the end of actions.
162  *
163  * It is in general not necessary for your to add this action as
164  * the system takes care of that for you automatically. It
165  * usually makes it simpler not to add the ACTION_END actions.
166  *
167  * Note that this is used once to end the entire list of actions.
168  * Actions within a function or other groups of actions are not
169  * terminated by an ACTION_END. Instead they have a size in bytes
170  * to skip their body and at the same time determine the end of
171  * actions to execute as required.
172  *
173  * \sa <a href="../SWFalexref.html#action_end">SWF Alexis' Reference&mdash;End</a>
174  *
175  * <hr>
176  */
177 
178 
179 /** \var sswf::Action::ACTION_NEXT_FRAME
180  *
181  * \brief Skip the next Show Frame.
182  *
183  * The ACTION_NEXT_FRAME is useful whenever you stop the playback
184  * and thus the program pointer remains within one frame. This
185  * action forces the animation to move to the next frame and
186  * display it.
187  *
188  * \sa sswf::Action::ACTION_PLAY
189  * \sa sswf::Action::ACTION_STOP
190  * \sa <a href="../SWFalexref.html#action_next_frame">SWF Alexis' Reference&mdash;Next Frame</a>
191  *
192  * <hr>
193  */
194 
195 
196 /** \var sswf::Action::ACTION_PREVIOUS_FRAME
197  *
198  * \brief Jump back one frame; before the previous ShowFrame.
199  *
200  * The ACTION_PREVIOUS_FRAME is useful whenever you stop the playback
201  * and thus the program pointer remains within one frame. This
202  * action forces the animation to move to the previous frame and
203  * display it.
204  *
205  * \sa sswf::Action::ACTION_PLAY
206  * \sa sswf::Action::ACTION_STOP
207  * \sa <a href="../SWFalexref.html#action_previous_frame">SWF Alexis' Reference&mdash;Next Frame</a>
208  *
209  * <hr>
210  */
211 
212 
213 /** \var sswf::Action::ACTION_PLAY
214  *
215  * \brief Start playing the animation.
216  *
217  * The ACTION_PLAY restart the playback of an animation. It is possible
218  * stop an animation with ACTION_STOP. The last of ACTION_PLAY or
219  * ACTION_STOP encountered in a frame is the one in effect.
220  *
221  * \sa ACTION_STOP
222  * \sa <a href="../SWFalexref.html#action_play">SWF Alexis' Reference&mdash;Play</a>
223  *
224  * <hr>
225  */
226 
227 
228 /** \var sswf::Action::ACTION_STOP
229  *
230  * \brief Start playing the animation.
231  *
232  * The ACTION_STOP stops the playback of an animation. It is possible
233  * restart an animation with ACTION_PLAY. The last of ACTION_PLAY or
234  * ACTION_STOP encountered in a frame is the one in effect.
235  *
236  * When a movie is marked as stopped, its current frame is displayed
237  * but no script is played. To restart the animation, you either have
238  * a button or another \e thread (i.e. a sprite) still running.
239  *
240  * Each sprite has its own loop and thus they can be considered threads
241  * thought each one's script will be executed serially.
242  *
243  * \sa ACTION_PLAY
244  * \sa <a href="../SWFalexref.html#action_stop">SWF Alexis' Reference&mdash;Stop</a>
245  *
246  * <hr>
247  */
248 
249 
250 /** \var sswf::Action::ACTION_TOGGLE_QUALITY
251  *
252  * \brief Switch between low and high quality rendering.
253  *
254  * The ACTION_TOGGLE_QUALITY is used to switch between the different
255  * quality modes available. In general, you shouldn't do that. However,
256  * if you detect that the realtime frame rate is much lower than it
257  * should be, you can request the quality to drop in order to increase
258  * the frame rate to reasonable levels.
259  *
260  * This tag should not be used anymore since you cannot know exactly
261  * what you are doing without first querying for the quality. Instead
262  * you can use a function call.
263  *
264  * \sa sswf::Action::ACTION_CALL_FUNCTION
265  * \sa <a href="../SWFalexref.html#action_toggle_quality">SWF Alexis' Reference&mdash;ToggleQuality</a>
266  *
267  * <hr>
268  */
269 
270 
271 /** \var sswf::Action::ACTION_STOP_SOUND
272  *
273  * \brief Stop play sounds.
274  *
275  * The ACTION_STOP_SOUND requests that the player stops playing any
276  * sound in the current movie. This means used in a sprite, it stops
277  * the sounds of that sprite and not the entire animation.
278  *
279  * \sa sswf::Action::ACTION_CALL_FUNCTION
280  * \sa <a href="../SWFalexref.html#action_stop_sound">SWF Alexis' Reference&mdash;StopSound</a>
281  *
282  * <hr>
283  */
284 
285 
286 /** \var sswf::Action::ACTION_ADD
287  *
288  * \brief Add two values on the stack.
289  *
290  * The ACTION_ADD pops two values from the stack, add them together
291  * and pushes the result back onto the stack.
292  *
293  * \note
294  * This action should not be used anymore. It was deprecated. Instead, you should use
295  * the ACTION_ADD_TYPED action which ensures proper casting (as expected in the
296  * JavaScript reference&mdash;ECMA).
297  *
298  * \par
299  * This is particularly important if you are mixing strings and numbers.
300  *
301  * \sa sswf::Action::ACTION_ADD_TYPED
302  * \sa sswf::Action::ACTION_SUBTRACT
303  * \sa <a href="../SWFalexref.html#action_add">SWF Alexis' Reference&mdash;Add</a>
304  *
305  * <hr>
306  */
307 
308 
309 /** \var sswf::Action::ACTION_SUBTRACT
310  *
311  * \brief Subtract two values on the stack.
312  *
313  * The ACTION_SUBTRACT pops two values from the stack, subtract one
314  * from the other and pushes the result back onto the stack.
315  *
316  * \sa sswf::Action::ACTION_ADD
317  * \sa <a href="../SWFalexref.html#action_subtract">SWF Alexis' Reference&mdash;Subtract</a>
318  *
319  * <hr>
320  */
321 
322 
323 /** \var sswf::Action::ACTION_MULTIPLY
324  *
325  * \brief Multiply two values on the stack.
326  *
327  * The ACTION_MULTIPLY pops two values from the stack, multiply them
328  * together and pushes the result back onto the stack.
329  *
330  * \sa sswf::Action::ACTION_DIVIDE
331  * \sa sswf::Action::ACTION_MODULO
332  * \sa <a href="../SWFalexref.html#action_multiply">SWF Alexis' Reference&mdash;Multiply</a>
333  *
334  * <hr>
335  */
336 
337 
338 /** \var sswf::Action::ACTION_DIVIDE
339  *
340  * \brief Divide two values on the stack.
341  *
342  * The ACTION_DIVIDE pops two values from the stack, divide one by the
343  * other and pushes the result back onto the stack.
344  *
345  * \sa sswf::Action::ACTION_MULTIPLY
346  * \sa sswf::Action::ACTION_MODULO
347  * \sa <a href="../SWFalexref.html#action_divide">SWF Alexis' Reference&mdash;Divide</a>
348  *
349  * <hr>
350  */
351 
352 
353 /** \var sswf::Action::ACTION_EQUAL
354  *
355  * \brief Test whether two objects are equal.
356  *
357  * The ACTION_EQUAL pops two values from the stack, compare them for equality
358  * and pushes the result back on the stack.
359  *
360  * There is not action \e not \e equal. Instead you need to use this action and
361  * an ACTION_LOGICAL_NOT.
362  *
363  * \note
364  * This action should not be used anymore. It was deprecated. Instead, you should use
365  * the ACTION_EQUAL_TYPED action which ensures proper casting (as expected in the
366  * JavaScript reference&mdash;ECMA).
367  *
368  * \sa sswf::Action::ACTION_EQUAL_TYPED
369  * \sa sswf::Action::ACTION_STRICT_EQUAL
370  * \sa sswf::Action::ACTION_LESS_THAN
371  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
372  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
373  * \sa sswf::Action::ACTION_LOGICAL_NOT
374  * \sa sswf::Action::ACTION_LOGICAL_AND
375  * \sa sswf::Action::ACTION_LOGICAL_OR
376  * \sa <a href="../SWFalexref.html#action_equal">SWF Alexis' Reference&mdash;Equal</a>
377  *
378  * <hr>
379  */
380 
381 
382 /** \var sswf::Action::ACTION_LESS_THAN
383  *
384  * \brief Test whether two objects are ordered.
385  *
386  * The ACTION_LESS_THAN pops two values from the stack, compare them for order
387  * and pushes the result back on the stack.
388  *
389  * Note that in older versions you only had a \c less \c than. In new SWF versions there is a
390  * \c greater \c than which makes it simpler to compare either side. With only a \c less
391  * \c than instruction, you need to use the ACTION_SWAP and the ACTION_LOGICAL_NOT to
392  * obtain all the possible behaviors.
393  *
394  * \note
395  * This action should not be used anymore. It was deprecated. Instead, you should use
396  * the ACTION_LESS_THAN_TYPED action which ensures proper casting (as expected in the
397  * JavaScript reference&mdash;ECMA).
398  *
399  * \sa sswf::Action::ACTION_EQUAL
400  * \sa sswf::Action::ACTION_EQUAL_TYPED
401  * \sa sswf::Action::ACTION_STRICT_EQUAL
402  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
403  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
404  * \sa sswf::Action::ACTION_LOGICAL_NOT
405  * \sa sswf::Action::ACTION_LOGICAL_AND
406  * \sa sswf::Action::ACTION_LOGICAL_OR
407  * \sa <a href="../SWFalexref.html#action_less_than">SWF Alexis' Reference&mdash;Less Than</a>
408  *
409  * <hr>
410  */
411 
412 
413 /** \var sswf::Action::ACTION_LOGICAL_AND
414  *
415  * \brief Test whether two objects are true.
416  *
417  * The ACTION_LOGICAL_AND pops two values from the stack, casts them to a
418  * boolean value, computes the result (if both values are true, then the
419  * result is true, otherwise it is false) and pushes the result back on
420  * the stack.
421  *
422  * \sa sswf::Action::ACTION_EQUAL
423  * \sa sswf::Action::ACTION_EQUAL_TYPED
424  * \sa sswf::Action::ACTION_STRICT_EQUAL
425  * \sa sswf::Action::ACTION_LESS_THAN
426  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
427  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
428  * \sa sswf::Action::ACTION_LOGICAL_NOT
429  * \sa sswf::Action::ACTION_LOGICAL_OR
430  * \sa sswf::Action::ACTION_AND
431  * \sa sswf::Action::ACTION_OR
432  * \sa sswf::Action::ACTION_XOR
433  * \sa <a href="../SWFalexref.html#action_logical_and">SWF Alexis' Reference&mdash;Logical And</a>
434  *
435  * <hr>
436  */
437 
438 
439 /** \var sswf::Action::ACTION_LOGICAL_OR
440  *
441  * \brief Combines two boolean value with an OR.
442  *
443  * The ACTION_LOGICAL_OR pops two values from the stack, cast them to boolean
444  * values, compute a logical or (i.e. if at least one value is true, use true
445  * otherwise use false) and pushes the result back on the stack.
446  *
447  * \sa sswf::Action::ACTION_EQUAL
448  * \sa sswf::Action::ACTION_EQUAL_TYPED
449  * \sa sswf::Action::ACTION_STRICT_EQUAL
450  * \sa sswf::Action::ACTION_LESS_THAN
451  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
452  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
453  * \sa sswf::Action::ACTION_LOGICAL_NOT
454  * \sa sswf::Action::ACTION_LOGICAL_AND
455  * \sa sswf::Action::ACTION_AND
456  * \sa sswf::Action::ACTION_OR
457  * \sa sswf::Action::ACTION_XOR
458  * \sa <a href="../SWFalexref.html#action_logical_or">SWF Alexis' Reference&mdash;Logical Or</a>
459  *
460  * <hr>
461  */
462 
463 
464 /** \var sswf::Action::ACTION_LOGICAL_NOT
465  *
466  * \brief Apply a logical not to the value on the stack.
467  *
468  * The ACTION_LOGICAL_NOT pops one object from the stack, cast it to a boolean
469  * value if necessary, then pushes \c true on the stack when the value is \c false
470  * and vice versa.
471  *
472  * This action is particularly useful when branching since SWF
473  * only supports a <i>branch if true</i> action (i.e. no <i>branch
474  * if false</i> action!)
475  *
476  * \sa sswf::Action::ACTION_BRANCH_IF_TRUE
477  * \sa sswf::Action::ACTION_EQUAL
478  * \sa sswf::Action::ACTION_EQUAL_TYPED
479  * \sa sswf::Action::ACTION_STRICT_EQUAL
480  * \sa sswf::Action::ACTION_LESS_THAN
481  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
482  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
483  * \sa sswf::Action::ACTION_LOGICAL_AND
484  * \sa sswf::Action::ACTION_LOGICAL_OR
485  * \sa sswf::Action::ACTION_AND
486  * \sa sswf::Action::ACTION_OR
487  * \sa sswf::Action::ACTION_XOR
488  * \sa <a href="../SWFalexref.html#action_logical_not">SWF Alexis' Reference&mdash;Logical Not</a>
489  *
490  * <hr>
491  */
492 
493 
494 /** \var sswf::Action::ACTION_STRING_EQUAL
495  *
496  * \brief Test whether two strings are equal.
497  *
498  * The ACTION_STRING_EQUAL pops two strings from the stack, compare them for equality
499  * and pushes the result back on the stack.
500  *
501  * This action will ensure that two strings which represent numbers are still compared
502  * as strings and not numbers.
503  *
504  * \note
505  * This action should not be used anymore. It was deprecated. Instead, you should use
506  * the ACTION_EQUAL_TYPED action which ensures proper casting (as expected in the
507  * JavaScript reference&mdash;ECMA).
508  *
509  * \sa sswf::Action::ACTION_EQUAL_TYPED
510  * \sa sswf::Action::ACTION_STRICT_EQUAL
511  * \sa sswf::Action::ACTION_STRING_LESS_THAN
512  * \sa sswf::Action::ACTION_STRING_GREATER_THAN
513  * \sa <a href="../SWFalexref.html#action_string_equal">SWF Alexis' Reference&mdash;String Equal</a>
514  *
515  * <hr>
516  */
517 
518 
519 /** \var sswf::Action::ACTION_STRING_LENGTH
520  *
521  * \brief Compute the length of a string in characters.
522  *
523  * The ACTION_STRING_LENGTH pops one string, counts the number of characters
524  * and pushes the result back on the stack.
525  *
526  * \note
527  * This action should not be used anymore. It was deprecated. Instead, you should use
528  * the ACTION_MBSTRING_LENGTH action which ensures the proper length for a UTF-8 string.
529  *
530  * \sa sswf::Action::ACTION_MBSTRING_LENGTH
531  * \sa <a href="../SWFalexref.html#action_string_length">SWF Alexis' Reference&mdash;String Length</a>
532  *
533  * <hr>
534  */
535 
536 
537 /** \var sswf::Action::ACTION_SUB_STRING
538  *
539  * \brief Retrieve part of a string.
540  *
541  * The ACTION_SUB_STRING pops one string and two numbers: one position
542  * and one length; then it generates a new string from the sub-string
543  * starting at that position and for that many characters; this is the
544  * result which is pushed backed on the stack.
545  *
546  * \note
547  * This action should not be used anymore. It was deprecated. Instead, you should use
548  * the ACTION_SUB_MBSTRING action which ensures the proper position and length for a
549  * UTF-8 string.
550  *
551  * \sa sswf::Action::ACTION_SUB_MBSTRING
552  * \sa <a href="../SWFalexref.html#action_substring">SWF Alexis' Reference&mdash;SubString</a>
553  *
554  * <hr>
555  */
556 
557 
558 /** \var sswf::Action::ACTION_POP
559  *
560  * \brief Pop one element from the stack.
561  *
562  * The ACTION_POP action is used to \e forget about the result of a function
563  * call.
564  *
565  * \sa sswf::Action::ACTION_DUPLICATE
566  * \sa sswf::Action::ACTION_SWAP
567  * \sa <a href="../SWFalexref.html#action_pop">SWF Alexis' Reference&mdash;Pop</a>
568  *
569  * <hr>
570  */
571 
572 
573 /** \var sswf::Action::ACTION_INTEGRAL_PART
574  *
575  * \brief Remove the fractional part of a float.
576  *
577  * The ACTION_INTEGRAL_PART action is used on a floating point to remove the
578  * fractional part.
579  *
580  * This action does not round the input. It only removes the fractional part.
581  * To get a rounding effect, add 0.5 to the float first.
582  *
583  * This is the equivalent of the floor() function in the C/C++ math library.
584  *
585  * One can use the modulo action with 1.0 to extract the fractional part.
586  *
587  * \sa sswf::Action::ACTION_MODULO
588  * \sa <a href="../SWFalexref.html#action_integral_part">SWF Alexis' Reference&mdash;Integral Part</a>
589  *
590  * <hr>
591  */
592 
593 
594 /** \var sswf::Action::ACTION_GET_VARIABLE
595  *
596  * \brief Read a variable.
597  *
598  * The ACTION_GET_VARIABLE action reads the content of a variable and puts it
599  * on the stack. The name of the variable is taken from the stack.
600  *
601  * The name can be a full path.
602  *
603  * \sa sswf::Action::ACTION_SET_VARIABLE
604  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
605  * \sa sswf::Action::ACTION_GET_PROPERTY
606  * \sa sswf::Action::ACTION_SET_PROPERTY
607  * \sa sswf::Action::ACTION_GET_MEMBER
608  * \sa sswf::Action::ACTION_SET_MEMBER
609  * \sa sswf::Action::ACTION_DELETE
610  * \sa <a href="../SWFalexref.html#action_get_variable">SWF Alexis' Reference&mdash;Get Variable</a>
611  *
612  * <hr>
613  */
614 
615 
616 /** \var sswf::Action::ACTION_SET_VARIABLE
617  *
618  * \brief Read a variable.
619  *
620  * The ACTION_SET_VARIABLE action reads the content of a variable and puts it
621  * on the stack. The new value for the variable is pop first from the stack,
622  * then the name of the variable.
623  *
624  * The name can be a full path.
625  *
626  * \sa sswf::Action::ACTION_GET_VARIABLE
627  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
628  * \sa sswf::Action::ACTION_GET_PROPERTY
629  * \sa sswf::Action::ACTION_SET_PROPERTY
630  * \sa sswf::Action::ACTION_GET_MEMBER
631  * \sa sswf::Action::ACTION_SET_MEMBER
632  * \sa sswf::Action::ACTION_DELETE
633  * \sa <a href="../SWFalexref.html#action_set_variable">SWF Alexis' Reference&mdash;Set Variable</a>
634  *
635  * <hr>
636  */
637 
638 
639 /** \var sswf::Action::ACTION_SET_TARGET2
640  *
641  * \brief Set an object as current.
642  *
643  * The ACTION_SET_TARGET2 action retreives one string from the stack. The string
644  * must be either the empty string (to cancel a previous set target) or the name
645  * of an existing object (sprite, movie).
646  *
647  * Actions such as ACTION_SET_PROPERTY and ACTION_GET_PROPERTY following a set
648  * target apply to the current object. In other words, when an empty string is
649  * specified, the actions apply to the main object, otherwise to the specified
650  * object.
651  *
652  * \sa sswf::Action::ACTION_GET_TARGET
653  * \sa sswf::Action::ACTION_SET_TARGET
654  * \sa sswf::Action::ACTION_WITH
655  * \sa <a href="../SWFalexref.html#action_set_target_dynamic">SWF Alexis' Reference&mdash;Set Target <i>(dynamic)</i></a>
656  *
657  * <hr>
658  */
659 
660 
661 /** \var sswf::Action::ACTION_CONCATENATE
662  *
663  * \brief Concatenate two strings together.
664  *
665  * The ACTION_CONCATENATE action retrieves two strings from the stack, concatenate
666  * them together and push the result back on the stack.
667  *
668  * If one of the input is not a string, the \c toString() function is called on the
669  * object. If not available, an empty string is used or the SWF throws (depending
670  * on the version and setup.)
671  *
672  * Newer versions should make use of the ACTION_ADD_TYPED instead. The add will
673  * concatenate strings properly as expected unless both operands are numbers in
674  * which case the usual addition is applied.
675  *
676  * \sa sswf::Action::ACTION_STRING_ADD_TYPED
677  * \sa sswf::Action::ACTION_STRING_EQUAL
678  * \sa sswf::Action::ACTION_STRICT_EQUAL
679  * \sa sswf::Action::ACTION_STRING_LENGTH
680  * \sa <a href="../SWFalexref.html#action_concatenate">SWF Alexis' Reference&mdash;Concatenate</a>
681  *
682  * <hr>
683  */
684 
685 
686 /** \var sswf::Action::ACTION_GET_PROPERTY
687  *
688  * \brief Read from an object property.
689  *
690  * The ACTION_GET_PROPERTY action reads the content of the specified property
691  * of the specified object (sprite, movie) and puts it on the stack. The \e name
692  * of the property is taken from the stack as a number.
693  *
694  * The \e name of a property is represented by a number. The number can be either
695  * an integer or a floating point, though it has been a rule to use floating points.
696  *
697  * In general, this is used by a compiler as an optimization. Otherwise, it is
698  * recommended to use the ACTION_GET_MEMBER with the name of the property in
699  * a string. Some of these numeric properties may be removed in future versions
700  * of SWF.
701  *
702  * \sa sswf::Action::ACTION_SET_PROPERTY
703  * \sa sswf::Action::ACTION_GET_VARIABLE
704  * \sa sswf::Action::ACTION_SET_VARIABLE
705  * \sa sswf::Action::ACTION_GET_MEMBER
706  * \sa sswf::Action::ACTION_SET_MEMBER
707  * \sa sswf::Action::ACTION_DELETE
708  * \sa <a href="../SWFalexref.html#action_get_property">SWF Alexis' Reference&mdash;Get Property</a>
709  *
710  * <hr>
711  */
712 
713 
714 /** \var sswf::Action::ACTION_SET_PROPERTY
715  *
716  * \brief Write to an object property.
717  *
718  * The ACTION_SET_PROPERTY action gets the new property value, the \e name of
719  * the property (as a number) and the name of the object (as a string) from
720  * the stack and saves the new property value in that object property.
721  *
722  * The \e name of a property is represented by a number. The number can be either
723  * an integer or a floating point, though it has been a rule to use floating points.
724  *
725  * In general, this is used by a compiler as an optimization. Otherwise, it is
726  * recommended to use the ACTION_SET_MEMBER with the name of the property in
727  * a string. Some of these numeric properties may be removed in future versions
728  * of SWF.
729  *
730  * \sa sswf::Action::ACTION_GET_PROPERTY
731  * \sa sswf::Action::ACTION_GET_VARIABLE
732  * \sa sswf::Action::ACTION_SET_VARIABLE
733  * \sa sswf::Action::ACTION_GET_MEMBER
734  * \sa sswf::Action::ACTION_SET_MEMBER
735  * \sa sswf::Action::ACTION_DELETE
736  * \sa <a href="../SWFalexref.html#action_set_property">SWF Alexis' Reference&mdash;Set Property</a>
737  *
738  * <hr>
739  */
740 
741 
742 /** \var sswf::Action::ACTION_DUPLICATE_SPRITE
743  *
744  * \brief Create a new sprite from an existing sprite.
745  *
746  * The ACTION_DUPLICATE_SPRITE action creates a duplicate of an existing
747  * sprite. The new way to do so is to use the ACTION_NEW which represents
748  * the ActionScript new operator.
749  *
750  * The new operator is somewhat different since it will also call the
751  * constructor, though some people may still want to use this action instead.
752  *
753  * \sa sswf::Action::ACTION_REMOVE_SPRITE
754  * \sa sswf::Action::ACTION_NEW
755  * \sa <a href="../SWFalexref.html#action_duplicate_sprite">SWF Alexis' Reference&mdash;Duplicate Sprite</a>
756  *
757  * <hr>
758  */
759 
760 
761 /** \var sswf::Action::ACTION_REMOVE_SPRITE
762  *
763  * \brief Remove an existing sprite from the display list.
764  *
765  * The ACTION_REMOVE_SPRITE action searches for the specified sprite and
766  * remove it from the display list. Once removed, the sprite is also
767  * deleted and cannot be reused.
768  *
769  * This action should be used whenever a sprite was created with the
770  * ACTION_DUPLICATE_SPRITE.
771  *
772  * Objects created with the ACTION_NEW operator need to be deleted with
773  * the ACTION_DELETE operator.
774  *
775  * \sa sswf::Action::ACTION_DUPLICATE_SPRITE
776  * \sa sswf::Action::ACTION_NEW
777  * \sa <a href="../SWFalexref.html#action_remove_sprite">SWF Alexis' Reference&mdash;Remove Sprite</a>
778  *
779  * <hr>
780  */
781 
782 
783 /** \var sswf::Action::ACTION_TRACE
784  *
785  * \brief Turn on TRACE mode.
786  *
787  * This is a Macromedia Flash internal action caught by the debugger.
788  *
789  * Whenever encountered, it starts tracing the execution of your code.
790  *
791  * In the player, it has no effect.
792  *
793  * \sa <a href="../SWFalexref.html#action_trace">SWF Alexis' Reference&mdash;Trace</a>
794  *
795  * <hr>
796  */
797 
798 
799 /** \var sswf::Action::ACTION_START_DRAG
800  *
801  * \brief Start dragging an object.
802  *
803  * This action has the effect of attaching an object to the user's mouse.
804  *
805  * The following movements of the mouse will move the object until the
806  * ACTION_STOP_DRAG is used.
807  *
808  * This action is often executed after an sswf::Event::EVENT_POINTER_DOWN.
809  *
810  * \sa sswf::Event::EVENT_POINTER_DOWN
811  * \sa sswf::Event::EVENT_POINTER_DRAG_ENTER
812  * \sa sswf::Event::EVENT_POINTER_DRAG_LEAVE
813  * \sa sswf::Action::ACTION_STOP_DRAG
814  * \sa <a href="../SWFalexref.html#action_start_drag">SWF Alexis' Reference&mdash;Start Drag</a>
815  *
816  * <hr>
817  */
818 
819 
820 /** \var sswf::Action::ACTION_STOP_DRAG
821  *
822  * \brief Stop dragging the dragged object.
823  *
824  * This action must be called once the drag action is over. This breaks
825  * the effect of having an object follow the user's mouse all over the
826  * place.
827  *
828  * This action is often executed after an sswf::Event::EVENT_POINTER_UP.
829  *
830  * \sa sswf::Event::EVENT_POINTER_UP
831  * \sa sswf::Event::EVENT_POINTER_DRAG_ENTER
832  * \sa sswf::Event::EVENT_POINTER_DRAG_LEAVE
833  * \sa sswf::Action::ACTION_STOP_DRAG
834  * \sa <a href="../SWFalexref.html#action_stop_drag">SWF Alexis' Reference&mdash;Stop Drag</a>
835  *
836  * <hr>
837  */
838 
839 
840 /** \var sswf::Action::ACTION_STRING_LESS_THAN
841  *
842  * \brief Test whether two strings are ordered.
843  *
844  * The ACTION_STRING_LESS_THAN pops two strings from the stack, compare them for order
845  * and pushes the result back on the stack.
846  *
847  * This action will ensure that two strings which represent numbers are still compared
848  * as strings and not numbers.
849  *
850  * \note
851  * This action should not be used anymore. It was deprecated. Instead, you should use
852  * the ACTION_LESS_THAN_TYPED action which ensures proper casting (as expected in the
853  * JavaScript reference&mdash;ECMA).
854  *
855  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
856  * \sa sswf::Action::ACTION_STRING_EQUAL
857  * \sa sswf::Action::ACTION_STRICT_EQUAL
858  * \sa sswf::Action::ACTION_STRING_GREATER_THAN
859  * \sa <a href="../SWFalexref.html#action_string_less_than">SWF Alexis' Reference&mdash;String Less Than</a>
860  *
861  * <hr>
862  */
863 
864 
865 /** \var sswf::Action::ACTION_THROW
866  *
867  * \brief Throw an exception.
868  *
869  * The ACTION_THROW pops one element from the stack and generates an
870  * exception of that type.
871  *
872  * One can use a try/catch/finaly block to manage exceptions.
873  *
874  * \sa sswf::Action::ACTION_TRY
875  * \sa <a href="../SWFalexref.html#action_throw">SWF Alexis' Reference&mdash;Throw</a>
876  *
877  * <hr>
878  */
879 
880 
881 /** \var sswf::Action::ACTION_CAST_OBJECT
882  *
883  * \brief Cast from one type to another.
884  *
885  * The ACTION_CAST_OBJECT action transform an object reference
886  * from one time to another. Really, in Javascript, this means
887  * making sure that an object is of a specified type. If not,
888  * you get NULL. Otherwise the action has no effect.
889  *
890  * This is similar to sswf::Action::ACTION_INSTANCE_OF except
891  * that it returns a reference to the object instead of a
892  * boolean value which often is more practical.
893  *
894  * \sa sswf::Action::ACTION_INSTANCE_OF
895  * \sa sswf::Action::ACTION_TYPE_OF
896  * \sa <a href="../SWFalexref.html#action_cast_object">SWF Alexis' Reference&mdash;Cast Object</a>
897  *
898  * <hr>
899  */
900 
901 
902 /** \var sswf::Action::ACTION_IMPLEMENTS
903  *
904  * \brief Define a list of interfaces that an object implements.
905  *
906  * The ACTION_IMPLEMENTS is used to mark an object as a derivation
907  * of one or more objects. These other objects are expected to be
908  * interfaces. This means they should only define abstract functions.
909  *
910  * \sa sswf::Action::ACTION_EXTENDS
911  * \sa <a href="../SWFalexref.html#action_implements">SWF Alexis' Reference&mdash;Implements</a>
912  *
913  * <hr>
914  */
915 
916 
917 /** \var sswf::Action::ACTION_FSCOMMAND2
918  *
919  * \brief Dynamic "Foreign Script Command".
920  *
921  * The ACTION_FSCOMMAND2 action pops an integer which is the number of
922  * strings to pop next. The first string popped is the name of the
923  * command to execute and the following strings are its parameters.
924  *
925  * FS in this action name means Foreign Script. In other words, not
926  * an ActionScript command, but a javascript command from within the
927  * browser.
928  *
929  * In order to execute dynamic ActionScript code, use the eval()
930  * function instead. Note that the SWF implementation of eval() is
931  * quite limited. So don't expect too much out of it.
932  *
933  * \sa sswf::Action::ACTION_DECLARE_FUNCTION
934  * \sa sswf::Action::ACTION_DECLARE_FUNCTION2
935  * \sa <a href="../SWFalexref.html#action_fscommand2">SWF Alexis' Reference&mdash;FSCommand2</a>
936  *
937  * <hr>
938  */
939 
940 
941 /** \var sswf::Action::ACTION_RANDOM
942  *
943  * \brief Generates a random value.
944  *
945  * The ACTION_RANDOM action pops one number from the stack and
946  * generates a random value between 0 and that number (the number
947  * not included.)
948  *
949  * The random value is not very good in older SWF players.
950  *
951  * It is suggested you use the Math.Random() function instead,
952  * which returns a value between 0.0 and 1.0.
953  *
954  * \sa sswf::Action::ACTION_CALL_METHOD
955  * \sa <a href="../SWFalexref.html#action_random">SWF Alexis' Reference&mdash;Random</a>
956  *
957  * <hr>
958  */
959 
960 
961 /** \var sswf::Action::ACTION_MBSTRING_LENGTH
962  *
963  * \brief Compute the length of a UTF-8 string in characters.
964  *
965  * The ACTION_MBSTRING_LENGTH pops one string, counts the number of characters
966  * and pushes the result back on the stack. The string is assumed to be defined
967  * in UTF-8.
968  *
969  * \sa sswf::Action::ACTION_STRING_LENGTH
970  * \sa <a href="../SWFalexref.html#action_string_length_mb">SWF Alexis' Reference&mdash;String Length</a> <i>(multi-bytes)</i>
971  *
972  * <hr>
973  */
974 
975 
976 /** \var sswf::Action::ACTION_ORD
977  *
978  * \brief Transform a character in the corresponding integer.
979  *
980  * The ACTION_ORD action pops one string and transform the first
981  * character in a number and push that number on the stack.
982  *
983  * This action can only deal with ASCII strings. Use the
984  * sswf::Action::ACTION_MBORD for international strings.
985  *
986  * \sa sswf::Action::ACTION_MBORD
987  * \sa sswf::Action::ACTION_CHR
988  * \sa sswf::Action::ACTION_MBCHR
989  * \sa <a href="../SWFalexref.html#action_ord">SWF Alexis' Reference&mdash;Ord</a>
990  *
991  * <hr>
992  */
993 
994 
995 /** \var sswf::Action::ACTION_CHR
996  *
997  * \brief Transform a number in the corresponding character.
998  *
999  * The ACTION_CHR action pops one number and transform it in a
1000  * character, then it pushes a string composed of that character
1001  * on the stack.
1002  *
1003  * This action can only deal with ASCII characters. Use the
1004  * sswf::Action::ACTION_MBCHR for international characters.
1005  *
1006  * \sa sswf::Action::ACTION_MBCHR
1007  * \sa sswf::Action::ACTION_ORD
1008  * \sa sswf::Action::ACTION_MBORD
1009  * \sa <a href="../SWFalexref.html#action_chr">SWF Alexis' Reference&mdash;Chr</a>
1010  *
1011  * <hr>
1012  */
1013 
1014 
1015 /** \var sswf::Action::ACTION_GET_TIMER
1016  *
1017  * \brief Push the current frame number on the stack.
1018  *
1019  * The ACTION_GET_TIMER action gets the frame counter and push it on the stack.
1020  * This is the main frame counter for the main SWF movie.
1021  *
1022  * In the newer versions of SWF you have access to a similar function on each
1023  * movie (I think it is called GetFrame(), but I'd have to verify...)
1024  *
1025  * \sa <a href="../SWFalexref.html#action_get_timer">SWF Alexis' Reference&mdash;Get Timer</a>
1026  *
1027  * <hr>
1028  */
1029 
1030 
1031 /** \var sswf::Action::ACTION_SUB_MBSTRING
1032  *
1033  * \brief Retrieve part of a string.
1034  *
1035  * The ACTION_SUB_MBSTRING pops one string and two numbers: one position
1036  * and one length; then it generates a new string from the sub-string
1037  * starting at that position and for that many characters; this is the
1038  * result which is pushed backed on the stack. This action views the
1039  * input string as a UTF-8 encoded string.
1040  *
1041  * \sa sswf::Action::ACTION_SUB_STRING
1042  * \sa <a href="../SWFalexref.html#action_substring">SWF Alexis' Reference&mdash;SubString</a>
1043  *
1044  * <hr>
1045  */
1046 
1047 
1048 /** \var sswf::Action::ACTION_MBORD
1049  *
1050  * \brief Transform a character in the corresponding integer.
1051  *
1052  * The ACTION_MBORD action pops one string and transform the first
1053  * character in a number and push that number on the stack.
1054  *
1055  * This action deals with any character (yet SWF is limited to
1056  * 16 bits characters or UCS-2).
1057  *
1058  * \sa sswf::Action::ACTION_ORD
1059  * \sa sswf::Action::ACTION_CHR
1060  * \sa sswf::Action::ACTION_MBCHR
1061  * \sa <a href="../SWFalexref.html#action_ord_mb">SWF Alexis' Reference&mdash;Ord <i>(multibyte)</i></a>
1062  *
1063  * <hr>
1064  */
1065 
1066 
1067 /** \var sswf::Action::ACTION_MBCHR
1068  *
1069  * \brief Transform a number in the corresponding character.
1070  *
1071  * The ACTION_MBCHR action pops one number and transform it in a
1072  * character, then it pushes a string composed of that character
1073  * on the stack.
1074  *
1075  * This action can deal with any international characters
1076  * (yet SWF is limited to 16 bits characters or UCS-2.)
1077  *
1078  * \sa sswf::Action::ACTION_CHR
1079  * \sa sswf::Action::ACTION_ORD
1080  * \sa sswf::Action::ACTION_MBORD
1081  * \sa <a href="../SWFalexref.html#action_chr_mb">SWF Alexis' Reference&mdash;Chr <i>(multibyte)</i></a>
1082  *
1083  * <hr>
1084  */
1085 
1086 
1087 /** \var sswf::Action::ACTION_DELETE
1088  *
1089  * \brief Delete an object.
1090  *
1091  * The ACTION_DELETE action pops an object and a string to delete
1092  * a property in an object. Note that an object does not need to
1093  * be deleted. If all references to that object disappear, then
1094  * the object is automatically deleted.
1095  *
1096  * It is possible to delete a global variable by pushing <b>undefined</b>
1097  * on the stack instead of an object.
1098  *
1099  * \sa sswf::Action::ACTION_NEW
1100  * \sa sswf::Action::ACTION_GET_VARIABLE
1101  * \sa sswf::Action::ACTION_SET_VARIABLE
1102  * \sa sswf::Action::ACTION_GET_MEMBER
1103  * \sa sswf::Action::ACTION_SET_MEMBER
1104  * \sa sswf::Action::ACTION_GET_PROPERTY
1105  * \sa sswf::Action::ACTION_SET_PROPERTY
1106  * \sa <a href="../SWFalexref.html#action_delete">SWF Alexis' Reference&mdash;Delete</a>
1107  *
1108  * <hr>
1109  */
1110 
1111 
1112 /** \var sswf::Action::ACTION_SET_LOCAL_VAR
1113  *
1114  * \brief Same as sswf::Action::ACTION_SET_LOCAL_VARIABLE.
1115  *
1116  * <hr>
1117  */
1118 
1119 
1120 /** \var sswf::Action::ACTION_SET_LOCAL_VARIABLE
1121  *
1122  * \brief Set a variable local to the function being executed.
1123  *
1124  * When running within a function, it is possible to create
1125  * a variable within this function. This is very useful to
1126  * avoid clashes between variable names between the different
1127  * functions you write.
1128  *
1129  * To get a local variable, use the sswf::Action::ACTION_GET_VARIABLE
1130  * action.
1131  *
1132  * See also the sswf::Action::ACTION_DECLARE_LOCAL_VARIABLE.
1133  *
1134  * \sa sswf::Action::ACTION_DECLARE_LOCAL_VARIABLE
1135  * \sa sswf::Action::ACTION_GET_VARIABLE
1136  * \sa sswf::Action::ACTION_SET_VARIABLE
1137  * \sa sswf::Action::ACTION_GET_PROPERTY
1138  * \sa sswf::Action::ACTION_SET_PROPERTY
1139  * \sa sswf::Action::ACTION_GET_MEMBER
1140  * \sa sswf::Action::ACTION_SET_MEMBER
1141  * \sa sswf::Action::ACTION_DELETE
1142  * \sa <a href="../SWFalexref.html#action_set_local_variable">SWF Alexis' Reference&mdash;Set Local Variable</a>
1143  *
1144  * <hr>
1145  */
1146 
1147 
1148 /** \var sswf::Action::ACTION_CALL_FUNCTION
1149  *
1150  * \brief Call a global function.
1151  *
1152  * This action is used to call a global or internal function.
1153  *
1154  * This action cannot be used to call a function on an object.
1155  * Use the sswf::Action::ACTION_CALL_METHOD instead.
1156  *
1157  * When a function returns, something will be on the stack.
1158  * A function declared as void in ActionScript usually
1159  * return an <b>undefined</b> entry. Just use
1160  * sswf::Action::ACTION_POP to get rid of it.
1161  * See the sswf::Action::ACTION_RETURN to see how you can
1162  * return right away from a function.
1163  *
1164  * The older versions (at least up to version 6) would return
1165  * as many things as you were pushing on the stack. I suggest
1166  * you make sure only one object is returned from your functions!
1167  *
1168  * \sa sswf::Action::ACTION_DECLARE_FUNCTION
1169  * \sa sswf::Action::ACTION_DECLARE_FUNCTION2
1170  * \sa sswf::Action::ACTION_RETURN
1171  * \sa sswf::Action::ACTION_CALL_METHOD
1172  * \sa sswf::Action::ACTION_NEW_METHOD
1173  * \sa sswf::Action::ACTION_NEW
1174  * \sa sswf::Action::ACTION_CALL_FRAME
1175  * \sa <a href="../SWFalexref.html#action_call_function">SWF Alexis' Reference&mdash;Call Function</a>
1176  *
1177  * <hr>
1178  */
1179 
1180 
1181 /** \var sswf::Action::ACTION_RETURN
1182  *
1183  * \brief End a function execution and return.
1184  *
1185  * The ACTION_RETURN ends a function execution.
1186  *
1187  * Whatever was last pushed on the stack is what the function
1188  * returns.
1189  *
1190  * In older versions (up to version 6 at least), the stack was not
1191  * purged meaning that you could return multiple objects on the
1192  * stack. This is supposedly fixed, but I did not test to confirm
1193  * whether this is really the case. So be careful and make sure
1194  * that you have only one object on the stack or expect the
1195  * unexpected!
1196  *
1197  * \sa sswf::Action::ACTION_CALL_FUNCTION
1198  * \sa sswf::Action::ACTION_CALL_METHOD
1199  * \sa sswf::Action::ACTION_NEW_METHOD
1200  * \sa sswf::Action::ACTION_NEW
1201  * \sa <a href="../SWFalexref.html#action_return">SWF Alexis' Reference&mdash;Return</a>
1202  *
1203  * <hr>
1204  */
1205 
1206 
1207 /** \var sswf::Action::ACTION_MODULO
1208  *
1209  * \brief Modulo of two values on the stack.
1210  *
1211  * The ACTION_MODULO pops two values from the stack, divide one by the
1212  * other and pushes the rest back onto the stack.
1213  *
1214  * Use this action with 1.0 to retrieve the fractional part of a floating
1215  * point value.
1216  *
1217  * \sa sswf::Action::ACTION_MULTIPLY
1218  * \sa sswf::Action::ACTION_DIVIDE
1219  * \sa sswf::Action::ACTION_INTEGRAL_PART
1220  * \sa <a href="../SWFalexref.html#action_modulo">SWF Alexis' Reference&mdash;Modulo</a>
1221  *
1222  * <hr>
1223  */
1224 
1225 
1226 /** \var sswf::Action::ACTION_NEW
1227  *
1228  * \brief Create a new instance of an object.
1229  *
1230  * The ACTION_NEW creates a new instance of an object. The name of the class
1231  * and the parameters used to call the constructor are taken from the stack.
1232  *
1233  * The constructor result will be discarded. The result of the ACTION_NEW
1234  * is the newly created object which in general will be saved in a variable
1235  * or a variable member (also called property.)
1236  *
1237  * To delete the object, remove all instances by deleting or reassigning
1238  * the variables holding the object.
1239  *
1240  * To call an overloaded new constructor, you need to use the
1241  * sswf::Action::ACTION_NEW_METHOD action instead.
1242  *
1243  * \sa sswf::Action::ACTION_DELETE
1244  * \sa sswf::Action::ACTION_SET_MEMBER
1245  * \sa sswf::Action::ACTION_SET_VARIABLE
1246  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
1247  * \sa sswf::Action::ACTION_CALL_FUNCTION
1248  * \sa sswf::Action::ACTION_CALL_METHOD
1249  * \sa sswf::Action::ACTION_NEW_METHOD
1250  * \sa <a href="../SWFalexref.html#action_new">SWF Alexis' Reference&mdash;New</a>
1251  *
1252  * <hr>
1253  */
1254 
1255 
1256 /** \var sswf::Action::ACTION_DECLARE_LOCAL_VAR
1257  *
1258  * \brief Same as sswf::Action::ACTION_DECLARE_LOCAL_VARIABLE.
1259  *
1260  * <hr>
1261  */
1262 
1263 
1264 /** \var sswf::Action::ACTION_DECLARE_LOCAL_VARIABLE
1265  *
1266  * \brief Declare names to be used for local variables.
1267  *
1268  * The ACTION_DECLARE_LOCAL_VARIABLE action takes an array of
1269  * strings naming all the variables that will be created in
1270  * this function and need to be created locally (i.e. not
1271  * visible outside of this function.)
1272  *
1273  * After this function, a regular sswf::Action::ACTION_SET_VARIABLE
1274  * will set a local variable if its name was specified
1275  * in the list of this ACTION_DECLARE_LOCAL_VARIABLE
1276  * array.
1277  *
1278  * This action has the side effect of setting the corresponding
1279  * variable to <b>undefined</b>. This hides any corresponding
1280  * global variables in case you try to get the variable before
1281  * setting it.
1282  *
1283  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
1284  * \sa sswf::Action::ACTION_GET_VARIABLE
1285  * \sa sswf::Action::ACTION_SET_VARIABLE
1286  * \sa <a href="../SWFalexref.html#action_declare_local_variable">SWF Alexis' Reference&mdash;Declare Local Variable</a>
1287  *
1288  * <hr>
1289  */
1290 
1291 
1292 /** \var sswf::Action::ACTION_DECLARE_ARRAY
1293  *
1294  * \brief Declare an array.
1295  *
1296  * The ACTION_DECLARE_ARRAY action creates an array object and
1297  * save the result on the stack.
1298  *
1299  * This action pops one number from the stack which is the number
1300  * of values pushed on the stack which will be used to initialize
1301  * the array. These values are then assigned to the array starting
1302  * at index 0. A counter of 0 means only one value is to be assigned.
1303  * A counter of 1 means 2 values are to be assigned. Etc.
1304  *
1305  * To initialize an array sporadically, use the
1306  * sswf::Action::ACTION_DECLARE_OBJECT instead.
1307  *
1308  * \sa sswf::Action::ACTION_DECLARE_OBJECT
1309  * \sa sswf::Action::ACTION_ENUMERATE
1310  * \sa <a href="../SWFalexref.html#action_declare_array">SWF Alexis' Reference&mdash;Declare Array</a>
1311  *
1312  * <hr>
1313  */
1314 
1315 
1316 /** \var sswf::Action::ACTION_DECLARE_OBJECT
1317  *
1318  * \brief Declare an object and its properties.
1319  *
1320  * The ACTION_DECLARE_OBJECT action creates an object and
1321  * save the result on the stack.
1322  *
1323  * This action pops the name of the new object and the number
1324  * of members defined on the stack. The stack holds the name
1325  * and the value of each pre-defined member. The value of a
1326  * member can be a function (when a function is declared
1327  * without a name, it is stacked!) Thus, in effect, you can
1328  * declare methods!
1329  *
1330  * It is possible to create an array with the ACTION_DECLARE_OBJECT
1331  * by specifying the indices as the variable member names. In this
1332  * case, you can initializes an array sporadically.
1333  *
1334  * \sa sswf::Action::ACTION_DECLARE_ARRAY
1335  * \sa sswf::Action::ACTION_ENUMERATE
1336  * \sa <a href="../SWFalexref.html#action_declare_object">SWF Alexis' Reference&mdash;Declare Object</a>
1337  *
1338  * <hr>
1339  */
1340 
1341 
1342 /** \var sswf::Action::ACTION_TYPE_OF
1343  *
1344  * \brief Determine the type of the data on the stack.
1345  *
1346  * The ACTION_TYPE_OF action pops one object from the stack,
1347  * determines its type, and push the name of the type back
1348  * on the stack as a string.
1349  *
1350  * It is suggested to use one of sswf::Action::ACTION_CAST_OBJECT
1351  * or sswf::Action::ACTION_INSTANCE_OF isntead.
1352  *
1353  * If you need to keep the data also, use the
1354  * sswf::Action::ACTION_DUPLICATE first.
1355  *
1356  * The possible types are:
1357  *
1358  * \code
1359  *  number
1360  *  boolean
1361  *  string
1362  *  object
1363  *  movieclip
1364  *  null
1365  *  undefined
1366  *  function
1367  * \endcode
1368  *
1369  * \sa sswf::Action::ACTION_CAST_OBJECT
1370  * \sa sswf::Action::ACTION_INSTANCE_OF
1371  * \sa <a href="../SWFalexref.html#action_type_of">SWF Alexis' Reference&mdash;Type Of</a>
1372  *
1373  * <hr>
1374  */
1375 
1376 
1377 /** \var sswf::Action::ACTION_GET_TARGET
1378  *
1379  * \brief Make this object the target.
1380  *
1381  * Get the path to the specified sprite and make it the
1382  * target (as with sswf::Action::ACTION_SET_TARGET2.)
1383  *
1384  * This function lets you specify a sprite instead of a
1385  * path which may be difficult to determine in some circumstances.
1386  *
1387  * \sa sswf::Action::ACTION_SET_TARGET
1388  * \sa sswf::Action::ACTION_SET_TARGET2
1389  * \sa sswf::Action::ACTION_WITH
1390  * \sa <a href="../SWFalexref.html#action_get_target">SWF Alexis' Reference&mdash;Get Target</a>
1391  *
1392  * <hr>
1393  */
1394 
1395 
1396 /** \var sswf::Action::ACTION_ENUMERATE
1397  *
1398  * \brief Enumerate an object or an array.
1399  *
1400  * The ACTION_ENUMERATE action pops an object, stack a NULL and
1401  * then stacks the object member names and corresponding values.
1402  *
1403  * This can be used with either an object or an array. In case
1404  * of an array, the indices replace the member names.
1405  *
1406  * Unfortunately, what is being enumerated cannot as is be used
1407  * to create a new object since there is no way to know how
1408  * many entries have been enumerated without first going through
1409  * the entire stack! Otherwise, the stack looks like what the
1410  * sswf::Action::ACTION_DECLARE_OBJECT accepts as parameters.
1411  *
1412  * \sa sswf::Action::ACTION_DECLARE_ARRAY
1413  * \sa sswf::Action::ACTION_DECLARE_OBJECT
1414  * \sa sswf::Action::ACTION_ENUMERATE_OBJECT
1415  * \sa <a href="../SWFalexref.html#action_enumerate">SWF Alexis' Reference&mdash;Enumerate</a>
1416  *
1417  * <hr>
1418  */
1419 
1420 
1421 /** \var sswf::Action::ACTION_ADD_TYPED
1422  *
1423  * \brief Add according to the operand types.
1424  *
1425  * The ACTION_ADD_TYPED action pops two objects and add them according
1426  * to their type. If both variables are strings, concatenate them.
1427  * If one of the variables is a floating point, convert the other
1428  * to a floating point if not already a floating point, then add them
1429  * and put the addition result back on the stack. If both are integers,
1430  * add them and put the result back on the stack.
1431  *
1432  * This is the prefered way to convert the + operator of ActionScript
1433  * since it follows the ECMA specification.
1434  *
1435  * \sa sswf::Action::ACTION_ADD
1436  * \sa sswf::Action::ACTION_SUBTRACT
1437  * \sa <a href="../SWFalexref.html#action_add_typed">SWF Alexis' Reference&mdash;Add <i>(Typed)</i></a>
1438  *
1439  * <hr>
1440  */
1441 
1442 
1443 /** \var sswf::Action::ACTION_LESS_THAN_TYPED
1444  *
1445  * \brief Compare according to the operand types.
1446  *
1447  * The ACTION_LESS_THAN_TYPED action pops two objects and compare
1448  * them according to their type.
1449  *
1450  * This is the prefered way to convert the &lt; operator of ActionScript
1451  * since it follows the ECMA specification.
1452  *
1453  * \sa sswf::Action::ACTION_EQUAL
1454  * \sa sswf::Action::ACTION_EQUAL_TYPED
1455  * \sa sswf::Action::ACTION_STRICT_EQUAL
1456  * \sa sswf::Action::ACTION_LESS_THAN
1457  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
1458  * \sa sswf::Action::ACTION_LOGICAL_NOT
1459  * \sa sswf::Action::ACTION_LOGICAL_AND
1460  * \sa sswf::Action::ACTION_LOGICAL_OR
1461  * \sa <a href="../SWFalexref.html#action_less_than_typed">SWF Alexis' Reference&mdash;Less Than <i>(Typed)</i></a>
1462  *
1463  * <hr>
1464  */
1465 
1466 
1467 /** \var sswf::Action::ACTION_EQUAL_TYPED
1468  *
1469  * \brief Compare according to the operand types.
1470  *
1471  * The ACTION_EQUAL_TYPED action pops two objects and compare
1472  * them according to their type.
1473  *
1474  * This is the prefered way to convert the == operator of ActionScript
1475  * since it follows the ECMA specification.
1476  *
1477  * \sa sswf::Action::ACTION_EQUAL
1478  * \sa sswf::Action::ACTION_STRICT_EQUAL
1479  * \sa sswf::Action::ACTION_LESS_THAN
1480  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
1481  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
1482  * \sa sswf::Action::ACTION_LOGICAL_NOT
1483  * \sa sswf::Action::ACTION_LOGICAL_AND
1484  * \sa sswf::Action::ACTION_LOGICAL_OR
1485  * \sa <a href="../SWFalexref.html#action_equal_typed">SWF Alexis' Reference&mdash;Equal <i>(Typed)</i></a>
1486  *
1487  * <hr>
1488  */
1489 
1490 
1491 /** \var sswf::Action::ACTION_NUMBER
1492  *
1493  * \brief Converts an object to a number.
1494  *
1495  * The ACTION_NUMBER action calls the method valueOf() of the object
1496  * on the stack and replaces that object with a number.
1497  *
1498  * If the operation fails, <b>undefined</b> is pushed on the stack.
1499  *
1500  * This is a good way to optimize a call to the valueOf() method of
1501  * any object. Also, it works on internal types.
1502  *
1503  * \sa sswf::Action::ACTION_STRING
1504  * \sa sswf::Action::ACTION_CALL_METHOD
1505  * \sa <a href="../SWFalexref.html#action_number">SWF Alexis' Reference&mdash;Number</a>
1506  *
1507  * <hr>
1508  */
1509 
1510 
1511 /** \var sswf::Action::ACTION_STRING
1512  *
1513  * \brief Converts an object to a string.
1514  *
1515  * The ACTION_STRING action calls the method toString() of the object
1516  * on the stack and replaces that object with a string representing
1517  * the object.
1518  *
1519  * If the operation fails, <b>undefined</b> is pushed on the stack.
1520  *
1521  * This is a good way to optimize a call to the toString() method of
1522  * any object. Also, it works on internal types.
1523  *
1524  * \sa sswf::Action::ACTION_STRING
1525  * \sa sswf::Action::ACTION_CALL_METHOD
1526  * \sa <a href="../SWFalexref.html#action_string">SWF Alexis' Reference&mdash;String</a>
1527  *
1528  * <hr>
1529  */
1530 
1531 
1532 /** \var sswf::Action::ACTION_DUPLICATE
1533  *
1534  * \brief Duplicate one element on the stack.
1535  *
1536  * The ACTION_DUPLICATE action pops one element from the stack and
1537  * pushes it back twice.
1538  *
1539  * \sa sswf::Action::ACTION_POP
1540  * \sa sswf::Action::ACTION_SWAP
1541  * \sa <a href="../SWFalexref.html#action_duplicate">SWF Alexis' Reference&mdash;Duplicate</a>
1542  *
1543  * <hr>
1544  */
1545 
1546 
1547 /** \var sswf::Action::ACTION_SWAP
1548  *
1549  * \brief Swap the two last elements on the stack.
1550  *
1551  * The ACTION_SWAP action pops two elements from the stack and push them
1552  * back the other way around.
1553  *
1554  * \sa sswf::Action::ACTION_POP
1555  * \sa sswf::Action::ACTION_SWAP
1556  * \sa <a href="../SWFalexref.html#action_swap">SWF Alexis' Reference&mdash;Swap</a>
1557  *
1558  * <hr>
1559  */
1560 
1561 
1562 /** \var sswf::Action::ACTION_GET_MEMBER
1563  *
1564  * \brief Read the value of an object member.
1565  *
1566  * The ACTION_GET_MEMBER action is similar to the sswf::Action::ACTION_GET_VARIABLE
1567  * but looks within an object for the variable definition and content.
1568  *
1569  * The value of a member can be a function as well as a value.
1570  *
1571  * The member name can be an index when accessing an array.
1572  *
1573  * This action replaces the sswf::Action::ACTION_GET_PROPERTY which used a number to
1574  * access a set of predefined member names.
1575  *
1576  * \sa sswf::Action::ACTION_SET_MEMBER
1577  * \sa sswf::Action::ACTION_GET_PROPERTY
1578  * \sa sswf::Action::ACTION_SET_PROPERTY
1579  * \sa sswf::Action::ACTION_GET_VARIABLE
1580  * \sa sswf::Action::ACTION_SET_VARIABLE
1581  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
1582  * \sa sswf::Action::ACTION_DELETE
1583  * \sa <a href="../SWFalexref.html#action_get_member">SWF Alexis' Reference&mdash;Get Member</a>
1584  *
1585  * <hr>
1586  */
1587 
1588 
1589 /** \var sswf::Action::ACTION_SET_MEMBER
1590  *
1591  * \brief Write the value of an object member.
1592  *
1593  * The ACTION_SET_MEMBER action is similar to the sswf::Action::ACTION_SET_VARIABLE
1594  * but creates the variable inside an object and that is called a member.
1595  *
1596  * The value of a member can be a function as well as a value. In case it is a
1597  * function, it can then be called with the sswf::Action::ACTION_CALL_METHOD
1598  * action.
1599  *
1600  * The member name can be an index when accessing an array.
1601  *
1602  * To get rid of a member, use the sswf::Action::ACTION_DELETE action.
1603  *
1604  * This action replaces the sswf::Action::ACTION_SET_PROPERTY which used a number to
1605  * access a set of predefined member names.
1606  *
1607  * \sa sswf::Action::ACTION_GET_MEMBER
1608  * \sa sswf::Action::ACTION_GET_PROPERTY
1609  * \sa sswf::Action::ACTION_SET_PROPERTY
1610  * \sa sswf::Action::ACTION_GET_VARIABLE
1611  * \sa sswf::Action::ACTION_SET_VARIABLE
1612  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
1613  * \sa sswf::Action::ACTION_DELETE
1614  * \sa <a href="../SWFalexref.html#action_set_member">SWF Alexis' Reference&mdash;Set Member</a>
1615  *
1616  * <hr>
1617  */
1618 
1619 
1620 /** \var sswf::Action::ACTION_INCREMENT
1621  *
1622  * \brief Add 1 to the value at the top of the stack.
1623  *
1624  * The ACTION_INCREMENT action adds one to the value on the stack. The
1625  * stack is expected to be an integer or a floating point value. Another
1626  * object will be converted to a number if possible.
1627  *
1628  * \sa sswf::Action::ACTION_DECREMENT
1629  * \sa <a href="../SWFalexref.html#action_increment">SWF Alexis' Reference&mdash;Increment</a>
1630  *
1631  * <hr>
1632  */
1633 
1634 
1635 /** \var sswf::Action::ACTION_DECREMENT
1636  *
1637  * \brief Subtract 1 from the value at the top of the stack.
1638  *
1639  * The ACTION_DECREMENT action subtracts one to the value on the stack. The
1640  * stack is expected to be an integer or a floating point value. Another
1641  * object will be converted to a number if possible.
1642  *
1643  * \sa sswf::Action::ACTION_DECREMENT
1644  * \sa <a href="../SWFalexref.html#action_decrement">SWF Alexis' Reference&mdash;Decrement</a>
1645  *
1646  * <hr>
1647  */
1648 
1649 
1650 /** \var sswf::Action::ACTION_CALL_METHOD
1651  *
1652  * \brief Call a method on an object.
1653  *
1654  * The ACTION_CALL_METHOD action calls the named method of an object
1655  * with the specified parameters.
1656  *
1657  * This is similar to the sswf::Action::ACTION_CALL_FUNCTION but
1658  * it calls the function defined within an object instead. This means
1659  * that the 'this' parameter will be defined in that function and it
1660  * can be used to access the members of the object.
1661  *
1662  * A call always returns a value. If the method is declared as a
1663  * function returning void (a procedure in effect), the function
1664  * returns <b>undefined</b>.
1665  *
1666  * \sa sswf::Action::ACTION_CALL_FUNCTION
1667  * \sa sswf::Action::ACTION_NEW_METHOD
1668  * \sa sswf::Action::ACTION_NEW
1669  * \sa sswf::Action::ACTION_RETURN
1670  * \sa <a href="../SWFalexref.html#action_call_method">SWF Alexis' Reference&mdash;Call Method</a>
1671  *
1672  * <hr>
1673  */
1674 
1675 
1676 /** \var sswf::Action::ACTION_NEW_METHOD
1677  *
1678  * \brief Create an object and call a constructor.
1679  *
1680  * The ACTION_NEW_METHOD action creates a new instance of an object
1681  * and then initializes it by calling a constructor depending on
1682  * its parameters (constructors can be overloaded in this case.)
1683  *
1684  * This is similar to the ACTION_NEW except that the proper overloaded
1685  * constructor is called automatically.
1686  *
1687  * \sa sswf::Action::ACTION_CALL_FUNCTION
1688  * \sa sswf::Action::ACTION_NEW_METHOD
1689  * \sa sswf::Action::ACTION_NEW
1690  * \sa sswf::Action::ACTION_RETURN
1691  * \sa <a href="../SWFalexref.html#action_new_method">SWF Alexis' Reference&mdash;New Method</a>
1692  *
1693  * <hr>
1694  */
1695 
1696 
1697 /** \var sswf::Action::ACTION_INSTANCE_OF
1698  *
1699  * \brief Check wether an object of an instance of a specified class.
1700  *
1701  * The ACTION_INSTANCE_OF action checks whether a given object was created
1702  * from a given class. Since everything in SWF is an object (including a
1703  * classes, interfaces, etc.), I'm not too sure how this works. I suppose
1704  * they can keep a link to the original object used to create another and
1705  * each object has a set of inheritance in case of multiple inheritance
1706  * (which should only happen with interfaces.)
1707  *
1708  * \sa sswf::Action::ACTION_CAST_OBJECT
1709  * \sa sswf::Action::ACTION_TYPE_OF
1710  * \sa <a href="../SWFalexref.html#action_instance_of">SWF Alexis' Reference&mdash;Instance Of</a>
1711  *
1712  * <hr>
1713  */
1714 
1715 
1716 /** \var sswf::Action::ACTION_ENUMERATE_OBJECT
1717  *
1718  * \brief Enumerate an object or an array.
1719  *
1720  * The ACTION_ENUMERATE_OBJECT action pops an object, stacks a NULL
1721  * and then stacks the object member names on the stack.
1722  *
1723  * This can be used with either an object or an array. In case
1724  * of an array, the indices replace the member names.
1725  *
1726  * \sa sswf::Action::ACTION_DECLARE_ARRAY
1727  * \sa sswf::Action::ACTION_DECLARE_OBJECT
1728  * \sa sswf::Action::ACTION_ENUMERATE
1729  * \sa <a href="../SWFalexref.html#action_enumerate_object">SWF Alexis' Reference&mdash;Enumerate Object</a>
1730  *
1731  * <hr>
1732  */
1733 
1734 
1735 /** \var sswf::Action::ACTION_AND
1736  *
1737  * \brief Apply a bitwise AND between two numbers.
1738  *
1739  * The ACTION_AND action applies a bitwise AND between two integer numbers.
1740  *
1741  * The SWF player does not support bitwise AND between floating points.
1742  *
1743  * This is the & operator in ActionScript.
1744  *
1745  * \sa sswf::Action::ACTION_LOGICAL_AND
1746  * \sa sswf::Action::ACTION_LOGICAL_OR
1747  * \sa sswf::Action::ACTION_LOGICAL_NOT
1748  * \sa sswf::Action::ACTION_OR
1749  * \sa sswf::Action::ACTION_XOR
1750  * \sa <a href="../SWFalexref.html#action_and">SWF Alexis' Reference&mdash;And</a>
1751  *
1752  * <hr>
1753  */
1754 
1755 
1756 /** \var sswf::Action::ACTION_OR
1757  *
1758  * \brief Apply a bitwise OR between two numbers.
1759  *
1760  * The ACTION_OR action applies a bitwise OR between two integer numbers.
1761  *
1762  * The SWF player does not support bitwise OR between floating points.
1763  *
1764  * This is the | operator in ActionScript.
1765  *
1766  * \sa sswf::Action::ACTION_LOGICAL_AND
1767  * \sa sswf::Action::ACTION_LOGICAL_OR
1768  * \sa sswf::Action::ACTION_LOGICAL_NOT
1769  * \sa sswf::Action::ACTION_AND
1770  * \sa sswf::Action::ACTION_XOR
1771  * \sa <a href="../SWFalexref.html#action_or">SWF Alexis' Reference&mdash;Or</a>
1772  *
1773  * <hr>
1774  */
1775 
1776 
1777 /** \var sswf::Action::ACTION_XOR
1778  *
1779  * \brief Apply a bitwise XOR between two numbers.
1780  *
1781  * The ACTION_XOR action applies a bitwise XOR between two integer numbers.
1782  *
1783  * The SWF player does not support bitwise XOR between floating points.
1784  *
1785  * This is the ^ operator in ActionScript.
1786  *
1787  * \sa sswf::Action::ACTION_LOGICAL_AND
1788  * \sa sswf::Action::ACTION_LOGICAL_OR
1789  * \sa sswf::Action::ACTION_LOGICAL_NOT
1790  * \sa sswf::Action::ACTION_AND
1791  * \sa sswf::Action::ACTION_OR
1792  * \sa <a href="../SWFalexref.html#action_xor">SWF Alexis' Reference&mdash;XOr</a>
1793  *
1794  * <hr>
1795  */
1796 
1797 
1798 /** \var sswf::Action::ACTION_SHIFT_LEFT
1799  *
1800  * \brief Shift bits to the left.
1801  *
1802  * The ACTION_SHIFT_LEFT action shifts the bits of an integer to the left.
1803  *
1804  * The SWF player does not support shifting floating points.
1805  *
1806  * This is the &lt;&lt; operator in ActionScript.
1807  *
1808  * \sa sswf::Action::ACTION_SHIFT_RIGHT
1809  * \sa <a href="../SWFalexref.html#action_shift_left">SWF Alexis' Reference&mdash;Shift Left</a>
1810  *
1811  * <hr>
1812  */
1813 
1814 
1815 /** \var sswf::Action::ACTION_SHIFT_RIGHT
1816  *
1817  * \brief Shift bits to the right.
1818  *
1819  * The ACTION_SHIFT_RIGHT action shifts the bits of an integer to the right.
1820  *
1821  * The integer is taken as a signed integer. This means that a negative integer
1822  * remains negative and a positive integer remains positive.
1823  *
1824  * The SWF player does not support shifting floating points.
1825  *
1826  * This is the &gt;&gt; operator in ActionScript.
1827  *
1828  * \sa sswf::Action::ACTION_SHIFT_RIGHT
1829  * \sa <a href="../SWFalexref.html#action_shift_right">SWF Alexis' Reference&mdash;Shift Right</a>
1830  *
1831  * <hr>
1832  */
1833 
1834 
1835 /** \var sswf::Action::ACTION_SHIFT_RIGHT_UNSIGNED
1836  *
1837  * \brief Shift bits to the right.
1838  *
1839  * The ACTION_SHIFT_RIGHT_UNSIGNED action shifts the bits of an integer to the right.
1840  *
1841  * The integer is taken as an unsigned integer. This means that the most significant
1842  * bits are cleared as the value is being shifted.
1843  *
1844  * The SWF player does not support shifting floating points.
1845  *
1846  * This is the &gt;&gt;&gt; operator in ActionScript.
1847  *
1848  * \sa sswf::Action::ACTION_SHIFT_RIGHT
1849  * \sa <a href="../SWFalexref.html#action_shift_right_unsigned">SWF Alexis' Reference&mdash;Shift Right Unsigned</a>
1850  *
1851  * <hr>
1852  */
1853 
1854 
1855 /** \var sswf::Action::ACTION_STRICT_EQUAL
1856  *
1857  * \brief Compare two objects without conversions.
1858  *
1859  * The ACTION_STRICT_EQUAL compare two objects without trying to convert one or the
1860  * other so they match. For instance, 0 == "0" is considered true, but 0 === "0"
1861  * is not. This action represents the === operation of ActionScript.
1862  *
1863  * \sa sswf::Action::ACTION_EQUAL
1864  * \sa sswf::Action::ACTION_EQUAL_TYPED
1865  * \sa sswf::Action::ACTION_LESS_THAN
1866  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
1867  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
1868  * \sa sswf::Action::ACTION_LOGICAL_NOT
1869  * \sa sswf::Action::ACTION_LOGICAL_AND
1870  * \sa sswf::Action::ACTION_LOGICAL_OR
1871  * \sa <a href="../SWFalexref.html#action_strict_equal">SWF Alexis' Reference&mdash;Strict Equal</a>
1872  *
1873  * <hr>
1874  */
1875 
1876 
1877 /** \var sswf::Action::ACTION_GREATER_THAN_TYPED
1878  *
1879  * \brief Compare according to the operand types.
1880  *
1881  * The ACTION_GREATER_THAN_TYPED action pops two objects and compare
1882  * them according to their type.
1883  *
1884  * This is the prefered way to convert the &gt; operator of ActionScript
1885  * since it follows the ECMA specification.
1886  *
1887  * \sa sswf::Action::ACTION_EQUAL
1888  * \sa sswf::Action::ACTION_EQUAL_TYPED
1889  * \sa sswf::Action::ACTION_STRICT_EQUAL
1890  * \sa sswf::Action::ACTION_LESS_THAN
1891  * \sa sswf::Action::ACTION_LESS_THAN_TYPED
1892  * \sa sswf::Action::ACTION_LOGICAL_NOT
1893  * \sa sswf::Action::ACTION_LOGICAL_AND
1894  * \sa sswf::Action::ACTION_LOGICAL_OR
1895  * \sa <a href="../SWFalexref.html#action_greater_than_typed">SWF Alexis' Reference&mdash;Greater Than <i>(Typed)</i></a>
1896  *
1897  * <hr>
1898  */
1899 
1900 
1901 /** \var sswf::Action::ACTION_STRING_GREATER_THAN
1902  *
1903  * \brief Test whether two strings are ordered.
1904  *
1905  * The ACTION_STRING_GREATER_THAN pops two strings from the stack, compare them for order
1906  * and pushes the result back on the stack.
1907  *
1908  * This action will ensure that two strings which represent numbers are still compared
1909  * as strings and not numbers.
1910  *
1911  * \note
1912  * This action should not be used anymore. It was deprecated. Instead, you should use
1913  * the ACTION_GREATER_THAN_TYPED action which ensures proper casting (as expected in the
1914  * JavaScript reference&mdash;ECMA).
1915  *
1916  * \sa sswf::Action::ACTION_GREATER_THAN_TYPED
1917  * \sa sswf::Action::ACTION_STRING_EQUAL
1918  * \sa sswf::Action::ACTION_STRICT_EQUAL
1919  * \sa sswf::Action::ACTION_STRING_LESS_THAN
1920  * \sa <a href="../SWFalexref.html#action_string_greater_than">SWF Alexis' Reference&mdash;String Greater Than</a>
1921  *
1922  * <hr>
1923  */
1924 
1925 
1926 /** \var sswf::Action::ACTION_EXTENDS
1927  *
1928  * \brief Mark a class as the extension of another.
1929  *
1930  * The ACTION_EXTENDS action is used to define the inheritance of a
1931  * class. It is used to implement the ActionScript:
1932  *
1933  * \code
1934  *  class A { ...};
1935  *  class B extends A { ... };
1936  * \endcode
1937  *
1938  * \sa sswf::Action::ACTION_IMPLEMENTS
1939  * \sa <a href="../SWFalexref.html#action_extends">SWF Alexis' Reference&mdash;Extends</a>
1940  *
1941  * <hr>
1942  */
1943 
1944 
1945 /** \var sswf::Action::ACTION_GOTO_FRAME
1946  *
1947  * \brief Change the frame number of the playback.
1948  *
1949  * The ACTION_GOTO_FRAME action changes the frame number of the playback.
1950  * This means the playback of the movie continues at the frame specified
1951  * by the ACTION_GOTO_FRAME. The frame is hard coded in the action so this
1952  * action is not usually very useful unless your frame number is a constant
1953  * number.
1954  *
1955  * Use the sswf::Action::ACTION_GOTO_EXPRESSION instead to be able to use
1956  * a variable frame number.
1957  *
1958  * \sa sswf::Action::ACTION_GOTO_LABEL
1959  * \sa sswf::Action::ACTION_GOTO_EXPRESSION
1960  * \sa <a href="../SWFalexref.html#action_goto_frame">SWF Alexis' Reference&mdash;Goto Frame</a>
1961  *
1962  * <hr>
1963  */
1964 
1965 
1966 /** \var sswf::Action::ACTION_URL
1967  *
1968  * \brief Load the specified URL.
1969  *
1970  * The ACTION_URL action loads the specified URL.
1971  *
1972  * The target specifies how the new URL should be loaded. "_level1"
1973  * means that the SWF movie is replaced. "_top" replaces the entire
1974  * window. "_blank" opens a new window. A frame name will reload that
1975  * frame.
1976  *
1977  * It is also possible to execute some Javascript code using the
1978  * javascript: protocol instead of http or https.
1979  *
1980  * \sa sswf::Action::ACTION_URL2
1981  * \sa <a href="../SWFalexref.html#action_get_url">SWF Alexis' Reference&mdash;Get URL</a>
1982  *
1983  * <hr>
1984  */
1985 
1986 
1987 /** \var sswf::Action::ACTION_STORE_REGISTER
1988  *
1989  * \brief Store the value currently at the top of the stack in a register.
1990  *
1991  * The ACTION_STORE_REGISTER action saves the value currently at the
1992  * top of the stack in the specified register. The value on the stack
1993  * is not popped. The maximum register number varies depending on the
1994  * version of the player and whether you are in a function or the
1995  * global space.
1996  *
1997  * A register can later be read with an sswf::Action::ACTION_PUSH_DATA.
1998  *
1999  * \sa sswf::Action::ACTION_PUSH_DATA
2000  * \sa <a href="../SWFalexref.html#action_store_register">SWF Alexis' Reference&mdash;Store Register</a>
2001  *
2002  * <hr>
2003  */
2004 
2005 
2006 /** \var sswf::Action::ACTION_DECLARE_DICTIONARY
2007  *
2008  * \brief Declare a special array of strings which can later be pushed on the stack.
2009  *
2010  * The ACTION_DECLARE_DICTIONARY action is a list of null terminated strings.
2011  * These strings are numbered from 0 to 65534 and can later be pushed on the
2012  * stack with an sswf::Action::ACTIO_PUSH_DATA.
2013  *
2014  * This is used to compress your movies. If the same rather long string needs to
2015  * be pushed onto the stack many times, repeating it in each Push Data would
2016  * generate a larger action script than putting it once in a dictionary and
2017  * pushing it using the special "push a dictionary entry" feature.
2018  *
2019  * The gain can be very small. You need to measure the length of the string,
2020  * the overhead of declaring a dictionary and the number of times a string is
2021  * used. If used once, no dictionary is necessary. If the string is one character,
2022  * using the dictionary will actually make you lose 1 byte per Push Data...
2023  *
2024  * \sa sswf::Action::ACTION_PUSH_DATA
2025  * \sa <a href="../SWFalexref.html#action_declare_dictionary">SWF Alexis' Reference&mdash;Declare Dictionary</a>
2026  *
2027  * <hr>
2028  */
2029 
2030 
2031 /** \var sswf::Action::ACTION_STRICT_MODE
2032  *
2033  * \brief Whether the ActionScript engine is strict or not.
2034  *
2035  * The ACTION_STRICT_MODE action sets the strict mode flag to true or false.
2036  *
2037  * When the strict mode is true, more checks are done to ensure that the
2038  * ActionScript running is more compliant to the ECMA specification.
2039  *
2040  * \sa sswf::Action::ACTION_PUSH_DATA
2041  * \sa <a href="../SWFalexref.html#action_strict_mode">SWF Alexis' Reference&mdash;Strict Mode</a>
2042  *
2043  * <hr>
2044  */
2045 
2046 
2047 /** \var sswf::Action::ACTION_WAIT_FOR_FRAME
2048  *
2049  * \brief Wait for the specified frame.
2050  *
2051  * The ACTION_WAIT_FOR_FRAME action is an old action used to wait for
2052  * a frame while loading on a slow modem and such. Thus you could know
2053  * what was loaded to know whether you could display such and such
2054  * sprite.
2055  *
2056  * Often, the actions to execute when the frame was finaly loaded is
2057  * an sswf::Action::ACTION_BRANCH_ALWAYS which skips the actions to
2058  * be executed when the frame was not yet loaded.
2059  *
2060  * There is now ways to check for the frame number and use a regular
2061  * sswf::Action::ACTION_BRANCH_IF_TRUE action instead.
2062  *
2063  * \sa sswf::Action::ACTION_PUSH_DATA
2064  * \sa <a href="../SWFalexref.html#action_wait_for_frame">SWF Alexis' Reference&mdash;Wait for Frame</a>
2065  *
2066  * <hr>
2067  */
2068 
2069 
2070 /** \var sswf::Action::ACTION_SET_TARGET
2071  *
2072  * \brief Apply actions to the specified sprite (or movie).
2073  *
2074  * The ACTION_SET_TARGET action is used to optimize the code or call
2075  * a sub-function which apply functions on what is considered the
2076  * current movie.
2077  *
2078  * This current movie is defined by name with this action. An empty
2079  * name refer to the main movie (the root). When the name of a
2080  * specific sprite is used, then that specific sprite functions
2081  * are called.
2082  *
2083  * \sa sswf::Action::ACTION_GET_TARGET
2084  * \sa sswf::Action::ACTION_SET_TARGET2
2085  * \sa sswf::Action::ACTION_WITH
2086  * \sa <a href="../SWFalexref.html#action_set_target">SWF Alexis' Reference&mdash;Set Target</a>
2087  *
2088  * <hr>
2089  */
2090 
2091 
2092 /** \var sswf::Action::ACTION_GOTO_LABEL
2093  *
2094  * \brief Change the current frame in the playback system.
2095  *
2096  * The ACTION_GOTO_LABEL action requests the current sprite to
2097  * now play starting at the named frame. A frame is named using
2098  * the <a href="../SWFalexref.html#tag_framelabel">FrameLabel</a> tag.
2099  *
2100  * \sa sswf::Action::ACTION_GOTO_EXPRESSION
2101  * \sa sswf::Action::ACTION_GOTO_FRAME
2102  * \sa <a href="../SWFalexref.html#action_goto_label">SWF Alexis' Reference&mdash;Goto Label</a>
2103  *
2104  * <hr>
2105  */
2106 
2107 
2108 /** \var sswf::Action::ACTION_WAIT_FOR_FRAME2
2109  *
2110  * \brief Wait for the specified frame.
2111  *
2112  * The ACTION_WAIT_FOR_FRAME2 action pops one value from the stack.
2113  * This value represents the frame it has to wait for.
2114  *
2115  * The action otherwise has a new of action it has to skip in case
2116  * the frame was not reached yet.
2117  *
2118  * \sa sswf::Action::ACTION_WAIT_FOR_FRAME
2119  * \sa <a href="../SWFalexref.html#action_wait_for_frame_dynamic">SWF Alexis' Reference&mdash;Wait for Frame <i>(dynamic)</i></a>
2120  *
2121  * <hr>
2122  */
2123 
2124 
2125 /** \var sswf::Action::ACTION_DECLARE_FUNCTION2
2126  *
2127  * \brief Declare a function.
2128  *
2129  * The ACTION_DECLARE_FUNCTION2 action creates a user function with
2130  * capabilities as defined in SWF version 7 (i.e. up to 255 registers
2131  * to use instead of local variables and for temporary computations.)
2132  *
2133  * These functions can also pre-define a set of registers to the
2134  * internal variables such as _root, _global and this.
2135  *
2136  * A function declared as void is not expected to return anything
2137  * on the stack. Yet the caller will get an <b>undefined</b> value.
2138  * A function not declared as void is expected to return a valid
2139  * value with the use of the sswf::Action::ACTION_RETURN action.
2140  *
2141  * \sa sswf::Action::ACTION_DECLARE_FUNCTION
2142  * \sa sswf::Action::ACTION_CALL_FUNCTION
2143  * \sa sswf::Action::ACTION_RETURN
2144  * \sa sswf::Action::ACTION_CALL_METHOD
2145  * \sa sswf::Action::ACTION_NEW_METHOD
2146  * \sa sswf::Action::ACTION_NEW
2147  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
2148  *
2149  * <hr>
2150  */
2151 
2152 
2153 /** \var sswf::Action::ACTION_TRY
2154  *
2155  * \brief Create a try/catch/finaly block.
2156  *
2157  * The ACTION_TRY action is used to create a block of actions to execute safely.
2158  * This means, if an exception occurs, it is possible to catch it. The entire
2159  * block is composed of one try block, zero or more catch blocks and zero or one
2160  * finaly block. There must be one catch or one finaly block. The finaly block is
2161  * always executed. A catch block is executed only if the corresponding exception
2162  * is caught.
2163  *
2164  * Note that internally, there is only one catch. Your compiler may decided to
2165  * offer you a way to catch a specific type of exception by checking the type of
2166  * the exception (see sswf::Action::ACTION_INSTANCE_OF).
2167  *
2168  * \sa sswf::Action::ACTION_THROW
2169  * \sa sswf::Action::ACTION_INSTANCE_OF
2170  * \sa <a href="../SWFalexref.html#action_try">SWF Alexis' Reference&mdash;Try</a>
2171  *
2172  * <hr>
2173  */
2174 
2175 
2176 /** \var sswf::Action::ACTION_WITH
2177  *
2178  * \brief Create a \e With block.
2179  *
2180  * The ACTION_WITH action is a block of actions which react to object names by
2181  * first searching the name specified by the With block.
2182  *
2183  * For instance, if you have an object named MyObject and you want to access
2184  * the field NiceField in that object, you need to use the name:
2185  *
2186  * \code
2187  *  v = MyObject.NiceField
2188  * \endcode
2189  *
2190  * In general this is not a problem, but when many fields need to be accessed,
2191  * it is possible to optimize using a \e With block:
2192  *
2193  * \code
2194  *  With MyObject
2195  *    v = NiceField
2196  * \endcode
2197  *
2198  * In this last case, the variable NiceField is first searched as a variable
2199  * member in the MyObject object.
2200  *
2201  * Note that this technic works to read variable members and modify existing
2202  * variable members. If you need to create a new member, you will need to
2203  * specify the object name.
2204  *
2205  * \note
2206  * A \e With blocks can include another \e With block. Total there can be
2207  * 20 levels of objects defined in this way. Extraneous levels will be
2208  * ignored in V7 and earlier. It should be throwing an exception in V8
2209  * (not tested--according to Macromedia, it already throws in V7...)
2210  *
2211  * \bug
2212  * Note that can also create bugs since you may be accessing the member of
2213  * an object when you wanted to access a global variable instead.
2214  *
2215  * \sa sswf::Action::ACTION_GET_MEMBER
2216  * \sa sswf::Action::ACTION_SET_MEMBER
2217  * \sa sswf::Action::ACTION_GET_PROPERTY
2218  * \sa sswf::Action::ACTION_SET_PROPERTY
2219  * \sa sswf::Action::ACTION_GET_VARIABLE
2220  * \sa sswf::Action::ACTION_SET_VARIABLE
2221  * \sa sswf::Action::ACTION_SET_LOCAL_VARIABLE
2222  * \sa sswf::Action::ACTION_DELETE
2223  * \sa sswf::Action::ACTION_SET_TARGET
2224  * \sa sswf::Action::ACTION_SET_TARGET2
2225  * \sa <a href="../SWFalexref.html#action_with">SWF Alexis' Reference&mdash;With</a>
2226  *
2227  * <hr>
2228  */
2229 
2230 
2231 /** \var sswf::Action::ACTION_PUSH_DATA
2232  *
2233  * \brief Push constants and register data on the stack.
2234  *
2235  * The ACTION_PUSH_DATA action defines a block of data to push on the
2236  * stack.
2237  *
2238  * It is possible to push a constant string, boolean, integer,
2239  * floating point, null and the undefined value.
2240  *
2241  * Also, it is possible to specify a register number to load. This is
2242  * the only way you can load a register set with
2243  * sswf::Action::ACTION_STORE_REGISTER.
2244  *
2245  * To read a variable, you first push its name on the stack using
2246  * this action, then you use the sswf::Action::ACTION_GET_VARIABLE.
2247  *
2248  * \sa sswf::Action::ACTION_STORE_REGISTER
2249  * \sa sswf::Action::ACTION_GET_VARIABLE
2250  * \sa <a href="../SWFalexref.html#action_push_data">SWF Alexis' Reference&mdash;Push Data</a>
2251  *
2252  * <hr>
2253  */
2254 
2255 
2256 /** \var sswf::Action::ACTION_BRANCH_ALWAYS
2257  *
2258  * \brief Change the current execution pointer.
2259  *
2260  * The ACTION_BRANCH_ALWAYS action changes the execution pointer
2261  * by the specified number of bytes. The offset is a signed 16
2262  * bits value. This means the jump is limited to a 64Kb span.
2263  * Note that most ActionScripts should anyway be limited to about
2264  * 32Kb.
2265  *
2266  * \sa sswf::Action::ACTION_STORE_REGISTER
2267  * \sa sswf::Action::ACTION_GET_VARIABLE
2268  * \sa <a href="../SWFalexref.html#action_branch_always">SWF Alexis' Reference&mdash;Branch Always</a>
2269  *
2270  * <hr>
2271  */
2272 
2273 
2274 /** \var sswf::Action::ACTION_URL2
2275  *
2276  * \brief Load the specified URL.
2277  *
2278  * The ACTION_URL2 action loads the specified URL. This is
2279  * similar to ACTION_URL except that the URL itself is taken
2280  * from the stack and thus can dynamically be defined (i.e.
2281  * read from a variable, created using an expression, etc.)
2282  *
2283  * \sa sswf::Action::ACTION_URL
2284  * \sa <a href="../SWFalexref.html#action_get_url2">SWF Alexis' Reference&mdash;Get Url2</a>
2285  *
2286  * <hr>
2287  */
2288 
2289 
2290 /** \var sswf::Action::ACTION_DECLARE_FUNCTION
2291  *
2292  * \brief Declare a function.
2293  *
2294  * The ACTION_DECLARE_FUNCTION action creates a user function with
2295  * capabilities as defined in SWF version 5.
2296  *
2297  * These functions do not support pre-set registers or more than 4
2298  * registers.
2299  *
2300  * A function declared as void is not expected to return anything
2301  * on the stack. Yet the caller will get an <b>undefined</b> value.
2302  * A function not declared as void is expected to return a valid
2303  * value with the use of the sswf::Action::ACTION_RETURN action.
2304  *
2305  * \sa sswf::Action::ACTION_DECLARE_FUNCTION2
2306  * \sa sswf::Action::ACTION_CALL_FUNCTION
2307  * \sa sswf::Action::ACTION_RETURN
2308  * \sa sswf::Action::ACTION_CALL_METHOD
2309  * \sa sswf::Action::ACTION_NEW_METHOD
2310  * \sa sswf::Action::ACTION_NEW
2311  * \sa <a href="../SWFalexref.html#action_declare_function">SWF Alexis' Reference&mdash;Declare Function</a>
2312  *
2313  * <hr>
2314  */
2315 
2316 
2317 /** \var sswf::Action::ACTION_BRANCH_IF_TRUE
2318  *
2319  * \brief Change the current execution pointer if true.
2320  *
2321  * The ACTION_BRANCH_IF_TRUE action branches if the value it pops
2322  * from the stack represents true. A true number is a non-zero
2323  * number. A true string is a non-empty string. Other objects
2324  * may have a toBoolean() function which returns true or false
2325  * according to their type.
2326  *
2327  * The same limitations apply to this branch as for the
2328  * sswf::Action::ACTION_BRANCH_ALWAYS action.
2329  *
2330  * To branch when false, use the sswf::Action::ACTION_LOGICAL_NOT
2331  * right before this branch.
2332  *
2333  * \sa sswf::Action::ACTION_LOGICAL_NOT
2334  * \sa sswf::Action::ACTION_BRANCH_ALWAYS
2335  * \sa sswf::Action::ACTION_CALL_FUNCTION
2336  * \sa sswf::Action::ACTION_RETURN
2337  * \sa sswf::Action::ACTION_CALL_METHOD
2338  * \sa sswf::Action::ACTION_NEW_METHOD
2339  * \sa sswf::Action::ACTION_NEW
2340  * \sa <a href="../SWFalexref.html#action_branch_if_true">SWF Alexis' Reference&mdash;Branch If True</a>
2341  *
2342  * <hr>
2343  */
2344 
2345 
2346 /** \var sswf::Action::ACTION_CALL_FRAME
2347  *
2348  * \brief Call the actions defined in a frame.
2349  *
2350  * The ACTION_CALL_FRAME action is an early bird function definition.
2351  * You should use the sswf::Action::ACTION_DECLARE_FUNCTION and then
2352  * an sswf::Action::ACTION_CALL_FUNCTION instead. This frame calling
2353  * is nothing more than a function call, really. The name or number
2354  * if the frame to call is popped from the stack.
2355  *
2356  * \bug
2357  * This tag takes a size of 0 since it does not need any data and yet
2358  * it has a value over 127.
2359  *
2360  * \sa sswf::Action::ACTION_CALL_FUNCTION
2361  * \sa sswf::Action::ACTION_DECLARE_FUNCTION
2362  * \sa sswf::Action::ACTION_DECLARE_FUNCTION2
2363  * \sa sswf::Action::ACTION_RETURN
2364  * \sa <a href="../SWFalexref.html#action_call_frame">SWF Alexis' Reference&mdash;Call Frame</a>
2365  *
2366  * <hr>
2367  */
2368 
2369 
2370 /** \var sswf::Action::ACTION_GOTO_EXPRESSION
2371  *
2372  * \brief Move the display pointer to the specified frame.
2373  *
2374  * The ACTION_GOTO_EXPRESSION action pops a string or integer from
2375  * the stack and go to the frame.
2376  *
2377  * The action also specifies whether the movie should stop or play.
2378  *
2379  * \sa sswf::Action::ACTION_GOTO_FRAME
2380  * \sa sswf::Action::ACTION_GOTO_LABEL
2381  * \sa <a href="../SWFalexref.html#action_goto_expression">SWF Alexis' Reference&mdash;Goto Expression</a>
2382  *
2383  * <hr>
2384  */
2385 
2386 
2387 /** \var sswf::Action::ACTION_max
2388  *
2389  * \brief The very last valid action.
2390  *
2391  * The ACTION_max definition is used to clamp action numbers valid in an SWF movie.
2392  * Note that this is not the largest action number but instead the maximum action
2393  * number which can possibly be accepted at all time (until the action scheme changes!)
2394  * At this time this value is 255 which is inclusive.
2395  *
2396  * \sa sswf::Action::ACTION_min
2397  *
2398  * <hr>
2399  */
2400 
2401 
2402 
2403 
2404 
2405 
2406 
2407 
2408 
2409 
2410 /** \brief Initialize an action.
2411  *
2412  * The Action constructor is used to initialize an action object.
2413  *
2414  * Once an action was created, you cannot change its type. You cannot
2415  * copy an action with the copy constructor or the assignment operator.
2416  * You can however sswf::Action::Duplicate() an action.
2417  *
2418  * The constructor will determine the version of the action. This is
2419  * important to determine the minimum version necessary for that
2420  * action to function in the output SWF animation.
2421  *
2422  * At this time, you can add actions to any tags (but this may change!)
2423  * However, only a few set of tags really support actions:
2424  *
2425  *	\li Button
2426  *	\li DoAction
2427  *	\li DoInitAction
2428  */
Action(TagBase * tag,action_t action)2429 Action::Action(TagBase *tag, action_t action)
2430 	: f_action(action), f_tag(tag)
2431 {
2432 	//
2433 	// TODO: should we put FSCOMMAND2 in version 7 or 8?
2434 	//	 (it appeared in Flash Lite 1.1)
2435 	//
2436 	static int		action_to_version[256] = {
2437 		/* 0x00-0x0F */
2438 		 1,  0,  0,  0,  1,  1,  1,  1,  1,  1, -4,  4,  4,  4, -4, -4,
2439 		/* 0x10-0x1F */
2440 		 4,  4,  4, -4,  4,  4,  0,  4,  4,  0,  0,  0,  4,  4,  0,  0,
2441 		/* 0x20-0x2F */
2442 		 4,  4,  4,  4,  4,  4,  4,  4,  4, -4,  7,  7,  7,  8,  0,  0,
2443 		/* 0x30-0x3F */
2444 		 4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  5,  5,  5,  5,  5,  5,
2445 		/* 0x40-0x4F */
2446 		 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
2447 		/* 0x50-0x5F */
2448 		 5,  5,  5,  5,  6,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2449 		/* 0x60-0x6F */
2450 		 5,  5,  5,  5,  5,  5,  6,  6,  6,  7,  0,  0,  0,  0,  0,  0,
2451 		/* 0x70-0x7F */
2452 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2453 		/* 0x80-0x8F */
2454 		/*   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
2455 		 0,  1,  0,  1,  0,  0,  0,  5,  5,  6,  1,  1,  3,  4,  7,  7,
2456 		/* 0x90-0x9F */
2457 		 0,  0,  0,  0,  5,  0,  4,  0,  0,  4,  4,  5,  0,  4,  4,  4,
2458 		/* 0xA0-0xAF */
2459 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2460 		/* 0xB0-0xBF */
2461 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2462 		/* 0xC0-0xCF */
2463 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2464 		/* 0xD0-0xDF */
2465 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2466 		/* 0xE0-0xEF */
2467 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
2468 		/* 0xF0-0xFF */
2469 		 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
2470 	};
2471 
2472 	assert(f_tag != 0, "all actions need to have a tag attached to them");
2473 	if(f_tag == 0) {
2474 		throw ErrorManager::InternalErrorException();
2475 	}
2476 
2477 	if(action == ACTION_LABEL) {
2478 		f_min_version = 1;
2479 	}
2480 	else {
2481 		assert(action >= ACTION_min && action <= ACTION_max, "trying to save an invalid action number");
2482 
2483 		/* I'm not too sure why I wanted the -4, I think that's because these
2484 		 * instructions are supposedly different in V4.x and V5.x plugins but
2485 		 * that doesn't seem to really be the case. Anyway, we ignore it with
2486 		 * the use of the labs() call below.
2487 		 */
2488 		f_min_version = (unsigned char) labs(action_to_version[action]);
2489 
2490 		assert(f_min_version != 0, "unknown action #%d or undefined version -- please define the version in Action::Action()", action);
2491 	}
2492 }
2493 
2494 
2495 
2496 /** \fn sswf::Action::~Action(void)
2497  *
2498  * \brief Clean up the action.
2499  *
2500  * This function exists because the Action class defines virtual function. It
2501  * has otherwise nothing to do here.
2502  */
2503 
2504 
2505 #if DEBUG
Action(const Action & action)2506 Action::Action(const Action& action)
2507 	 : f_action(action.f_action)	// required by Visual C++ because f_action is constant
2508 {
2509 }
operator =(const Action & action)2510 Action& Action::operator = (const Action& action)
2511 {
2512 	return *this;
2513 }
2514 #endif
2515 
2516 
2517 /** \brief Retrieve the largest register number used.
2518  *
2519  * This function goes through the list of actions defined
2520  * in the Vectors array and determines what the largest
2521  * register used by any of the instructions is in that
2522  * array.
2523  *
2524  * This is necessary to determine the largest used register
2525  * in a version 7 function (See
2526  * <a href="../SWFalexref.html#action_declare_function2">Declare Function (V7)</a>.)
2527  * Before version 7, there could only be 4 registers and you
2528  * never had to determine which ones were used.
2529  *
2530  * \param[in] list A Vectors of actions
2531  *
2532  * \return The largest register number or -1 if the list of
2533  * actions does not use any register.
2534  *
2535  * \sa sswf::Action::GetMaxRegister
2536  */
GetMaximumRegister(const Vectors & list)2537 int Action::GetMaximumRegister(const Vectors& list)
2538 {
2539 	Action		*a;
2540 	int		idx, max, r, register_number;
2541 	Vectors		*sub_list;
2542 
2543 	register_number = -1;
2544 	max = list.Count();
2545 	for(idx = 0; idx < max; idx++) {
2546 		a = dynamic_cast<Action *>(list.Get(idx));
2547 		if(a->f_action >= 128) {
2548 			sub_list = a->SubList();
2549 			if(sub_list != 0) {
2550 				// Function, With and others are nested type
2551 				// of entries and they may include higher
2552 				// action versions
2553 				r = GetMaximumRegister(*sub_list);
2554 				if(r > register_number) {
2555 					register_number = r;
2556 				}
2557 			}
2558 		}
2559 		r = a->GetMaxRegister();
2560 		if(r > register_number) {
2561 			register_number = r;
2562 		}
2563 	}
2564 
2565 	return register_number;
2566 }
2567 
2568 
2569 /** \brief Retrive the minimum version required to use this list of actions.
2570  *
2571  * This function sweeps through all the actions found in an
2572  * array and determines the minimum SWF version required for the
2573  * script to run.
2574  *
2575  * For instance, the 'New Method' action requires at least a version 5
2576  * Flash Player to work.
2577  */
MinimumListVersion(const Vectors & list)2578 int Action::MinimumListVersion(const Vectors& list)
2579 {
2580 	Action		*a;
2581 	int		idx, max, v, version;
2582 	Vectors		*sub_list;
2583 
2584 	version = 1;
2585 	max = list.Count();
2586 	for(idx = 0; idx < max; idx++) {
2587 		a = dynamic_cast<Action *>(list.Get(idx));
2588 		if(a->f_action >= 128) {
2589 			sub_list = a->SubList();
2590 			if(sub_list != 0) {
2591 				// Function, With and others are nested type
2592 				// of entries and they may include higher
2593 				// action versions
2594 				v = MinimumListVersion(*sub_list);
2595 				if(v > version) {
2596 					version = v;
2597 				}
2598 			}
2599 		}
2600 		// Now Version() is a virtual function since
2601 		// ActionTry has to check three sub-lists
2602 		v = a->Version();
2603 		if(v > version) {
2604 			version = v;
2605 		}
2606 	}
2607 
2608 	return version;
2609 }
2610 
2611 
2612 /** \brief Save a list of actions in a Data buffer.
2613  *
2614  * This function is used to save a list of actions in a Data buffer
2615  * for output in a Flash animation.
2616  *
2617  * \param[in] list	The list of actions to be saved, it can be NULL
2618  * \param[in] data	The Data buffer where the result is saved
2619  * \param[in] extra	Another list of actions saved after the 'list' of actions, usually is NULL
2620  *
2621  * \return 0 when no error occured, non-zero otherwise
2622  */
SaveList(const Vectors * list,Data & data,const Vectors * extra)2623 ErrorManager::error_code_t Action::SaveList(const Vectors *list, Data& data, const Vectors *extra)
2624 {
2625 	Action				*a;
2626 	int				idx, max;
2627 	const Vectors			*saved, *lst;
2628 	bool				has_end;
2629 	ErrorManager::error_code_t	ec;
2630 
2631 	saved = extra;
2632 	ec = ErrorManager::ERROR_CODE_NONE;
2633 
2634 	has_end = false;
2635 	lst = list;
2636 	while(lst != 0) {
2637 		max = lst->Count();
2638 		for(idx = 0; idx < max; idx++) {
2639 			if(has_end) {
2640 				ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_ENDED_ACTION_SCRIPT, "action END found before the end of your action script."));
2641 			}
2642 
2643 			a = dynamic_cast<Action *>(lst->Get(idx));
2644 
2645 //printf("Action[%d] %p: id %d, tag = %p\n", idx, a, a->f_action, a->f_tag);
2646 
2647 			// the offset is necessary to compute offsets of branch instructions
2648 			// and also the With operator
2649 			a->f_offset = data.ByteSize();
2650 
2651 			if(a->f_action != ACTION_LABEL) {
2652 				// there is nothing to save in a label
2653 				ec = ErrorManager::KeepFirst(ec, a->Save(data));
2654 				if(a->f_action == ACTION_END) {
2655 					has_end = true;
2656 				}
2657 			}
2658 		}
2659 		lst = extra;
2660 		extra = 0;
2661 	}
2662 	if(!has_end) {
2663 		data.PutByte(Action::ACTION_END);		// end the list of actions
2664 	}
2665 
2666 
2667 	/* now we do the 2nd pass! */
2668 	lst = list;
2669 	while(lst != 0) {
2670 		max = lst->Count();
2671 		for(idx = 0; idx < max; idx++) {
2672 			a = dynamic_cast<Action *>(lst->Get(idx));
2673 			ec = ErrorManager::KeepFirst(ec, a->Save2ndPass(*lst, data));
2674 		}
2675 		lst = saved;
2676 		saved = 0;
2677 	}
2678 
2679 	return ec;
2680 }
2681 
2682 
2683 /** \brief Save the action in a Data buffer.
2684  *
2685  * This function saves 'this' Action in the specified Data buffer.
2686  *
2687  * Simple actions have their byte code saved and the function returns.
2688  *
2689  * Composed actions have their SaveData() virtual function called.
2690  *
2691  * Also, actions which can include sub-ations (such as a Function or
2692  * a With action) get their SubList() saved as well.
2693  *
2694  * The result in an SWF animation just looks like a long list of
2695  * byte codes. The reality is that this technique generates blocks
2696  * of actions.
2697  *
2698  * \param[in] data The data buffer where the actions need to be saved
2699  */
Save(Data & data)2700 ErrorManager::error_code_t Action::Save(Data& data)
2701 {
2702 	Data				sub_data, nested_data;
2703 	Vectors				*sub_list;
2704 	ErrorManager::error_code_t	ec;
2705 
2706 	ec = ErrorManager::ERROR_CODE_NONE;
2707 
2708 	data.PutByte(f_action);
2709 
2710 	if(f_action >= 128) {
2711 		sub_list = SubList();
2712 		if(sub_list != 0) {	// Function & With are nested type of entries
2713 			ec = SaveList(sub_list, nested_data);
2714 
2715 			// get rid of the ACTION_END
2716 			nested_data.SetSize(nested_data.GetSize() - CHAR_BIT);
2717 
2718 			if(nested_data.ByteSize() >= USHRT_MAX) {
2719 				ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_ACTION_OVERFLOW, "too many nested instructions; length overflow."));
2720 			}
2721 		}
2722 
2723 		ec = ErrorManager::KeepFirst(ec, SaveData(sub_data, nested_data));
2724 		data.PutShort((short) sub_data.ByteSize());
2725 		data.Append(sub_data);
2726 
2727 		if(nested_data.ByteSize() > 0) {
2728 			data.Append(nested_data);
2729 		}
2730 	}
2731 
2732 	return ec;
2733 }
2734 
2735 
2736 /** \brief Query for the Vectors of sub-actions.
2737  *
2738  * By default, this function returns a NULL pointer. Actions which support
2739  * sub-actions (such as a ActionFunction or ActionWith) will return their
2740  * array of sub-actions.
2741  *
2742  * return A pointer to a list of actions or NULL
2743  */
SubList(void)2744 Vectors *Action::SubList(void)
2745 {
2746 	return 0;
2747 }
2748 
2749 
2750 /** \brief Save a string in a way compatible to the actions.
2751  *
2752  * This functions saves a string in the Data buffer in a way that
2753  * the SWF actions can read it.
2754  *
2755  * The function simply calls the SaveString() of the corresponding tag
2756  * thus converting the string as required for a version 5 or earlier
2757  * movie. Strings are otherwise expected to be in UTF-8.
2758  *
2759  * \param[in] data The Data buffer where the string is to be saved
2760  * \param[in] string The string to save in the Data buffer
2761  *
2762  * \return The size of the string not including the null terminator,
2763  * 		or -1 if the function failed
2764  */
SaveString(Data & data,const char * string)2765 ErrorManager::error_code_t Action::SaveString(Data& data, const char *string)
2766 {
2767 	return f_tag->SaveString(data, string);
2768 }
2769 
2770 
2771 /** \brief Save extraneous data.
2772  *
2773  * All the actions having a byte code larger than 127 include extra-data.
2774  *
2775  * These actions need to overload this function and save these extraneous data
2776  * when requested to do so.
2777  *
2778  * The default function asserts.
2779  *
2780  * \note
2781  * This function is not a pure virtual because actions with a byte code of 0 to
2782  * 127 do not need to be derived.
2783  *
2784  * \param[in] data The Data buffer where the extraneous information is to be saved
2785  * \param[in] nested_data When the action supports sub-actions, the Data buffer
2786  * 		where these sub-actions have been saved
2787  */
SaveData(Data & data,Data & nested_data)2788 ErrorManager::error_code_t Action::SaveData(Data& data, Data& nested_data)
2789 {
2790 	assert(0, "the action 0x%02X which has an action number of 128 or more needs to overload the SaveData() function", f_action);
2791 	OnError(ErrorManager::ERROR_CODE_INTERNAL_ERROR, "the action 0x%02X which has an action number of 128 or more needs to overload the SaveData() function", f_action);
2792 	return ErrorManager::ERROR_CODE_INTERNAL_ERROR;
2793 }
2794 
2795 
2796 /** \brief Last chance for an action to save itself right.
2797  *
2798  * This function is called after all the actions have been
2799  * saved in a list of actions (i.e. sswf::Action::SaveList()
2800  * calls sswf::Action::Save() on all the actions of a list
2801  * and then sswf::Action::Save2ndPass().)
2802  *
2803  * At this time, the only action which requires this second
2804  * pass is the sswf::ActionBranch. It will search for a
2805  * label and save the proper offset from itself to the
2806  * label.
2807  *
2808  * \bug
2809  * The Data buffer should not be grown by the Save2ndPass().
2810  * Instead it should be tweaked (i.e. some bytes overwritten
2811  * as required.)
2812  *
2813  * \param[in] list The list of all the actions being saved
2814  * \param[in] data The Data buffer where the actions were saved
2815  */
Save2ndPass(const Vectors & list,Data & data)2816 ErrorManager::error_code_t Action::Save2ndPass(const Vectors& list, Data& data)
2817 {
2818 	/* most actions don't require a 2nd pass */
2819 	return ErrorManager::ERROR_CODE_NONE;
2820 }
2821 
2822 
2823 /** \brief Create a clone of 'this' Action.
2824  *
2825  * This function creates a clone of 'this' Action.
2826  *
2827  * The function knows how to create a new Action which is a clone of this
2828  * Action.
2829  *
2830  * Actions with extraneous data will overwrite this function and
2831  * duplicate their extraneous data as required.
2832  *
2833  * \note
2834  * This function needs to be used instead of the copy operator
2835  * since depending on the type of action, the result will be
2836  * different.
2837  *
2838  * For example, if the action to duplicate is an ActionBranch
2839  * you would need to do a new ActionBranch and not a new Action.
2840  * The Duplicate function takes care of that for you.
2841  *
2842  * \return A new action pointer
2843  */
Duplicate(void) const2844 Action *Action::Duplicate(void) const
2845 {
2846 	// errors are checked in the object which attach this action to its
2847 	// memory manager
2848 	return new Action(f_tag, f_action);
2849 }
2850 
2851 
2852 /** \fn unsigned long sswf::Action::Offset(void) const
2853  *
2854  * \brief Retrieve the offset position of this action.
2855  *
2856  * The position of an action can be used to compute different
2857  * offsets such as the ActionBranch offset to get the current
2858  * ActionScript pointer to a specific position in the
2859  * script.
2860  *
2861  * \return The offset in bytes of this action
2862  */
2863 
2864 
2865 /** \fn virtual unsigned char sswf::Action::Version(void) const
2866  *
2867  * \brief Retrieve the minimum version required for this action.
2868  *
2869  * The minimum version required for any action is defined on
2870  * creation of the action. The sswf::Action::Action(TagBase *tag, action_t action)
2871  * function has a table which tells it the minimum SWF version
2872  * required for such and such action to work thus you can query
2873  * this value at any time.
2874  *
2875  * \return The minimum version required for this action to work
2876  */
2877 
2878 
2879 
2880 
2881 /** \brief Send an error to the error manager.
2882  *
2883  * This function calls the
2884  * sswf::ErrorManager::OnError(error_code_t errcode, const char *message, va_list ap)
2885  * function whenever possible.
2886  *
2887  * The function will not be called if the action was not given a valid
2888  * tag object pointer on creation.
2889  *
2890  * \param[in] errcode	The error code that this call represents
2891  * \param[in] message	The message of this error
2892  * \param[in] ...	The parameters to the message
2893  *
2894  * \return Usually the input errcode parameter
2895  */
OnError(ErrorManager::error_code_t errcode,const char * message,...) const2896 ErrorManager::error_code_t Action::OnError(ErrorManager::error_code_t errcode, const char *message, ...) const
2897 {
2898 	va_list ap;
2899 	va_start(ap, message);
2900 	ErrorManager::error_code_t ec = f_tag->OnError(errcode, message, ap);
2901 	va_end(ap);
2902 
2903 	return ec;
2904 }
2905 
2906 
2907 
2908 /** \brief Search for a label within a list of actions.
2909  *
2910  * A special SSWF Action is the Label Action. The label action
2911  * is NOT saved in the output SWF animation files. However, it is
2912  * required to allow branches to jump from one place to another
2913  * without the burden of using just offsets to know where the
2914  * label would otherwise be.
2915  *
2916  * The ActionBranch will search for labels.
2917  *
2918  * \note
2919  * The SSWF implementation never allowed a branch to jump to a
2920  * label defined outside of the block of actions where it (the
2921  * branch) is defined. This conforms to version 6 of SWF.
2922  *
2923  * \param[in] list The list of actions to be searched
2924  * \param[in] label The label to be searched
2925  *
2926  * \return A pointer to an ActionLabel or NULL when not found
2927  */
FindLabel(const Vectors & list,const char * label)2928 ActionLabel *Action::FindLabel(const Vectors& list, const char *label)
2929 {
2930 	Action		*a;
2931 	ActionLabel	*l;
2932 	int		idx;
2933 
2934 	if(label == 0) {
2935 		return 0;
2936 	}
2937 
2938 	idx = list.Count();
2939 	while(idx > 0) {
2940 		idx--;
2941 		a = dynamic_cast<Action *>(list.Get(idx));
2942 		if(a->f_action == ACTION_LABEL) {
2943 			l = dynamic_cast<ActionLabel *>(a);
2944 			if(l->GetLabel() != 0) if(strcasecmp(l->GetLabel(), label) == 0) {
2945 				return l;
2946 			}
2947 		}
2948 	}
2949 
2950 	return 0;
2951 }
2952 
2953 
2954 
2955 ////////////////////////////// Action BRANCH
2956 
2957 /** \class sswf::ActionBranch
2958  *
2959  * \brief An action to change the execution pointer.
2960  *
2961  * The ActionBranch class is used to create a branch or jump from one
2962  * place to another in your ActionScript. Depending on the type of
2963  * Branch that you define, it will always be taken, or it will be
2964  * taken only when the current value on the stack is true.
2965  *
2966  * By default, if you do not specify the type of branch, it will
2967  * always branch.
2968  *
2969  * \sa <a href="../SWFalexref.html#action_branch_always">SWF Alexis' Reference&mdash;Branch Always</a>
2970  * \sa <a href="../SWFalexref.html#action_branch_if_true">SWF Alexis' Reference&mdash;Branch If True</a>
2971  */
2972 
2973 /** \brief Initialize an branch action.
2974  *
2975  * This function initializes an ActionBranch object. You can specify which
2976  * action whether you want the branch to be conditional or not.
2977  *
2978  * \param[in] tag The tag in which this action is being created
2979  * \param[in] action The branch to be created, one of: ACTION_BRANCH_ALWAYS
2980  *		or ACTION_BRANCH_IF_TRUE
2981  */
ActionBranch(TagBase * tag,action_t action)2982 ActionBranch::ActionBranch(TagBase *tag, action_t action)
2983 	: Action(tag, action)
2984 {
2985 	assert(action == ACTION_BRANCH_ALWAYS || action == ACTION_BRANCH_IF_TRUE, "The ActionBranch expects ACTION_BRANCH_ALWAYS or ACTION_BRANCH_IF_TRUE.");
2986 
2987 	if(action != ACTION_BRANCH_ALWAYS && action != ACTION_BRANCH_IF_TRUE) {
2988 		throw ErrorManager::InternalErrorException();
2989 	}
2990 
2991 	f_label = 0;
2992 }
2993 
2994 
2995 /** \brief Set the label this branch needs to branch to.
2996  *
2997  * This function defines the label this branch needs to branch to. This
2998  * label will be searched in the same block the ActionBranch is inserted
2999  * in. (note that their is no 'if' block in byte code ActionScript.)
3000  *
3001  * There should be an ActionLabel for each different label defined in
3002  * ActionBranch objects.
3003  *
3004  * \param[in] label The label to branch to
3005  */
SetLabel(const char * label)3006 void ActionBranch::SetLabel(const char *label)
3007 {
3008 	MemFree(f_label);
3009 	f_label = StrDup(label);
3010 }
3011 
3012 
3013 
3014 /** \brief Duplicate an ActionBranch object.
3015  *
3016  * This function creates a new ActionBranch and copies the label from this
3017  * ActionBranch to the new one.
3018  *
3019  * \return The ActionBranch copy
3020  */
Duplicate(void) const3021 Action *ActionBranch::Duplicate(void) const
3022 {
3023 	ActionBranch		*a;
3024 
3025 	a = new ActionBranch(Tag(), f_action);
3026 	if(f_label != 0) {
3027 		a->SetLabel(f_label);
3028 	}
3029 
3030 	return a;
3031 }
3032 
3033 
3034 /** \brief Save a branch offset placeholder.
3035  *
3036  * This function saves 2 bytes which represent the offset
3037  * where the branch needs to go.
3038  *
3039  * Since at this time we cannot be sure of the exact offset
3040  * (forward offset are not yet known), we just save an offset
3041  * of zero. The Save2ndPass() will save the real offset.
3042  *
3043  * \param[in] data The Data buffer where the offset is saved
3044  * \param[in] nested_data Branches have no nested data
3045  */
SaveData(Data & data,Data & nested_data)3046 ErrorManager::error_code_t ActionBranch::SaveData(Data& data, Data& nested_data)
3047 {
3048 	data.PutShort(0);		// unknown offset yet (we do it on the 2nd pass)
3049 	return ErrorManager::ERROR_CODE_NONE;
3050 }
3051 
3052 
3053 /** \brief Save the real branch offset.
3054  *
3055  * This function searches the whole list of actions for the label
3056  * specified in the branch. If the label cannot be found, this is an
3057  * error and the function fails.
3058  *
3059  * When the label is found, the offset to that label is read and
3060  * used to compute the offset we need to save in the branch byte codes.
3061  *
3062  * If the branch cannot be generated because the offset is out of bounds
3063  * (i.e. smaller than 0x8000 or larger than 0x7FFF) then an error is
3064  * generated and the function fails.
3065  *
3066  * \param[in] list The list of actions where the label is searched
3067  * \param[in] data The Data buffer where the resulting offset is saved
3068  */
Save2ndPass(const Vectors & list,Data & data)3069 ErrorManager::error_code_t ActionBranch::Save2ndPass(const Vectors& list, Data& data)
3070 {
3071 	ActionLabel	*l;
3072 	long		offset;
3073 
3074 	// look for that label...
3075 	l = FindLabel(list, f_label);
3076 	if(l == 0) {
3077 		return OnError(ErrorManager::ERROR_CODE_LABEL_NOT_FOUND, "could not find label \"%s\" in the list of actions.", f_label);
3078 	}
3079 
3080 	// NOTE: the result is a signed value!
3081 	offset = l->Offset() - f_offset - 1 - 2 - 2;
3082 	data.OverwriteShort(f_offset + 1 + 2, (short) offset);
3083 
3084 	if(offset < (short) 0x8000 || offset > (short) 0x7FFF) {
3085 		return OnError(ErrorManager::ERROR_CODE_LABEL_OVERFLOW, "label \"%s\" is out of bounds.", f_label);
3086 	}
3087 
3088 	return ErrorManager::ERROR_CODE_NONE;
3089 }
3090 
3091 
3092 /** \fn virtual int sswf::Action::GetMaxRegister(void) const
3093  *
3094  * \brief Retrieve the largest register used by this action.
3095  *
3096  * This function goes through all the list and sub-lists of
3097  * actions and retrieve the largest register currently in use.
3098  *
3099  * \note
3100  * Objects with sub-lists accessible with the sswf::Action::SubList(void)
3101  * function do not need to implement this GetMaxRegister() function.
3102  *
3103  * \sa sswf::Action::GetMaximumRegister(const Vectors& list)
3104  */
3105 
3106 
3107 /** \fn TagBase *sswf::Action::Tag(void) const
3108  *
3109  * \brief Get the tag in which this action resides.
3110  *
3111  * This function returns the pointer to the tag this action
3112  * was created in (see the constructor!).
3113  *
3114  * \return The pointer of the tag this action was created in
3115  *
3116  * \sa sswf::Action::Action(TagBase *tag, action_t action);
3117  */
3118 
3119 
3120 /** \var const action_t sswf::Action::f_action;
3121  *
3122  * \brief This action code (ACTION_...).
3123  *
3124  * This variable member holds the action code of this action.
3125  * It is currently read-only since changing it would require
3126  * changes to the minimum version and size information.
3127  */
3128 
3129 /** \var unsigned long sswf::Action::f_offset;
3130  *
3131  * \brief The byte position of this action in its list.
3132  *
3133  * This offset defines the position at which the action was
3134  * inserted in the Data buffer while in the sswf::Action::Save() function.
3135  *
3136  * \bug
3137  * This offset is not defined until the sswf::Action::Save() function reaches
3138  * this specific action in its list of actions.
3139  * This is why there is a sswf::Action::Save2ndPass() so the ActionBranch
3140  * action can properly calculate forward references.
3141  */
3142 
3143 
3144 
3145 
3146 
3147 
3148 
3149 ////////////////////////////// Action CALL FRAME
3150 
3151 /** \class sswf::ActionCallFrame
3152  *
3153  * \brief Change the SWF pointer to the specified frame.
3154  *
3155  * This tag was improperly given a number larger than 127. It actually
3156  * uses no immediate data, instead it uses the current number on the
3157  * stack.
3158  *
3159  * None-the-less, I had to create a specific Action for this tag
3160  * in order to overload the SaveData() function which would otherwise
3161  * generate an assert.
3162  *
3163  * \sa <a href="../SWFalexref.html#action_call_frame">SWF Alexis' Reference&mdash;Call Frame</a>
3164  */
ActionCallFrame(TagBase * tag)3165 ActionCallFrame::ActionCallFrame(TagBase *tag)
3166 	: Action(tag, ACTION_CALL_FRAME)
3167 {
3168 }
3169 
3170 
3171 /** \brief A do nothing function.
3172  *
3173  * This function is used to prevent the default SaveData() from generating
3174  * an assert. This is an error from Macromedia which should have created
3175  * a code byte smaller than 128 for this action and did not.
3176  *
3177  * This function just returns right away.
3178  *
3179  * \param[in] data The Data buffer to save extraneous data (i.e. ignored)
3180  * \param[in] nested_data The pre-saved sub-actions (i.e. ignored)
3181  */
SaveData(Data & data,Data & nested_data)3182 ErrorManager::error_code_t ActionCallFrame::SaveData(Data& data, Data& nested_data)
3183 {
3184 	// it is necessary to have a SaveData() function
3185 	// but there isn't any need for us to have anything
3186 	// there since the call frame data is always empty
3187 	return ErrorManager::ERROR_CODE_NONE;
3188 }
3189 
3190 
3191 ////////////////////////////// Action DICTIONARY
3192 
3193 /** \class sswf::ActionDictionary
3194  *
3195  * \brief Create a dictionary action.
3196  *
3197  * This action holds pre-defined string constants. These can later be retrieved
3198  * using a query in a ActionPushData action.
3199  *
3200  * Note that too small a string will not benefit from being saved in a dictionary.
3201  * Similarly, if the dictionary is used for only one string, it usually won't help.
3202  *
3203  * Note that there should be only one single dictionary per Action list. The
3204  * dictionary is visible through all the different blocks/level that an Action
3205  * list represents. The consequences of saving more than one ActionDictionary
3206  * in the same list are undefined.
3207  *
3208  * \sa <a href="../SWFalexref.html#action_declare_dictionary">SWF Alexis' Reference&mdash;Declare Dictionary</a>
3209  */
3210 
3211 /** \brief Initializes the dictionary.
3212  *
3213  * Create an empty tag of type ACTION_DECLARE_DICTIONARY.
3214  */
ActionDictionary(TagBase * tag)3215 ActionDictionary::ActionDictionary(TagBase *tag)
3216 	: Action(tag, ACTION_DECLARE_DICTIONARY)
3217 {
3218 }
3219 
3220 
3221 /** \brief Add a string to a dictionary.
3222  *
3223  * This function adds the specified string to the dictionary.
3224  *
3225  * There is no limit to the string or the number of string one
3226  * can add to a dictionary, except for the total size of an
3227  * action block.
3228  *
3229  * \param[in] string The string to append
3230  */
AddString(const char * string)3231 void ActionDictionary::AddString(const char *string)
3232 {
3233 	string_t	*str;
3234 
3235 	str = new string_t;
3236 	MemAttach(str, sizeof(string_t), "ActionDictionary::AddString() -- adding a string to the dictionary");
3237 	str->f_string = StrDup(string);
3238 	f_strings.Set(-1, str);
3239 }
3240 
3241 
3242 
3243 /** \brief Duplicate a dictionary.
3244  *
3245  * This function creates a new ActionDictionary and then copy all the
3246  * strings from 'this' dictionary to the new dictionary.
3247  *
3248  * \return A pointer to the new dictionary.
3249  */
Duplicate(void) const3250 Action *ActionDictionary::Duplicate(void) const
3251 {
3252 	string_t		*str;
3253 	ActionDictionary	*d;
3254 	int			max, idx;
3255 
3256 	d = new ActionDictionary(Tag());
3257 	max = f_strings.Count();
3258 	for(idx = 0; idx < max; idx++) {
3259 		str = dynamic_cast<string_t *>(f_strings.Get(idx));
3260 		d->AddString(str->f_string);
3261 	}
3262 
3263 	return d;
3264 }
3265 
3266 
3267 
3268 /** \brief Save the dictionary strings.
3269  *
3270  * This function is used to save the dictionary strings
3271  * in the specified Data buffer.
3272  *
3273  * \param[in] data The Data buffer where the strings are to be saved
3274  * \param[in] nested_data The sub-actions of the dictionary (i.e. none)
3275  */
SaveData(Data & data,Data & nested_data)3276 ErrorManager::error_code_t ActionDictionary::SaveData(Data& data, Data& nested_data)
3277 {
3278 	string_t			*str;
3279 	int				max, idx;
3280 	ErrorManager::error_code_t	ec;
3281 
3282 	max = f_strings.Count();
3283 	if(max > 256) {
3284 		// we can't save more than 256 strings -- we should
3285 		// warn the user somehow that there is something wrong
3286 		// here!
3287 		max = 256;
3288 	}
3289 	data.PutShort(max);
3290 	for(idx = 0; idx < max; idx++) {
3291 		str = dynamic_cast<string_t *>(f_strings.Get(idx));
3292 		ec = SaveString(data, str->f_string);
3293 		if(ec != ErrorManager::ERROR_CODE_NONE) {
3294 			return ec;
3295 		}
3296 	}
3297 
3298 	return ErrorManager::ERROR_CODE_NONE;
3299 }
3300 
3301 
3302 
3303 
3304 ////////////////////////////// Action FUNCTION
3305 
3306 /** \class sswf::ActionFunction
3307  *
3308  * \brief The action to hold an ActionScript function.
3309  *
3310  * This class is used to create an ActionFunction, meaning a
3311  * function to be called from within an ActionScript.
3312  *
3313  * \sa <a href="../SWFalexref.html#action_declare_function">SWF Alexis' Reference&mdash;Declare Function</a>
3314  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3315  */
3316 
3317 
3318 /** \enum sswf::ActionFunction::action_function_t
3319  *
3320  * \brief List the flags supported by the DeclareFunction2 tag
3321  *
3322  * These flags can be used to very much optimize ActionScripts.
3323  *
3324  * Each special variable and arguments to functions can be saved
3325  * in registers for fast retrieval.
3326  *
3327  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3328  *
3329  * <hr>
3330  */
3331 
3332 
3333 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_THIS
3334  *
3335  * \brief Make 'this' variable ready
3336  *
3337  * The ACTION_FUNCTION_LOAD_THIS loads a register with the value of
3338  * 'this'. The register depends on what is loaded before.
3339  *
3340  * \sa sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_THIS
3341  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3342  *
3343  * <hr>
3344  */
3345 
3346 
3347 /** \var sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_THIS
3348  *
3349  * \brief Don't create the 'this' variable
3350  *
3351  * The ACTION_FUNCTION_SUPPRESS_THIS can be used so 'this' variable
3352  * is not even created. This can speed things up.
3353  *
3354  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_THIS
3355  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3356  *
3357  * <hr>
3358  */
3359 
3360 
3361 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_ARGUMENTS
3362  *
3363  * \brief Load arguments in registers
3364  *
3365  * The ACTION_FUNCTION_LOAD_ARGUMENTS loads a register with the value of
3366  * each of the arguments specified when calling this function. The
3367  * registers depend on what is loaded before.
3368  *
3369  * \sa sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_ARGUMENTS
3370  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3371  *
3372  * <hr>
3373  */
3374 
3375 
3376 /** \var sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_ARGUMENTS
3377  *
3378  * \brief Ignore all arguments
3379  *
3380  * The ACTION_FUNCTION_SUPPRESS_ARGUMENTS ensures that the ActionScript
3381  * interpreter does not spend any time saving the arguments. This useful
3382  * for virtual functions support.
3383  *
3384  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_ARGUMENTS
3385  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3386  *
3387  * <hr>
3388  */
3389 
3390 
3391 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_SUPER
3392  *
3393  * \brief Make the 'super' variable ready
3394  *
3395  * The ACTION_FUNCTION_LOAD_SUPER loads a register with the value of
3396  * 'super'. The register depends on what is loaded before.
3397  *
3398  * \sa sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_SUPER
3399  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3400  *
3401  * <hr>
3402  */
3403 
3404 
3405 /** \var sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_SUPER
3406  *
3407  * \brief Don't bother creating the 'super' variable
3408  *
3409  * The ACTION_FUNCTION_SUPPRESS_SUPER asks the ActionScript interpreter
3410  * to not bother creating the super variable. This can speed things
3411  * up.
3412  *
3413  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_SUPER
3414  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3415  *
3416  * <hr>
3417  */
3418 
3419 
3420 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_ROOT
3421  *
3422  * \brief Make the 'root' variable ready
3423  *
3424  * The ACTION_FUNCTION_LOAD_ROOT loads a register with the value of
3425  * 'root'. The register depends on what is loaded before.
3426  *
3427  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_THIS
3428  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_PARENT
3429  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_GLOBAL
3430  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3431  *
3432  * <hr>
3433  */
3434 
3435 
3436 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_PARENT
3437 		ACTION_FUNCTION_LOAD_PARENT        = 0x0080,
3438 		ACTION_FUNCTION_LOAD_GLOBAL        = 0x0100
3439  *
3440  * \brief Make the 'parent' variable ready
3441  *
3442  * The ACTION_FUNCTION_LOAD_PARENT loads a register with the value of
3443  * 'parent'. The register depends on what is loaded before.
3444  *
3445  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_THIS
3446  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_ROOT
3447  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_GLOBAL
3448  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3449  *
3450  * <hr>
3451  */
3452 
3453 
3454 /** \var sswf::ActionFunction::ACTION_FUNCTION_LOAD_GLOBAL
3455  *
3456  * \brief Make the 'global' variable ready
3457  *
3458  * The ACTION_FUNCTION_LOAD_THIS loads a register with the value of
3459  * 'global'. The register depends on what is loaded before.
3460  *
3461  * \sa sswf::ActionFunction::ACTION_FUNCTION_SUPPRESS_THIS
3462  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_ROOT
3463  * \sa sswf::ActionFunction::ACTION_FUNCTION_LOAD_PARENT
3464  * \sa <a href="../SWFalexref.html#action_declare_function2">SWF Alexis' Reference&mdash;Declare Function (V7)</a>
3465  */
3466 
3467 
3468 /** \enum sswf::ActionFunction::as_set_prop_flags_t
3469  *
3470  * \brief List of flags available to call the ASSetPropFlags() function
3471  *
3472  * This undocumented function is used to change the properties of an
3473  * object variable member or function member. The properties are defined
3474  * by three flags:
3475  *
3476  * \li Is hidden&mdash;whether the member can be seen by an enumeration action
3477  * \li Can delete&mdash;whether the member can be removed
3478  * \li Can overwrite&mdash;whether the member can be modified (this does not
3479  * prevent the content of a variable member from being modified)
3480  *
3481  * \sa sswf::ActionFunction::PROP_FLAG_IS_HIDDEN
3482  * \sa sswf::ActionFunction::PROP_FLAG_CAN_DELETE
3483  * \sa sswf::ActionFunction::PROP_FLAG_CAN_OVERWRITE
3484  *
3485  * <hr>
3486  */
3487 
3488 
3489 /** \var sswf::ActionFunction::PROP_FLAG_IS_HIDDEN
3490  *
3491  * \brief Prevent the enumeration actions from showing this member
3492  *
3493  * The PROP_FLAG_IS_HIDDEN flag, if set, prevents the enumeration functions
3494  * from listing to corresponding member.
3495  *
3496  * \sa sswf::ActionFunction::PROP_FLAG_CAN_DELETE
3497  * \sa sswf::ActionFunction::PROP_FLAG_CAN_OVERWRITE
3498  *
3499  * <hr>
3500  */
3501 
3502 
3503 /** \var sswf::ActionFunction::PROP_FLAG_CAN_DELETE
3504  *
3505  * \brief Whether a member can be removed from an object
3506  *
3507  * The PROP_FLAG_CAN_DELETE flag, if set, lets the user delete requests
3508  * function. Once deleted, a member loses its property flag setup. If
3509  * the member is re-created later, it may be required to set this flag
3510  * again to delete it again.
3511  *
3512  * \sa sswf::ActionFunction::PROP_FLAG_IS_HIDDEN
3513  * \sa sswf::ActionFunction::PROP_FLAG_CAN_OVERWRITE
3514  *
3515  * <hr>
3516  */
3517 
3518 
3519 /** \var sswf::ActionFunction::PROP_FLAG_CAN_OVERWRITE
3520  *
3521  * \brief Whether a member can be overwritten in an object
3522  *
3523  * The PROP_FLAG_CAN_OVERWRITE flag, if set, means that the
3524  * corresponding member can be replaced (i.e. set with a
3525  * different type, or in case of a function, by a different
3526  * function.)
3527  *
3528  * This flag does not prevent a variable member from being
3529  * modified.
3530  *
3531  * \sa sswf::ActionFunction::PROP_FLAG_IS_HIDDEN
3532  * \sa sswf::ActionFunction::PROP_FLAG_CAN_DELETE
3533  */
3534 
3535 
3536 
3537 
3538 /** \brief Initializes ActionFunction objects.
3539  *
3540  * This function is used to initialize ActionFunction objects.
3541  *
3542  * In debug mode it will test that the action is valid. It has
3543  * to be set to either:
3544  *
3545  * ACTION_DECLARE_FUNCTION or ACTION_DECLARE_FUNCTION2
3546  *
3547  * The former can be used for movies version 5 or 6, the
3548  * latter for movies version 7 or more.
3549  *
3550  * \param[in] tag The tag holding this action
3551  * \param[in] action The type of function to create
3552  */
ActionFunction(TagBase * tag,action_t action)3553 ActionFunction::ActionFunction(TagBase *tag, action_t action)
3554 	: Action(tag, action)
3555 {
3556 	assert(action == ACTION_DECLARE_FUNCTION || action == ACTION_DECLARE_FUNCTION2, "The ActionFunction expects ACTION_DECLARE_FUNCTION or ACTION_DECLARE_FUNCTION2.");
3557 	if(action != ACTION_DECLARE_FUNCTION && action != ACTION_DECLARE_FUNCTION2) {
3558 		throw ErrorManager::InternalErrorException();
3559 	}
3560 
3561 	f_name = 0;
3562 	f_registers_count = 0;
3563 	f_flags = 0;
3564 }
3565 
3566 
3567 /** \brief Define the name of the function.
3568  *
3569  * This function saves the specified name as the name of the function.
3570  *
3571  * This is the name you need to use to call the function later.
3572  *
3573  * Note that an object function member has no name.
3574  *
3575  * \param[in] name The new function name
3576  */
SetName(const char * name)3577 void ActionFunction::SetName(const char *name)
3578 {
3579 	MemFree(f_name);
3580 	f_name = StrDup(name);
3581 }
3582 
3583 
3584 /** \brief Set the maximum number of registers to use with this function.
3585  *
3586  * With an ACTION_DECLARE_FUNCTION2, you can use as many as 255 registers
3587  * in your function, otherwise you are limited to 4 as before version 7.
3588  * Also, before version 7, the parameters cannot automatically be assigned
3589  * to registers and thus this function is not necessary.
3590  *
3591  * \param[in] count The number of registers you want to use
3592  */
SetRegistersCount(unsigned int count)3593 void ActionFunction::SetRegistersCount(unsigned int count)
3594 {
3595 	if(count > 255) {
3596 		f_registers_count = 255;
3597 	}
3598 	else {
3599 		f_registers_count = count;
3600 	}
3601 }
3602 
3603 
3604 /** \brief Add a function parameter.
3605  *
3606  * This function adds a parameter to the ActionFunction.
3607  *
3608  * The name is mandatory for an
3609  * ACTION_DECLARE_FUNCTION and optional for an ACTION_DECLARE_FUNCTION2.
3610  * There are some special parameter names for an ACTION_DECLARE_FUNCTION2
3611  * to create or not system registers. The special names are as follow:
3612  *
3613  * 	\li this &mdash; put 'this' in a register
3614  * 	\li /this &mdash; do not create 'this' even when available
3615  * 	\li arguments &mdash; put 'arguments' in a register
3616  * 	\li /arguments &mdash; do not create the 'arguments' array
3617  * 	\li super &mdash; put 'super' in a register
3618  * 	\li /super &mdash; do not create 'super'
3619  * 	\li _root &mdash; put '_root' in a register
3620  * 	\li /_root &mdash; cancel the action of '_root'
3621  * 	\li _parent &mdash; put '_parent' in a register
3622  * 	\li /_parent &mdash; cancel the action of '_parent'
3623  * 	\li _global &mdash; put '_global' in a register
3624  * 	\li /_global &mdash; cancel the action of '_global'
3625  *
3626  * The register number is used only by an ACTION_DECLARE_FUNCTION2.
3627  * By default the register number is set to -1 which means that no register
3628  * is assigned to that parameter. You can use 0 to have the system automatically
3629  * assign a register number to your parameter.
3630  *
3631  * According to my testings, the register 255 cannot be used. So you are limited
3632  * to a register number from 1 to 254. However, don't forget that system parameters
3633  * must use the first few registers! If the register number you specify is larger
3634  * than the one defined by the sswf::ActionFunction::SetRegistersCount(unsigned int count)
3635  * then it is increased as required.
3636  *
3637  * \param[in] name The name of the parameter
3638  * \param[in] register_number The assigned register for that parameter
3639  */
AddParameter(const char * name,int register_number)3640 void ActionFunction::AddParameter(const char *name, int register_number)
3641 {
3642 	parameter_t	*param;
3643 
3644 	if(name != 0 && f_action == ACTION_DECLARE_FUNCTION2) {
3645 		if(strcmp(name, "this") == 0) {
3646 			f_flags |= ACTION_FUNCTION_LOAD_THIS;
3647 			f_flags &= ~ACTION_FUNCTION_SUPPRESS_THIS;
3648 			return;
3649 		}
3650 		if(strcmp(name, "/this") == 0) {
3651 			f_flags |= ACTION_FUNCTION_SUPPRESS_THIS;
3652 			f_flags &= ~ACTION_FUNCTION_LOAD_THIS;
3653 			return;
3654 		}
3655 		if(strcmp(name, "arguments") == 0) {
3656 			f_flags |= ACTION_FUNCTION_LOAD_ARGUMENTS;
3657 			f_flags &= ~ACTION_FUNCTION_SUPPRESS_ARGUMENTS;
3658 			return;
3659 		}
3660 		if(strcmp(name, "/arguments") == 0) {
3661 			f_flags |= ACTION_FUNCTION_SUPPRESS_ARGUMENTS;
3662 			f_flags &= ~ACTION_FUNCTION_LOAD_ARGUMENTS;
3663 			return;
3664 		}
3665 		if(strcmp(name, "super") == 0) {
3666 			f_flags |= ACTION_FUNCTION_LOAD_SUPER;
3667 			f_flags &= ~ACTION_FUNCTION_SUPPRESS_SUPER;
3668 			return;
3669 		}
3670 		if(strcmp(name, "/super") == 0) {
3671 			f_flags |= ACTION_FUNCTION_SUPPRESS_SUPER;
3672 			f_flags &= ~ACTION_FUNCTION_LOAD_SUPER;
3673 			return;
3674 		}
3675 		if(strcmp(name, "_root") == 0) {
3676 			f_flags |= ACTION_FUNCTION_LOAD_ROOT;
3677 			return;
3678 		}
3679 		if(strcmp(name, "/_root") == 0) {
3680 			f_flags &= ~ACTION_FUNCTION_LOAD_ROOT;
3681 			return;
3682 		}
3683 		if(strcmp(name, "_parent") == 0) {
3684 			f_flags |= ACTION_FUNCTION_LOAD_PARENT;
3685 			return;
3686 		}
3687 		if(strcmp(name, "/_parent") == 0) {
3688 			f_flags &= ~ACTION_FUNCTION_LOAD_PARENT;
3689 			return;
3690 		}
3691 		if(strcmp(name, "_global") == 0) {
3692 			f_flags |= ACTION_FUNCTION_LOAD_GLOBAL;
3693 			return;
3694 		}
3695 		if(strcmp(name, "/_global") == 0) {
3696 			f_flags &= ~ACTION_FUNCTION_LOAD_GLOBAL;
3697 			return;
3698 		}
3699 	}
3700 
3701 	assert(register_number > -2 && register_number < 255, "ActionFunction::AddParameter() -- invalid register number specification for a function parameter");
3702 
3703 	param = new parameter_t;
3704 	MemAttach(param, sizeof(parameter_t), "ActionFunction::AddParameter() -- parameter_t structure");
3705 	param->f_name = StrDup(name);
3706 	param->f_register_number = register_number;
3707 	if((int) f_registers_count <= register_number) {
3708 		f_registers_count = register_number + 1;
3709 	}
3710 	f_parameters.Set(-1, param);
3711 }
3712 
3713 
3714 /** \brief Add an action in the function.
3715  *
3716  * Most functions include a set of actions to be executed when
3717  * called. These actions are added using this functions. It is
3718  * also possible to get a pointer to the sub-actions Vectors
3719  * and directly add the actions in the Vectors object.
3720  *
3721  * These actions are seen as the function block.
3722  *
3723  * \param[in] action The action to add to this function
3724  *
3725  * \sa sswf::ActionFunction::SubList(void)
3726  */
AddAction(Action * action)3727 void ActionFunction::AddAction(Action *action)
3728 {
3729 	f_actions.Set(-1, action);
3730 }
3731 
3732 
3733 /** \brief Duplicate the function action.
3734  *
3735  * This function duplicates a function. This includes all the
3736  * parameters and actions as well as the name and number of
3737  * registers used in the list of parameters.
3738  *
3739  * \return A pointer to a new ActionFunction object
3740  */
Duplicate(void) const3741 Action *ActionFunction::Duplicate(void) const
3742 {
3743 	parameter_t	*param;
3744 	ActionFunction	*f;
3745 	Action		*a;
3746 	int		max, idx;
3747 
3748 	f = new ActionFunction(Tag(), f_action);
3749 	f->SetName(f_name);
3750 	f->SetRegistersCount(f_registers_count);
3751 	f->f_flags = f_flags;	// this wouldn't be set just by duplicating the parameters
3752 
3753 	max = f_parameters.Count();
3754 	for(idx = 0; idx < max; idx++) {
3755 		param = dynamic_cast<parameter_t *>(f_parameters.Get(idx));
3756 		f->AddParameter(param->f_name, param->f_register_number);
3757 	}
3758 
3759 	max = f_actions.Count();
3760 	for(idx = 0; idx < max; idx++) {
3761 		a = dynamic_cast<Action *>(f_actions.Get(idx));
3762 		f->AddAction(a->Duplicate());
3763 	}
3764 
3765 	return f;
3766 }
3767 
3768 
3769 /** \brief Get a pointer to the Vectors of sub-actions.
3770  *
3771  * This function can be used to retrieve a pointer to the
3772  * sub-actions Vectors object. This can be used to add
3773  * actions to the function in a way similar to the main
3774  * block.
3775  *
3776  * \return A pointer to a Vectors object expecting actions
3777  */
SubList(void)3778 Vectors *ActionFunction::SubList(void)
3779 {
3780 	return &f_actions;
3781 }
3782 
3783 
3784 /** \brief Save the function header and nested data.
3785  *
3786  * This function creates the function header which includes
3787  * its name, all the parameters, whether to create or suppress
3788  * system registers and the size of the function block.
3789  *
3790  * Note that the function block cannot be larger than about
3791  * 64Kb.
3792  *
3793  * \param[in] data The Data buffer where the function is saved
3794  * \param[in] nested_data The Data buffer holding the function
3795  * 		block
3796  */
SaveData(Data & data,Data & nested_data)3797 ErrorManager::error_code_t ActionFunction::SaveData(Data& data, Data& nested_data)
3798 {
3799 	parameter_t			*param;
3800 	int				max, idx, reg;
3801 	char				regs[256];
3802 	ErrorManager::error_code_t	ec;
3803 
3804 	ec = SaveString(data, f_name);
3805 
3806 	max = f_parameters.Count();
3807 	data.PutShort(max);
3808 
3809 	if(f_action == ACTION_DECLARE_FUNCTION2) {
3810 
3811 		GetMaxRegister();
3812 
3813 		data.PutByte(f_registers_count);
3814 		data.PutShort(f_flags);
3815 
3816 		// mark the used registers
3817 		memset(regs, 0, sizeof(regs));
3818 
3819 		idx = 0;
3820 
3821 		if((f_flags & ACTION_FUNCTION_LOAD_THIS) != 0) {
3822 			idx++;
3823 			regs[idx] = 1;
3824 		}
3825 		if((f_flags & ACTION_FUNCTION_LOAD_SUPER) != 0) {
3826 			idx++;
3827 			regs[idx] = 1;
3828 		}
3829 		if((f_flags & ACTION_FUNCTION_LOAD_ROOT) != 0) {
3830 			idx++;
3831 			regs[idx] = 1;
3832 		}
3833 		if((f_flags & ACTION_FUNCTION_LOAD_PARENT) != 0) {
3834 			idx++;
3835 			regs[idx] = 1;
3836 		}
3837 		if((f_flags & ACTION_FUNCTION_LOAD_GLOBAL) != 0) {
3838 			idx++;
3839 			regs[idx] = 1;
3840 		}
3841 
3842 		// TODO: we need to make sure that user registers don't
3843 		//	 overlap with system registers
3844 		for(idx = 0; idx < max; idx++) {
3845 			param = dynamic_cast<parameter_t *>(f_parameters.Get(idx));
3846 			if(param->f_register_number > 0 && param->f_register_number < 256) {
3847 				regs[param->f_register_number] = 1;
3848 			}
3849 		}
3850 
3851 		reg = 1;
3852 		for(idx = 0; idx < max; idx++) {
3853 			param = dynamic_cast<parameter_t *>(f_parameters.Get(idx));
3854 			if(param->f_register_number == 0) {	// auto-assign register?
3855 				while(reg < 255 && regs[reg] != 0) {
3856 					reg++;
3857 				}
3858 				// TODO: should the max. by 255 instead? (TBD)
3859 				if(reg >= 256) {
3860 					ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_REGISTER_OVERFLOW, "too many registers used in this function."));
3861 					data.PutByte(0);
3862 					data.PutByte(0);
3863 				}
3864 				else {
3865 					regs[reg] = 1;
3866 					data.PutByte(reg);
3867 					reg++;
3868 					data.PutByte(0);	// no variable name
3869 				}
3870 			}
3871 			else if(param->f_register_number > 0) {	// user defined register?
3872 				// TODO: we need error handling to tell whether the
3873 				//	 same register is used multiple times
3874 				data.PutByte(param->f_register_number);
3875 				regs[param->f_register_number] = 1;
3876 				if(*param->f_name != '\0') {
3877 					ec = ErrorManager::KeepFirst(ec, SaveString(data, param->f_name));
3878 				}
3879 				else {
3880 					data.PutByte(0);	// no variable name
3881 				}
3882 			}
3883 			else {
3884 				data.PutByte(0);	// no register; use variable name
3885 				ec = ErrorManager::KeepFirst(ec, SaveString(data, param->f_name));
3886 			}
3887 		}
3888 	}
3889 	else {
3890 		for(idx = 0; idx < max; idx++) {
3891 			param = dynamic_cast<parameter_t *>(f_parameters.Get(idx));
3892 			ec = ErrorManager::KeepFirst(ec, SaveString(data, param->f_name));
3893 		}
3894 	}
3895 
3896 	// the actions were already saved by the Action::Save() function!
3897 	data.PutShort((unsigned short) nested_data.ByteSize());
3898 
3899 	return ec;
3900 }
3901 
3902 
3903 
3904 
3905 ////////////////////////////// Action GOTO
3906 
3907 /** \class sswf::ActionGoto
3908  *
3909  * \brief A goto action to change the current frame.
3910  *
3911  * This action is used in ActionScripts to change the current frame
3912  * to display.
3913  *
3914  * \sa <a href="../SWFalexref.html#action_goto_expression">SWF Alexis' Reference&mdash;Goto Expression</a>
3915  * \sa <a href="../SWFalexref.html#action_goto_frame">SWF Alexis' Reference&mdash;Goto Frame</a>
3916  * \sa <a href="../SWFalexref.html#action_goto_label">SWF Alexis' Reference&mdash;Goto Label</a>
3917  */
3918 
3919 /** \brief Initializes the ActionGoto action.
3920  *
3921  * This function initializes the ActionGoto. This means the frame
3922  * name is set to NULL and the playback flag is set to false
3923  * (i.e. go to that frame and stop playing.)
3924  *
3925  * The valid actions are:
3926  *
3927  *	\li ACTION_GOTO_FRAME
3928  *	\li ACTION_GOTO_LABEL
3929  *	\li ACTION_GOTO_EXPRESSION
3930  */
ActionGoto(TagBase * tag,action_t action)3931 ActionGoto::ActionGoto(TagBase *tag, action_t action)
3932 	: Action(tag, action)
3933 {
3934 	assert(action == ACTION_GOTO_FRAME || action == ACTION_GOTO_LABEL || action == ACTION_GOTO_EXPRESSION,
3935 			"The ActionGoto expects ACTION_GOTO_FRAME, ACTION_GOTO_LABEL or ACTION_GOTO_EXPRESSION.");
3936 	if(action != ACTION_GOTO_FRAME && action != ACTION_GOTO_LABEL && action != ACTION_GOTO_EXPRESSION) {
3937 		throw ErrorManager::InternalErrorException();
3938 	}
3939 	f_frame_name = 0;
3940 	f_play = false;
3941 }
3942 
3943 
3944 /** \brief Set the name of the frame to go to.
3945  *
3946  * It is possible to give a name to a frame. This action can then be used
3947  * to go to that frame. You need to use an ACTION_GOTO_FRAME or ACTION_GOTO_LABEL
3948  * for this purpose. The ACTION_GOTO_EXPRESSION uses the last string on the stack
3949  * instead.
3950  *
3951  * In case of an ACTION_GOTO_FRAME, the name can actually be a frame number
3952  * in ASCII (i.e. "15"), otherwise it is the SSWF label name of a frame.
3953  *
3954  * In case of an ACTION_GOTO_LABEL, whether the label exists in the movie is not
3955  * being tested by the library.
3956  *
3957  * \param[in] frame_name The name of the frame you want to go to
3958  */
SetFrameName(const char * frame_name)3959 void ActionGoto::SetFrameName(const char *frame_name)
3960 {
3961 	MemFree(f_frame_name);
3962 	f_frame_name = StrDup(frame_name);
3963 }
3964 
3965 
3966 /** \fn void sswf::ActionGoto::SetPlay(bool play)
3967  *
3968  * \brief Set whether the animation continues to play after the goto.
3969  *
3970  * This function is used to define whether the animation should continue
3971  * to play after it jumped to the specified frame.
3972  *
3973  * By default, the action says that the animation should stop playing.
3974  *
3975  * \param[in] play The flag to tell whether it should play (true) or not (false)
3976  */
3977 
3978 
3979 /** \brief Create a duplicate of this action goto.
3980  *
3981  * Create a new ActionGoto object copy the frame name and whether to continue
3982  * or stop playback.
3983  *
3984  * \return The new ActionGoto object
3985  */
Duplicate(void) const3986 Action *ActionGoto::Duplicate(void) const
3987 {
3988 	ActionGoto	*a;
3989 
3990 	a = new ActionGoto(Tag(), f_action);
3991 	a->SetFrameName(f_frame_name);
3992 	a->SetPlay(f_play);
3993 
3994 	return a;
3995 }
3996 
3997 
3998 /** \brief Save the extraneous information of the ActionGoto.
3999  *
4000  * Save the label information of the ActionGoto object.
4001  *
4002  * \param[in] data The Data buffer where the ActionGoto is to be saved
4003  * \param[in] nested_data There is no nested data in an ActionGoto
4004  */
SaveData(Data & data,Data & nested_data)4005 ErrorManager::error_code_t ActionGoto::SaveData(Data& data, Data& nested_data)
4006 {
4007 	TagBase				*tag;
4008 	const char			*s;
4009 	long				no;
4010 	ErrorManager::error_code_t	ec;
4011 
4012 	ec = ErrorManager::ERROR_CODE_NONE;
4013 
4014 	switch(f_action) {
4015 	case ACTION_GOTO_LABEL:
4016 		/* in this case the user wants to use a label */
4017 		ec = SaveString(data, f_frame_name);
4018 		break;
4019 
4020 	case ACTION_GOTO_FRAME:
4021 		/* here we have to find what ShowFrame is linked to this entry */
4022 		no = 0;
4023 		s = f_frame_name;
4024 		while(*s >= '0' && *s <= '9') {
4025 			no = no * 10 + *s - '0';
4026 			++s;
4027 		}
4028 		if(*s == '\0' && s != f_frame_name) {
4029 			data.PutShort(no);
4030 		}
4031 		else {
4032 			tag = Tag()->FindLabelledTag(f_frame_name);
4033 			if(tag == 0) {
4034 				/* ha! couldn't find this object... */
4035 				ec = OnError(ErrorManager::ERROR_CODE_OBJECT_NOT_FOUND, "cannot find any tag labelled '%s'.", f_frame_name);
4036 				data.PutShort(0);	// a default, just so the file is not boggus.
4037 			}
4038 			else {
4039 				data.PutShort(tag->WhichFrame());
4040 			}
4041 		}
4042 		break;
4043 
4044 	case ACTION_GOTO_EXPRESSION:
4045 		// TODO: my doc. says this is a char not a short...
4046 		//	 we need to test to know who's right!
4047 		data.PutShort(f_play);
4048 		break;
4049 
4050 	default:
4051 		assert(0, "invalid f_action for an ActionGoto() object");
4052 		ec = OnError(ErrorManager::ERROR_CODE_INTERNAL_ERROR, "invalid f_action for an ActionGoto() object");
4053 		break;
4054 
4055 	}
4056 
4057 	return ec;
4058 }
4059 
4060 
4061 ////////////////////////////// Action LABEL
4062 
4063 /** \class sswf::ActionLabel
4064  *
4065  * \brief Create a label in an action script.
4066  *
4067  * An ActionLabel is an SSWF addition which is not saved in the SWF
4068  * movie. It is used to indicate where a BranchAction can branch.
4069  */
4070 
4071 
4072 /** \brief Initialize an ActionLabel.
4073  *
4074  * An action label is set to "no name" by default. You are expected
4075  * to call SetLabel() once initialized.
4076  *
4077  * \param[in] tag The tag including this action
4078  */
ActionLabel(TagBase * tag)4079 ActionLabel::ActionLabel(TagBase *tag)
4080 	: Action(tag, ACTION_LABEL)
4081 {
4082 	f_label = 0;
4083 }
4084 
4085 
4086 /** \brief Set the name of an ActionLabel.
4087  *
4088  * This function defines the name of an ActionLabel. The name
4089  * can be any valid string. It should not be empty.
4090  *
4091  * \param[in] label The new label name
4092  */
SetLabel(const char * label)4093 void ActionLabel::SetLabel(const char *label)
4094 {
4095 	MemFree(f_label);
4096 	f_label = StrDup(label);
4097 }
4098 
4099 
4100 /** \fn ActionLabel::GetLabel(void) const
4101  *
4102  * \brief Get the name of this label.
4103  *
4104  * This function retrieves the name of this label. It is used to search
4105  * all the labels in an array of actions.
4106  *
4107  * \return The name of this label
4108  */
4109 
4110 
4111 /** \brief Create a duplicate of the label.
4112  *
4113  * This function creates a new label action and copies the
4114  * label of 'this' action.
4115  *
4116  * \return The pointer to the new ActionLabel
4117  */
Duplicate(void) const4118 Action *ActionLabel::Duplicate(void) const
4119 {
4120 	ActionLabel		*a;
4121 
4122 	a = new ActionLabel(Tag());
4123 	if(f_label != 0) {
4124 		a->SetLabel(f_label);
4125 	}
4126 
4127 	return a;
4128 }
4129 
4130 
4131 ////////////////////////////// Action PUSH DATA
4132 
4133 /** \class sswf::ActionPushData
4134  *
4135  * \brief The PushData action adds data on the ActionScript stack.
4136  *
4137  * Create a PushData action each time you need some constant data
4138  * or the content of a register on the ActionScript stack.
4139  *
4140  * \sa <a href="../SWFalexref.html#action_push_data">SWF Alexis' Reference&mdash;Push Data</a>
4141  */
4142 
4143 
4144 /** \brief The PushData constructor initialize an ActionPushData object
4145  *
4146  * The ActionPushData constructor expects a valid parent tag (a TagHeader
4147  * or a TagSprite.) Call the Add functions to add the different values
4148  * necessary on the stack.
4149  *
4150  * \param[in] tag The tag in which this action is inserted
4151  */
ActionPushData(TagBase * tag)4152 ActionPushData::ActionPushData(TagBase *tag)
4153 	: Action(tag, ACTION_PUSH_DATA)
4154 {
4155 }
4156 
4157 /** \fn sswf::ActionPushData::AddEmptyString(void)
4158  *
4159  * \brief Add an empty string on the stack
4160  *
4161  * This function is the same as AddString(NULL).
4162  *
4163  * \sa sswf::ActionPushData::AddString()
4164  */
4165 
4166 
4167 
4168 /** \fn sswf::ActionPushData::AddTrue(void)
4169  *
4170  * \brief Add the boolean value True
4171  *
4172  * This function is the same as AddBoolean(true).
4173  *
4174  * \sa sswf::ActionPushData::AddBoolean()
4175  */
4176 
4177 
4178 
4179 /** \fn sswf::ActionPushData::AddFalse(void)
4180  *
4181  * \brief Add the boolean value False
4182  *
4183  * This function is the same as AddBoolean(false).
4184  *
4185  * \sa sswf::ActionPushData::AddBoolean()
4186  */
4187 
4188 
4189 
4190 /** \brief Add a string to the ActionPushData.
4191  *
4192  * This function adds a string to the action.
4193  *
4194  * \sa sswf::ActionPushData::AddEmptyString()
4195  * \param[in] string The string to add to the action
4196  */
AddString(const char * string)4197 void ActionPushData::AddString(const char *string)
4198 {
4199 	action_immediate_t	*imm;
4200 
4201 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_STRING);
4202 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddString() -- immediate data structure");
4203 	if(string != 0) {
4204 		imm->f_data.f_string = StrDup(string);
4205 	}
4206 	f_data.Set(-1, imm);
4207 }
4208 
4209 
4210 /** \brief Add a boolean value to the ActionPushData.
4211  *
4212  * This function adds a boolean value (true or false) to the ActionPushData.
4213  * Note that it is a good idea to use a boolean value for an ACTION_BRANCH_IF_TRUE
4214  * byte code. However, this is very similar to an integer or even a float.
4215  *
4216  * \param[in] value The boolean value (true or false)
4217  */
AddBoolean(bool value)4218 void ActionPushData::AddBoolean(bool value)
4219 {
4220 	action_immediate_t	*imm;
4221 
4222 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_BOOLEAN);
4223 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddBoolean() -- immediate data structure");
4224 	imm->f_data.f_boolean = value;
4225 	f_data.Set(-1, imm);
4226 }
4227 
4228 
4229 /** \brief Add an integer to the ActionPushData.
4230  *
4231  * This function adds a 32 bits integer to the ActionPushData
4232  *
4233  * \param[in] value A 32 bits integer
4234  */
AddInteger(long value)4235 void ActionPushData::AddInteger(long value)
4236 {
4237 	action_immediate_t	*imm;
4238 
4239 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_INTEGER);
4240 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddInteger() -- immediate data structure");
4241 	imm->f_data.f_integer32 = value;
4242 	f_data.Set(-1, imm);
4243 }
4244 
4245 
4246 /** \brief Add a floating point value to the ActionPushData.
4247  *
4248  * This function adds a 32 bits floating point to the ActionPushData object.
4249  *
4250  * \param[in] value A 32 bits floating point value
4251  */
AddFloat(float value)4252 void ActionPushData::AddFloat(float value)
4253 {
4254 	action_immediate_t	*imm;
4255 
4256 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_FLOAT);
4257 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddDouble() -- immediate data structure");
4258 	imm->f_data.f_float32 = value;
4259 	f_data.Set(-1, imm);
4260 }
4261 
4262 
4263 /** \brief Add a floating point to the ActionPushData.
4264  *
4265  * This function adds a 64 bits floating point value to the ActionPushData object
4266  *
4267  * \param[in] value The 64 bits floating point value
4268  */
AddDouble(double value)4269 void ActionPushData::AddDouble(double value)
4270 {
4271 	action_immediate_t	*imm;
4272 
4273 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_DOUBLE);
4274 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddDouble() -- immediate data structure");
4275 	imm->f_data.f_float64 = value;
4276 	f_data.Set(-1, imm);
4277 }
4278 
4279 
4280 /** \brief Add the special value NULL to the ActionPushData.
4281  *
4282  * This function is used to add the special value NULL to an
4283  * ActionPushData. This value is also called Nil in some
4284  * ActionScripts. It represents a "no object reference".
4285  */
AddNull(void)4286 void ActionPushData::AddNull(void)
4287 {
4288 	action_immediate_t	*imm;
4289 
4290 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_NULL);
4291 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddNull() -- immediate data structure");
4292 	f_data.Set(-1, imm);
4293 }
4294 
4295 
4296 /** \brief Add the undefined value to the ActionPushData.
4297  *
4298  * This function is used to add the special value Undefined to
4299  * an ActionPushData. This is value is used to test whether
4300  * some object, function, variable is defined or not.
4301  *
4302  * It can also be used to pass as a parameter to a function
4303  * which requires a parameter you cannot define.
4304  */
AddUndefined(void)4305 void ActionPushData::AddUndefined(void)
4306 {
4307 	action_immediate_t	*imm;
4308 
4309 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_UNDEFINED);
4310 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddUndefined() -- immediate data structure");
4311 	f_data.Set(-1, imm);
4312 }
4313 
4314 
4315 /** \brief Add a string from the dictionary.
4316  *
4317  * This function adds a string to the ActionPushData object. The index
4318  * is the string index in this ActionScript dictionary.
4319  *
4320  * Don't forget that you can have only one dictionary within one tag.
4321  *
4322  * \param[in] index The index of the string to be added on the stack
4323  */
AddLookup(unsigned short index)4324 void ActionPushData::AddLookup(unsigned short index)
4325 {
4326 	action_immediate_t	*imm;
4327 
4328 	imm = new action_immediate_t(index >= 256 ? ACTION_IMMEDIATE_TYPE_LOOKUP_LARGE : ACTION_IMMEDIATE_TYPE_LOOKUP);
4329 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddLookup() -- immediate data structure");
4330 	imm->f_data.f_lookup = index;
4331 	f_data.Set(-1, imm);
4332 }
4333 
4334 
4335 /** \brief Add the content of a register.
4336  *
4337  * This function adds the content of the specified register. This is particularly
4338  * useful for version 7+ functions which can save all their parameters in registers.
4339  * Then you avoid an ActionGetVariable.
4340  *
4341  * The register index is limited to 0, 1, 2 and 3 for the main script and any scripts
4342  * before version 7. Since version 7, registers can be set from 0 to 254 within a
4343  * function 2 declaration.
4344  *
4345  * \param[in] reg_index The index of the register to read
4346  */
AddRegister(unsigned char reg_index)4347 void ActionPushData::AddRegister(unsigned char reg_index)
4348 {
4349 	action_immediate_t	*imm;
4350 
4351 	// we would need to know whether we're in a function
4352 	// (limit outside a function is 0..3 and in a function 0..255 or 254)
4353 	//assert(reg_index < 256, "invalid register index, limited to the range 0..3 inclusive");
4354 
4355 	imm = new action_immediate_t(ACTION_IMMEDIATE_TYPE_REGISTER);
4356 	MemAttach(imm, sizeof(action_immediate_t), "ActionPushData::AddRegister() -- immediate data structure");
4357 	imm->f_data.f_register = reg_index;
4358 	f_data.Set(-1, imm);
4359 }
4360 
4361 
4362 
4363 
4364 /** \brief Duplicate an ActionPushData.
4365  *
4366  * This function creates a new ActionPushData object and copies
4367  * 'this' ActionPushData in it.
4368  *
4369  * The function copies all the data which was added to the
4370  * ActionPushData.
4371  *
4372  * \return The new ActionPushData pointer
4373  */
Duplicate(void) const4374 Action *ActionPushData::Duplicate(void) const
4375 {
4376 	ActionPushData		*a;
4377 	action_immediate_t	*imm;
4378 	int			i, max;
4379 
4380 	a = new ActionPushData(Tag());
4381 
4382 	max = f_data.Count();
4383 	for(i = 0; i < max; i++) {
4384 		imm = dynamic_cast<action_immediate_t *>(f_data.Get(i));
4385 		switch(imm->f_type) {
4386 		case ACTION_IMMEDIATE_TYPE_STRING:
4387 			a->AddString(imm->f_data.f_string);
4388 			break;
4389 
4390 		case ACTION_IMMEDIATE_TYPE_FLOAT:
4391 			a->AddFloat(imm->f_data.f_float32);
4392 			break;
4393 
4394 		case ACTION_IMMEDIATE_TYPE_BOOLEAN:
4395 			a->AddBoolean(imm->f_data.f_boolean);
4396 			break;
4397 
4398 		case ACTION_IMMEDIATE_TYPE_DOUBLE:
4399 			a->AddDouble(imm->f_data.f_float64);
4400 			break;
4401 
4402 		case ACTION_IMMEDIATE_TYPE_INTEGER:
4403 			a->AddInteger(imm->f_data.f_integer32);
4404 			break;
4405 
4406 		case ACTION_IMMEDIATE_TYPE_LOOKUP:
4407 		case ACTION_IMMEDIATE_TYPE_LOOKUP_LARGE:
4408 			a->AddLookup(imm->f_data.f_lookup);
4409 			break;
4410 
4411 		case ACTION_IMMEDIATE_TYPE_REGISTER:
4412 			a->AddRegister(imm->f_data.f_register);
4413 			break;
4414 
4415 		case ACTION_IMMEDIATE_TYPE_NULL:
4416 			a->AddNull();
4417 			break;
4418 
4419 		case ACTION_IMMEDIATE_TYPE_UNDEFINED:
4420 			a->AddUndefined();
4421 			break;
4422 
4423 		default:
4424 			assert(0, "unknown immediate data type");
4425 			/*NOTREACHED*/
4426 
4427 		}
4428 	}
4429 
4430 	return a;
4431 }
4432 
4433 
4434 /** \brief Search the action for registers and return the largest number.
4435  *
4436  * This function defines what the largest register is in this
4437  * ActionPushData.
4438  *
4439  * \return The largest register used in this ActionPushData
4440  */
GetMaxRegister(void) const4441 int ActionPushData::GetMaxRegister(void) const
4442 {
4443 	action_immediate_t	*imm;
4444 	int			register_number;
4445 	int			i;
4446 
4447 	register_number = -1;
4448 
4449 	i = f_data.Count();
4450 	while(i > 0) {
4451 		i--;
4452 		imm = dynamic_cast<action_immediate_t *>(f_data.Get(i));
4453 		switch(imm->f_type) {
4454 		case ACTION_IMMEDIATE_TYPE_STRING:
4455 		case ACTION_IMMEDIATE_TYPE_FLOAT:
4456 		case ACTION_IMMEDIATE_TYPE_BOOLEAN:
4457 		case ACTION_IMMEDIATE_TYPE_DOUBLE:
4458 		case ACTION_IMMEDIATE_TYPE_INTEGER:
4459 		case ACTION_IMMEDIATE_TYPE_NULL:
4460 		case ACTION_IMMEDIATE_TYPE_UNDEFINED:
4461 			break;
4462 
4463 		case ACTION_IMMEDIATE_TYPE_LOOKUP:
4464 		case ACTION_IMMEDIATE_TYPE_LOOKUP_LARGE:
4465 			// here we would need to check in the dictionary
4466 			// to know whether the dictionary is itself defining
4467 			// a register...
4468 			break;
4469 
4470 		case ACTION_IMMEDIATE_TYPE_REGISTER:
4471 			if((int) imm->f_data.f_register > register_number) {
4472 				register_number = imm->f_data.f_register;
4473 			}
4474 			break;
4475 
4476 		default:
4477 			assert(0, "unknown immediate data type");
4478 			/*NOTREACHED*/
4479 
4480 		}
4481 	}
4482 
4483 	return register_number;
4484 }
4485 
4486 
4487 /** \brief Save the ActionPushData data.
4488  *
4489  * This function is used to save the actual data of the ActionPushData
4490  * in the Data buffer.
4491  *
4492  * \param[in] data The Data buffer where the ActionPushData is saved
4493  * \param[in] nested_data There is no nested data in an ActionPushData
4494  */
SaveData(Data & data,Data & nested_data)4495 ErrorManager::error_code_t ActionPushData::SaveData(Data& data, Data& nested_data)
4496 {
4497 	action_immediate_t		*imm;
4498 	int32_t				*ptr;
4499 	int				i, max;
4500 	ErrorManager::error_code_t	ec;
4501 
4502 	ec = ErrorManager::ERROR_CODE_NONE;
4503 
4504 	max = f_data.Count();
4505 	i = 0;
4506 	while(i < max) {
4507 		imm = dynamic_cast<action_immediate_t *>(f_data.Get(i));
4508 		data.PutByte(imm->f_type);
4509 		switch(imm->f_type) {
4510 		case ACTION_IMMEDIATE_TYPE_STRING:
4511 			ec = ErrorManager::KeepFirst(ec, SaveString(data, imm->f_data.f_string));
4512 			break;
4513 
4514 		case ACTION_IMMEDIATE_TYPE_FLOAT:
4515 			ptr = (int32_t *) &imm->f_data;	// .f_float32
4516 			data.PutLong(*ptr);
4517 			break;
4518 
4519 		case ACTION_IMMEDIATE_TYPE_BOOLEAN:
4520 			data.PutByte(imm->f_data.f_boolean);
4521 			break;
4522 
4523 		case ACTION_IMMEDIATE_TYPE_DOUBLE:
4524 			ptr = (int32_t *) &imm->f_data;	// .f_float64
4525 #if BYTE_ORDER == LITTLE_ENDIAN
4526 			// AMD/Intel like
4527 			data.PutLong(ptr[1]);
4528 			data.PutLong(ptr[0]);
4529 #else
4530 			// RISC like
4531 			data.PutLong(ptr[0]);
4532 			data.PutLong(ptr[1]);
4533 #endif
4534 			break;
4535 
4536 		case ACTION_IMMEDIATE_TYPE_INTEGER:
4537 			data.PutLong(imm->f_data.f_integer32);
4538 			break;
4539 
4540 		case ACTION_IMMEDIATE_TYPE_REGISTER:
4541 			data.PutByte(imm->f_data.f_register);
4542 			break;
4543 
4544 		case ACTION_IMMEDIATE_TYPE_LOOKUP:
4545 			// in this case we know that f_lookup < 256
4546 			data.PutByte((unsigned char) imm->f_data.f_lookup);
4547 			break;
4548 
4549 		case ACTION_IMMEDIATE_TYPE_LOOKUP_LARGE:
4550 			data.PutShort(imm->f_data.f_lookup);
4551 			break;
4552 
4553 		case ACTION_IMMEDIATE_TYPE_NULL:
4554 		case ACTION_IMMEDIATE_TYPE_UNDEFINED:
4555 			break;
4556 
4557 		default:
4558 			assert(0, "unknown immediate data type");
4559 			ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_INTERNAL_ERROR, "unknown immediate data type"));
4560 			break;
4561 
4562 		}
4563 		i++;
4564 	}
4565 
4566 	return ec;
4567 }
4568 
4569 
4570 
4571 ////////////////////////////// Action SET TARGET
4572 
4573 /** \class sswf::ActionSetTarget
4574  *
4575  * \brief This class is used to define the sprite on which the actions apply.
4576  *
4577  * Before becoming fully object oriented, ActionScript used this
4578  * action to define the name of the Sprite on which the actions
4579  * had an effect.
4580  *
4581  * Using an empty name would reset the ActionScript to its default
4582  * behavior.
4583  *
4584  * \sa <a href="../SWFalexref.html#action_set_target">SWF Alexis' Reference&mdash;Set Target</a>
4585  * \sa <a href="../SWFalexref.html#action_set_target_dynamic">SWF Alexis' Reference&mdash;Set Target <i>(dynamic)</i></a>
4586  */
4587 
4588 /** \brief Initializes the ActionSetTarget.
4589  *
4590  * By default, the constructor creates an action target with no
4591  * name (i.e. reset to normal default behavior).
4592  *
4593  * Use the sswf::ActionSetTarget::SetTarget() function to define
4594  * which sprite should be affected.
4595  *
4596  * \param[in] tag The tag in which this action is saved.
4597  */
ActionSetTarget(TagBase * tag)4598 ActionSetTarget::ActionSetTarget(TagBase *tag)
4599 	: Action(tag, ACTION_SET_TARGET)
4600 {
4601 	f_target = 0;
4602 }
4603 
4604 
4605 /** \brief Set the name of the Sprite to affect.
4606  *
4607  * This function should be called with the name of the Sprite
4608  * which needs to be affected by the following actions.
4609  *
4610  * Set the name to NULL or an empty string to cancel a
4611  * previous ActionSetTarget (this is the default so you
4612  * do not have to do so.)
4613  */
SetTarget(const char * target)4614 void ActionSetTarget::SetTarget(const char *target)
4615 {
4616 	MemFree(f_target);
4617 	f_target = StrDup(target);
4618 }
4619 
4620 
4621 /** \brief Create a duplicate of this action.
4622  *
4623  * This function creates a new ActionSetTarget and copy the
4624  * target name of 'this' SetTarget and return the result.
4625  *
4626  * \return The pointer to the new ActionSetTarget
4627  */
Duplicate(void) const4628 Action *ActionSetTarget::Duplicate(void) const
4629 {
4630 	ActionSetTarget	*a;
4631 
4632 	a = new ActionSetTarget(Tag());
4633 	a->SetTarget(f_target);
4634 
4635 	return a;
4636 }
4637 
4638 
4639 /** \brief Save the extra data of the ActionSetTarget.
4640  *
4641  * This function saves the name of the target as expected
4642  * by this function.
4643  *
4644  * \param[in] data The Data buffer where the target name is saved
4645  * \param[in] nested_data The ActionSetTarget has no nested data
4646  */
SaveData(Data & data,Data & nested_data)4647 ErrorManager::error_code_t ActionSetTarget::SaveData(Data& data, Data& nested_data)
4648 {
4649 	return SaveString(data, f_target);
4650 }
4651 
4652 
4653 
4654 
4655 
4656 ////////////////////////////// Action STORE REGISTER
4657 
4658 /** \class sswf::ActionStoreRegister
4659  *
4660  * \brief Store the top stack value in a register.
4661  *
4662  * This action is used to save the current content of the stack
4663  * in a register. Later, you can read the register with an
4664  * sswf::ActionPushData action.
4665  *
4666  * \sa <a href="../SWFalexref.html#action_store_register">SWF Alexis' Reference&mdash;Store Register</a>
4667  */
4668 
4669 /** \brief Initialize the ActionStoreRegister.
4670  *
4671  * Initialize the ActionStoreRegister by setting the register
4672  * number to zero. Use the SetRegister() function to change
4673  * the default.
4674  *
4675  * \param[in] tag The tag in which this action is being added
4676  */
ActionStoreRegister(TagBase * tag)4677 ActionStoreRegister::ActionStoreRegister(TagBase *tag)
4678 	: Action(tag, ACTION_STORE_REGISTER)
4679 {
4680 	f_reg = 0;
4681 }
4682 
4683 
4684 /** \brief Defines which register will hold the stack content.
4685  *
4686  * This function can be used to define the register number
4687  * to hold the current stack content.
4688  *
4689  * Outside a function, only registers 0 to 3 are acceptable.
4690  *
4691  * Inside a function (DeclareFunction2--Version 7 of SWF),
4692  * all registers from 0 to 254 are acceptable. (from my
4693  * testing it seems that register 255 does not work.)
4694  *
4695  * \param[in] reg The new register to assign to this action
4696  */
SetRegister(unsigned char reg)4697 void ActionStoreRegister::SetRegister(unsigned char reg)
4698 {
4699 	f_reg = reg;
4700 }
4701 
4702 
4703 /** \brief Create a clone of this action.
4704  *
4705  * This function allocates a new ActionStoreRegister object,
4706  * it copies the register number and returns the pointer of
4707  * the new action.
4708  *
4709  * \return The action clone pointer
4710  */
Duplicate(void) const4711 Action *ActionStoreRegister::Duplicate(void) const
4712 {
4713 	ActionStoreRegister	*a;
4714 
4715 	a = new ActionStoreRegister(Tag());
4716 	a->SetRegister(f_reg);
4717 
4718 	return a;
4719 }
4720 
4721 
4722 /** \brief Get the maximum register number in use.
4723  *
4724  * This function gets the larger register number in
4725  * use by this action. This is actually equal to the
4726  * register you defined with SetRegister() or zero.
4727  *
4728  * \return The largest register number in use by this action
4729  */
GetMaxRegister(void) const4730 int ActionStoreRegister::GetMaxRegister(void) const
4731 {
4732 	return f_reg;
4733 }
4734 
4735 
4736 /** \brief Save the extraneous data for this action.
4737  *
4738  * This means saving one byte with the register number.
4739  *
4740  * \param[in] data The Data buffer where the register number is to be saved
4741  * \param[in] nested_data The ActionStoreRegister does not support nested data
4742  */
SaveData(Data & data,Data & nested_data)4743 ErrorManager::error_code_t ActionStoreRegister::SaveData(Data& data, Data& nested_data)
4744 {
4745 	data.PutByte(f_reg);
4746 
4747 	return ErrorManager::ERROR_CODE_NONE;
4748 }
4749 
4750 
4751 
4752 
4753 
4754 ////////////////////////////// Action STRICT MODE
4755 
4756 /** \class sswf::ActionStrictMode
4757  *
4758  * \brief This action is used to define the current scripting mode.
4759  *
4760  * It can be strict (i.e. follows JavaScript specification
4761  * to the letter) or lazy (i.e. accepts old ActionScript
4762  * commands).
4763  *
4764  * \sa <a href="../SWFalexref.html#action_strict_mode">SWF Alexis' Reference&mdash;Strict Mode</a>
4765  */
4766 
4767 /** \brief Initialize the ActionStrictMode object.
4768  *
4769  * This constructor marks the mode as <i>not strict</i>.
4770  *
4771  * Use the SetStrict() function to change the mode.
4772  *
4773  * \param[in] tag The tag in which this action is being created
4774  */
ActionStrictMode(TagBase * tag)4775 ActionStrictMode::ActionStrictMode(TagBase *tag)
4776 	: Action(tag, ACTION_STRICT_MODE)
4777 {
4778 	f_strict = false;
4779 }
4780 
4781 
4782 /** \brief Change the mode as required.
4783  *
4784  * This function lets you change the mode from strict (true)
4785  * to lazy (false).
4786  *
4787  * \param[in] strict Set to 'true' to enter strict mode
4788  */
SetStrict(bool strict)4789 void ActionStrictMode::SetStrict(bool strict)
4790 {
4791 	f_strict = strict;
4792 }
4793 
4794 
4795 /** \brief Create a clone of this ActionStrictMode object.
4796  *
4797  * This function creates a new ActionStringMode object; it
4798  * copies 'this' strict mode in the new action and then
4799  * it returns the pointer of the new action.
4800  *
4801  * \return The pointer to the new action
4802  */
Duplicate(void) const4803 Action *ActionStrictMode::Duplicate(void) const
4804 {
4805 	ActionStrictMode	*a;
4806 
4807 	a = new ActionStrictMode(Tag());
4808 	a->SetStrict(f_strict);
4809 
4810 	return a;
4811 }
4812 
4813 
4814 /** \brief Save the mode in the Data buffer.
4815  *
4816  * This function saves the strict mode in the Data buffer passed in.
4817  *
4818  * \param[in] data The Data buffer where the strict mode is saved
4819  * \param[in] nested_data The ActionStrictMode has no nested_data
4820  */
SaveData(Data & data,Data & nested_data)4821 ErrorManager::error_code_t ActionStrictMode::SaveData(Data& data, Data& nested_data)
4822 {
4823 	data.PutByte(f_strict);
4824 
4825 	return ErrorManager::ERROR_CODE_NONE;
4826 }
4827 
4828 
4829 
4830 
4831 
4832 ////////////////////////////// Action TRY
4833 
4834 /** \class sswf::ActionTry
4835  *
4836  * \brief This action encompasses the Try, Catch and Finally actions.
4837  *
4838  * This action creates two or three blocks of sub-actions. The first
4839  * block (the 'try' block) is protected, meaning that if an error occurs
4840  * within that block code, it will not break execution. Instead it will
4841  * continue with the 'catch' block if present and terminate the 'finally'
4842  * block if it exists.
4843  *
4844  * It is necessary to at least have one of the 'catch' or 'finally' blocks.
4845  * The 'try' block is mandatory.
4846  *
4847  * \sa <a href="../SWFalexref.html#action_try">SWF Alexis' Reference&mdash;Try</a>
4848  */
4849 
4850 /** \brief Initialize the ActionTry action.
4851  *
4852  * This constructor marks the Try action as not having any catch or
4853  * finally blocks, no name and no register.
4854  *
4855  * Use the AddTryAction() or SubListTry() to add actions to the try block.
4856  *
4857  * Use the AddCatchAction() or SubListCatch() to add actions to the
4858  * catch block.
4859  *
4860  * Use the AddFinallyAction() or SubListFinally() to add actions to
4861  * the finally block.
4862  *
4863  * Use the SetIdentifier(int register_number) function with an integer
4864  * to define a register number for the catch variable.
4865  *
4866  * Use the SetIdentifier(const char *name) function with a string to
4867  * define the name of a variable to use as the catch variable.
4868  *
4869  * \param[in] tag The tag in which this action is inserted
4870  */
ActionTry(TagBase * tag)4871 ActionTry::ActionTry(TagBase *tag)
4872 	: Action(tag, ACTION_TRY)
4873 {
4874 	f_register = -1;
4875 	f_variable_name = 0;
4876 	f_has_catch = false;
4877 	f_has_finally = false;
4878 }
4879 
4880 
4881 /** \brief Add an action to the try block.
4882  *
4883  * This function adds the specified action to the try block. There should
4884  * be at least one action in the try block.
4885  *
4886  * The action is not duplicated.
4887  *
4888  * \param[in] action The pointer to the action to add to the try block or NULL
4889  */
AddTryAction(Action * action)4890 void ActionTry::AddTryAction(Action *action)
4891 {
4892 	if(action != 0) {
4893 		f_actions_try.Set(-1, action);
4894 	}
4895 }
4896 
4897 
4898 /** \brief Add an action to the catch block.
4899  *
4900  * This function adds the specified action to the catch block. The catch
4901  * block can be empty, in which case you must have a non-empty finally block.
4902  *
4903  * The action passed is not duplicated.
4904  *
4905  * This function has the side effect of marking the action as having
4906  * a catch block, unless the pointer is null.
4907  *
4908  * \param[in] action The pointer to the action to add to the catch block or NULL
4909  */
AddCatchAction(Action * action)4910 void ActionTry::AddCatchAction(Action *action)
4911 {
4912 	if(action != 0) {
4913 		f_has_catch = true;
4914 		f_actions_catch.Set(-1, action);
4915 	}
4916 }
4917 
4918 
4919 /** \brief Add an action to the finally block.
4920  *
4921  * This function adds the specified action to the finally block. The finally
4922  * block can be empty, in which case you must have a non-empty catch block.
4923  *
4924  * The action passed is not duplicated.
4925  *
4926  * This function has the side effect of marking the action as having
4927  * a finally block, unless the pointer is null.
4928  *
4929  * \param[in] action The pointer to the action to add to the finally block or NULL
4930  */
AddFinallyAction(Action * action)4931 void ActionTry::AddFinallyAction(Action *action)
4932 {
4933 	if(action != 0) {
4934 		f_has_finally = true;
4935 		f_actions_finally.Set(-1, action);
4936 	}
4937 }
4938 
4939 
4940 /** \brief Request the error to be saved in a register.
4941  *
4942  * The catch block, when called, receives an error variable.
4943  * This variable can be saved in a register. To archive this,
4944  * set the register number that you want to use for this catch
4945  * block.
4946  *
4947  * This function has priority over the SetIdentifier(const char *name)
4948  * function. This means the register number will be used instead of
4949  * the register name if defined.
4950  *
4951  * The register number can be any number between 0 and 254.
4952  *
4953  * If the register number is set to -1, then it is ignored.
4954  *
4955  * \param[in] register_number The register to use in the catch block to access the error
4956  */
SetIdentifier(int register_number)4957 void ActionTry::SetIdentifier(int register_number)
4958 {
4959 	f_register = register_number;
4960 }
4961 
4962 
4963 /** \brief Request the error to be saved in a named variable.
4964  *
4965  * This function defines the name to use as the catch variable.
4966  * When a register number from 0 to 254 was defined with SetIdentifier(),
4967  * this variable name is ignored.
4968  *
4969  * \param[in] name The name of the variable to use within the catch block to access the error
4970  */
SetIdentifier(const char * name)4971 void ActionTry::SetIdentifier(const char *name)
4972 {
4973 	MemFree(f_variable_name);
4974 	f_variable_name = StrDup(name);
4975 }
4976 
4977 
4978 /** \brief Create a clone of this action.
4979  *
4980  * This function creates a new ActionTry object, it copies the register
4981  * number, variable name, has catch & finally flags and then copy the
4982  * lists of actions (try, catch and finally blocks.)
4983  *
4984  * \return The pointer to the new action
4985  */
Duplicate(void) const4986 Action *ActionTry::Duplicate(void) const
4987 {
4988 	ActionTry	*t;
4989 	Action		*a;
4990 	int		max, idx;
4991 
4992 	t = new ActionTry(Tag());
4993 	t->SetIdentifier(f_register);
4994 	t->SetIdentifier(f_variable_name);
4995 	t->f_has_catch = f_has_catch;
4996 	t->f_has_finally = f_has_finally;
4997 
4998 	max = f_actions_try.Count();
4999 	for(idx = 0; idx < max; idx++) {
5000 		a = dynamic_cast<Action *>(f_actions_try.Get(idx));
5001 		t->AddTryAction(a->Duplicate());
5002 	}
5003 
5004 	max = f_actions_catch.Count();
5005 	for(idx = 0; idx < max; idx++) {
5006 		a = dynamic_cast<Action *>(f_actions_catch.Get(idx));
5007 		t->AddCatchAction(a->Duplicate());
5008 	}
5009 
5010 	max = f_actions_finally.Count();
5011 	for(idx = 0; idx < max; idx++) {
5012 		a = dynamic_cast<Action *>(f_actions_finally.Get(idx));
5013 		t->AddFinallyAction(a->Duplicate());
5014 	}
5015 
5016 	return t;
5017 }
5018 
5019 
5020 /** \brief The version required to save this action.
5021  *
5022  * This function goes through all the sub-action lists to determine
5023  * the minimum version necessary to save it.
5024  *
5025  * The ActionTry itself requires version 7, but actions in the
5026  * sub-lists may require a higher version.
5027  *
5028  * \return The minimum version required to have the request work
5029  */
Version(void) const5030 unsigned char ActionTry::Version(void) const
5031 {
5032 	int		v, version;
5033 
5034 	// Until version 8, this Version() function is
5035 	// useless... But that's here for forward compatibility
5036 	// since when version 8 comes out I'd probably forget
5037 	// to come back to it!
5038 	version = 7;		// the ActionTry is version 7 by itself
5039 
5040 	v = MinimumListVersion(f_actions_try);
5041 	if(v > version) {
5042 		version = v;
5043 	}
5044 
5045 	v = MinimumListVersion(f_actions_catch);
5046 	if(v > version) {
5047 		version = v;
5048 	}
5049 
5050 	v = MinimumListVersion(f_actions_finally);
5051 	if(v > version) {
5052 		version = v;
5053 	}
5054 
5055 	return version;
5056 }
5057 
5058 
5059 /** \brief Defines the maximum register number in use.
5060  *
5061  * This function overwrites the default sswf::Action::GetMaxRegister()
5062  * function in order to retrieve the largest register in use in any
5063  * of the sub-action blocks (try, catch, finally).
5064  *
5065  * \return The largest register in use within this ActionTry object
5066  */
GetMaxRegister(void) const5067 int ActionTry::GetMaxRegister(void) const
5068 {
5069 	int		result, r;
5070 
5071 	result = GetMaximumRegister(f_actions_try);
5072 
5073 	r = GetMaximumRegister(f_actions_catch);
5074 	if(r > result) {
5075 		result = r;
5076 	}
5077 
5078 	r = GetMaximumRegister(f_actions_finally);
5079 	if(r > result) {
5080 		result = r;
5081 	}
5082 
5083 	return result;
5084 }
5085 
5086 
5087 
5088 
5089 /** \brief Retrieve the Vectors to the try action block.
5090  *
5091  * This function can be used to retrieve a direct pointer to the Vectors
5092  * holding the action block for the 'try' block.
5093  *
5094  * \return A pointer to the action list for the 'try' block
5095  */
SubListTry(void)5096 Vectors *ActionTry::SubListTry(void)
5097 {
5098 	return &f_actions_try;
5099 }
5100 
5101 
5102 /** \brief Retrieve the Vectors to the catch action block.
5103  *
5104  * This function can be used to retrieve a direct pointer to the Vectors
5105  * holding the action block for the 'catch' block.
5106  *
5107  * \warning
5108  * This function has the side effect of setting the catch block flag
5109  * to true, meaning that the catch block exists. You should always add
5110  * at least one item in the Vectors to validate this properly.
5111  *
5112  * \return A pointer to the action list for the 'catch' block
5113  */
SubListCatch(void)5114 Vectors *ActionTry::SubListCatch(void)
5115 {
5116 	f_has_catch = true;
5117 	return &f_actions_catch;
5118 }
5119 
5120 
5121 /** \brief Retrieve the Vectors to the finally action block.
5122  *
5123  * This function can be used to retrieve a direct pointer to the Vectors
5124  * holding the action block for the 'finally' block.
5125  *
5126  * \warning
5127  * This function has the side effect of setting the finally block flag
5128  * to true, meaning that the finally block exists. You should always add
5129  * at least one item in the Vectors to validate this properly.
5130  *
5131  * \return A pointer to the action list for the 'finally' block
5132  */
SubListFinally(void)5133 Vectors *ActionTry::SubListFinally(void)
5134 {
5135 	f_has_finally = true;
5136 	return &f_actions_finally;
5137 }
5138 
5139 
5140 /** \brief Save the ActionTry extraneous data.
5141  *
5142  * The SaveData() function saves the try, catch and finally blocks in
5143  * the nested_data and the try header in the Data buffers.
5144  *
5145  * Note that the maximum size for any one sub-block is 65535 bytes.
5146  * A larger sub-block will generate an error and the save will fail.
5147  *
5148  * This function should not be called until at least one of the
5149  * catch or finally block has been created.
5150  *
5151  * \param[in] data The Data buffer where the ActionTry header is saved
5152  * \param[in] nested_data This buffer is used to save the try, catch and finally blocks
5153  */
SaveData(Data & data,Data & nested_data)5154 ErrorManager::error_code_t ActionTry::SaveData(Data& data, Data& nested_data)
5155 {
5156 	Data				try_data, catch_data, finally_data;
5157 	unsigned long			try_size, catch_size, finally_size;
5158 	bool				bad;
5159 	ErrorManager::error_code_t	ec;
5160 
5161 	assert(f_has_finally || f_has_catch, "an ActionTry needs at least one of CATCH or FINALLY");
5162 	if(!f_has_finally && !f_has_catch) {
5163 		ec = OnError(ErrorManager::ERROR_CODE_INTERNAL_ERROR, "an ActionTry needs at least one of CATCH or FINALLY");
5164 	}
5165 	else {
5166 		ec = ErrorManager::ERROR_CODE_NONE;
5167 	}
5168 
5169 	ec = ErrorManager::KeepFirst(ec, SaveList(&f_actions_try, try_data));
5170 	ec = ErrorManager::KeepFirst(ec, SaveList(&f_actions_catch, catch_data));
5171 	ec = ErrorManager::KeepFirst(ec, SaveList(&f_actions_finally, finally_data));
5172 
5173 	// get rid of the ACTION_END
5174 	try_data.SetSize(try_data.GetSize() - CHAR_BIT);
5175 	catch_data.SetSize(catch_data.GetSize() - CHAR_BIT);
5176 	finally_data.SetSize(finally_data.GetSize() - CHAR_BIT);
5177 
5178 	try_size = try_data.ByteSize();
5179 	catch_size = catch_data.ByteSize();
5180 	finally_size = finally_data.ByteSize();
5181 
5182 	if((bad = try_size >= USHRT_MAX)) {
5183 		ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_ACTION_OVERFLOW, "too many nested instructions in a TRY; length overflow."));
5184 		bad = true;
5185 	}
5186 	if(catch_size >= USHRT_MAX) {
5187 		ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_ACTION_OVERFLOW, "too many nested instructions in a CATCH; length overflow."));
5188 		bad = true;
5189 	}
5190 	if(finally_size >= USHRT_MAX) {
5191 		ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_ACTION_OVERFLOW, "too many nested instructions in a FINALLY; length overflow."));
5192 		bad = true;
5193 	}
5194 	if(bad) {
5195 		try_size = 0;
5196 		catch_size = 0;
5197 		finally_size = 0;
5198 	}
5199 
5200 	data.WriteBits(0, 5);
5201 	data.WriteBits(f_register < 0 ? 0 : 1, 1);
5202 	data.WriteBits(f_has_finally, 1);
5203 	data.WriteBits(f_has_catch, 1);
5204 	data.PutShort((short) finally_size);
5205 	data.PutShort((short) catch_size);
5206 	data.PutShort((short) try_size);
5207 	if(f_register < 0) {
5208 		ec = ErrorManager::KeepFirst(ec, SaveString(data, f_variable_name));
5209 	}
5210 	else {
5211 		data.PutByte(f_register);
5212 	}
5213 	if(bad) {
5214 		return ec;
5215 	}
5216 
5217 	nested_data.Append(try_data);
5218 	nested_data.Append(catch_data);
5219 	nested_data.Append(finally_data);
5220 
5221 	return ec;
5222 }
5223 
5224 
5225 
5226 
5227 
5228 ////////////////////////////// Action URL
5229 
5230 /** \class sswf::ActionURL
5231  *
5232  * \brief Go to a static or dynamic URL.
5233  *
5234  * The ActionURL class is used to define a URL to load in the
5235  * user browser.
5236  *
5237  * Use the SetURL() or SetMethod() functions to setup this
5238  * action appropriately.
5239  *
5240  * \note
5241  * The ACTION_URL expects a SetURL() call.
5242  *
5243  * The ACTION_URL2 expects a SetMethod() call.
5244  *
5245  * If the ActionURL does not automatically choose which of the
5246  * ACTION_URL or ACTION_URL2 to save it is because the former
5247  * does not use the stack whereas the latter does. Thus this
5248  * action by itself cannot know which action to save.
5249  *
5250  * \sa <a href="../SWFalexref.html#action_get_url">SWF Alexis' Reference&mdash;Get URL</a>
5251  * \sa <a href="../SWFalexref.html#action_get_url2">SWF Alexis' Reference&mdash;Get URL 2</a>
5252  */
5253 
5254 
5255 /** \enum sswf::ActionURL::url_method_t
5256  *
5257  * \brief The different methods which can be used with the ActionURL
5258  *
5259  * The ActionURL can pass the data to the server with a GET, a POST
5260  * or with no variable.
5261  *
5262  * \sa sswf::ActionURL::URL_METHOD_UNDEFINED
5263  * \sa sswf::ActionURL::URL_METHOD_NOVARIABLE
5264  * \sa sswf::ActionURL::URL_METHOD_NOVARIABLES
5265  * \sa sswf::ActionURL::URL_METHOD_GET
5266  * \sa sswf::ActionURL::URL_METHOD_POST
5267  *
5268  * <hr>
5269  */
5270 
5271 
5272 /** \var sswf::ActionURL::URL_METHOD_UNDEFINED
5273  *
5274  * \brief The method is still undefined
5275  *
5276  * This is the default method value. It is required to be defined before
5277  * the action is saved in a Flash animation.
5278  *
5279  * <hr>
5280  */
5281 
5282 
5283 /** \var sswf::ActionURL::URL_METHOD_NOVARIABLE
5284  *
5285  * \brief Send the request without any variable
5286  *
5287  * Send the URL with no variable.
5288  *
5289  * <hr>
5290  */
5291 
5292 
5293 /** \var sswf::ActionURL::URL_METHOD_NOVARIABLES
5294  *
5295  * \brief Send the request without any variable
5296  *
5297  * Send the URL with no variable.
5298  *
5299  * <hr>
5300  */
5301 
5302 
5303 /** \var sswf::ActionURL::URL_METHOD_GET
5304  *
5305  * \brief Send the request using an HTTP GET
5306  *
5307  * Send the request as an HTTP GET with the variables
5308  * appended at the end of the URL.
5309  *
5310  * <hr>
5311  */
5312 
5313 
5314 /** \var sswf::ActionURL::URL_METHOD_POST
5315  *
5316  * \brief Send the request using an HTTP POST
5317  *
5318  * Send the request as an HTTP POST with the variables
5319  * sent one per line, starting on the line after the URL.
5320  */
5321 
5322 
5323 
5324 
5325 /** \brief Initialize the ActionURL action.
5326  *
5327  * The constructor defines default values to the different variable
5328  * members. It sets the URL to none, the target to none and the
5329  * method to URL_METHOD_NOVARIABLES.
5330  *
5331  * This function can be called with either ACTION_URL or
5332  * ACTION_URL2.
5333  *
5334  * \param[in] tag The tag in which this action is being added
5335  * \param[in] action The SWF action to save this action
5336  */
ActionURL(TagBase * tag,action_t action)5337 ActionURL::ActionURL(TagBase *tag, action_t action)
5338 	: Action(tag, action)
5339 {
5340 	assert(action == ACTION_URL || action == ACTION_URL2, "only ACTION_URL or ACTION_URL2 can be specified to the ActionURL object.");
5341 	if(action != ACTION_URL && action != ACTION_URL2) {
5342 		throw ErrorManager::InternalErrorException();
5343 	}
5344 	f_url = 0;
5345 	f_target = 0;
5346 	f_method = URL_METHOD_NOVARIABLES;
5347 }
5348 
5349 
5350 /** \brief Set the URL and target names.
5351  *
5352  * This function is used to define a valid URL and target.
5353  *
5354  * The target can be the name of a window or set to '_top'
5355  * to replace the content of the current window.
5356  *
5357  * This function assumes that you defined the action as
5358  * ACTION_URL.
5359  *
5360  * \param[in] url A standard URL (i.e. http://sswf.m2osw.com)
5361  * \param[in] target A window name or a standard HTML target
5362  */
SetURL(const char * url,const char * target)5363 void ActionURL::SetURL(const char *url, const char *target)
5364 {
5365 	MemFree(f_url);
5366 	MemFree(f_target);
5367 	f_url = StrDup(url);
5368 	f_target = StrDup(target);
5369 }
5370 
5371 
5372 /** \brief Set the method used to pass the URL to the browser.
5373  *
5374  * Set the method to use execute the URL, this assumes that you
5375  * defined this action as an ACTION_URL2. This is one of the
5376  * following values:
5377  *
5378  *	URL_METHOD_NOVARIABLE or URL_METHOD_NOVARIABLES
5379  *	URL_METHOD_GET
5380  *	URL_METHOD_POST
5381  *
5382  * \param[in] method One of the available methods
5383  */
SetMethod(url_method_t method)5384 void ActionURL::SetMethod(url_method_t method)
5385 {
5386 	f_method = method;
5387 }
5388 
5389 
5390 /** \brief Create a clone of this action.
5391  *
5392  * This function creates a new ActionURL object and copy the
5393  * URL, target and method in it. Finally, it returns the pointer
5394  * to the new action.
5395  *
5396  * \return The pointer to the clone action
5397  */
Duplicate(void) const5398 Action *ActionURL::Duplicate(void) const
5399 {
5400 	ActionURL	*a;
5401 
5402 	a = new ActionURL(Tag(), f_action);
5403 	a->SetURL(f_url, f_target);
5404 	a->SetMethod(f_method);
5405 
5406 	return a;
5407 }
5408 
5409 
5410 /** \brief Save the action extraneous data in the Data buffer.
5411  *
5412  * This function saves the URL/target information (ACTION_URL) or
5413  * the method (ACTION_URL2) in the the Data buffer.
5414  *
5415  * \param[in] data The Data buffer where the URL information is saved
5416  * \param[in] nested_data There is no nested data in an ActionURL
5417  */
SaveData(Data & data,Data & nested_data)5418 ErrorManager::error_code_t ActionURL::SaveData(Data& data, Data& nested_data)
5419 {
5420 	if(f_action == ACTION_URL) {
5421 		ErrorManager::error_code_t ec = SaveString(data, f_url);
5422 		return ErrorManager::KeepFirst(ec, SaveString(data, f_target));
5423 	}
5424 
5425 	data.PutByte(f_method);
5426 
5427 	return ErrorManager::ERROR_CODE_NONE;
5428 }
5429 
5430 
5431 
5432 
5433 
5434 
5435 ////////////////////////////// Action WAIT FOR FRAME
5436 
5437 /** \class sswf::ActionWaitForFrame
5438  *
5439  * \brief Create an action used to wait for a frame to be loaded.
5440  *
5441  * This class creates an action one can use to wait for a certain
5442  * frame to be saved. As long as that frame is not loaded, the
5443  * sub-actions are skipped. Once the frame was loaded, the actions
5444  * are executed. These actions can result in the execution of the
5445  * rest of the movie.
5446  *
5447  * \warning
5448  * The WaitForFrame action uses a byte to define the number of the
5449  * sub-actions to skip. That means a maximum of 255 actions, which is
5450  * relatively small for an ActionScript. In general, you can bypass
5451  * the problem by calling a function.
5452  *
5453  * \note
5454  * This is 255 actions. Thus in bytes it can be much larger. However,
5455  * do NOT try to define a function or an object within this block.
5456  * It is likely to fail.
5457  *
5458  * \bug
5459  * It could be that the ACTION_WAIT_FOR_FRAME and ACTION_WAIT_FOR_FRAME2
5460  * should each have its own class since the dynamic version should
5461  * not be given a frame name (it is taken dynamically!). On the other
5462  * hand it could be that I could change the code and if you define a
5463  * frame name then I force the ACTION_WAIT_FOR_FRAME and by default
5464  * I would use ACTION_WAIT_FOR_FRAME2. In this latter case, I would
5465  * need a PreSave() to determine the action before to save the result.
5466  *
5467  * \sa <a href="../SWFalexref.html#action_wait_for_frame">SWF Alexis' Reference&mdash;Wait For Frame</a>
5468  * \sa <a href="../SWFalexref.html#action_wait_for_frame_dynamic">SWF Alexis' Reference&mdash;Wait For Frame <i>(dynamic)</i></a>
5469  */
5470 
5471 /** \brief Initialize the ActionWaitForFrame object.
5472  *
5473  * This constructor initializes the ActionWaitForFrame object with
5474  * a frame with no name and no actions.
5475  *
5476  * The action parameter can be set to:
5477  *
5478  *	ACTION_WAIT_FOR_FRAME
5479  *	ACTION_WAIT_FOR_FRAME2
5480  *
5481  * \param[in] tag The tag in which this action is being added
5482  * \param[in] action One of the wait for action codes
5483  */
ActionWaitForFrame(TagBase * tag,action_t action)5484 ActionWaitForFrame::ActionWaitForFrame(TagBase *tag, action_t action)
5485 	: Action(tag, action)
5486 {
5487 	assert(action == ACTION_WAIT_FOR_FRAME || action == ACTION_WAIT_FOR_FRAME2, "the action of an ActionWaitForFrame needs to be ACTION_WAIT_FOR_FRAME or ACTION_WAIT_FOR_FRAME2");
5488 	if(action != ACTION_WAIT_FOR_FRAME && action != ACTION_WAIT_FOR_FRAME2) {
5489 		throw ErrorManager::InternalErrorException();
5490 	}
5491 	// f_actions = ... -- auto-init with Vectors constructor
5492 	f_frame_name = 0;
5493 }
5494 
5495 
5496 /** \brief Set the name of the frame to wait for.
5497  *
5498  * In case you used ACTION_WAIT_FOR_FRAME, this is the name of
5499  * the frame to wait for.
5500  *
5501  * \param[in] frame_name The name of the frame to wait for
5502  */
SetFrameName(const char * frame_name)5503 void ActionWaitForFrame::SetFrameName(const char *frame_name)
5504 {
5505 	MemFree(f_frame_name);
5506 	f_frame_name = StrDup(frame_name);
5507 }
5508 
5509 
5510 /** \brief Add a sub-action to the wait frame action.
5511  *
5512  * This function adds a sub-action to execute once the movie loaded the
5513  * specified frame.
5514  *
5515  * You can also access the list of sub-actions using the
5516  * sswf::ActioWaitForFrame::SubList() function.
5517  *
5518  * Note that the total number of these actions is 255 (and not
5519  * 255 bytes!) This makes it difficult to read this action.
5520  *
5521  * \param[in] action The action to append to this wait for frame
5522  */
AddAction(Action * action)5523 void ActionWaitForFrame::AddAction(Action *action)
5524 {
5525 	f_actions.Set(-1, action);
5526 }
5527 
5528 
5529 /** \brief Create a clone of this action.
5530  *
5531  * This function creates a new ActionWaitForFrame and copies the
5532  * frame name and all the sub-actions in it. Finally, it returns
5533  * the pointer of the new action.
5534  *
5535  * \return The pointer of the clone action
5536  */
Duplicate(void) const5537 Action *ActionWaitForFrame::Duplicate(void) const
5538 {
5539 	ActionWaitForFrame	*w;
5540 	Action			*a;
5541 	int			idx, max;
5542 
5543 	w = new ActionWaitForFrame(Tag(), f_action);
5544 	w->SetFrameName(f_frame_name);
5545 	max = f_actions.Count();
5546 	for(idx = 0; idx < max; idx++) {
5547 		a = dynamic_cast<Action *>(f_actions.Get(idx));
5548 		w->AddAction(a->Duplicate());
5549 	}
5550 
5551 	return w;
5552 }
5553 
5554 
5555 /** \brief Return the Vectors holding the sub-actions.
5556  *
5557  * This function is used to retrieve the pointer of the Vectors
5558  * used to register all the sub-actions of this ActionWaitForFrame
5559  * object.
5560  *
5561  * \return The Vectors pointers of the sub-actions
5562  */
SubList(void)5563 Vectors *ActionWaitForFrame::SubList(void)
5564 {
5565 	return &f_actions;
5566 }
5567 
5568 
5569 /** \brief Save the extraneous data of the ActionWaitForFrame object.
5570  *
5571  * This function saves the frame number (ACTION_WAIT_FOR_FRAME) and
5572  * the number of nested actions.
5573  *
5574  * If the specified frame is not found or no frame name is specified
5575  * for an ACTION_WAIT_FOR_FRAME, then an error results.
5576  *
5577  * \param[in] data The Data buffer where the information is saved
5578  * \param[in] nested_data The Action::Save() function defines this buffer,
5579  * 		this function does not need it since the size is not
5580  * 		what is saved in these actions
5581  */
SaveData(Data & data,Data & nested_data)5582 ErrorManager::error_code_t ActionWaitForFrame::SaveData(Data& data, Data& nested_data)
5583 {
5584 	TagBase				*tag;
5585 	ErrorManager::error_code_t	ec;
5586 
5587 	ec = ErrorManager::ERROR_CODE_NONE;
5588 
5589 	if(f_actions.Count() > 255) {
5590 		ec = OnError(ErrorManager::ERROR_CODE_ACTION_OVERFLOW, "too many actions within a WaitForFrame; please, use branches as may be required.");
5591 	}
5592 
5593 	if(f_action == ACTION_WAIT_FOR_FRAME) {
5594 		if(f_frame_name == 0 || *f_frame_name == '\0') {
5595 			// we save the frame name within the tag in this case
5596 			// so we actually need it!
5597 			ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_MISSING_FRAME_NAME, "a frame name was expected for action WaitForFrame."));
5598 			data.PutShort(0);	// a default, just so the file is not boggus.
5599 		}
5600 		else {
5601 			tag = Tag()->FindLabelledTag(f_frame_name);
5602 			if(tag == 0) {
5603 				/* ha! couldn't find this object... */
5604 				ec = ErrorManager::KeepFirst(ec, OnError(ErrorManager::ERROR_CODE_OBJECT_NOT_FOUND, "cannot find any tag labelled '%s'.", f_frame_name));
5605 				data.PutShort(0);	// a default, just so the file is not boggus.
5606 			}
5607 			else {
5608 				data.PutShort(tag->WhichFrame());
5609 			}
5610 		}
5611 	}
5612 
5613 	data.PutByte(f_actions.Count());
5614 
5615 	return ec;
5616 }
5617 
5618 
5619 ////////////////////////////// Action WITH
5620 
5621 /** \class sswf::ActionWith
5622  *
5623  * \brief Block including variable member names refering to the With object.
5624  *
5625  * This action is supposed to be useful to optimize JavaScript code by
5626  * not having to fully qualify variables by their respective object name.
5627  *
5628  * For instance, the following code:
5629  *
5630  *	\code
5631  *	obj.a = 1;
5632  *	obj.b = 2;
5633  *	obj.c = 3;
5634  *	obj.d = 4;
5635  *	obj.e = 5;
5636  *	\endcode
5637  *
5638  * can be simplified using a 'with' instruction as follow:
5639  *
5640  *	\code
5641  *	with obj {
5642  *		a = 1;
5643  *		b = 2;
5644  *		c = 3;
5645  *		d = 4;
5646  *		e = 5;
5647  *	}
5648  *	\endcode
5649  *
5650  * \sa <a href="../SWFalexref.html#action_with">SWF Alexis' Reference&mdash;With</a>
5651  */
5652 
5653 /** \brief Initialize the ActionWith object.
5654  *
5655  * This function initialize the 'with' object by making the 'with' block
5656  * empty.
5657  *
5658  * \param[in] tag The tag where the With is inserted
5659  */
ActionWith(TagBase * tag)5660 ActionWith::ActionWith(TagBase *tag)
5661 	: Action(tag, ACTION_WITH)
5662 {
5663 }
5664 
5665 
5666 /** \brief Add an action to the 'with' block.
5667  *
5668  * The 'with' block is a list of actions which can be grown using this
5669  * function. Note that you can have several levels of 'with' (i.e. within
5670  * a 'with' block you can have another 'with' block to a depth of 7 up to
5671  * version 5 of SWF, and 15 in version 6 of SWF.)
5672  *
5673  * Of course, it can be quite tedious to know what variable reference
5674  * which object when all the objects have variable and function members
5675  * of the same name (it should be the inner most object which has a match.)
5676  *
5677  * Note that the action being added is not duplicated.
5678  *
5679  * \param[in] action The pointer to the action to add to this ActionWith
5680  */
AddAction(Action * action)5681 void ActionWith::AddAction(Action *action)
5682 {
5683 	f_actions.Set(-1, action);
5684 }
5685 
5686 
5687 /** \brief Create a clone of this ActionWith object.
5688  *
5689  * This function creates a new ActionWith object and copies all the
5690  * actions of 'this' ActionWith in it. Finally, it returns a pointer
5691  * to the newly allocated object.
5692  *
5693  * \return The newly allocated action pointer
5694  */
Duplicate(void) const5695 Action *ActionWith::Duplicate(void) const
5696 {
5697 	ActionWith	*w;
5698 	Action		*a;
5699 	int		max, idx;
5700 
5701 	w = new ActionWith(Tag());
5702 	max = f_actions.Count();
5703 	for(idx = 0; idx < max; idx++) {
5704 		a = dynamic_cast<Action *>(f_actions.Get(idx));
5705 		w->AddAction(a->Duplicate());
5706 	}
5707 
5708 	return w;
5709 }
5710 
5711 
5712 /** \brief The sub-list of actions of this ActionWith.
5713  *
5714  * This function returns a direct pointer to the Vectors of this
5715  * ActioWith object. This Vectors array holds all the actions to
5716  * execute once the specified frame was loaded.
5717  *
5718  * Do not forget that the actions are limited to a byte size of
5719  * 65535 in the outer most ActionWith object.
5720  *
5721  * \return A Vectors pointer to fill with actions
5722  */
SubList(void)5723 Vectors *ActionWith::SubList(void)
5724 {
5725 	return &f_actions;
5726 }
5727 
5728 
5729 /** \brief Save the byte size of the nested data.
5730  *
5731  * This function saves the extraneous data for an ActionWith object
5732  * which is the size of the nested data buffer in bytes.
5733  *
5734  * \param[in] data The Data buffer where the size is to be saved
5735  * \param[in] nested_data The Data buffer which holds the sub-actions
5736  */
SaveData(Data & data,Data & nested_data)5737 ErrorManager::error_code_t ActionWith::SaveData(Data& data, Data& nested_data)
5738 {
5739 	// the actions were already saved by the Action::Save() function!
5740 	data.PutShort((unsigned short) nested_data.ByteSize());
5741 
5742 	return ErrorManager::ERROR_CODE_NONE;
5743 }
5744 
5745 
5746 
5747 /* The following options fold the documentation; use 'zi' to turn on and off
5748  *
5749  * vim: foldexpr=getline(v\:lnum)!~'^/\\*\\*'&&getline(v\:lnum)!~'^\ \\*'?0\:1 foldcolumn=2 foldmethod=expr
5750  */
5751