⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsonreader.cs

📁 Open Flash Chart is a program for creating charts in Flash to display in Web pages. You can create b
💻 CS
📖 第 1 页 / 共 3 页
字号:
			}

			return jsArray.ToArray();
		}

		private object ReadString(Type expectedType)
		{
			if (this.Source[this.index] != JsonReader.OperatorStringDelim &&
				this.Source[this.index] != JsonReader.OperatorStringDelimAlt)
			{
				throw new JsonDeserializationException(JsonReader.ErrorExpectedString, this.index);
			}

			char startStringDelim = this.Source[this.index];

			// consume opening quote
			this.index++;
			if (this.index >= this.SourceLength)
			{
				throw new JsonDeserializationException(JsonReader.ErrorUnterminatedString, this.index);
			}

			int start = this.index;
			StringBuilder builder = new StringBuilder();

			while (this.Source[this.index] != startStringDelim)
			{
				if (this.Source[this.index] == JsonReader.OperatorCharEscape)
				{
					// copy chunk before decoding
					builder.Append(this.Source, start, this.index - start);

					// consume escape char
					this.index++;
					if (this.index >= this.SourceLength)
					{
						throw new JsonDeserializationException(JsonReader.ErrorUnterminatedString, this.index);
					}

					// decode
					switch (this.Source[this.index])
					{
						case '0':
						{
							// don't allow NULL char '\0'
							// causes CStrings to terminate
							break;
						}
						case 'b':
						{
							// backspace
							builder.Append('\b');
							break;
						}
						case 'f':
						{
							// formfeed
							builder.Append('\f');
							break;
						}
						case 'n':
						{
							// newline
							builder.Append('\n');
							break;
						}
						case 'r':
						{
							// carriage return
							builder.Append('\r');
							break;
						}
						case 't':
						{
							// tab
							builder.Append('\t');
							break;
						}
						case 'u':
						{
							// Unicode escape sequence
							// e.g. Copyright: "\u00A9"

							// unicode ordinal
							int utf16;
							if (this.index+4 < this.SourceLength &&
								Int32.TryParse(
									this.Source.Substring(this.index+1, 4),
									NumberStyles.AllowHexSpecifier,
									NumberFormatInfo.InvariantInfo,
									out utf16))
							{
								builder.Append(Char.ConvertFromUtf32(utf16));
								this.index += 4;
							}
							else
							{
								// using FireFox style recovery, if not a valid hex
								// escape sequence then treat as single escaped 'u'
								// followed by rest of string
								builder.Append(this.Source[this.index]);
							}
							break;
						}
						default:
						{
							builder.Append(Source[this.index]);
							break;
						}
					}

					this.index++;
					if (this.index >= this.SourceLength)
					{
						throw new JsonDeserializationException(JsonReader.ErrorUnterminatedString, this.index);
					}

					start = this.index;
				}
				else
				{
					// next char
					index++;
					if (this.index >= this.SourceLength)
					{
						throw new JsonDeserializationException(JsonReader.ErrorUnterminatedString, this.index);
					}
				}
			}

			// copy rest of string
			builder.Append(this.Source, start, this.index-start);

			// consume closing quote
			this.index++;

			if (expectedType != null && expectedType != typeof(String))
			{
				return JsonReader.CoerceType(expectedType, builder.ToString(), this.index, this.AllowNullValueTypes);
			}

			return builder.ToString();
		}

		private object ReadNumber(Type expectedType)
		{
			bool hasDecimal = false;
			bool hasExponent = false;
			int start = this.index;
			int precision = 0;
			int exponent = 0;

			// optional minus part
			if (this.Source[this.index] == JsonReader.OperatorNegate)
			{
				// consume sign
				this.index++;
				if (this.index >= this.SourceLength || !Char.IsDigit(this.Source[this.index]))
					throw new JsonDeserializationException(JsonReader.ErrorIllegalNumber, this.index);
			}

			// integer part
			while ((this.index < this.SourceLength) && Char.IsDigit(this.Source[this.index]))
			{
				// consume digit
				this.index++;
			}

			// optional decimal part
			if ((this.index < this.SourceLength) && (this.Source[this.index] == '.'))
			{
				hasDecimal = true;

				// consume decimal
				this.index++;
				if (this.index >= this.SourceLength || !Char.IsDigit(this.Source[this.index]))
				{
					throw new JsonDeserializationException(JsonReader.ErrorIllegalNumber, this.index);
				}

				// fraction part
				while (this.index < this.SourceLength && Char.IsDigit(this.Source[this.index]))
				{
					// consume digit
					this.index++;
				}
			}

			// note the number of significant digits
			precision = this.index-start - (hasDecimal ? 1 : 0);

			// optional exponent part
			if (this.index < this.SourceLength && (this.Source[this.index] == 'e' || this.Source[this.index] == 'E'))
			{
				hasExponent = true;

				// consume 'e'
				this.index++;
				if (this.index >= this.SourceLength)
				{
					throw new JsonDeserializationException(JsonReader.ErrorIllegalNumber, this.index);
				}

				int expStart = this.index;

				// optional minus/plus part
				if (this.Source[this.index] == JsonReader.OperatorNegate || this.Source[this.index] == JsonReader.OperatorUnaryPlus)
				{
					// consume sign
					this.index++;
					if (this.index >= this.SourceLength || !Char.IsDigit(this.Source[this.index]))
					{
						throw new JsonDeserializationException(JsonReader.ErrorIllegalNumber, this.index);
					}
				}
				else
				{
					if (!Char.IsDigit(this.Source[this.index]))
					{
						throw new JsonDeserializationException(JsonReader.ErrorIllegalNumber, this.index);
					}
				}

				// exp part
				while (this.index < this.SourceLength && Char.IsDigit(this.Source[this.index]))
				{
					// consume digit
					this.index++;
				}

				Int32.TryParse(this.Source.Substring(expStart, this.index-expStart), NumberStyles.Integer,
					NumberFormatInfo.InvariantInfo, out exponent);
			}

			// at this point, we have the full number string and know its characteristics
			string numberString = this.Source.Substring(start, this.index - start);

			if (!hasDecimal && !hasExponent && precision < 19)
			{
				// is Integer value

				// parse as most flexible
				decimal number = Decimal.Parse(
					numberString,
					NumberStyles.Integer,
					NumberFormatInfo.InvariantInfo);

				if (expectedType != null)
				{
					return JsonReader.CoerceType(expectedType, number, this.index, this.AllowNullValueTypes);
				}

				if (number >= Int32.MinValue && number <= Int32.MaxValue)
				{
					// use most common
					return (int)number;
				}
				if (number >= Int64.MinValue && number <= Int64.MaxValue)
				{
					// use more flexible
					return (long)number;
				}

				// use most flexible
				return number;
			}
			else
			{
				// is Floating Point value

				if (expectedType == typeof(Decimal))
				{
					// special case since Double does not convert to Decimal
					return Decimal.Parse(
						numberString,
						NumberStyles.Float,
						NumberFormatInfo.InvariantInfo);
				}

				// use native EcmaScript number (IEEE 754)
				double number = Double.Parse(
					numberString,
					NumberStyles.Float,
					NumberFormatInfo.InvariantInfo);

				if (expectedType != null)
				{
					return JsonReader.CoerceType(expectedType, number, this.index, this.AllowNullValueTypes);
				}

				return number;
			}
		}

		#endregion Parsing Methods

		#region Object Methods

		/// <summary>
		/// If a Type Hint is present then this method attempts to
		/// use it and move any previously parsed data over.
		/// </summary>
		/// <param name="objectType">reference to the objectType</param>
		/// <param name="memberMap">reference to the memberMap</param>
		/// <param name="result">the previous result</param>
		/// <param name="typeInfo">the type info string to use</param>
		/// <returns></returns>
		private Object ProcessTypeHint(
			ref Type objectType,
			ref Dictionary<string, MemberInfo> memberMap,
			IDictionary result,
			string typeInfo)
		{
			if (String.IsNullOrEmpty(typeInfo))
			{
				return result;
			}

			Type hintedType = Type.GetType(typeInfo, false);
			if (hintedType == null)
			{
				return result;
			}
			objectType = hintedType;

			object newResult = this.InstantiateObject(hintedType, ref memberMap);
			if (memberMap != null)
			{
				Type memberType;
				MemberInfo memberInfo;

				// copy any values into new object
				foreach (object key in result.Keys)
				{
					JsonReader.GetMemberInfo(memberMap, key as String, out memberType, out memberInfo);
					this.SetMemberValue(newResult, memberType, memberInfo, result[key]);
				}
			}

			return newResult;
		}

		private Object InstantiateObject(Type objectType, ref Dictionary<string, MemberInfo> memberMap)
		{
			Object result;
			ConstructorInfo ctor = objectType.GetConstructor(Type.EmptyTypes);
			if (ctor == null)
			{
				throw new JsonDeserializationException(JsonReader.ErrorDefaultCtor, this.index);
			}
			result = ctor.Invoke(null);

			// don't incurr the cost of member map if a dictionary
			if (!typeof(IDictionary).IsAssignableFrom(objectType))
			{
				memberMap = this.CreateMemberMap(objectType);
			}
			return result;
		}

		private Dictionary<string, MemberInfo> CreateMemberMap(Type objectType)
		{
			if (this.MemberMapCache == null)
			{
				// instantiate space for cache
				this.MemberMapCache = new Dictionary<Type, Dictionary<string, MemberInfo>>();
			}
			else if (this.MemberMapCache.ContainsKey(objectType))
			{
				// map was stored in cache
				return this.MemberMapCache[objectType];
			}

			// create a new map
			Dictionary<string, MemberInfo> memberMap = new Dictionary<string, MemberInfo>();

			// load properties into property map
			PropertyInfo[] properties = objectType.GetProperties();
			foreach (PropertyInfo info in properties)
			{
				if (!info.CanRead || !info.CanWrite)
				{
					continue;
				}

				if (JsonIgnoreAttribute.IsJsonIgnore(info))
				{
					continue;
				}

				string jsonName = JsonNameAttribute.GetJsonName(info);
				if (String.IsNullOrEmpty(jsonName))
				{
					memberMap[info.Name] = info;
				}
				else
				{
					memberMap[jsonName] = info;
				}
			}

			// load public fields into property map
			FieldInfo[] fields = objectType.GetFields();
			foreach (FieldInfo info in fields)
			{
				if (!info.IsPublic)
				{
					continue;
				}

				if (JsonIgnoreAttribute.IsJsonIgnore(info))
				{
					continue;
				}

				string jsonName = JsonNameAttribute.GetJsonName(info);
				if (String.IsNullOrEmpty(jsonName))
				{
					memberMap[info.Name] = info;
				}
				else
				{
					memberMap[jsonName] = info;
				}
			}

			// store in cache for repeated usage
			this.MemberMapCache[objectType] = memberMap;

			return memberMap;
		}

		private static void GetMemberInfo(
			Dictionary<string, MemberInfo> memberMap,
			string memberName,
			out Type memberType,
			out MemberInfo memberInfo)
		{
			memberType = null;
			memberInfo = null;

			if (memberMap != null &&
				memberMap.ContainsKey(memberName))
			{
				// Check properties for object member
				memberInfo = memberMap[memberName];

				if (memberInfo is PropertyInfo)
				{
					// maps to public property
					memberType = ((PropertyInfo)memberInfo).PropertyType;
				}
				else if (memberInfo is FieldInfo)
				{
					// maps to public field
					memberType = ((FieldInfo)memberInfo).FieldType;
				}
				else
				{
					// none found
					memberType = null;
				}
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -