| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163 | using System;using System.Collections;using System.Text;using System.Collections.Generic;using UnityEngine;// Source: UIToolkit -- https://github.com/prime31/UIToolkit/blob/master/Assets/Plugins/MiniJSON.cs// Based on the JSON parser from // http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html/// <summary>/// This class encodes and decodes JSON strings./// Spec. details, see http://www.json.org//// /// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable./// All numbers are parsed to doubles./// </summary>public class FlareJson{	private const int TOKEN_NONE = 0;	private const int TOKEN_CURLY_OPEN = 1;	private const int TOKEN_CURLY_CLOSE = 2;	private const int TOKEN_SQUARED_OPEN = 3;	private const int TOKEN_SQUARED_CLOSE = 4;	private const int TOKEN_COLON = 5;	private const int TOKEN_COMMA = 6;	private const int TOKEN_STRING = 7;	private const int TOKEN_NUMBER = 8;	private const int TOKEN_TRUE = 9;	private const int TOKEN_FALSE = 10;	private const int TOKEN_NULL = 11;	private const int BUILDER_CAPACITY = 2000;	/// <summary>	/// On decoding, this value holds the position at which the parse failed (-1 = no error).	/// </summary>	protected static int lastErrorIndex = -1;	protected static string lastDecode = "";		public static Color decodeColor(Hashtable table){				float r = float.Parse(table["r"].ToString());		float g = float.Parse(table["g"].ToString());		float b = float.Parse(table["b"].ToString());		float a = float.Parse(table["a"].ToString());				return new Color(r,g,b,a);	}		public static Vector4 decodeVector4(Hashtable table){				float r = float.Parse(table["r"].ToString());		float g = float.Parse(table["g"].ToString());		float b = float.Parse(table["b"].ToString());		float a = float.Parse(table["a"].ToString());				return new Vector4(r,g,b,a);	}		public static Vector3 decodeVector3(Hashtable table){				float r = float.Parse(table["r"].ToString());		float g = float.Parse(table["g"].ToString());		float b = float.Parse(table["b"].ToString());				return new Vector4(r,g,b);	}		public static Vector2 decodeVector2(Hashtable table){				float x = float.Parse(table["x"].ToString());		float y = float.Parse(table["y"].ToString());				return new Vector2(x,y);	}			public static AnimationCurve decodeAnimCurve(Hashtable table){		AnimationCurve curve = new AnimationCurve ();				foreach (System.Collections.DictionaryEntry key in table) {			Hashtable keyTable = (Hashtable)table [key.Key];			float time = float.Parse(keyTable["time"].ToString());			float value = float.Parse(keyTable["value"].ToString());			float _in = float.Parse(keyTable["in"].ToString());			float _out = float.Parse(keyTable["out"].ToString());//			float tangentMode = float.Parse(keyTable["tangentMode"].ToString());			Keyframe newKey = new Keyframe(time,value,_in,_out);			//			newKey.tangentMode = tangentMode;			curve.AddKey(newKey);		}		return curve;	}	public static bool decodeBool(string str){		int num =  int.Parse(str);		if(num == 1)			return true;		else			return false;	}	public static void LoadFlareData (ProFlare flare, TextAsset asset)	{				string jsonString = asset.text;//		Debug.Log ("LoadFlareData");		Hashtable decodedHash = jsonDecode (jsonString) as Hashtable;				if (decodedHash == null) {			Debug.LogWarning ("Unable to parse Json file: " + asset.name);			return;		} 		Hashtable meta = (Hashtable)decodedHash["meta"];					flare.GlobalScale = float.Parse(meta["GlobalScale"].ToString());		flare.GlobalBrightness = float.Parse(meta["GlobalBrightness"].ToString());		flare.GlobalTintColor = FlareJson.decodeColor((Hashtable)meta["GlobalTintColor"]);		flare.MultiplyScaleByTransformScale = FlareJson.decodeBool(meta["MultiplyScaleByTransformScale"].ToString());		//Distance Fall off		flare.useMaxDistance = FlareJson.decodeBool(meta["useMaxDistance"].ToString());		flare.useDistanceScale = FlareJson.decodeBool(meta["useDistanceScale"].ToString());		flare.useDistanceFade = FlareJson.decodeBool(meta["useDistanceFade"].ToString());		flare.GlobalMaxDistance = float.Parse(meta["GlobalMaxDistance"].ToString());							//Angle Culling Properties		flare.UseAngleLimit = FlareJson.decodeBool(meta["UseAngleLimit"].ToString());		flare.maxAngle = float.Parse(meta["maxAngle"].ToString());		flare.UseAngleScale = FlareJson.decodeBool(meta["UseAngleScale"].ToString());		flare.UseAngleBrightness = FlareJson.decodeBool(meta["UseAngleBrightness"].ToString());		flare.UseAngleCurve = FlareJson.decodeBool(meta["UseAngleCurve"].ToString());		flare.AngleCurve = FlareJson.decodeAnimCurve ((Hashtable)meta ["AngleCurve"]);		//			public LayerMask mask = 1;		flare.RaycastPhysics = FlareJson.decodeBool(meta["RaycastPhysics"].ToString());		flare.OffScreenFadeDist = float.Parse(meta["OffScreenFadeDist"].ToString());		flare.useDynamicEdgeBoost = FlareJson.decodeBool(meta["useDynamicEdgeBoost"].ToString());		flare.DynamicEdgeBoost = float.Parse(meta["DynamicEdgeBoost"].ToString());		flare.DynamicEdgeBrightness = float.Parse(meta["DynamicEdgeBrightness"].ToString());		flare.DynamicEdgeRange = float.Parse(meta["DynamicEdgeRange"].ToString());		flare.DynamicEdgeBias = float.Parse(meta["DynamicEdgeBias"].ToString());		flare.DynamicEdgeCurve = FlareJson.decodeAnimCurve ((Hashtable)meta ["DynamicEdgeCurve"]);		flare.useDynamicCenterBoost = FlareJson.decodeBool(meta["useDynamicCenterBoost"].ToString());		flare.DynamicCenterBoost = float.Parse(meta["DynamicCenterBoost"].ToString());		flare.DynamicCenterBrightness = float.Parse(meta["DynamicCenterBrightness"].ToString());		flare.DynamicCenterRange = float.Parse(meta["DynamicCenterRange"].ToString());		flare.DynamicCenterBias = float.Parse(meta["DynamicCenterBias"].ToString());		flare.neverCull = FlareJson.decodeBool(meta["neverCull"].ToString());		flare.Elements.Clear ();		Hashtable elements = (Hashtable)meta["Elements"];		foreach (System.Collections.DictionaryEntry item in elements) {			Hashtable element = (Hashtable)elements[item.Key];			ProFlareElement elementNew = new ProFlareElement();						elementNew.Editing = FlareJson.decodeBool(element["Editing"].ToString());			elementNew.Visible = FlareJson.decodeBool(element["Visible"].ToString());			elementNew.SpriteName = element["SpriteName"].ToString();			elementNew.flare = flare;			elementNew.flareAtlas = flare._Atlas;			elementNew.Brightness = float.Parse(element["Brightness"].ToString());			elementNew.Scale = float.Parse(element["Scale"].ToString());			elementNew.ScaleRandom = float.Parse(element["ScaleRandom"].ToString());			elementNew.ScaleFinal = float.Parse(element["ScaleFinal"].ToString());			elementNew.RandomColorAmount = FlareJson.decodeVector4((Hashtable)element["RandomColorAmount"]);//			//Element OffSet Properties			elementNew.position = float.Parse(element["position"].ToString());			elementNew.useRangeOffset = FlareJson.decodeBool(element["useRangeOffset"].ToString());			elementNew.SubElementPositionRange_Min = float.Parse(element["SubElementPositionRange_Min"].ToString());			elementNew.SubElementPositionRange_Max = float.Parse(element["SubElementPositionRange_Max"].ToString());			elementNew.SubElementAngleRange_Min = float.Parse(element["SubElementAngleRange_Min"].ToString());			elementNew.SubElementAngleRange_Max = float.Parse(element["SubElementAngleRange_Max"].ToString());			elementNew.OffsetPosition = FlareJson.decodeVector3((Hashtable)element["OffsetPosition"]);			elementNew.Anamorphic = FlareJson.decodeVector3((Hashtable)element["Anamorphic"]);			elementNew.OffsetPostion = FlareJson.decodeVector3((Hashtable)element["OffsetPostion"]);//			//Element Rotation Properties			elementNew.angle = float.Parse(element["angle"].ToString());			elementNew.useRandomAngle = FlareJson.decodeBool(element["useRandomAngle"].ToString());			elementNew.useStarRotation = FlareJson.decodeBool(element["useStarRotation"].ToString());			elementNew.AngleRandom_Min = float.Parse(element["AngleRandom_Min"].ToString());			elementNew.AngleRandom_Max = float.Parse(element["AngleRandom_Max"].ToString());			elementNew.OrientToSource = FlareJson.decodeBool(element["OrientToSource"].ToString());			elementNew.rotateToFlare = FlareJson.decodeBool(element["rotateToFlare"].ToString());			elementNew.rotationSpeed = float.Parse(element["rotationSpeed"].ToString());			elementNew.rotationOverTime = float.Parse(element["rotationOverTime"].ToString());//			//Colour Properties,			elementNew.useColorRange = FlareJson.decodeBool(element["useColorRange"].ToString());			elementNew.OffsetPosition = FlareJson.decodeVector3((Hashtable)element["OffsetPosition"]);			elementNew.ElementTint = FlareJson.decodeColor((Hashtable)element["ElementTint"]);			elementNew.SubElementColor_Start = FlareJson.decodeColor((Hashtable)element["SubElementColor_Start"]);			elementNew.SubElementColor_End = FlareJson.decodeColor((Hashtable)element["SubElementColor_End"]);//			//Scale Curve			elementNew.useScaleCurve = FlareJson.decodeBool(element["useScaleCurve"].ToString());			elementNew.ScaleCurve = FlareJson.decodeAnimCurve ((Hashtable)element ["ScaleCurve"]);//			//Override Properties			elementNew.OverrideDynamicEdgeBoost = FlareJson.decodeBool(element["OverrideDynamicEdgeBoost"].ToString());			elementNew.DynamicEdgeBoostOverride = float.Parse(element["DynamicEdgeBoostOverride"].ToString());			elementNew.OverrideDynamicCenterBoost = FlareJson.decodeBool(element["OverrideDynamicCenterBoost"].ToString());			elementNew.DynamicCenterBoostOverride = float.Parse(element["DynamicCenterBoostOverride"].ToString());			elementNew.OverrideDynamicEdgeBrightness = FlareJson.decodeBool(element["OverrideDynamicEdgeBrightness"].ToString());			elementNew.DynamicEdgeBrightnessOverride = float.Parse(element["DynamicEdgeBrightnessOverride"].ToString());			elementNew.OverrideDynamicCenterBrightness = FlareJson.decodeBool(element["OverrideDynamicCenterBrightness"].ToString());			elementNew.DynamicCenterBrightnessOverride = float.Parse(element["DynamicCenterBrightnessOverride"].ToString());			elementNew.type = (ProFlareElement.Type)(int.Parse(element["type"].ToString()));			elementNew.size = FlareJson.decodeVector2((Hashtable)element["size"]);			Hashtable subElements = (Hashtable)element["subElements"];			if(subElements != null)			foreach (System.Collections.DictionaryEntry subItem in subElements) {				Hashtable subElement = (Hashtable)subElements[subItem.Key];				SubElement subElementNew = new SubElement();				subElementNew.color = FlareJson.decodeColor((Hashtable)subElement["color"]);				subElementNew.position = float.Parse(subElement["position"].ToString());				subElementNew.offset = FlareJson.decodeVector3((Hashtable)subElement["offset"]);				subElementNew.angle = float.Parse(subElement["angle"].ToString());				subElementNew.scale = float.Parse(subElement["scale"].ToString());				subElementNew.random = float.Parse(subElement["random"].ToString());				subElementNew.random2 = float.Parse(subElement["random2"].ToString());				subElementNew.RandomScaleSeed = float.Parse(subElement["RandomScaleSeed"].ToString());				subElementNew.RandomColorSeedR = float.Parse(subElement["RandomColorSeedR"].ToString());				subElementNew.RandomColorSeedG = float.Parse(subElement["RandomColorSeedG"].ToString());				subElementNew.RandomColorSeedB = float.Parse(subElement["RandomColorSeedB"].ToString());				subElementNew.RandomColorSeedA = float.Parse(subElement["RandomColorSeedA"].ToString());				elementNew.subElements.Add(subElementNew);			}			bool Found = false;			for(int i2 = 0; i2 < flare._Atlas.elementsList.Count; i2++){				if(elementNew.SpriteName == flare._Atlas.elementsList[i2].name){					Found = true;					elementNew.elementTextureID = i2;				}			}			if(Found)				flare.Elements.Add(elementNew);			else				Debug.LogWarning("ProFlares - Flare Element Missing From Atlas Not Adding - "+elementNew.SpriteName);		}		foreach (ProFlareBatch batch in flare.FlareBatches) {			batch.dirty = true;		}	}	/// <summary>	/// Parse the specified JSon file, loading sprite information for the specified atlas.	/// </summary>	public static void LoadSpriteData (ProFlareAtlas atlas, TextAsset asset)	{		if (asset == null || atlas == null) return;		string jsonString = asset.text;				Hashtable decodedHash = jsonDecode(jsonString) as Hashtable;				if (decodedHash == null)		{			Debug.LogWarning("Unable to parse Json file: " + asset.name);			return;		} 		List<ProFlareAtlas.Element> oldElements = atlas.elementsList;				atlas.elementsList = new List<ProFlareAtlas.Element>();				Vector2 TextureScale = Vector2.one;				//Find Texture Size		Hashtable meta = (Hashtable)decodedHash["meta"];		foreach (System.Collections.DictionaryEntry item in meta)		{			if(item.Key.ToString() == "size"){				Hashtable sizeTable = (Hashtable)item.Value;								TextureScale.x = int.Parse(sizeTable["w"].ToString());				TextureScale.y = int.Parse(sizeTable["h"].ToString());			}		}				//Debug.LogError(TextureScale);				Hashtable frames = (Hashtable)decodedHash["frames"];		foreach (System.Collections.DictionaryEntry item in frames)		{			ProFlareAtlas.Element newElement = new ProFlareAtlas.Element();			newElement.name = item.Key.ToString();			bool exists = false;			// Check to see if this sprite exists			foreach (ProFlareAtlas.Element oldSprite in oldElements)			{				if (oldSprite.name.Equals(newElement.name, StringComparison.OrdinalIgnoreCase))				{					exists = true;					break;				}			} 			if (!exists)			{				newElement.name = newElement.name.Replace(".png", "");				newElement.name = newElement.name.Replace(".tga", "");				newElement.name = newElement.name.Replace(".psd", "");				newElement.name = newElement.name.Replace(".PSD", "");			} 			Hashtable table = (Hashtable)item.Value;			Hashtable frame = (Hashtable)table["frame"];			int frameX = int.Parse(frame["x"].ToString());			int frameY = int.Parse(frame["y"].ToString());			int frameW = int.Parse(frame["w"].ToString());			int frameH = int.Parse(frame["h"].ToString()); 			Rect finalUVs = new Rect(frameX, frameY, frameW, frameH);						Rect rect = new Rect(frameX, frameY, frameW, frameH);						float width = TextureScale.x;			float height = TextureScale.y;						if (width != 0f && height != 0f)			{				finalUVs.xMin = rect.xMin / width;				finalUVs.xMax = rect.xMax / width;				finalUVs.yMin = 1f - rect.yMax / height;				finalUVs.yMax = 1f - rect.yMin / height;			}						newElement.UV = finalUVs;			newElement.Imported = true;			  						atlas.elementsList.Add(newElement);		}				foreach (ProFlareAtlas.Element oldSprite in oldElements)		{			if (!oldSprite.Imported)			{				atlas.elementsList.Add(oldSprite);			}		}		// Sort imported sprites alphabetically				atlas.elementsList.Sort(CompareSprites);				Debug.Log("PROFLARES - Imported " + atlas.elementsList.Count + " Elements");				// Unload the asset		asset = null;		Resources.UnloadUnusedAssets();	}	/// <summary>	/// Sprite comparison function for sorting.	/// </summary>		static int CompareSprites (ProFlareAtlas.Element a, ProFlareAtlas.Element b) { return a.name.CompareTo(b.name); }	/// <summary>	/// Copy the inner rectangle from one sprite to another.	/// </summary>	/*	static void CopyInnerRect (ProFlareAtlas.Element oldSprite, ProFlareAtlas.Element newElement)	{		float offsetX = oldSprite.inner.xMin - oldSprite.outer.xMin;		float offsetY = oldSprite.inner.yMin - oldSprite.outer.yMin;		float sizeX = oldSprite.inner.width;		float sizeY = oldSprite.inner.height;		if (Mathf.Approximately(newElement.outer.width, oldSprite.outer.width))		{			// The sprite has not been rotated or it's a square			newElement.inner = new Rect(newElement.outer.xMin + offsetX, newElement.outer.yMin + offsetY, sizeX, sizeY);		}		else if (Mathf.Approximately(newElement.outer.width, oldSprite.outer.height))		{			// The sprite was rotated since the last time it was imported			newElement.inner = new Rect(newElement.outer.xMin + offsetY, newElement.outer.yMin + offsetX, sizeY, sizeX);		}	}	 */	/// <summary>	/// Parses the string json into a value	/// </summary>	/// <param name="json">A JSON string.</param>	/// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns>	public static object jsonDecode( string json )	{		// save the string for debug information		FlareJson.lastDecode = json;		if( json != null )		{			char[] charArray = json.ToCharArray();			int index = 0;			bool success = true;			object value = FlareJson.parseValue( charArray, ref index, ref success );			if( success ){				Debug.Log("jsonDecode success"); 				FlareJson.lastErrorIndex = -1;			}			else{				FlareJson.lastErrorIndex = index;			}			return value;		}		else		{			return null;		}	}	/// <summary>	/// Converts a Hashtable / ArrayList / Dictionary(string,string) object into a JSON string	/// </summary>	/// <param name="json">A Hashtable / ArrayList</param>	/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>	public static string jsonEncode( object json )	{		var builder = new StringBuilder( BUILDER_CAPACITY );		var success = FlareJson.serializeValue( json, builder );				return ( success ? builder.ToString() : null );	}	/// <summary>	/// On decoding, this function returns the position at which the parse failed (-1 = no error).	/// </summary>	/// <returns></returns>	public static bool lastDecodeSuccessful()	{		return ( FlareJson.lastErrorIndex == -1 );	}	/// <summary>	/// On decoding, this function returns the position at which the parse failed (-1 = no error).	/// </summary>	/// <returns></returns>	public static int getLastErrorIndex()	{		return FlareJson.lastErrorIndex;	}	/// <summary>	/// If a decoding error occurred, this function returns a piece of the JSON string 	/// at which the error took place. To ease debugging.	/// </summary>	/// <returns></returns>	public static string getLastErrorSnippet()	{		if( FlareJson.lastErrorIndex == -1 )		{			return "";		}		else		{			int startIndex = FlareJson.lastErrorIndex - 5;			int endIndex = FlareJson.lastErrorIndex + 15;			if( startIndex < 0 )				startIndex = 0;			if( endIndex >= FlareJson.lastDecode.Length )				endIndex = FlareJson.lastDecode.Length - 1;			return FlareJson.lastDecode.Substring( startIndex, endIndex - startIndex + 1 );		}	}		#region Parsing		protected static Hashtable parseObject( char[] json, ref int index )	{		Hashtable table = new Hashtable();		int token;		// {		nextToken( json, ref index );		bool done = false;		while( !done )		{			token = lookAhead( json, index );			if( token == FlareJson.TOKEN_NONE )			{				return null;			}			else if( token == FlareJson.TOKEN_COMMA )			{				nextToken( json, ref index );			}			else if( token == FlareJson.TOKEN_CURLY_CLOSE )			{				nextToken( json, ref index );				return table;			}			else			{				// name				string name = parseString( json, ref index );				if( name == null )				{					return null;				}				// :				token = nextToken( json, ref index );				if( token != FlareJson.TOKEN_COLON )					return null;				// value				bool success = true;				object value = parseValue( json, ref index, ref success );				if( !success )					return null;				table[name] = value;			}		}		return table;	}		protected static ArrayList parseArray( char[] json, ref int index )	{		ArrayList array = new ArrayList();		// [		nextToken( json, ref index );		bool done = false;		while( !done )		{			int token = lookAhead( json, index );			if( token == FlareJson.TOKEN_NONE )			{				return null;			}			else if( token == FlareJson.TOKEN_COMMA )			{				nextToken( json, ref index );			}			else if( token == FlareJson.TOKEN_SQUARED_CLOSE )			{				nextToken( json, ref index );				break;			}			else			{				bool success = true;				object value = parseValue( json, ref index, ref success );				if( !success )					return null;				array.Add( value );			}		}		return array;	}		protected static object parseValue( char[] json, ref int index, ref bool success )	{		switch( lookAhead( json, index ) )		{			case FlareJson.TOKEN_STRING:				return parseString( json, ref index );			case FlareJson.TOKEN_NUMBER:				return parseNumber( json, ref index );			case FlareJson.TOKEN_CURLY_OPEN:				return parseObject( json, ref index );			case FlareJson.TOKEN_SQUARED_OPEN:				return parseArray( json, ref index );			case FlareJson.TOKEN_TRUE:				nextToken( json, ref index );				return Boolean.Parse( "TRUE" );			case FlareJson.TOKEN_FALSE:				nextToken( json, ref index );				return Boolean.Parse( "FALSE" );			case FlareJson.TOKEN_NULL:				nextToken( json, ref index );				return null;			case FlareJson.TOKEN_NONE:				break;		}		success = false;		return null;	}		protected static string parseString( char[] json, ref int index )	{		string s = "";		char c;		eatWhitespace( json, ref index );				// "		c = json[index++];		bool complete = false;		while( !complete )		{			if( index == json.Length )				break;			c = json[index++];			if( c == '"' )			{				complete = true;				break;			}			else if( c == '\\' )			{				if( index == json.Length )					break;				c = json[index++];				if( c == '"' )				{					s += '"';				}				else if( c == '\\' )				{					s += '\\';				}				else if( c == '/' )				{					s += '/';				}				else if( c == 'b' )				{					s += '\b';				}				else if( c == 'f' )				{					s += '\f';				}				else if( c == 'n' )				{					s += '\n';				}				else if( c == 'r' )				{					s += '\r';				}				else if( c == 't' )				{					s += '\t';				}				else if( c == 'u' )				{					int remainingLength = json.Length - index;					if( remainingLength >= 4 )					{						char[] unicodeCharArray = new char[4];						Array.Copy( json, index, unicodeCharArray, 0, 4 );						// Drop in the HTML markup for the unicode character						s += "&#x" + new string( unicodeCharArray ) + ";";						/*uint codePoint = UInt32.Parse(new string(unicodeCharArray), NumberStyles.HexNumber);// convert the integer codepoint to a unicode char and add to strings += Char.ConvertFromUtf32((int)codePoint);*/						// skip 4 chars						index += 4;					}					else					{						break;					}				}			}			else			{				s += c;			}		}		if( !complete )			return null;		return s;	}			protected static double parseNumber( char[] json, ref int index )	{		eatWhitespace( json, ref index );		int lastIndex = getLastIndexOfNumber( json, index );		int charLength = ( lastIndex - index ) + 1;		char[] numberCharArray = new char[charLength];		Array.Copy( json, index, numberCharArray, 0, charLength );		index = lastIndex + 1;		return Double.Parse( new string( numberCharArray ) ); // , CultureInfo.InvariantCulture);	}			protected static int getLastIndexOfNumber( char[] json, int index )	{		int lastIndex;		for( lastIndex = index; lastIndex < json.Length; lastIndex++ )			if( "0123456789+-.eE".IndexOf( json[lastIndex] ) == -1 )			{				break;			}		return lastIndex - 1;	}			protected static void eatWhitespace( char[] json, ref int index )	{		for( ; index < json.Length; index++ )			if( " \t\n\r".IndexOf( json[index] ) == -1 )			{				break;			}	}			protected static int lookAhead( char[] json, int index )	{		int saveIndex = index;		return nextToken( json, ref saveIndex );	}		protected static int nextToken( char[] json, ref int index )	{		eatWhitespace( json, ref index );		if( index == json.Length )		{			return FlareJson.TOKEN_NONE;		}				char c = json[index];		index++;		switch( c )		{			case '{':				return FlareJson.TOKEN_CURLY_OPEN;			case '}':				return FlareJson.TOKEN_CURLY_CLOSE;			case '[':				return FlareJson.TOKEN_SQUARED_OPEN;			case ']':				return FlareJson.TOKEN_SQUARED_CLOSE;			case ',':				return FlareJson.TOKEN_COMMA;			case '"':				return FlareJson.TOKEN_STRING;			case '0':			case '1':			case '2':			case '3':			case '4': 			case '5':			case '6':			case '7':			case '8':			case '9':			case '-': 				return FlareJson.TOKEN_NUMBER;			case ':':				return FlareJson.TOKEN_COLON;		}		index--;		int remainingLength = json.Length - index;		// false		if( remainingLength >= 5 )		{			if( json[index] == 'f' &&				json[index + 1] == 'a' &&				json[index + 2] == 'l' &&				json[index + 3] == 's' &&				json[index + 4] == 'e' )			{				index += 5;				return FlareJson.TOKEN_FALSE;			}		}		// true		if( remainingLength >= 4 )		{			if( json[index] == 't' &&				json[index + 1] == 'r' &&				json[index + 2] == 'u' &&				json[index + 3] == 'e' )			{				index += 4;				return FlareJson.TOKEN_TRUE;			}		}		// null		if( remainingLength >= 4 )		{			if( json[index] == 'n' &&				json[index + 1] == 'u' &&				json[index + 2] == 'l' &&				json[index + 3] == 'l' )			{				index += 4;				return FlareJson.TOKEN_NULL;			}		}		return FlareJson.TOKEN_NONE;	}	#endregion			#region Serialization		protected static bool serializeObjectOrArray( object objectOrArray, StringBuilder builder )	{		if( objectOrArray is Hashtable )		{			return serializeObject( (Hashtable)objectOrArray, builder );		}		else if( objectOrArray is ArrayList )			{				return serializeArray( (ArrayList)objectOrArray, builder );			}			else			{				return false;			}	}		protected static bool serializeObject( Hashtable anObject, StringBuilder builder )	{		builder.Append( "{" );		IDictionaryEnumerator e = anObject.GetEnumerator();		bool first = true;		while( e.MoveNext() )		{			string key = e.Key.ToString();			object value = e.Value;			if( !first )			{				builder.Append( ", " );			}			serializeString( key, builder );			builder.Append( ":" );			if( !serializeValue( value, builder ) )			{				return false;			}			first = false;		}		builder.Append( "}" );		return true;	}			protected static bool serializeDictionary( Dictionary<string,string> dict, StringBuilder builder )	{		builder.Append( "{" );				bool first = true;		foreach( var kv in dict )		{			if( !first )				builder.Append( ", " );						serializeString( kv.Key, builder );			builder.Append( ":" );			serializeString( kv.Value, builder );			first = false;		}		builder.Append( "}" );		return true;	}			protected static bool serializeArray( ArrayList anArray, StringBuilder builder )	{		builder.Append( "[" );		bool first = true;		for( int i = 0; i < anArray.Count; i++ )		{			object value = anArray[i];			if( !first )			{				builder.Append( ", " );			}			if( !serializeValue( value, builder ) )			{				return false;			}			first = false;		}		builder.Append( "]" );		return true;	}		protected static bool serializeValue( object value, StringBuilder builder )	{		// Type t = value.GetType();		// Debug.Log("type: " + t.ToString() + " isArray: " + t.IsArray);		if( value == null )		{			builder.Append( "null" );		}		else if( value.GetType().IsArray )		{			serializeArray( new ArrayList( (ICollection)value ), builder );		}		else if( value is string )		{			serializeString( (string)value, builder );		}		else if( value is Char )		{			serializeString( Convert.ToString( (char)value ), builder );		}		else if( value is Hashtable )		{			serializeObject( (Hashtable)value, builder );		}		else if( value is Dictionary<string,string> )		{			serializeDictionary( (Dictionary<string,string>)value, builder );		}		else if( value is ArrayList )		{			serializeArray( (ArrayList)value, builder );		}		else if( ( value is Boolean ) && ( (Boolean)value == true ) )		{			builder.Append( "true" );		}		else if( ( value is Boolean ) && ( (Boolean)value == false ) )		{			builder.Append( "false" );		}		else if( value.GetType().IsPrimitive )		{			serializeNumber( Convert.ToDouble( value ), builder );		}		else		{			return false;		}		return true;	}		protected static void serializeString( string aString, StringBuilder builder )	{		builder.Append( "\"" );		char[] charArray = aString.ToCharArray();		for( int i = 0; i < charArray.Length; i++ )		{			char c = charArray[i];			if( c == '"' )			{				builder.Append( "\\\"" );			}			else if( c == '\\' )			{				builder.Append( "\\\\" );			}			else if( c == '\b' )			{				builder.Append( "\\b" );			}			else if( c == '\f' )			{				builder.Append( "\\f" );			}			else if( c == '\n' )			{				builder.Append( "\\n" );			}			else if( c == '\r' )			{				builder.Append( "\\r" );			}			else if( c == '\t' )			{				builder.Append( "\\t" );			}			else			{				int codepoint = Convert.ToInt32( c );				if( ( codepoint >= 32 ) && ( codepoint <= 126 ) )				{					builder.Append( c );				}				else				{					builder.Append( "\\u" + Convert.ToString( codepoint, 16 ).PadLeft( 4, '0' ) );				}			}		}		builder.Append( "\"" );	}		protected static void serializeNumber( double number, StringBuilder builder )	{		builder.Append( Convert.ToString( number ) ); // , CultureInfo.InvariantCulture));	}		#endregion	}
 |