forked from LeenkxTeam/LNXSDK
		
	Update Files
This commit is contained in:
		
							
								
								
									
										324
									
								
								Kha/Tools/macos/std/haxe/format/JsonParser.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								Kha/Tools/macos/std/haxe/format/JsonParser.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,324 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package haxe.format;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	An implementation of JSON parser in Haxe.
 | 
			
		||||
 | 
			
		||||
	This class is used by `haxe.Json` when native JSON implementation
 | 
			
		||||
	is not available.
 | 
			
		||||
 | 
			
		||||
	@see https://haxe.org/manual/std-Json-parsing.html
 | 
			
		||||
**/
 | 
			
		||||
class JsonParser {
 | 
			
		||||
	/**
 | 
			
		||||
		Parses given JSON-encoded `str` and returns the resulting object.
 | 
			
		||||
 | 
			
		||||
		JSON objects are parsed into anonymous structures and JSON arrays
 | 
			
		||||
		are parsed into `Array<Dynamic>`.
 | 
			
		||||
 | 
			
		||||
		If given `str` is not valid JSON, an exception will be thrown.
 | 
			
		||||
 | 
			
		||||
		If `str` is null, the result is unspecified.
 | 
			
		||||
	**/
 | 
			
		||||
	static public inline function parse(str:String):Dynamic {
 | 
			
		||||
		return new JsonParser(str).doParse();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var str:String;
 | 
			
		||||
	var pos:Int;
 | 
			
		||||
 | 
			
		||||
	function new(str:String) {
 | 
			
		||||
		this.str = str;
 | 
			
		||||
		this.pos = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function doParse():Dynamic {
 | 
			
		||||
		var result = parseRec();
 | 
			
		||||
		var c;
 | 
			
		||||
		while (!StringTools.isEof(c = nextChar())) {
 | 
			
		||||
			switch (c) {
 | 
			
		||||
				case ' '.code, '\r'.code, '\n'.code, '\t'.code:
 | 
			
		||||
				// allow trailing whitespace
 | 
			
		||||
				default:
 | 
			
		||||
					invalidChar();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parseRec():Dynamic {
 | 
			
		||||
		while (true) {
 | 
			
		||||
			var c = nextChar();
 | 
			
		||||
			switch (c) {
 | 
			
		||||
				case ' '.code, '\r'.code, '\n'.code, '\t'.code:
 | 
			
		||||
				// loop
 | 
			
		||||
				case '{'.code:
 | 
			
		||||
					var obj = {}, field = null, comma:Null<Bool> = null;
 | 
			
		||||
					while (true) {
 | 
			
		||||
						var c = nextChar();
 | 
			
		||||
						switch (c) {
 | 
			
		||||
							case ' '.code, '\r'.code, '\n'.code, '\t'.code:
 | 
			
		||||
							// loop
 | 
			
		||||
							case '}'.code:
 | 
			
		||||
								if (field != null || comma == false)
 | 
			
		||||
									invalidChar();
 | 
			
		||||
								return obj;
 | 
			
		||||
							case ':'.code:
 | 
			
		||||
								if (field == null)
 | 
			
		||||
									invalidChar();
 | 
			
		||||
								Reflect.setField(obj, field, parseRec());
 | 
			
		||||
								field = null;
 | 
			
		||||
								comma = true;
 | 
			
		||||
							case ','.code:
 | 
			
		||||
								if (comma) comma = false else invalidChar();
 | 
			
		||||
							case '"'.code:
 | 
			
		||||
								if (field != null || comma) invalidChar();
 | 
			
		||||
								field = parseString();
 | 
			
		||||
							default:
 | 
			
		||||
								invalidChar();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				case '['.code:
 | 
			
		||||
					var arr = [], comma:Null<Bool> = null;
 | 
			
		||||
					while (true) {
 | 
			
		||||
						var c = nextChar();
 | 
			
		||||
						switch (c) {
 | 
			
		||||
							case ' '.code, '\r'.code, '\n'.code, '\t'.code:
 | 
			
		||||
							// loop
 | 
			
		||||
							case ']'.code:
 | 
			
		||||
								if (comma == false) invalidChar();
 | 
			
		||||
								return arr;
 | 
			
		||||
							case ','.code:
 | 
			
		||||
								if (comma) comma = false else invalidChar();
 | 
			
		||||
							default:
 | 
			
		||||
								if (comma) invalidChar();
 | 
			
		||||
								pos--;
 | 
			
		||||
								arr.push(parseRec());
 | 
			
		||||
								comma = true;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				case 't'.code:
 | 
			
		||||
					var save = pos;
 | 
			
		||||
					if (nextChar() != 'r'.code || nextChar() != 'u'.code || nextChar() != 'e'.code) {
 | 
			
		||||
						pos = save;
 | 
			
		||||
						invalidChar();
 | 
			
		||||
					}
 | 
			
		||||
					return true;
 | 
			
		||||
				case 'f'.code:
 | 
			
		||||
					var save = pos;
 | 
			
		||||
					if (nextChar() != 'a'.code || nextChar() != 'l'.code || nextChar() != 's'.code || nextChar() != 'e'.code) {
 | 
			
		||||
						pos = save;
 | 
			
		||||
						invalidChar();
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				case 'n'.code:
 | 
			
		||||
					var save = pos;
 | 
			
		||||
					if (nextChar() != 'u'.code || nextChar() != 'l'.code || nextChar() != 'l'.code) {
 | 
			
		||||
						pos = save;
 | 
			
		||||
						invalidChar();
 | 
			
		||||
					}
 | 
			
		||||
					return null;
 | 
			
		||||
				case '"'.code:
 | 
			
		||||
					return parseString();
 | 
			
		||||
				case '0'.code, '1'.code, '2'.code, '3'.code, '4'.code, '5'.code, '6'.code, '7'.code, '8'.code, '9'.code, '-'.code:
 | 
			
		||||
					return parseNumber(c);
 | 
			
		||||
				default:
 | 
			
		||||
					invalidChar();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function parseString() {
 | 
			
		||||
		var start = pos;
 | 
			
		||||
		var buf:StringBuf = null;
 | 
			
		||||
		#if target.unicode
 | 
			
		||||
		var prev = -1;
 | 
			
		||||
		inline function cancelSurrogate() {
 | 
			
		||||
			// invalid high surrogate (not followed by low surrogate)
 | 
			
		||||
			buf.addChar(0xFFFD);
 | 
			
		||||
			prev = -1;
 | 
			
		||||
		}
 | 
			
		||||
		#end
 | 
			
		||||
		while (true) {
 | 
			
		||||
			var c = nextChar();
 | 
			
		||||
			if (c == '"'.code)
 | 
			
		||||
				break;
 | 
			
		||||
			if (c == '\\'.code) {
 | 
			
		||||
				if (buf == null) {
 | 
			
		||||
					buf = new StringBuf();
 | 
			
		||||
				}
 | 
			
		||||
				buf.addSub(str, start, pos - start - 1);
 | 
			
		||||
				c = nextChar();
 | 
			
		||||
				#if target.unicode
 | 
			
		||||
				if (c != "u".code && prev != -1)
 | 
			
		||||
					cancelSurrogate();
 | 
			
		||||
				#end
 | 
			
		||||
				switch (c) {
 | 
			
		||||
					case "r".code:
 | 
			
		||||
						buf.addChar("\r".code);
 | 
			
		||||
					case "n".code:
 | 
			
		||||
						buf.addChar("\n".code);
 | 
			
		||||
					case "t".code:
 | 
			
		||||
						buf.addChar("\t".code);
 | 
			
		||||
					case "b".code:
 | 
			
		||||
						buf.addChar(8);
 | 
			
		||||
					case "f".code:
 | 
			
		||||
						buf.addChar(12);
 | 
			
		||||
					case "/".code, '\\'.code, '"'.code:
 | 
			
		||||
						buf.addChar(c);
 | 
			
		||||
					case 'u'.code:
 | 
			
		||||
						var uc:Int = Std.parseInt("0x" + str.substr(pos, 4));
 | 
			
		||||
						pos += 4;
 | 
			
		||||
						#if !target.unicode
 | 
			
		||||
						if (uc <= 0x7F)
 | 
			
		||||
							buf.addChar(uc);
 | 
			
		||||
						else if (uc <= 0x7FF) {
 | 
			
		||||
							buf.addChar(0xC0 | (uc >> 6));
 | 
			
		||||
							buf.addChar(0x80 | (uc & 63));
 | 
			
		||||
						} else if (uc <= 0xFFFF) {
 | 
			
		||||
							buf.addChar(0xE0 | (uc >> 12));
 | 
			
		||||
							buf.addChar(0x80 | ((uc >> 6) & 63));
 | 
			
		||||
							buf.addChar(0x80 | (uc & 63));
 | 
			
		||||
						} else {
 | 
			
		||||
							buf.addChar(0xF0 | (uc >> 18));
 | 
			
		||||
							buf.addChar(0x80 | ((uc >> 12) & 63));
 | 
			
		||||
							buf.addChar(0x80 | ((uc >> 6) & 63));
 | 
			
		||||
							buf.addChar(0x80 | (uc & 63));
 | 
			
		||||
						}
 | 
			
		||||
						#else
 | 
			
		||||
						if (prev != -1) {
 | 
			
		||||
							if (uc < 0xDC00 || uc > 0xDFFF)
 | 
			
		||||
								cancelSurrogate();
 | 
			
		||||
							else {
 | 
			
		||||
								buf.addChar(((prev - 0xD800) << 10) + (uc - 0xDC00) + 0x10000);
 | 
			
		||||
								prev = -1;
 | 
			
		||||
							}
 | 
			
		||||
						} else if (uc >= 0xD800 && uc <= 0xDBFF)
 | 
			
		||||
							prev = uc;
 | 
			
		||||
						else
 | 
			
		||||
							buf.addChar(uc);
 | 
			
		||||
						#end
 | 
			
		||||
					default:
 | 
			
		||||
						throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1);
 | 
			
		||||
				}
 | 
			
		||||
				start = pos;
 | 
			
		||||
			}
 | 
			
		||||
			#if !(target.unicode)
 | 
			
		||||
			// ensure utf8 chars are not cut
 | 
			
		||||
			else if (c >= 0x80) {
 | 
			
		||||
				pos++;
 | 
			
		||||
				if (c >= 0xFC)
 | 
			
		||||
					pos += 4;
 | 
			
		||||
				else if (c >= 0xF8)
 | 
			
		||||
					pos += 3;
 | 
			
		||||
				else if (c >= 0xF0)
 | 
			
		||||
					pos += 2;
 | 
			
		||||
				else if (c >= 0xE0)
 | 
			
		||||
					pos++;
 | 
			
		||||
			}
 | 
			
		||||
			#end
 | 
			
		||||
		else if (StringTools.isEof(c))
 | 
			
		||||
			throw "Unclosed string";
 | 
			
		||||
		}
 | 
			
		||||
		#if target.unicode
 | 
			
		||||
		if (prev != -1)
 | 
			
		||||
			cancelSurrogate();
 | 
			
		||||
		#end
 | 
			
		||||
		if (buf == null) {
 | 
			
		||||
			return str.substr(start, pos - start - 1);
 | 
			
		||||
		} else {
 | 
			
		||||
			buf.addSub(str, start, pos - start - 1);
 | 
			
		||||
			return buf.toString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline function parseNumber(c:Int):Dynamic {
 | 
			
		||||
		var start = pos - 1;
 | 
			
		||||
		var minus = c == '-'.code, digit = !minus, zero = c == '0'.code;
 | 
			
		||||
		var point = false, e = false, pm = false, end = false;
 | 
			
		||||
		while (true) {
 | 
			
		||||
			c = nextChar();
 | 
			
		||||
			switch (c) {
 | 
			
		||||
				case '0'.code:
 | 
			
		||||
					if (zero && !point)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					if (minus) {
 | 
			
		||||
						minus = false;
 | 
			
		||||
						zero = true;
 | 
			
		||||
					}
 | 
			
		||||
					digit = true;
 | 
			
		||||
				case '1'.code, '2'.code, '3'.code, '4'.code, '5'.code, '6'.code, '7'.code, '8'.code, '9'.code:
 | 
			
		||||
					if (zero && !point)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					if (minus)
 | 
			
		||||
						minus = false;
 | 
			
		||||
					digit = true;
 | 
			
		||||
					zero = false;
 | 
			
		||||
				case '.'.code:
 | 
			
		||||
					if (minus || point || e)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					digit = false;
 | 
			
		||||
					point = true;
 | 
			
		||||
				case 'e'.code, 'E'.code:
 | 
			
		||||
					if (minus || zero || e)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					digit = false;
 | 
			
		||||
					e = true;
 | 
			
		||||
				case '+'.code, '-'.code:
 | 
			
		||||
					if (!e || pm)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					digit = false;
 | 
			
		||||
					pm = true;
 | 
			
		||||
				default:
 | 
			
		||||
					if (!digit)
 | 
			
		||||
						invalidNumber(start);
 | 
			
		||||
					pos--;
 | 
			
		||||
					end = true;
 | 
			
		||||
			}
 | 
			
		||||
			if (end)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var f = Std.parseFloat(str.substr(start, pos - start));
 | 
			
		||||
		if(point) {
 | 
			
		||||
			return f;
 | 
			
		||||
		} else {
 | 
			
		||||
			var i = Std.int(f);
 | 
			
		||||
			return if (i == f) i else f;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline function nextChar() {
 | 
			
		||||
		return StringTools.fastCodeAt(str, pos++);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function invalidChar() {
 | 
			
		||||
		pos--; // rewind
 | 
			
		||||
		throw "Invalid char " + StringTools.fastCodeAt(str, pos) + " at position " + pos;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function invalidNumber(start:Int) {
 | 
			
		||||
		throw "Invalid number at position " + start + ": " + str.substr(start, pos - start);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										291
									
								
								Kha/Tools/macos/std/haxe/format/JsonPrinter.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								Kha/Tools/macos/std/haxe/format/JsonPrinter.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,291 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package haxe.format;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	An implementation of JSON printer in Haxe.
 | 
			
		||||
 | 
			
		||||
	This class is used by `haxe.Json` when native JSON implementation
 | 
			
		||||
	is not available.
 | 
			
		||||
 | 
			
		||||
	@see https://haxe.org/manual/std-Json-encoding.html
 | 
			
		||||
**/
 | 
			
		||||
class JsonPrinter {
 | 
			
		||||
	/**
 | 
			
		||||
		Encodes `o`'s value and returns the resulting JSON string.
 | 
			
		||||
 | 
			
		||||
		If `replacer` is given and is not null, it is used to retrieve
 | 
			
		||||
		actual object to be encoded. The `replacer` function takes two parameters,
 | 
			
		||||
		the key and the value being encoded. Initial key value is an empty string.
 | 
			
		||||
 | 
			
		||||
		If `space` is given and is not null, the result will be pretty-printed.
 | 
			
		||||
		Successive levels will be indented by this string.
 | 
			
		||||
	**/
 | 
			
		||||
	static public function print(o:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String):String {
 | 
			
		||||
		var printer = new JsonPrinter(replacer, space);
 | 
			
		||||
		printer.write("", o);
 | 
			
		||||
		return printer.buf.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var buf:#if flash flash.utils.ByteArray #else StringBuf #end;
 | 
			
		||||
	var replacer:(key:Dynamic, value:Dynamic) -> Dynamic;
 | 
			
		||||
	var indent:String;
 | 
			
		||||
	var pretty:Bool;
 | 
			
		||||
	var nind:Int;
 | 
			
		||||
 | 
			
		||||
	function new(replacer:(key:Dynamic, value:Dynamic) -> Dynamic, space:String) {
 | 
			
		||||
		this.replacer = replacer;
 | 
			
		||||
		this.indent = space;
 | 
			
		||||
		this.pretty = space != null;
 | 
			
		||||
		this.nind = 0;
 | 
			
		||||
 | 
			
		||||
		#if flash
 | 
			
		||||
		buf = new flash.utils.ByteArray();
 | 
			
		||||
		buf.endian = flash.utils.Endian.BIG_ENDIAN;
 | 
			
		||||
		buf.position = 0;
 | 
			
		||||
		#else
 | 
			
		||||
		buf = new StringBuf();
 | 
			
		||||
		#end
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline function ipad():Void {
 | 
			
		||||
		if (pretty)
 | 
			
		||||
			add(StringTools.lpad('', indent, nind * indent.length));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline function newl():Void {
 | 
			
		||||
		if (pretty)
 | 
			
		||||
			addChar('\n'.code);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function write(k:Dynamic, v:Dynamic) {
 | 
			
		||||
		if (replacer != null)
 | 
			
		||||
			v = replacer(k, v);
 | 
			
		||||
		switch (Type.typeof(v)) {
 | 
			
		||||
			case TUnknown:
 | 
			
		||||
				add('"???"');
 | 
			
		||||
			case TObject:
 | 
			
		||||
				objString(v);
 | 
			
		||||
			case TInt:
 | 
			
		||||
				add(#if (jvm || hl) Std.string(v) #else v #end);
 | 
			
		||||
			case TFloat:
 | 
			
		||||
				add(Math.isFinite(v) ? Std.string(v) : 'null');
 | 
			
		||||
			case TFunction:
 | 
			
		||||
				add('"<fun>"');
 | 
			
		||||
			case TClass(c):
 | 
			
		||||
				if (c == String)
 | 
			
		||||
					quote(v);
 | 
			
		||||
				else if (c == Array) {
 | 
			
		||||
					var v:Array<Dynamic> = v;
 | 
			
		||||
					addChar('['.code);
 | 
			
		||||
 | 
			
		||||
					var len = v.length;
 | 
			
		||||
					var last = len - 1;
 | 
			
		||||
					for (i in 0...len) {
 | 
			
		||||
						if (i > 0)
 | 
			
		||||
							addChar(','.code)
 | 
			
		||||
						else
 | 
			
		||||
							nind++;
 | 
			
		||||
						newl();
 | 
			
		||||
						ipad();
 | 
			
		||||
						write(i, v[i]);
 | 
			
		||||
						if (i == last) {
 | 
			
		||||
							nind--;
 | 
			
		||||
							newl();
 | 
			
		||||
							ipad();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					addChar(']'.code);
 | 
			
		||||
				} else if (c == haxe.ds.StringMap) {
 | 
			
		||||
					var v:haxe.ds.StringMap<Dynamic> = v;
 | 
			
		||||
					var o = {};
 | 
			
		||||
					for (k in v.keys())
 | 
			
		||||
						Reflect.setField(o, k, v.get(k));
 | 
			
		||||
					objString(o);
 | 
			
		||||
				} else if (c == Date) {
 | 
			
		||||
					var v:Date = v;
 | 
			
		||||
					quote(v.toString());
 | 
			
		||||
				} else
 | 
			
		||||
					classString(v);
 | 
			
		||||
			case TEnum(_):
 | 
			
		||||
				var i:Dynamic = Type.enumIndex(v);
 | 
			
		||||
				add(i);
 | 
			
		||||
			case TBool:
 | 
			
		||||
				add(#if (php || jvm || hl) (v ? 'true' : 'false') #else v #end);
 | 
			
		||||
			case TNull:
 | 
			
		||||
				add('null');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	extern inline function addChar(c:Int) {
 | 
			
		||||
		#if flash
 | 
			
		||||
		buf.writeByte(c);
 | 
			
		||||
		#else
 | 
			
		||||
		buf.addChar(c);
 | 
			
		||||
		#end
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	extern inline function add(v:String) {
 | 
			
		||||
		#if flash
 | 
			
		||||
		// argument is not always a string but will be automatically casted
 | 
			
		||||
		buf.writeUTFBytes(v);
 | 
			
		||||
		#else
 | 
			
		||||
		buf.add(v);
 | 
			
		||||
		#end
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function classString(v:Dynamic) {
 | 
			
		||||
		fieldsString(v, Type.getInstanceFields(Type.getClass(v)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline function objString(v:Dynamic) {
 | 
			
		||||
		fieldsString(v, Reflect.fields(v));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function fieldsString(v:Dynamic, fields:Array<String>) {
 | 
			
		||||
		addChar('{'.code);
 | 
			
		||||
		var len = fields.length;
 | 
			
		||||
		var last = len - 1;
 | 
			
		||||
		var first = true;
 | 
			
		||||
		for (i in 0...len) {
 | 
			
		||||
			var f = fields[i];
 | 
			
		||||
			var value = Reflect.field(v, f);
 | 
			
		||||
			if (Reflect.isFunction(value))
 | 
			
		||||
				continue;
 | 
			
		||||
			if (first) {
 | 
			
		||||
				nind++;
 | 
			
		||||
				first = false;
 | 
			
		||||
			} else
 | 
			
		||||
				addChar(','.code);
 | 
			
		||||
			newl();
 | 
			
		||||
			ipad();
 | 
			
		||||
			quote(f);
 | 
			
		||||
			addChar(':'.code);
 | 
			
		||||
			if (pretty)
 | 
			
		||||
				addChar(' '.code);
 | 
			
		||||
			write(f, value);
 | 
			
		||||
			if (i == last) {
 | 
			
		||||
				nind--;
 | 
			
		||||
				newl();
 | 
			
		||||
				ipad();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		addChar('}'.code);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function quote(s:String) {
 | 
			
		||||
		#if neko
 | 
			
		||||
		if (s.length != neko.Utf8.length(s)) {
 | 
			
		||||
			quoteUtf8(s);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		#end
 | 
			
		||||
		addChar('"'.code);
 | 
			
		||||
		var i = 0;
 | 
			
		||||
		var length = s.length;
 | 
			
		||||
		#if hl
 | 
			
		||||
		var prev = -1;
 | 
			
		||||
		#end
 | 
			
		||||
		while (i < length) {
 | 
			
		||||
			var c = StringTools.unsafeCodeAt(s, i++);
 | 
			
		||||
			switch (c) {
 | 
			
		||||
				case '"'.code:
 | 
			
		||||
					add('\\"');
 | 
			
		||||
				case '\\'.code:
 | 
			
		||||
					add('\\\\');
 | 
			
		||||
				case '\n'.code:
 | 
			
		||||
					add('\\n');
 | 
			
		||||
				case '\r'.code:
 | 
			
		||||
					add('\\r');
 | 
			
		||||
				case '\t'.code:
 | 
			
		||||
					add('\\t');
 | 
			
		||||
				case 8:
 | 
			
		||||
					add('\\b');
 | 
			
		||||
				case 12:
 | 
			
		||||
					add('\\f');
 | 
			
		||||
				default:
 | 
			
		||||
					#if flash
 | 
			
		||||
					if (c >= 128)
 | 
			
		||||
						add(String.fromCharCode(c))
 | 
			
		||||
					else
 | 
			
		||||
						addChar(c);
 | 
			
		||||
					#elseif hl
 | 
			
		||||
					if (prev >= 0) {
 | 
			
		||||
						if (c >= 0xD800 && c <= 0xDFFF) {
 | 
			
		||||
							addChar((((prev - 0xD800) << 10) | (c - 0xDC00)) + 0x10000);
 | 
			
		||||
							prev = -1;
 | 
			
		||||
						} else {
 | 
			
		||||
							addChar("□".code);
 | 
			
		||||
							prev = c;
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						if (c >= 0xD800 && c <= 0xDFFF)
 | 
			
		||||
							prev = c;
 | 
			
		||||
						else
 | 
			
		||||
							addChar(c);
 | 
			
		||||
					}
 | 
			
		||||
					#else
 | 
			
		||||
					addChar(c);
 | 
			
		||||
					#end
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		#if hl
 | 
			
		||||
		if (prev >= 0)
 | 
			
		||||
			addChar("□".code);
 | 
			
		||||
		#end
 | 
			
		||||
		addChar('"'.code);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#if neko
 | 
			
		||||
	function quoteUtf8(s:String) {
 | 
			
		||||
		var u = new neko.Utf8();
 | 
			
		||||
		neko.Utf8.iter(s, function(c) {
 | 
			
		||||
			switch (c) {
 | 
			
		||||
				case '\\'.code, '"'.code:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar(c);
 | 
			
		||||
				case '\n'.code:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar('n'.code);
 | 
			
		||||
				case '\r'.code:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar('r'.code);
 | 
			
		||||
				case '\t'.code:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar('t'.code);
 | 
			
		||||
				case 8:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar('b'.code);
 | 
			
		||||
				case 12:
 | 
			
		||||
					u.addChar('\\'.code);
 | 
			
		||||
					u.addChar('f'.code);
 | 
			
		||||
				default:
 | 
			
		||||
					u.addChar(c);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		buf.add('"');
 | 
			
		||||
		buf.add(u.toString());
 | 
			
		||||
		buf.add('"');
 | 
			
		||||
	}
 | 
			
		||||
	#end
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user