/*
* JSwiff is an open source Java API for Macromedia Flash file generation
* and manipulation
*
* Copyright (C) 2004-2005 Ralf Terdic (contact@jswiff.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.jswiff.xml;
import com.jswiff.swfrecords.RegisterParam;
import com.jswiff.swfrecords.actions.*;
import com.jswiff.util.Base64;
import org.dom4j.Attribute;
import org.dom4j.Element;
import java.util.Iterator;
import java.util.List;
class ActionXMLReader {
static Action readAction(Element element) {
String name = element.getName();
Action action;
if (name.equals("add")) {
action = new Add();
} else if (name.equals("add2")) {
action = new Add2();
} else if (name.equals("and")) {
action = new And();
} else if (name.equals("asciitochar")) {
action = new AsciiToChar();
} else if (name.equals("bitand")) {
action = new BitAnd();
} else if (name.equals("bitlshift")) {
action = new BitLShift();
} else if (name.equals("bitor")) {
action = new BitOr();
} else if (name.equals("bitrshift")) {
action = new BitRShift();
} else if (name.equals("biturshift")) {
action = new BitURShift();
} else if (name.equals("bitxor")) {
action = new BitXor();
} else if (name.equals("call")) {
action = new Call();
} else if (name.equals("callfunction")) {
action = new CallFunction();
} else if (name.equals("callmethod")) {
action = new CallMethod();
} else if (name.equals("castop")) {
action = new CastOp();
} else if (name.equals("chartoascii")) {
action = new CharToAscii();
} else if (name.equals("clonesprite")) {
action = new CloneSprite();
} else if (name.equals("constantpool")) {
action = readConstantPool(element);
} else if (name.equals("decrement")) {
action = new Decrement();
} else if (name.equals("definefunction")) {
action = readDefineFunction(element);
} else if (name.equals("definefunction2")) {
action = readDefineFunction2(element);
} else if (name.equals("definelocal")) {
action = new DefineLocal();
} else if (name.equals("definelocal2")) {
action = new DefineLocal2();
} else if (name.equals("delete")) {
action = new Delete();
} else if (name.equals("delete2")) {
action = new Delete2();
} else if (name.equals("divide")) {
action = new Divide();
} else if (name.equals("enddrag")) {
action = new EndDrag();
} else if (name.equals("enumerate")) {
action = new Enumerate();
} else if (name.equals("enumerate2")) {
action = new Enumerate2();
} else if (name.equals("equals")) {
action = new Equals();
} else if (name.equals("equals2")) {
action = new Equals2();
} else if (name.equals("extends")) {
action = new Extends();
} else if (name.equals("getmember")) {
action = new GetMember();
} else if (name.equals("getproperty")) {
action = new GetProperty();
} else if (name.equals("gettime")) {
action = new GetTime();
} else if (name.equals("geturl")) {
action = readGetURL(element);
} else if (name.equals("geturl2")) {
action = readGetURL2(element);
} else if (name.equals("getvariable")) {
action = new GetVariable();
} else if (name.equals("gotoframe")) {
action = readGoToFrame(element);
} else if (name.equals("gotoframe2")) {
action = readGoToFrame2(element);
} else if (name.equals("gotolabel")) {
action = readGoToLabel(element);
} else if (name.equals("greater")) {
action = new Greater();
} else if (name.equals("if")) {
action = readIf(element);
} else if (name.equals("implementsop")) {
action = new ImplementsOp();
} else if (name.equals("increment")) {
action = new Increment();
} else if (name.equals("initarray")) {
action = new InitArray();
} else if (name.equals("initobject")) {
action = new InitObject();
} else if (name.equals("instanceof")) {
action = new InstanceOf();
} else if (name.equals("jump")) {
action = readJump(element);
} else if (name.equals("less")) {
action = new Less();
} else if (name.equals("less2")) {
action = new Less2();
} else if (name.equals("mbasciitochar")) {
action = new MBAsciiToChar();
} else if (name.equals("mbchartoascii")) {
action = new MBCharToAscii();
} else if (name.equals("mbstringextract")) {
action = new MBStringExtract();
} else if (name.equals("mbstringlength")) {
action = new MBStringLength();
} else if (name.equals("modulo")) {
action = new Modulo();
} else if (name.equals("multiply")) {
action = new Multiply();
} else if (name.equals("newmethod")) {
action = new NewMethod();
} else if (name.equals("newobject")) {
action = new NewObject();
} else if (name.equals("nextframe")) {
action = new NextFrame();
} else if (name.equals("not")) {
action = new Not();
} else if (name.equals("or")) {
action = new Or();
} else if (name.equals("play")) {
action = new Play();
} else if (name.equals("pop")) {
action = new Pop();
} else if (name.equals("previousframe")) {
action = new PreviousFrame();
} else if (name.equals("push")) {
action = readPush(element);
} else if (name.equals("pushduplicate")) {
action = new PushDuplicate();
} else if (name.equals("randomnumber")) {
action = new RandomNumber();
} else if (name.equals("removesprite")) {
action = new RemoveSprite();
} else if (name.equals("return")) {
action = new Return();
} else if (name.equals("setmember")) {
action = new SetMember();
} else if (name.equals("setproperty")) {
action = new SetProperty();
} else if (name.equals("settarget")) {
action = readSetTarget(element);
} else if (name.equals("settarget2")) {
action = new SetTarget2();
} else if (name.equals("setvariable")) {
action = new SetVariable();
} else if (name.equals("stackswap")) {
action = new StackSwap();
} else if (name.equals("startdrag")) {
action = new StartDrag();
} else if (name.equals("stop")) {
action = new Stop();
} else if (name.equals("stopsounds")) {
action = new StopSounds();
} else if (name.equals("storeregister")) {
action = readStoreRegister(element);
} else if (name.equals("strictequals")) {
action = new StrictEquals();
} else if (name.equals("stringadd")) {
action = new StringAdd();
} else if (name.equals("stringequals")) {
action = new StringEquals();
} else if (name.equals("stringextract")) {
action = new StringExtract();
} else if (name.equals("stringgreater")) {
action = new StringGreater();
} else if (name.equals("stringlength")) {
action = new StringLength();
} else if (name.equals("stringless")) {
action = new StringLess();
} else if (name.equals("subtract")) {
action = new Subtract();
} else if (name.equals("targetpath")) {
action = new TargetPath();
} else if (name.equals("throw")) {
action = new Throw();
} else if (name.equals("tointeger")) {
action = new ToInteger();
} else if (name.equals("tonumber")) {
action = new ToNumber();
} else if (name.equals("tostring")) {
action = new ToString();
} else if (name.equals("togglequality")) {
action = new ToggleQuality();
} else if (name.equals("trace")) {
action = new Trace();
} else if (name.equals("try")) {
action = readTry(element);
} else if (name.equals("typeof")) {
action = new TypeOf();
} else if (name.equals("waitforframe")) {
action = readWaitForFrame(element);
} else if (name.equals("waitforframe2")) {
action = readWaitForFrame2(element);
} else if (name.equals("with")) {
action = readWith(element);
} else if (name.equals("unknownaction")) {
action = readUnknownAction(element);
} else {
throw new IllegalArgumentException(
"Unexpected action record name: " + name);
}
Attribute label = element.attribute("label");
if (label != null) {
action.setLabel(label.getValue());
}
return action;
}
private static ConstantPool readConstantPool(Element element) {
List constantElements = element.elements();
ConstantPool constantPool = new ConstantPool();
List constants = constantPool.getConstants();
for (Iterator it = constantElements.iterator(); it.hasNext();) {
Element constantElement = (Element) it.next();
String content = RecordXMLReader.getElement(
"value", constantElement).getText();
String constant = (RecordXMLReader.getBooleanAttribute(
"base64", constantElement)) ? Base64.decodeString(content) : content;
constants.add(constant);
}
return constantPool;
}
private static DefineFunction readDefineFunction(Element element) {
String name = RecordXMLReader.getStringAttribute(
"name", element);
List parameterElements = RecordXMLReader.getElement("parameters", element)
.elements();
int arrayLength = parameterElements.size();
String[] parameters = new String[arrayLength];
for (int i = 0; i < arrayLength; i++) {
Element parameterElement = (Element) parameterElements.get(i);
parameters[i] = RecordXMLReader.getStringAttribute(
"name", parameterElement);
}
DefineFunction defineFunction = new DefineFunction(name, parameters);
RecordXMLReader.readActionBlock(defineFunction.getBody(), element);
return defineFunction;
}
private static DefineFunction2 readDefineFunction2(Element element) {
String name = RecordXMLReader.getStringAttribute(
"name", element);
short registerCount = RecordXMLReader.getShortAttribute(
"registercount", element);
List parameterElements = RecordXMLReader.getElement(
"parameters", element).elements();
int arrayLength = parameterElements.size();
RegisterParam[] parameters = new RegisterParam[arrayLength];
for (int i = 0; i < arrayLength; i++) {
Element parameterElement = (Element) parameterElements.get(i);
String paramName = RecordXMLReader.getStringAttribute(
"name", parameterElement);
short register = RecordXMLReader.getShortAttribute(
"register", parameterElement);
parameters[i] = new RegisterParam(register, paramName);
}
DefineFunction2 defineFunction2 = new DefineFunction2(
name, registerCount, parameters);
Element preloadElement = RecordXMLReader.getElement(
"preload", element);
if (RecordXMLReader.getBooleanAttribute("arguments", preloadElement)) {
defineFunction2.preloadArguments();
}
if (RecordXMLReader.getBooleanAttribute("global", preloadElement)) {
defineFunction2.preloadGlobal();
}
if (RecordXMLReader.getBooleanAttribute("parent", preloadElement)) {
defineFunction2.preloadParent();
}
if (RecordXMLReader.getBooleanAttribute("root", preloadElement)) {
defineFunction2.preloadRoot();
}
if (RecordXMLReader.getBooleanAttribute("super", preloadElement)) {
defineFunction2.preloadSuper();
}
if (RecordXMLReader.getBooleanAttribute("this", preloadElement)) {
defineFunction2.preloadThis();
}
Element suppressElement = RecordXMLReader.getElement("suppress", element);
if (RecordXMLReader.getBooleanAttribute("arguments", suppressElement)) {
defineFunction2.suppressArguments();
}
if (RecordXMLReader.getBooleanAttribute("super", suppressElement)) {
defineFunction2.suppressSuper();
}
if (RecordXMLReader.getBooleanAttribute("this", suppressElement)) {
defineFunction2.suppressThis();
}
RecordXMLReader.readActionBlock(defineFunction2.getBody(), element);
return defineFunction2;
}
private static GetURL readGetURL(Element element) {
String url = RecordXMLReader.getStringAttribute("url", element);
String target = RecordXMLReader.getStringAttribute("target", element);
return new GetURL(url, target);
}
private static GetURL2 readGetURL2(Element element) {
String sendVarsMethodString = RecordXMLReader.getStringAttribute(
"sendvarsmethod", element);
byte sendVarsMethod;
if (sendVarsMethodString.equals("get")) {
sendVarsMethod = GetURL2.METHOD_GET;
} else if (sendVarsMethodString.equals("post")) {
sendVarsMethod = GetURL2.METHOD_POST;
} else if (sendVarsMethodString.equals("none")) {
sendVarsMethod = GetURL2.METHOD_NONE;
} else {
throw new IllegalArgumentException(
"Illegal sendvars method: " + sendVarsMethodString);
}
boolean loadTarget = RecordXMLReader.getBooleanAttribute(
"loadtarget", element);
boolean loadVariables = RecordXMLReader.getBooleanAttribute(
"loadvariables", element);
return new GetURL2(sendVarsMethod, loadTarget, loadVariables);
}
private static GoToFrame readGoToFrame(Element element) {
return new GoToFrame(RecordXMLReader.getIntAttribute("frame", element));
}
private static GoToFrame2 readGoToFrame2(Element element) {
boolean play = RecordXMLReader.getBooleanAttribute("play", element);
int sceneBias = RecordXMLReader.getIntAttribute("scenebias", element);
return new GoToFrame2(play, sceneBias);
}
private static GoToLabel readGoToLabel(Element element) {
return new GoToLabel(
RecordXMLReader.getStringAttribute("framelabel", element));
}
private static If readIf(Element element) {
return new If(RecordXMLReader.getStringAttribute("branchlabel", element));
}
private static Jump readJump(Element element) {
return new Jump(RecordXMLReader.getStringAttribute("branchlabel", element));
}
private static Push readPush(Element element) {
List valueElements = element.elements();
Push push = new Push();
for (Iterator it = valueElements.iterator(); it.hasNext();) {
Element valueElement = (Element) it.next();
String type = valueElement.getName();
StackValue value = new StackValue();
if (type.equals("boolean")) {
value.setBoolean(
RecordXMLReader.getBooleanAttribute("value", valueElement));
} else if (type.equals("constant16")) {
value.setConstant16(
RecordXMLReader.getIntAttribute("id", valueElement));
} else if (type.equals("constant8")) {
value.setConstant8(
RecordXMLReader.getShortAttribute("id", valueElement));
} else if (type.equals("double")) {
value.setDouble(
RecordXMLReader.getDoubleAttribute("value", valueElement));
} else if (type.equals("float")) {
value.setFloat(
RecordXMLReader.getFloatAttribute("value", valueElement));
} else if (type.equals("integer")) {
value.setInteger(
RecordXMLReader.getIntAttribute("value", valueElement));
} else if (type.equals("null")) {
value.setNull();
} else if (type.equals("register")) {
value.setRegisterNumber(
RecordXMLReader.getShortAttribute("number", valueElement));
} else if (type.equals("string")) {
value.setString(
RecordXMLReader.getStringAttribute("value", valueElement));
} else if (type.equals("undefined")) {
value.setUndefined();
} else {
throw new IllegalArgumentException(
"Unexpected stack value type: " + type);
}
push.addValue(value);
}
return push;
}
private static SetTarget readSetTarget(Element element) {
return new SetTarget(RecordXMLReader.getStringAttribute("name", element));
}
private static StoreRegister readStoreRegister(Element element) {
return new StoreRegister(
RecordXMLReader.getShortAttribute("number", element));
}
private static Try readTry(Element element) {
Try tryAction;
Attribute catchRegister = element.attribute("catchregister");
if (catchRegister != null) {
tryAction = new Try(Short.parseShort(catchRegister.getValue()));
} else {
Attribute catchVariable = element.attribute("catchvariable");
if (catchVariable != null) {
tryAction = new Try(catchVariable.getValue());
} else {
throw new MissingNodeException(
"Neither catch register nor catch variable specified within try action!");
}
}
RecordXMLReader.readActionBlock(
tryAction.getTryBlock(), RecordXMLReader.getElement("try", element));
Element catchElement = element.element("catch");
if (catchElement != null) {
RecordXMLReader.readActionBlock(tryAction.getCatchBlock(), catchElement);
}
Element finallyElement = element.element("finally");
if (finallyElement != null) {
RecordXMLReader.readActionBlock(
tryAction.getFinallyBlock(), finallyElement);
}
return tryAction;
}
private static UnknownAction readUnknownAction(Element element) {
return new UnknownAction(
RecordXMLReader.getShortAttribute("code", element),
Base64.decode(element.getText()));
}
private static WaitForFrame readWaitForFrame(Element element) {
int frame = RecordXMLReader.getIntAttribute("frame", element);
short skipCount = RecordXMLReader.getShortAttribute("skipcount", element);
return new WaitForFrame(frame, skipCount);
}
private static WaitForFrame2 readWaitForFrame2(Element element) {
return new WaitForFrame2(
RecordXMLReader.getShortAttribute("skipcount", element));
}
private static With readWith(Element element) {
With with = new With();
RecordXMLReader.readActionBlock(with.getWithBlock(), element);
return with;
}
}