Sign in to follow this  
MatsVed

[web] Converting from ActionScript (Flash) to C#

Recommended Posts

[Note: I posted this here as well because I'm assuming people viewing this forum will be more familiar with ActionScript] Hey! I need some help with converting code written in ActionScript for Adobe Flash to C#. Here's the class I'm trying to convert:
package com.frankula.parsers {
	
	import flash.utils.Proxy;
	import flash.utils.flash_proxy;
	
	public final class IFFChunkID extends Proxy {
		
		private static var _instance:IFFChunkID;
		private static var _converted:Object;
		private static var _returnType:String;
		// rsmp : the resource map that tells where everything else is
		public static function get rsmp():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['rsmp'];
		}
		
		public static function get BCON():* { 
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['BCON'];
		}
		
		public static function get TRCN():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['TRCN'];
		}
		
		public static function get BHAV():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['BHAV'];
		}
		
		public static function get OBJf():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['OBJf'];
		}
		
		public static function get objt():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['objt'];
		}
		
		public static function get SLOT():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['SLOT'];
		}
		
		public static function get TREE():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['TREE'];
		}
		
		public static function get TRPR():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['TRPR'];
		}
		// OBJD : data about the object (cost, category, etc)
		public static function get OBJD():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['OBJD'];
		}
		// CTSS : Catalog text strings in one or more languages
		public static function get CTSS():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['CTSS'];
		}
		// DGRP : draw group resources that define where sprite images go
		public static function get DGRP():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['DGRP'];
		}
		// SPR2 : sprite image resources
		public static function get SPR2():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['SPR2'];
		}
		// SPRn : more sprite image resources
		public static function get SPRn():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['SPR#'];
		}
		// PALT : palettes used by the sprite image resources
		public static function get PALT():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['PALT'];
		}
		// BMP_ : Windows BMP format bitmaps; used in catalogs and thought balloons
		public static function get BMP():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['BMP_'];
		}
		// FBMP : Windows BMP format bitmaps; used in some .flr floor files
		public static function get FBMP():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['FBMP'];
		}
		// STRn : text strings (animation names, alerts. etc.) in one or more languages
		public static function get STRn():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['STR#'];
		}
		// TTAs : pie menutext strings in one or more languages
		public static function get TTAs():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['TTAs'];
		}
		// TTAB : binary menu data
		public static function get TTAB():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['TTAB'];
		}
		// uChr : text strings used in .FAM files
		public static function get uChr():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['uChr'];
		}
		// CARR : Carreer data (sim job info)
		public static function get CARR():* {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			return IFFChunkID._instance['CARR'];
		}
		
		public static function encode(str:String):* {
			return IFFChunkID._instance[str];
		}
		
		public static function decode(val:uint):* {
			var hex:String = val.toString(16);
			return String.fromCharCode(((val & 0xff000000) >> 24), ((val & 0x00ff0000) >> 16), ((val & 0x0000ff00) >> 8), (val & 0x000000ff));
		}
		
		public static function invert2(val:uint):uint {
			return ((val >> 8) & 0xff)+((val << 8) & 0xff00);
		}
		
		public static function invert4(val:uint):uint {
			return ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24);
		}
		
		public static function set returnType(type:String):void {
			(IFFChunkID._instance == null) ? IFFChunkID.getInstance() : null;
			IFFChunkID._returnType = type;
		}
		
		public function IFFChunkID(singletonEnforcer:SingletonEnforcer) {
		}
		
		private static function getInstance():IFFChunkID {
			if (IFFChunkID._instance == null) {
				IFFChunkID._instance = new IFFChunkID(new SingletonEnforcer());
				IFFChunkID._converted = new Object();
				IFFChunkID._returnType = IFFChunkReturnType.UINT;
			}
			return IFFChunkID._instance;
		}
		
		flash_proxy override function getProperty(name:*):* {
			if (name != null) {
				if (name.toString().length == 4) {
					if (IFFChunkID._converted[name] == null) { IFFChunkID._converted[name] = toChunkID(name); }
					if (IFFChunkID._returnType == IFFChunkReturnType.UINT) {
						return IFFChunkID._converted[name];
					} else if (IFFChunkID._returnType == IFFChunkReturnType.HEX) {
						return IFFChunkID._converted[name].toString(16);
					}
				} else { throw new Error(name+" is not a valid chunk ID"); }
			}
		}
		
		private function toChunkID(id:String):uint {
			var a:int = id.charCodeAt(0);
			var b:int = id.charCodeAt(1);
			var c:int = id.charCodeAt(2);
			var d:int = id.charCodeAt(3);
			return ((a << 24) | (b << 16) | (c << 8) | d);
		}
		
	}
}

internal final class SingletonEnforcer {}

Can someone please help me figure out exactly how this class works? I know it's a singleton, but I don't really know much more than that. Here is an example of how this class is used:
		private function parseData(byteArray:ByteArray = null):void {
			var len:int = Math.floor(byteArray.bytesAvailable)-4;
			IFFChunkID["returnType"] = IFFChunkReturnType.UINT;
			byteArray.position = 0;
			for (var i:int=0; i<len; i++) {
				byteArray.position = i;
				var nVal:uint = byteArray.readUnsignedInt();
				if (
					(nVal == IFFChunkID.rsmp) || (nVal == IFFChunkID.BCON) ||
					(nVal == IFFChunkID.BHAV) || (nVal == IFFChunkID.BMP)  ||
					(nVal == IFFChunkID.CTSS) || (nVal == IFFChunkID.DGRP) ||
					(nVal == IFFChunkID.FBMP) || (nVal == IFFChunkID.OBJD) ||
					(nVal == IFFChunkID.OBJf) || (nVal == IFFChunkID.objt) ||
					(nVal == IFFChunkID.PALT) || (nVal == IFFChunkID.SLOT) ||
					(nVal == IFFChunkID.SPR2) || (nVal == IFFChunkID.SPRn) ||
					(nVal == IFFChunkID.TRCN) || (nVal == IFFChunkID.TREE) ||
					(nVal == IFFChunkID.TRPR) || (nVal == IFFChunkID.TTAB) ||
					(nVal == IFFChunkID.TTAs) || (nVal == IFFChunkID.uChr) ||
					(nVal == IFFChunkID.CARR)
				) {
					var chunk:IFFChunk = toChunk(nVal, byteArray);
					i += chunk.length;
					_mainChunks.push(chunk);
				}
			}
			//trace("rscs : "+_mainChunks.length);
			parseObjects();
		}

Here's what I've converted so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IffLib.Parsers
{
    public class IffChunkID
    {
        private static readonly IffChunkID m_Instance = new IffChunkID();

        private static string m_ReturnType;

        public string ReturnType
        {
            set
            {
                IffChunkID.m_ReturnType = value;
            }
        }

        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static IffChunkID()
        {
        }

        IffChunkID()
        {
        }

        public static IffChunkID Instance
        {
            get 
            {
                m_ReturnType = IffChunkReturnType.UINT;
                return m_Instance;
            }
        }

        public static string Decode (uint Value)
        {
            string Hex = Value.ToString("X");
            return new string(new char[] 
            { 
                (char)((Value & 0xff000000) >> 24), 
                (char)((Value & 0x00ff0000) >> 16), (char)((Value & 0x0000ff00) >> 8), 
                (char)(Value & 0x000000ff) 
            });
        }

        public static uint Invert2(uint Value)
        {
            return ((Value >> 8) & 0xff) + ((Value << 8) & 0xff00);
        }

        public static uint Invert4(uint Value)
        {
            return ((Value & 0xff000000) >> 24) | ((Value & 0x00ff0000) >> 8) | ((Value & 0x0000ff00) << 8) | ((Value & 0x000000ff) << 24);
        }

        private static uint ToChunkID(string ID)
        {
            int A = ID[0];
            int B = ID[1];
            int C = ID[2];
            int D = ID[3];

            return (uint)((A << 24) | (B << 16) | (C << 8) | D);
        }
    }
}


One theory I have is that _converted is some kind of array containing elenents of... some kind of type. What kind of type, I'm not sure. :| If this theory is correct, the above example would be the ActionScript way of implementing [Array]Indexers like in C#. Bah... I'm confused!! Someone please help!! IffChunkReturnType simply looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IffLib.Parsers
{
    internal class IffChunkReturnType
    {
        public static string UINT = "uint";
        public static string HEX = "hex";
    }
}

Share this post


Link to post
Share on other sites
Quote:
Original post by MatsVed
Can someone please help me figure out exactly how this class works?

Have you looked at the base class?
http://livedocs.adobe.com/flex/2/langref/flash/utils/Proxy.html
Quote:
One theory I have is that _converted is some kind of array containing elenents of... some kind of type.

It looks a bit funky, but from what I can determine without diving too much into the code, is that it's used as a collection, where both the keys and the values can be (a reference to) any type (of object). Ideally you want to find out what its role is in the context of the class behavior and functionality. Perhaps there is a better solution than having this _converted member, especially if you'll be writing it in a different language (and accompanying library). The amount of code you need to 'convert' isn't that much, so it's reasonable and most probably better to try to copy the functionality of this class rather than trying to translate the actual source code line by line.

Share this post


Link to post
Share on other sites
Thanks for your insight!
I found some old C++ code that worked better.
Turns out *.iff is a very quirky fileformat with different endianness and very sketchy documentation at best.

Share this post


Link to post
Share on other sites
Thanks for your insight!
I found some old C++ code that worked better.
Turns out *.iff is a very quirky fileformat with different endianness and very sketchy documentation at best.

Share this post


Link to post
Share on other sites
Thanks for your insight!
I found some old C++ code that worked better.
Turns out *.iff is a very quirky fileformat with different endianness and very sketchy documentation at best.

Share this post


Link to post
Share on other sites
Thanks for your insight!
I found some old C++ code that worked better.
Turns out *.iff is a very quirky fileformat with different endianness and very sketchy documentation at best.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this