package
{
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.desktop.*;
import flash.errors.*;
import flash.system.*;
import flash.utils.*;
import by.blooddy.crypto.*;
public class Exporter extends MovieClip
{
public static var Instance:Exporter = null;
public static var DefaultPort:int = 7890;
private var driver:Socket = null;
public function Exporter()
{
Instance = this;
try
{
NativeApplication.nativeApplication.addEventListener("invoke", ApplicationInvoked);
}
catch (e)
{
// not an air runtime app
ConnectDriver(DefaultPort); // try default port
}
}
public function ApplicationInvoked(e)
{
if (e.arguments.length == 1)
{
ConnectDriver(parseInt(e.arguments[0]));
}
else
{
ConnectDriver(DefaultPort);
}
}
private function ConnectDriver(port)
{
Trace("Attempting to connect to driver");
try
{
var s:Socket = new Socket();
s.addEventListener(IOErrorEvent.IO_ERROR, DriverError);
s.addEventListener(Event.CONNECT, DriverConnected);
s.connect("localhost", port);
}
catch (e)
{
Trace("Error establishing wrapper connection");
}
}
private function DriverError(e)
{
Trace(" Failed to connect");
}
private function DriverConnected(e)
{
Trace(" Connected");
driver = e.target as Socket;
driver.addEventListener(ProgressEvent.SOCKET_DATA, DriverRecv);
}
private function Quit()
{
fscommand("quit");
try
{
NativeApplication.nativeApplication.exit();
} catch (e)
{
}
}
private var jobQueue:Array = new Array();
private var activeJob:Job = null;
private function QueueJob(jobParams)
{
var input:ByteArray = null;
if (jobParams.hasOwnProperty("input"))
{
input = Base64.decode("" + jobParams.input);
}
if (!jobParams.hasOwnProperty("id"))
{
Print("Failure: job details didn't contain job id");
CheckNewJob();
return;
}
var id:int = parseInt(jobParams.id);
if (!jobParams.hasOwnProperty("name"))
{
Print("Failure: job " + id + " details didn't contain job name");
JobFailed(id);
return;
}
var name:String = "" + jobParams.name;
delete jobParams.command;
delete jobParams.input;
delete jobParams.id;
var job:Job = new Job(id, name, input, jobParams);
jobQueue.push(job);
CheckNewJob();
}
private function JobFailed(id:int)
{
DriverCommand("done", {id:id});
CheckNewJob();
}
private function CheckNewJob()
{
if (activeJob == null && jobQueue.length > 0)
{
activeJob = jobQueue.shift();
activeJob.Go(JobComplete);
}
}
private function JobComplete()
{
Trace("Done: " + activeJob.GetID());
DriverCommand("done", activeJob.GetCompletedData());
activeJob = null;
CheckNewJob();
}
private function DispatchCommand(cmdData)
{
try
{
if (cmdData.hasOwnProperty("command"))
{
var cmd = "" + cmdData.command;
//Trace("cmd: " + cmd);
switch (cmd)
{
case "trace":
Trace(cmdData.string);
break;
case "exit":
Quit();
break;
case "job":
QueueJob(cmdData);
break;
default:
Trace("Recv unknown: " + JSON.stringify(cmdData));
break;
}
}
} catch (e)
{
Print(e.getStackTrace());
}
}
private var buffer:ByteArray = new ByteArray();
private var swpBuffer:ByteArray = new ByteArray();
private function DriverRecv(e)
{
var oldPos = buffer.position;
//Trace("recv");
try
{
driver.readBytes(buffer, buffer.length, driver.bytesAvailable);
//Trace(buffer.length - buffer.position);
var msg = buffer.readUTF();
buffer.readBytes(swpBuffer);
buffer.clear();
var tmp = buffer;
buffer = swpBuffer;
swpBuffer = tmp;
var cmdData = JSON.parse(msg);
DispatchCommand(cmdData);
}
catch (eof:EOFError)
{
buffer.position = oldPos;
//Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position));
// wait for more data
}
catch (err:IOError)
{
Trace("Driver IO error");
}
catch (err)
{
Trace("Problem reading from driver:\n" + err.toString());
}
}
private function DriverCommand(cmd:String, data = null)
{
var obj = {command:cmd};
if (data != null)
{
for (var k in data)
{
obj[k] = data[k];
}
}
DriverSend(JSON.stringify(obj));
}
private function DriverSend(str:String)
{
if (driver != null)
{
Trace(str);
driver.writeUTF(str);
driver.flush();
}
}
public function Trace(str)
{
str = "" + str;
traceText.x = 2;
trace(str);
traceText.width = stage.stageWidth - 4;
traceText.height = stage.stageHeight - 4;
if (traceText.text == "")
{
traceText.text = str;
}
else
{
traceText.appendText("\n" + str);
}
traceText.y = stage.height - traceText.textHeight - 2;
}
public function Print(str:String, localTrace:Boolean = true)
{
if (localTrace || driver == null)
{
Trace(str);
}
else
{
trace(str);
}
if (driver != null)
{
DriverCommand("print", {string:str + "\n"});
}
}
}
}