Writing and saving XML with AS3 - actionscript-3

I want to create a XML file and fill it with generated data. Here is a code I have. There is no error but it does not create any file under same folder. It is a AIR Desktop project and if I change it to FileReference option that pops up a dialog box and can successfully save.
var objects = ["one","two","three"];
var values = ["1", "2", "3"];
var file = new File();
var fileStream = new FileStream();
file = File.applicationStorageDirectory.resolvePath("ayara.xml");
var myXmlTag = "<ayar>";
for(var lp:int = 0; lp < 1; lp++)
{
myXmlTag += "<Etkinlik>"
for(var i = 0; i < objects.length; i++)
{
myXmlTag += "<" + objects[i] + ">" + values[i] + "</" + objects[i] + ">";
}
myXmlTag += "</Etkinlik>"
}
myXmlTag += "</ayar>";
var xmlfinal:XML = XML(myXmlTag );
fileStream.openAsync(file, FileMode.WRITE);
fileStream.writeUTF(xmlfinal);
Am I missing something or executing things in wrong way? I have checked posts about handling XML files and there is nothing much different from that.

Related

How to write a sequence of bytes to binary file using JScript?

I'm trying to write Array(1, 2) to binary file as bytes.
So output file should contain 00000001 00000010.
I understood that I have to use ADODB.Stream, but I haven't found any solution for such simple task.
var data = new Array(1, 2)
out = WScript.CreateObject("ADODB.Stream")
out.Type = 1
out.Open()
out.Write(data)
out.SaveToFile("output.bin", 2)
out.Close()
Code above gives error:
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
Any ideas how to convert data array to acceptable type?
You can use the WriteAll function described here: Reading and Writing Binary Files Using JScript. Copyright: Dr Alexander J Turner.
Please note, the Stream shall be of type text, and then you will need to do the text<->binary conversion.
I just tested all the code and it worked fine for me.
Here is a complete example:
var bf1 = new BinaryFile("C:/Temp/test.bin");
var outBuf = '';
for(var i=0, l=data.length; i<l; i++) {
outBuf += String.fromCharCode(data[i]);
}
bf1.WriteAll(outBuf);
The result looks like this:
EDIT:
I just did a more compact adaptation of the code, to avoid the hex conversion and the double loop:
// Codepage conversion table
var _c=[199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,
201,230,198,244,246,242,251,249,255,214,220,162,163,165,8359,402,
225,237,243,250,241,209,170,186,191,8976,172,189,188,161,171,187,
9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,
9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,
9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,
945,223,915,960,931,963,181,964,934,920,937,948,8734,966,949,8745,
8801,177,8805,8804,8992,8993,247,8776,176,8729,183,8730,8319,178,9632,160],
_w=[],
_r=[];
// Create forward lookup to write & reverse lookup to read
for(var i=0, l=256; i<l; i++) {
var c = (i<128) ? i : _c[i-128];
_w[i] = c;
_r[c] = i;
}
// Read binary data from disk
function binFileToArray(fileName, binArray){
var inStream = new ActiveXObject("ADODB.Stream");
inStream.Type = 2;
inStream.CharSet = '437';
inStream.Open();
inStream.LoadFromFile(fileName);
var inString = inStream.ReadText();
inStream.Close();
for(var i=0, l=inString.length; i<l; i++) {
binArray.push(_r[inString.charCodeAt(i)]);
}
}
// Write binary data to disk
function binArrayToFile(binArray, fileName){
var outStream = new ActiveXObject('ADODB.Stream');
var outString = '';
for(var i=0, l=binArray.length; i<l; i++) {
outString += String.fromCharCode(_w[binArray[i]]);
}
outStream.Type = 2;
outStream.CharSet = '437';
outStream.Open();
outStream.WriteText(outString);
outStream.SaveToFile(fileName, 2);
outStream.Close();
}
// TEST: read binary file from disk & write array back to disk
var testArray = [];
binFileToArray('c:/temp/test.bin', testArray);
binArrayToFile(testArray, 'c:/temp/test2.bin');
// both files equals

How to get Text Input In Adobe AIR

I'm new to Adobe AIR and here is what i'm doing, (please note that i'm doing this by AS3 code:
Adding a VGroup to the Canvas control.
var vIncomeHeader:VGroup = new VGroup();
vIncomeHeader.width = 1326;
vIncomeHeader.height = 29;
vIncomeHeader.id = "vIncomeHeader";
canvasIncome.addChild(vIncomeHeader);
Creating and adding a HGroup to the VGroup created in step one.
Creating 5 TextInput and adding it to HGroup. First textbox is editable and rest are not editable.
var hfIncomeHeader:HGroup = new HGroup();
var txt:TextInput = new TextInput();
vIncomeHeader.addElement(hfIncomeHeader);
var lp:int =0;
var lp-inner:int =0;
for (lp=0; lp<10; lp++)
{
hfIncomeHeader = new HGroup();
hfIncomeHeader.width = 1326;
hfIncomeHeader.height = 29;
//Amount
txt = new TextInput();
txt.id = "txtAmount_" + lp;
txt.width = 120;
txt.height = 22;
txt.restrict = "0-9.\\";
txt.addEventListener(Event.CHANGE, txtChangeIncomeAmount);
hfIncomeHeader.addElement(txt);
for (lp-inner=0; lp-inner<4; lp-inner++)
{
//Income Type
txt = new TextInput();
txt.id = "txt_" + lp + "_" + lp-inner;
txt.width = 120;
txt.height = 22;
hfIncomeHeader.addElement(txt);
}
}
//txtChangeIncomeAmount
protected function txtChangeIncomeAmount(event:Object):void
{
// HOW TO Do IT
}
[Second and third steps are part of a for loop from 0 to 10]
Now, what I want to do is to write the number in first textbox and automatically fill the same number to other 4 textboxes of that HGroup.
You can set names to your TextInput and then get them by names. Something like that:
...
txt.name = "txt_" + lp-inner;
...
protected function txtChangeIncomeAmount(event:Event):void
{
var txt:TextInput;
for (var i:uint = 0; i < 4; i++)
{
txt = hfIncomeHeader.getChildByName("txt_" + i) as TextInput;
txt.text = (event.currentTarget as TextInput).text;
}
}

duplicateMovieClip in Action Script 3

My question is how to do this:
https://www.dropbox.com/s/zi63y771h38a2vo/Example.fla
In Action Script 3.0.
This is working timeline source code, with ready indexing values + sorting news via array.
Simple as that, how to create same thing in ActionScript 3.0?
I was searching on the websites/forums and I couldn't find any answer that was satisfying me, so I decided to create an account in here and ask for help.
If someone could remake this example on ActionScript 3.0, this could help us all, because I saw a lot of questions about duplicateMovieClip() function, but there were no strict answer + example on it, so maybe let's create this?
This is my suggestion, code is in file or here:
stop();
var IDMovieClip = 0;
var IDarray = 0;
var Duplicate:MovieClip;
MC._visible = false;
var ARRAY:Array = new Array();
ENTER.onRelease = function() {
Duplicate = MC.duplicateMovieClip(IDMovieClip, _root.getNextHighestDepth());
var ref = eval(Duplicate);
ref.ID = IDMovieClip;
ref.sortedID = IDarray;
_root[ref.ID].windowID.text = "ID: " + ref.ID;
Duplicate.Close.onRollOver = function() {
trace(_root[ref.ID]._target);
};
Duplicate.Close.onRelease = function() {
_root.ARRAY.splice(_root[ref.ID].sortedID,1);
removeMovieClip(_root[ref.ID]);
IDarray -= 1;
_root.doSort();
};
ARRAY.push([IDarray, IDMovieClip]);
doSort();
IDMovieClip += 1;
IDarray += 1;
};
doSort = function () {
for (var i = 0; i < ARRAY.length; i++) {
_root[ARRAY[i][1]]._y = 10 + ((_root[ARRAY[i][1]]._height + 10) * i);
_root[ARRAY[i][1]].sortID.text = i;
_root[ARRAY[i][1]].sortedID = i;
trace(ARRAY[i]);
}
};
FLA PROJECT DESIGN IN JPG (MovieClips/Placement etc)
(what You need to run it, if You dont want to download it from my DropBox)
If anyone could help, that would be great.
There is no duplicateMovieClip in AS3, in ActionScript 3, you instantiate movie clips. I didn't find place for all used variables, I think it's part of some project, so you should adapt code for your needs. You also should read a bit about Export for ActionScript.
//Container for your objects
var movieHolder: Sprite = new Sprite();
var id:uint = 0;
const padding: int = 10;
//Handler, that will add new objects to the scene
enter.addEventListener(MouseEvent.CLICK, onClickEnter);
addChild(movieHolder);
movieHolder.x = movieHolder.y = padding;
function onClickClose(e:MouseEvent):void {
movieHolder.removeChild(DisplayObject(e.currentTarget).parent);
sortMovies();
}
function onClickEnter(e:MouseEvent):void {
//Set up for MovieClip with form export for ActionScript
var movie:MyFormMovie = new MyFormMovie();
movie.windowID.text = "ID: " + id;
movie.Close.addEventListener(MouseEvent.CLICK, onClickClose, false, 0, true);
movieHolder.addChild(movie);
sortMovies();
id++;
}
function sortMovies():void {
var i: uint, len: uint = movieHolder.numChildren, movie: MyFormMovie;
var posY: uint;
for(i; i < len; ++i){
movie = movieHolder.getChildAt(i) as MyFormMovie;
movie.y = posY;
movie.sortID.text = i.toString();
posY += movie.height + padding;
}
}

Flex string never cleared from the memory --> It is cleared eventually

I have this weird problem for a while and try to solve it to look up on the net for proper solution but still I am clueless.
When I check my application's memory usage with flex profiler (4.6) the portion of String keep increasing and eventually reach the point of crash.
And I pin pointed where this increasing occurs from my application's source code.
It is the local string variable that I passed to Json.decode(). It never cleared.
All the instance of the json string that I got from the socket server remains in the memory til app crashes even if profiler says there is 0 path to the String.
I don't know how to clear these Strings. It only keeps growing.
Please help me. I have been struggled with this for a week now.
Thanks for any support in advance.
portion of my source code that I think the source of the leak is as following.
protected function evtserverReseved(event:ProgressEvent):void{
var tmpArr:ByteArray = new ByteArray();
var tempByteArray:ByteArray = new ByteArray();
socEvtServer.readBytes(tmpArr, 0, socEvtServer.bytesAvailable);
tempByteArray.writeBytes(leftOverMessageNotify, 0, leftOverMessageNotify.length);
tempByteArray.writeBytes(tmpArr, 0, tmpArr.length);
leftOverMessageNotify = new ByteArray();
parseByteArray(tempByteArray);
}
private function parseByteArray(rawArray:ByteArray):void{
if(( rawArray[0] == 0x30 || rawArray[0] == 0x31 ) && rawArray[1] == 0x00 ){
var log:String = "";
for(var i:int=0; i<16; i++){
if(rawArray[i]==0){
}else{
log += rawArray[i]-48;
}
}
sizeOfFullListNotify = uint(log);
commonFunction.printLog("Event Server eventNotify sizeOfFullListNotify=" + sizeOfFullListNotify);
rawArray.position = 16;
}
var tempIdx:uint = rawArray.position;
var tempLength:uint = rawArray.length;
if(sizeOfFullListNotify <= tempLength - tempIdx){
var tempArray:ByteArray = new ByteArray();
var tempLeftOver:ByteArray = new ByteArray();
var j:uint;
for(j=0; j <sizeOfFullListNotify ; j++){
tempArray[j] = rawArray[j+tempIdx];
}
var euckrString:Object = tempArray.readMultiByte( tempArray.length,"euc-kr").replace(" ","").replace("\n","");
//commonFunction.printLog("Total memory=" + flash.system.System.totalMemory +", Free memory=" + flash.system.System.freeMemory + ", Event Server eventNotify JSON 수신 data size=" +euckrString.toString().length+ ", body=" + euckrString.toString() );
var ob:Object = com.adobe.serialization.json.JSON.decode(euckrString.toString());
commonFunction.printLog("Total memory=" + flash.system.System.totalMemory +", Free memory=" + flash.system.System.freeMemory + ", Event Server eventNotify JSON data size=" +euckrString.length+ ", body=" + euckrString );
if(ob.method != null){
//gridBox.DT_HOUSE.addItemAt(ob,0);
gridBox.DT_HOUSE.push(ob);
totlaReceivedList++;
}else if(!(ob.result is String)){
//confirm for registerEventNotify
commonFunction.printLog("confirm for registerEventNotify");
}
if(sizeOfFullListNotify < tempLength - tempIdx){
for(var k:uint=0; k <tempLength-tempIdx-sizeOfFullListNotify ; k++){
tempLeftOver[k] = rawArray[k+j+tempIdx];
}
parseByteArray(tempLeftOver);
}else{
//leftOverMessageNotify = new ByteArray();
}
}else{
//leftOverMessageNotify = rawArray;
for(var i:int = 0 ; i<rawArray.length ; i++){
leftOverMessageNotify[i] = rawArray[i];
}
rawArray = null;
}
}
var euckrString:Object(String) is the portion that never cleared from the memory.
It keeps stacking till crashes.

AS3: How do I save out the data from a datagrid into a line-by-line text file?

I've got a datagrid populated with text file that has line-by-line words(ie. one per line). The datagrid has 5 columns. Every 5 words out of the text file is put in a new row. The datagrid can then be added to or removed from. How would I go about rewriting the text file using all the values in the datagrid?
This is how the datagrid gets populated. How can I go through the entire datagrid cell for cell and rewrite the data in the text file?
var loadFavourites: URLLoader = new URLLoader();;
var arFavourites = new Array();
loadFavourites.addEventListener(Event.COMPLETE, onLoadedFavourites);
loadFavourites.load(new URLRequest("lists/Favourites.txt"));
function onLoadedFavourites(event:Event):void
{
arFavourites = event.target.data.split("\r\n");
for (var i:int = 0; i <= arFavourites.length; i++)
{
if (i != 0 && i % 5 == 0)
{
dg.addItem({Place: arFavourites[i-5],Subject:arFavourites[i-4],Object:arFavourites[i-3],Feeling:arFavourites[i-2],Action:arFavourites[i-1]});
}
}
}
Add Record:
var i:int=0;
var tPlace = mc_places.mc_places_text.txtPlaces.text;
var tSubject = mc_subject.mc_subject_text.txtSubject.text;
var tObject = mc_object.mc_object_text.txtObject.text;
var tFeeling = mc_feeling.mc_feeling_text.txtFeeling.text;
var tAction = mc_action.mc_action_text.txtAction.text;
arFavourites[FavCount+1]=tPlace;
arFavourites[FavCount+2]=tSubject;
arFavourites[FavCount+3]=tObject;
arFavourites[FavCount+4]=tFeeling;
arFavourites[FavCount+5]=tAction;
dg.addItem({Place: arFavourites[FavCount+1],Subject:arFavourites[FavCount+2],Object:arFavourites[FavCount+3],Feeling:arFavourites[FavCount+4],Action:arFavourites[FavCount+5]});
dg.scrollToIndex(dg.length-1);
FavCount=FavCount+5;
for (i=0; i<arFavourites.length; i++) {
trace(arFavourites[i]);
}
Remove Record:
var k:int;
var i:int;
trace("Selected Index: " + dg.selectedIndex);
if (dg.length == 0) {
return;
}
for (k=0; k<dg.length; k++) {
if (dg.isItemSelected(dg.getItemAt(k))) {
for (i=0; i<arFavourites.length; i++) {
if (arFavourites[i] == dg.getItemAt(k)[1]) {
arFavourites.splice(i,1);
}
if (arFavourites[i] == dg.getItemAt(k)[2]) {
arFavourites.splice(i,1);
}
if (arFavourites[i] == dg.getItemAt(k)[3]) {
arFavourites.splice(i,1);
}
if (arFavourites[i] == dg.getItemAt(k)[4]) {
arFavourites.splice(i,1);
}
if (arFavourites[i] == dg.getItemAt(k)[5]) {
arFavourites.splice(i,1);
}
}
dg.removeItemAt(k);
dg.scrollToIndex(k);
dg.clearSelection();
break;
}
}
Well, what I would do is basically just the reverse. First you'd get the values of the DataGrid and put them back in an Array in the same order as before:
var newFavArray:Array = new Array();
for (var i:int = 1; i <= dg.length; i++)
{
newFavourites[i * 5 - 5] = dg.getItemAt(i - 1).Place;
newFavourites[i * 5 - 4] = dg.getItemAt(i - 1).Subject;
newFavourites[i * 5 - 3] = dg.getItemAt(i - 1).Object;
newFavourites[i * 5 - 2] = dg.getItemAt(i - 1).Feeling;
newFavourites[i * 5 - 1] = dg.getItemAt(i - 1).Action;
}
(I whipped this up fairly quick, if you can find a better way of using i to access the Array and the DataGrid feel free to use it.)
Then you convert it to a String:
var newFavString:String = newFavArray.join("\r\n");
And then finally save it to the file however you want (overwriting the old values of course). Since it's an AIR app, it's best to use the File and FileStream classes for this:
var favFile:File = File.applicationStorageDirectory.resolvePath("lists/Favourites.txt");
var favStream:FileStream = new FileStream();
favStream.open(favFile, FileMode.WRITE);
favStream.writeUTFBytes(newFavString);
favStream.close();
I'm not sure what your workflow is but personally I'd put all of this in a function:
function saveFavourites():void
{
var newFavArray:Array = new Array();
for (var i:int = 1; i <= dg.length; i++)
{
newFavArray[i * 5 - 5] = dg.getItemAt(i - 1).Place;
newFavArray[i * 5 - 4] = dg.getItemAt(i - 1).Subject;
newFavArray[i * 5 - 3] = dg.getItemAt(i - 1).Object;
newFavArray[i * 5 - 2] = dg.getItemAt(i - 1).Feeling;
newFavArray[i * 5 - 1] = dg.getItemAt(i - 1).Action;
}
var newFavString:String = newFavArray.join("\r\n");
var favFile:File = File.applicationStorageDirectory.resolvePath("lists/Favourites.txt");
var favStream:FileStream = new FileStream();
favStream.open(favFile, FileMode.WRITE);
favStream.writeUTFBytes(newFavString);
favStream.close();
}
which you can run whenever you want to.
If you haven't used File and FileStream before, it'd be worth it to check them out and see how they work. They're only available in AIR but they're much better and superior to URLRequest and URLLoader. You may also want to use them to load your file. They are only useful for local files though, if the file is online or something then I'm sure URLLoader is fine.