├── README.md ├── UnitTest ├── UnitTest.sln ├── ParserUnitTests.cs └── UnitTests.csproj ├── LICENSE ├── TinyJSONExt.cs └── TinyJSON.cs /README.md: -------------------------------------------------------------------------------- 1 | # TinyJSON 2 | C#实现的JSON解析器,核心目标是效率和使用简单,并附带有严格的语法检查。 3 | 该解析器扩展了一个注释相关的语法,/**/包围的内容被视为注释,此外完全遵循JSON的语法规范(注释是否合法可以通过选项设置,默认不支持注释)。 4 | 此外解析器还支持Object的键不需要引号,允许Object/Array的最后一个元素保留逗号 5 | 6 | 7 | 接下来需要添加的特性: 8 | 9 | + 增加对象序列化成JSON字符串的自动反射支持 10 | + JSON解析支持严格模式和禁止注释的选项(此时只支持解析完全符合标准的JSON字符串) 11 | + JSON解析时出错,提供详细错误信息 12 | 13 | >-------------2018-5-10------------- 14 | > 15 | >修改API版本(破坏向下兼容,如果要使用原来的版本,请使用v1.0分支),并提供JSON字符串映射到对象的自动反射支持 16 | 17 | >-------------2016-10-31------------- 18 | > 19 | >序列化新增支持匿名函数的接口 20 | 21 | >-------------2016-06-27------------- 22 | > 23 | >修改底层实现,增加新的SAX事件类型解析支持(便于集成到自定义数据类型解析),原DOM解析接口基于SAX解析接口实现,Printer增加Format格式化接口(同样基于SAX接口实现) -------------------------------------------------------------------------------- /UnitTest/UnitTest.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests.csproj", "{36E24A29-D440-4D6B-8333-E974E753383D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {36E24A29-D440-4D6B-8333-E974E753383D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {36E24A29-D440-4D6B-8333-E974E753383D}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {36E24A29-D440-4D6B-8333-E974E753383D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {36E24A29-D440-4D6B-8333-E974E753383D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 libla 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /UnitTest/ParserUnitTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace TinyJSON.UnitTests 4 | { 5 | [TestClass()] 6 | public class ParserUnitTests 7 | { 8 | [TestMethod] 9 | public void LoadUnitTest() 10 | { 11 | string right = @"{ 12 | ""array"": [1.44, 2, 3], 13 | ""object"": {""key1"":""value1"", ""key2"":256}, 14 | ""string"": ""The quick brown fox \""jumps\"" over the lazy dog "", 15 | ""unicode"": ""\u3041 Men\u54c8 sesiu00f3n"", 16 | ""int"": 65536, 17 | ""float"": -3.1415926e-1, 18 | ""bool"": true, 19 | ""null"": null 20 | }"; 21 | string wrong = @"[,]"; 22 | JSON json = new JSON(); 23 | Assert.IsNotNull(json.Parse(right)); 24 | Assert.IsNull(json.Parse(wrong)); 25 | Assert.IsNotNull(json.Dump(json.Parse(right))); 26 | Assert.IsNotNull(json.Parse(json.Dump(json.Parse(right)))); 27 | } 28 | 29 | [TestMethod] 30 | public void ReflectUnitTest() 31 | { 32 | string right = @"{ 33 | ""array"": [1.44, 2, 3], 34 | ""object"": {""key1"":""value1"", ""key2"":256}, 35 | ""string"": ""The quick brown fox \""jumps\"" over the lazy dog "", 36 | ""unicode"": ""\u3041 Men\u54c8 sesiu00f3n"", 37 | ""int"": 65536, 38 | ""float"": -3.1415926e-1, 39 | ""bool"": true 40 | }"; 41 | 42 | ReflectTest test = new ReflectTest(); 43 | JSON json = new JSON(); 44 | JSON.Value? value = json.Parse(right); 45 | Assert.IsTrue(value.HasValue); 46 | Assert.IsNotNull(value.Value.AsObject()); 47 | Assert.IsTrue(test.Read(value.Value.AsObject())); 48 | Assert.AreEqual(test.array.Length, 3); 49 | Assert.AreEqual(test.obj.key1, "value1"); 50 | Assert.AreEqual(test.obj.key2, 256); 51 | Assert.AreEqual(test.str, @"The quick brown fox ""jumps"" over the lazy dog "); 52 | Assert.AreEqual(test.i, 65536); 53 | Assert.AreEqual(test.f, -3.1415926e-1); 54 | Assert.AreEqual(test.b, true); 55 | } 56 | 57 | private class ReflectTest : JSON.Readable 58 | { 59 | public double[] array; 60 | [JSON.Entity(Name = "object")] public ReflectSubTest obj; 61 | [JSON.Entity(Name = "string")] public string str; 62 | public string unicode; 63 | [JSON.Entity(Name = "int")] public int i; 64 | [JSON.Entity(Name = "float")] public double f; 65 | [JSON.Entity(Name = "bool")] public bool b; 66 | 67 | public bool Read(JSON.Object o) 68 | { 69 | return o.Help(this); 70 | } 71 | } 72 | 73 | private class ReflectSubTest : JSON.Readable 74 | { 75 | public string key1; 76 | public int key2; 77 | 78 | public bool Read(JSON.Object o) 79 | { 80 | return o.Help(this); 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /UnitTest/UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {36E24A29-D440-4D6B-8333-E974E753383D} 7 | Library 8 | Properties 9 | UnitTestUnitTests 10 | UnitTestUnitTests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | False 62 | 63 | 64 | False 65 | 66 | 67 | False 68 | 69 | 70 | False 71 | 72 | 73 | 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /TinyJSONExt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Collections.Generic; 4 | 5 | namespace TinyJSON 6 | { 7 | public sealed partial class JSON 8 | { 9 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 10 | public class EntityAttribute : Attribute 11 | { 12 | public string Name; 13 | public bool Required; 14 | 15 | public EntityAttribute() 16 | { 17 | Name = null; 18 | Required = false; 19 | } 20 | } 21 | } 22 | 23 | public static partial class JSONExt 24 | { 25 | public static bool Help(this JSON.Object o, ref T value) where T : struct, JSON.Readable 26 | { 27 | return ReadHelper.Read(o, ref value); 28 | } 29 | 30 | public static bool Help(this JSON.Object o, T value) where T : class, JSON.Readable 31 | { 32 | return ReadHelper.Read(o, ref value); 33 | } 34 | 35 | #region 自动映射Object和指定数据类型 36 | private static bool Get(JSON.Object o, string key, ref bool b) 37 | { 38 | return o.Get(key, ref b); 39 | } 40 | 41 | private static bool Get(JSON.Object o, string key, ref int i) 42 | { 43 | return o.Get(key, ref i); 44 | } 45 | 46 | private static bool Get(JSON.Object o, string key, ref double d) 47 | { 48 | return o.Get(key, ref d); 49 | } 50 | 51 | private static bool Get(JSON.Object o, string key, ref string s) 52 | { 53 | return o.Get(key, ref s); 54 | } 55 | 56 | private static bool Get(JSON.Object o, string key, ref JSON.Object oo) 57 | { 58 | return o.Get(key, ref oo); 59 | } 60 | 61 | private static bool Get(JSON.Object o, string key, ref JSON.Array a) 62 | { 63 | return o.Get(key, ref a); 64 | } 65 | 66 | private static bool GetEnum(JSON.Object o, Type type, string key, ref object value) 67 | { 68 | string result = default(string); 69 | if (!o.Get(key, ref result)) 70 | return false; 71 | try 72 | { 73 | value = Enum.Parse(type, result); 74 | } 75 | catch (Exception) 76 | { 77 | return false; 78 | } 79 | return true; 80 | } 81 | 82 | private static bool GetEnumNullable(JSON.Object o, Type type, string key, ref object value) 83 | { 84 | string result = default(string); 85 | if (!o.Get(key, ref result)) 86 | return false; 87 | if (string.IsNullOrEmpty(result)) 88 | { 89 | value = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(type)); 90 | return true; 91 | } 92 | object tmp; 93 | try 94 | { 95 | tmp = Enum.Parse(type, result); 96 | } 97 | catch (Exception) 98 | { 99 | return false; 100 | } 101 | value = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(type), tmp); 102 | return true; 103 | } 104 | 105 | private static bool GetEnumArray(JSON.Object o, Type type, string key, ref object value) 106 | { 107 | JSON.Array result = default(JSON.Array); 108 | if (!o.Get(key, ref result)) 109 | return false; 110 | int count = result.Count; 111 | Array array = Array.CreateInstance(type, count); 112 | for (int i = 0; i < count; ++i) 113 | { 114 | string tmp1 = default(string); 115 | if (!o.Get(key, ref tmp1)) 116 | return false; 117 | object tmp2; 118 | try 119 | { 120 | tmp2 = Enum.Parse(type, tmp1); 121 | } 122 | catch (Exception) 123 | { 124 | return false; 125 | } 126 | array.SetValue(tmp2, i); 127 | } 128 | value = array; 129 | return true; 130 | } 131 | 132 | private static bool GetType(JSON.Object o, Type type, string key, ref object value) 133 | { 134 | JSON.Object result = default(JSON.Object); 135 | if (!o.Get(key, ref result)) 136 | return false; 137 | JSON.Readable tmp; 138 | try 139 | { 140 | tmp = (JSON.Readable)Activator.CreateInstance(type); 141 | } 142 | catch (Exception) 143 | { 144 | return false; 145 | } 146 | if (!tmp.Read(result)) 147 | return false; 148 | value = tmp; 149 | return true; 150 | } 151 | 152 | private static bool GetTypeNullable(JSON.Object o, Type type, string key, ref object value) 153 | { 154 | JSON.Object result = default(JSON.Object); 155 | if (!o.Get(key, ref result)) 156 | return false; 157 | if (result == null) 158 | { 159 | value = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(type)); 160 | return true; 161 | } 162 | JSON.Readable tmp; 163 | try 164 | { 165 | tmp = (JSON.Readable)Activator.CreateInstance(type); 166 | } 167 | catch (Exception) 168 | { 169 | return false; 170 | } 171 | if (!tmp.Read(result)) 172 | return false; 173 | value = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(type), tmp); 174 | return true; 175 | } 176 | 177 | private static bool GetTypeArray(JSON.Object o, Type type, string key, ref object value) 178 | { 179 | JSON.Array result = default(JSON.Array); 180 | if (!o.Get(key, ref result)) 181 | return false; 182 | int count = result.Count; 183 | Array array = Array.CreateInstance(type, count); 184 | for (int i = 0; i < count; ++i) 185 | { 186 | JSON.Object tmp1 = default(JSON.Object); 187 | if (!o.Get(key, ref tmp1)) 188 | return false; 189 | JSON.Readable tmp2; 190 | try 191 | { 192 | tmp2 = (JSON.Readable)Activator.CreateInstance(type); 193 | } 194 | catch (Exception) 195 | { 196 | return false; 197 | } 198 | if (!tmp2.Read(tmp1)) 199 | return false; 200 | array.SetValue(tmp2, i); 201 | } 202 | value = array; 203 | return true; 204 | } 205 | 206 | private enum Modify 207 | { 208 | None, 209 | Array, 210 | Option, 211 | } 212 | 213 | private static MethodInfo FindReadValue(Type type, out bool needtype) 214 | { 215 | MethodInfo method = typeof(JSONExt).GetMethod("Get", 216 | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, 217 | new[] {typeof(JSON.Object), typeof(string), type.MakeByRefType()}, null); 218 | if (method != null) 219 | { 220 | needtype = false; 221 | return method; 222 | } 223 | needtype = true; 224 | Modify modify = Modify.None; 225 | if (type.IsArray) 226 | { 227 | if (type.GetArrayRank() > 1) 228 | return null; 229 | modify = Modify.Array; 230 | type = type.GetElementType(); 231 | } 232 | else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 233 | { 234 | modify = Modify.Option; 235 | type = type.GetGenericArguments()[0]; 236 | } 237 | if (type.IsEnum) 238 | { 239 | return typeof(JSONExt).GetMethod( 240 | modify == Modify.Array ? "GetEnumArray" : (modify == Modify.Option ? "GetEnumNullable" : "GetEnum"), 241 | BindingFlags.Static | BindingFlags.NonPublic, null, 242 | new[] {typeof(JSON.Object), typeof(Type), typeof(string), typeof(object).MakeByRefType()}, null); 243 | } 244 | if (typeof(JSON.Readable).IsAssignableFrom(type) && type.GetConstructor(Type.EmptyTypes) != null) 245 | { 246 | return typeof(JSONExt).GetMethod( 247 | modify == Modify.Array ? "GetTypeArray" : (modify == Modify.Option ? "GetTypeNullable" : "GetType"), 248 | BindingFlags.Static | BindingFlags.NonPublic, null, 249 | new[] {typeof(JSON.Object), typeof(Type), typeof(string), typeof(object).MakeByRefType()}, null); 250 | } 251 | return null; 252 | } 253 | 254 | private static string GetName(MemberInfo member) 255 | { 256 | var attrs = member.GetCustomAttributes(typeof(JSON.EntityAttribute), true); 257 | if (attrs.Length != 0) 258 | { 259 | string s = ((JSON.EntityAttribute)attrs[0]).Name; 260 | if (!string.IsNullOrEmpty(s)) 261 | return s; 262 | } 263 | return member.Name; 264 | } 265 | 266 | private static bool IsRequired(MemberInfo member) 267 | { 268 | var attrs = member.GetCustomAttributes(typeof(JSON.EntityAttribute), true); 269 | return attrs.Length != 0 && ((JSON.EntityAttribute)attrs[0]).Required; 270 | } 271 | 272 | private static class ReadHelper 273 | { 274 | private delegate bool Reader(JSON.Object o, ref T value); 275 | private static readonly List readers; 276 | 277 | static ReadHelper() 278 | { 279 | readers = new List(); 280 | foreach (MemberInfo member in typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance)) 281 | { 282 | Type type; 283 | if (member.MemberType == MemberTypes.Field) 284 | { 285 | type = ((FieldInfo)member).FieldType; 286 | } 287 | else 288 | { 289 | if (member.MemberType != MemberTypes.Property) 290 | continue; 291 | PropertyInfo property = (PropertyInfo)member; 292 | if (property.GetSetMethod() == null || property.GetGetMethod() == null) 293 | continue; 294 | type = property.PropertyType; 295 | } 296 | bool needtype; 297 | MethodInfo method = FindReadValue(type, out needtype); 298 | if (method == null) 299 | { 300 | string name = member.Name; 301 | readers.Add((JSON.Object o, ref T value) => { throw new MissingFieldException(typeof(T).FullName, name); }); 302 | } 303 | else 304 | { 305 | string name = GetName(member); 306 | bool require = IsRequired(member); 307 | if (needtype) 308 | { 309 | if (member.MemberType == MemberTypes.Field) 310 | { 311 | FieldInfo field = (FieldInfo)member; 312 | readers.Add((JSON.Object o, ref T value) => 313 | { 314 | object[] args = new object[4]; 315 | args[0] = o; 316 | args[1] = type; 317 | args[2] = name; 318 | args[3] = field.GetValue(value); 319 | bool result = (bool)method.Invoke(null, args); 320 | if (!result) 321 | return !require; 322 | field.SetValue(value, args[3]); 323 | return true; 324 | }); 325 | } 326 | else 327 | { 328 | PropertyInfo property = (PropertyInfo)member; 329 | MethodInfo setter = property.GetSetMethod(); 330 | MethodInfo getter = property.GetGetMethod(); 331 | readers.Add((JSON.Object o, ref T value) => 332 | { 333 | object[] args = new object[4]; 334 | args[0] = o; 335 | args[1] = type; 336 | args[2] = name; 337 | args[3] = getter.Invoke(value, null); 338 | bool result = (bool)method.Invoke(null, args); 339 | if (!result) 340 | return !require; 341 | setter.Invoke(value, new[] {args[3]}); 342 | return true; 343 | }); 344 | } 345 | } 346 | else 347 | { 348 | if (member.MemberType == MemberTypes.Field) 349 | { 350 | FieldInfo field = (FieldInfo)member; 351 | readers.Add((JSON.Object o, ref T value) => 352 | { 353 | object[] args = new object[3]; 354 | args[0] = o; 355 | args[1] = name; 356 | args[2] = field.GetValue(value); 357 | bool result = (bool)method.Invoke(null, args); 358 | if (!result) 359 | return !require; 360 | field.SetValue(value, args[2]); 361 | return true; 362 | }); 363 | } 364 | else 365 | { 366 | PropertyInfo property = (PropertyInfo)member; 367 | MethodInfo setter = property.GetSetMethod(); 368 | MethodInfo getter = property.GetGetMethod(); 369 | readers.Add((JSON.Object o, ref T value) => 370 | { 371 | object[] args = new object[4]; 372 | args[0] = o; 373 | args[1] = name; 374 | args[2] = getter.Invoke(value, null); 375 | bool result = (bool)method.Invoke(null, args); 376 | if (!result) 377 | return !require; 378 | setter.Invoke(value, new[] {args[2]}); 379 | return true; 380 | }); 381 | } 382 | } 383 | } 384 | } 385 | } 386 | 387 | public static bool Read(JSON.Object o, ref T value) 388 | { 389 | for (int i = 0, j = readers.Count; i < j; ++i) 390 | { 391 | if (!readers[i](o, ref value)) 392 | return false; 393 | } 394 | return true; 395 | } 396 | } 397 | #endregion 398 | } 399 | } -------------------------------------------------------------------------------- /TinyJSON.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using System.Globalization; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | 8 | namespace TinyJSON 9 | { 10 | public sealed partial class JSON 11 | { 12 | public abstract class Object : IEnumerable 13 | { 14 | protected abstract IEnumerator Keys(); 15 | public abstract Type Type(string key); 16 | 17 | public abstract bool Get(string key, ref bool b); 18 | public abstract bool Get(string key, ref int i); 19 | public abstract bool Get(string key, ref double d); 20 | public abstract bool Get(string key, ref string s); 21 | public abstract bool Get(string key, ref Object o); 22 | public abstract bool Get(string key, ref Array a); 23 | 24 | public Value this[string key] 25 | { 26 | get 27 | { 28 | switch (Type(key)) 29 | { 30 | case JSON.Type.Bool: 31 | { 32 | bool b = false; 33 | if (Get(key, ref b)) 34 | return b; 35 | } 36 | break; 37 | case JSON.Type.Int: 38 | { 39 | int i = 0; 40 | if (Get(key, ref i)) 41 | return i; 42 | } 43 | break; 44 | case JSON.Type.Double: 45 | { 46 | double d = 0; 47 | if (Get(key, ref d)) 48 | return d; 49 | } 50 | break; 51 | case JSON.Type.String: 52 | { 53 | string s = null; 54 | if (Get(key, ref s)) 55 | return s; 56 | } 57 | break; 58 | case JSON.Type.Object: 59 | { 60 | Object o = null; 61 | if (Get(key, ref o)) 62 | return o; 63 | } 64 | break; 65 | case JSON.Type.Array: 66 | { 67 | Array a = null; 68 | if (Get(key, ref a)) 69 | return a; 70 | } 71 | break; 72 | } 73 | return Value.Null; 74 | } 75 | } 76 | 77 | public IEnumerator GetEnumerator() 78 | { 79 | return Keys(); 80 | } 81 | 82 | IEnumerator IEnumerable.GetEnumerator() 83 | { 84 | return GetEnumerator(); 85 | } 86 | } 87 | 88 | public abstract class Array : IEnumerable 89 | { 90 | public abstract int Count { get; } 91 | public abstract Type Type(int index); 92 | 93 | public abstract bool Get(int index, ref bool b); 94 | public abstract bool Get(int index, ref int i); 95 | public abstract bool Get(int index, ref double d); 96 | public abstract bool Get(int index, ref string s); 97 | public abstract bool Get(int index, ref Object o); 98 | public abstract bool Get(int index, ref Array a); 99 | 100 | public Value this[int index] 101 | { 102 | get 103 | { 104 | switch (Type(index)) 105 | { 106 | case JSON.Type.Bool: 107 | { 108 | bool b = false; 109 | if (Get(index, ref b)) 110 | return b; 111 | } 112 | break; 113 | case JSON.Type.Int: 114 | { 115 | int i = 0; 116 | if (Get(index, ref i)) 117 | return i; 118 | } 119 | break; 120 | case JSON.Type.Double: 121 | { 122 | double d = 0; 123 | if (Get(index, ref d)) 124 | return d; 125 | } 126 | break; 127 | case JSON.Type.String: 128 | { 129 | string s = null; 130 | if (Get(index, ref s)) 131 | return s; 132 | } 133 | break; 134 | case JSON.Type.Object: 135 | { 136 | Object o = null; 137 | if (Get(index, ref o)) 138 | return o; 139 | } 140 | break; 141 | case JSON.Type.Array: 142 | { 143 | Array a = null; 144 | if (Get(index, ref a)) 145 | return a; 146 | } 147 | break; 148 | } 149 | return Value.Null; 150 | } 151 | } 152 | 153 | public Enumerator GetEnumerator() 154 | { 155 | return new Enumerator(this); 156 | } 157 | 158 | IEnumerator IEnumerable.GetEnumerator() 159 | { 160 | return GetEnumerator(); 161 | } 162 | 163 | IEnumerator IEnumerable.GetEnumerator() 164 | { 165 | return GetEnumerator(); 166 | } 167 | 168 | public struct Enumerator : IEnumerator 169 | { 170 | private readonly Array array; 171 | private int index; 172 | 173 | internal Enumerator(Array array) 174 | { 175 | this.array = array; 176 | this.index = -1; 177 | } 178 | 179 | public void Dispose() {} 180 | 181 | public bool MoveNext() 182 | { 183 | if (array == null) 184 | return false; 185 | if (++index >= array.Count) 186 | return false; 187 | return true; 188 | } 189 | 190 | public void Reset() 191 | { 192 | index = -1; 193 | } 194 | 195 | public Value Current 196 | { 197 | get { return array[index]; } 198 | } 199 | 200 | object IEnumerator.Current 201 | { 202 | get { return Current; } 203 | } 204 | } 205 | } 206 | 207 | public struct Value 208 | { 209 | public Type Type { get; private set; } 210 | private bool b; 211 | private int i; 212 | private double d; 213 | private string s; 214 | private Object o; 215 | private Array a; 216 | 217 | public static readonly Value Null = new Value {Type = Type.Null}; 218 | 219 | public static implicit operator Value(bool b) 220 | { 221 | return new Value {Type = Type.Bool, b = b}; 222 | } 223 | 224 | public static implicit operator Value(bool? b) 225 | { 226 | return b.HasValue ? new Value {Type = Type.Bool, b = b.Value} : Null; 227 | } 228 | 229 | public static implicit operator Value(int i) 230 | { 231 | return new Value {Type = Type.Int, i = i}; 232 | } 233 | 234 | public static implicit operator Value(int? i) 235 | { 236 | return i.HasValue ? new Value {Type = Type.Int, i = i.Value} : Null; 237 | } 238 | 239 | public static implicit operator Value(double d) 240 | { 241 | return new Value {Type = Type.Double, d = d}; 242 | } 243 | 244 | public static implicit operator Value(double? d) 245 | { 246 | return d.HasValue ? new Value {Type = Type.Double, d = d.Value} : Null; 247 | } 248 | 249 | public static implicit operator Value(string s) 250 | { 251 | return s != null ? new Value {Type = Type.String, s = s} : Null; 252 | } 253 | 254 | public static implicit operator Value(Object o) 255 | { 256 | return o != null ? new Value {Type = Type.Object, o = o} : Null; 257 | } 258 | 259 | public static implicit operator Value(Array a) 260 | { 261 | return a != null ? new Value {Type = Type.Array, a = a} : Null; 262 | } 263 | 264 | public static explicit operator bool(Value v) 265 | { 266 | bool? result = v.AsBool(); 267 | if (result.HasValue) 268 | return result.Value; 269 | throw new InvalidCastException(); 270 | } 271 | 272 | public static explicit operator int(Value v) 273 | { 274 | int? result = v.AsInt(); 275 | if (result.HasValue) 276 | return result.Value; 277 | throw new InvalidCastException(); 278 | } 279 | 280 | public static explicit operator double(Value v) 281 | { 282 | double? result = v.AsDouble(); 283 | if (result.HasValue) 284 | return result.Value; 285 | throw new InvalidCastException(); 286 | } 287 | 288 | public static explicit operator string(Value v) 289 | { 290 | if (v.Type == Type.Null) 291 | return null; 292 | string result = v.AsString(); 293 | if (result != null) 294 | return result; 295 | throw new InvalidCastException(); 296 | } 297 | 298 | public static explicit operator Object(Value v) 299 | { 300 | if (v.Type == Type.Null) 301 | return null; 302 | Object result = v.AsObject(); 303 | if (result != null) 304 | return result; 305 | throw new InvalidCastException(); 306 | } 307 | 308 | public static explicit operator Array(Value v) 309 | { 310 | if (v.Type == Type.Null) 311 | return null; 312 | Array result = v.AsArray(); 313 | if (result != null) 314 | return result; 315 | throw new InvalidCastException(); 316 | } 317 | 318 | public bool? AsBool() 319 | { 320 | if (Type == Type.Bool) 321 | return b; 322 | return null; 323 | } 324 | 325 | public int? AsInt() 326 | { 327 | if (Type == Type.Int) 328 | return i; 329 | double r = Math.Round(d); 330 | if (Type == Type.Double && Math.Abs(d - r) < double.Epsilon && r >= int.MinValue && r <= int.MaxValue) 331 | return (int)r; 332 | return null; 333 | } 334 | 335 | public double? AsDouble() 336 | { 337 | if (Type == Type.Int) 338 | return i; 339 | if (Type == Type.Double) 340 | return d; 341 | return null; 342 | } 343 | 344 | public string AsString() 345 | { 346 | return Type == Type.String ? s : null; 347 | } 348 | 349 | public Object AsObject() 350 | { 351 | return Type == Type.Object ? o : null; 352 | } 353 | 354 | public Array AsArray() 355 | { 356 | return Type == Type.Array ? a : null; 357 | } 358 | } 359 | 360 | public enum Type 361 | { 362 | Null, 363 | Bool, 364 | Int, 365 | Double, 366 | String, 367 | Object, 368 | Array, 369 | } 370 | 371 | #region 自定义事件接口 372 | public interface Handler 373 | { 374 | bool StartArray(); 375 | bool StartTable(); 376 | bool EndArray(); 377 | bool EndTable(); 378 | bool Key(string key); 379 | bool Null(); 380 | bool Bool(bool b); 381 | bool String(string s); 382 | bool Double(double d); 383 | bool Int(int i); 384 | bool Flush(); 385 | } 386 | 387 | public interface Writer 388 | { 389 | bool Write(Handler handler); 390 | } 391 | 392 | public delegate void ValueAction(Value value); 393 | public delegate bool WriteAction(Handler handler); 394 | #endregion 395 | 396 | #region 选项 397 | public struct ParseOptions 398 | { 399 | public bool strict; 400 | public bool comment; 401 | public bool eof; 402 | } 403 | 404 | public struct DumpOptions 405 | { 406 | public bool pretty; 407 | public bool escape; 408 | } 409 | #endregion 410 | 411 | #region 默认接口 412 | public static Handler DefaultHandler(ValueAction action) 413 | { 414 | return new NodeHandler {result = action}; 415 | } 416 | 417 | public static Writer DefaultWriter(Value value) 418 | { 419 | return new NodeWriter(value); 420 | } 421 | 422 | public static Object From(Dictionary dict) 423 | { 424 | return new NodeObject(dict); 425 | } 426 | 427 | public static Array From(List list) 428 | { 429 | return new NodeArray(list); 430 | } 431 | #endregion 432 | 433 | #region 对外解析接口 434 | public bool Parse(TextReader reader, Handler handler, ParseOptions options) 435 | { 436 | input = reader; 437 | token = input.Read(); 438 | if (!Skip()) 439 | return false; 440 | if (!ReadValue(handler)) 441 | return false; 442 | if (!handler.Flush()) 443 | return false; 444 | return !options.eof || Flush(); 445 | } 446 | 447 | public bool Parse(TextReader reader, Handler handler) 448 | { 449 | return Parse(reader, handler, new ParseOptions {strict = false, comment = true, eof = false}); 450 | } 451 | 452 | public bool Parse(string text, Handler handler, ParseOptions options) 453 | { 454 | return Parse(new StringReader(text), handler, options); 455 | } 456 | 457 | public bool Parse(string text, Handler handler) 458 | { 459 | return Parse(new StringReader(text), handler, new ParseOptions {strict = false, comment = true, eof = true}); 460 | } 461 | 462 | public Value? Parse(TextReader reader, ParseOptions options) 463 | { 464 | NodeHandler handler = new NodeHandler(); 465 | return Parse(reader, handler, options) ? handler.root : null; 466 | } 467 | 468 | public Value? Parse(TextReader reader) 469 | { 470 | NodeHandler handler = new NodeHandler(); 471 | return Parse(reader, handler) ? handler.root : null; 472 | } 473 | 474 | public Value? Parse(string text, ParseOptions options) 475 | { 476 | return Parse(new StringReader(text), options); 477 | } 478 | 479 | public Value? Parse(string text) 480 | { 481 | return Parse(new StringReader(text)); 482 | } 483 | #endregion 484 | 485 | #region 对外序列化接口 486 | private Buffer normalbuffer; 487 | private Buffer prettybuffer; 488 | 489 | public bool Dump(Writer writer, Handler handler) 490 | { 491 | return writer.Write(handler); 492 | } 493 | 494 | public bool Dump(TextWriter output, Writer writer, DumpOptions options) 495 | { 496 | Buffer buffer; 497 | if (options.pretty) 498 | { 499 | if (prettybuffer == null) 500 | prettybuffer = new PrettyBuffer(); 501 | buffer = prettybuffer; 502 | } 503 | else 504 | { 505 | if (normalbuffer == null) 506 | normalbuffer = new Buffer(); 507 | buffer = normalbuffer; 508 | } 509 | buffer.escape = options.escape; 510 | buffer.writer = output; 511 | buffer.Reset(); 512 | bool result = Dump(writer, buffer); 513 | buffer.writer = null; 514 | return result; 515 | } 516 | 517 | public bool Dump(TextWriter output, Writer writer) 518 | { 519 | return Dump(output, writer, new DumpOptions {pretty = false, escape = false}); 520 | } 521 | 522 | public string Dump(Writer writer, DumpOptions options) 523 | { 524 | StringWriter output = new StringWriter(); 525 | return Dump(output, writer, options) ? output.ToString() : null; 526 | } 527 | 528 | public string Dump(Writer writer) 529 | { 530 | StringWriter output = new StringWriter(); 531 | return Dump(output, writer) ? output.ToString() : null; 532 | } 533 | 534 | public bool Dump(WriteAction writer, Handler handler) 535 | { 536 | return new ActionWriter(writer).Write(handler); 537 | } 538 | 539 | public bool Dump(TextWriter output, WriteAction writer, DumpOptions options) 540 | { 541 | return Dump(output, new ActionWriter(writer), options); 542 | } 543 | 544 | public bool Dump(TextWriter output, WriteAction writer) 545 | { 546 | return Dump(output, new ActionWriter(writer)); 547 | } 548 | 549 | public string Dump(WriteAction writer, DumpOptions options) 550 | { 551 | return Dump(new ActionWriter(writer), options); 552 | } 553 | 554 | public string Dump(WriteAction writer) 555 | { 556 | return Dump(new ActionWriter(writer)); 557 | } 558 | 559 | public bool Dump(Value value, Handler handler) 560 | { 561 | return new NodeWriter(value).Write(handler); 562 | } 563 | 564 | public bool Dump(Value? value, Handler handler) 565 | { 566 | return value.HasValue && new NodeWriter(value.Value).Write(handler); 567 | } 568 | 569 | public bool Dump(TextWriter output, Value value, DumpOptions options) 570 | { 571 | return Dump(output, new NodeWriter(value), options); 572 | } 573 | 574 | public bool Dump(TextWriter output, Value? value, DumpOptions options) 575 | { 576 | return value.HasValue && Dump(output, new NodeWriter(value.Value), options); 577 | } 578 | 579 | public bool Dump(TextWriter output, Value value) 580 | { 581 | return Dump(output, new NodeWriter(value)); 582 | } 583 | 584 | public bool Dump(TextWriter output, Value? value) 585 | { 586 | return value.HasValue && Dump(output, new NodeWriter(value.Value)); 587 | } 588 | 589 | public string Dump(Value value, DumpOptions options) 590 | { 591 | return Dump(new NodeWriter(value), options); 592 | } 593 | 594 | public string Dump(Value? value, DumpOptions options) 595 | { 596 | return value.HasValue ? Dump(new NodeWriter(value.Value), options) : null; 597 | } 598 | 599 | public string Dump(Value value) 600 | { 601 | return Dump(new NodeWriter(value)); 602 | } 603 | 604 | public string Dump(Value? value) 605 | { 606 | return value.HasValue ? Dump(new NodeWriter(value.Value)) : null; 607 | } 608 | #endregion 609 | 610 | #region 解析实现 611 | private int token; 612 | private TextReader input; 613 | private StringBuilder builder; 614 | 615 | private bool ReadValue(Handler handler) 616 | { 617 | switch (token) 618 | { 619 | case '{': 620 | return ReadTable(handler); 621 | case '[': 622 | return ReadArray(handler); 623 | case 't': 624 | case 'f': 625 | return ReadBool(handler); 626 | case 'n': 627 | return ReadNull(handler); 628 | case '"': 629 | case '\'': 630 | return ReadString(handler); 631 | case '-': 632 | case '0': 633 | case '1': 634 | case '2': 635 | case '3': 636 | case '4': 637 | case '5': 638 | case '6': 639 | case '7': 640 | case '8': 641 | case '9': 642 | return ReadNumber(handler); 643 | case '/': 644 | Next(); 645 | switch (token) 646 | { 647 | case '/': 648 | return ReadCommentLine(); 649 | case '*': 650 | return ReadComments(); 651 | } 652 | return false; 653 | } 654 | return false; 655 | } 656 | 657 | private bool ReadTable(Handler handler) 658 | { 659 | if (!handler.StartTable()) 660 | return false; 661 | while (true) 662 | { 663 | Next(); 664 | if (!Skip()) 665 | return false; 666 | if (token == '}') 667 | { 668 | Next(); 669 | if (!handler.EndTable()) 670 | return false; 671 | break; 672 | } 673 | if (!ReadKey(handler)) 674 | return false; 675 | if (!Skip()) 676 | return false; 677 | if (token != ':') 678 | return false; 679 | Next(); 680 | if (!Skip()) 681 | return false; 682 | if (!ReadValue(handler)) 683 | return false; 684 | if (!Skip()) 685 | return false; 686 | if (token == '}') 687 | { 688 | Next(); 689 | if (!handler.EndTable()) 690 | return false; 691 | break; 692 | } 693 | if (token != ',') 694 | return false; 695 | } 696 | return true; 697 | } 698 | 699 | private bool ReadArray(Handler handler) 700 | { 701 | if (!handler.StartArray()) 702 | return false; 703 | while (true) 704 | { 705 | Next(); 706 | if (!Skip()) 707 | return false; 708 | if (token == ']') 709 | { 710 | Next(); 711 | if (!handler.EndArray()) 712 | return false; 713 | break; 714 | } 715 | if (!ReadValue(handler)) 716 | return false; 717 | if (!Skip()) 718 | return false; 719 | if (token == ']') 720 | { 721 | Next(); 722 | if (!handler.EndArray()) 723 | return false; 724 | break; 725 | } 726 | if (token != ',') 727 | return false; 728 | } 729 | return true; 730 | } 731 | 732 | private bool ReadBool(Handler handler) 733 | { 734 | if (token == 't') 735 | { 736 | if (Next() == 'r' && Next() == 'u' && Next() == 'e') 737 | { 738 | Next(); 739 | return handler.Bool(true); 740 | } 741 | } 742 | else 743 | { 744 | if (Next() == 'a' && Next() == 'l' && Next() == 's' && Next() == 'e') 745 | { 746 | Next(); 747 | return handler.Bool(false); 748 | } 749 | } 750 | return false; 751 | } 752 | 753 | private bool ReadNull(Handler handler) 754 | { 755 | if (Next() == 'u' && Next() == 'l' && Next() == 'l') 756 | { 757 | Next(); 758 | return handler.Null(); 759 | } 760 | return false; 761 | } 762 | 763 | private bool ReadNumber(Handler handler) 764 | { 765 | bool minus = false; 766 | if (token == '-') 767 | { 768 | minus = true; 769 | Next(); 770 | } 771 | if (token < '0' || token > '9') 772 | return false; 773 | uint u = 0; 774 | double d = 0; 775 | bool isfloat = false; 776 | while (token >= '0' && token <= '9') 777 | { 778 | if (isfloat) 779 | { 780 | d = d * 10 + (token - '0'); 781 | } 782 | else 783 | { 784 | uint uu = (uint)(token - '0'); 785 | if (u > int.MaxValue / 10 || (u == int.MaxValue / 10 && uu > int.MaxValue % 10)) 786 | { 787 | isfloat = true; 788 | d = u; 789 | continue; 790 | } 791 | u = u * 10 + uu; 792 | } 793 | Next(); 794 | } 795 | int dot = 0; 796 | if (token == '.') 797 | { 798 | if (!isfloat) 799 | { 800 | isfloat = true; 801 | d = u; 802 | } 803 | Next(); 804 | while (token >= '0' && token <= '9') 805 | { 806 | d = d * 10 + (token - '0'); 807 | --dot; 808 | Next(); 809 | } 810 | if (dot == 0) 811 | return false; 812 | } 813 | int exp = 0; 814 | if (token == 'E' || token == 'e') 815 | { 816 | if (!isfloat) 817 | { 818 | isfloat = true; 819 | d = u; 820 | } 821 | bool expMinus = false; 822 | Next(); 823 | if (token == '+') 824 | { 825 | Next(); 826 | } 827 | else if (token == '-') 828 | { 829 | expMinus = true; 830 | Next(); 831 | } 832 | if (token < '0' || token > '9') 833 | return false; 834 | while (token >= '0' && token <= '9') 835 | { 836 | exp = exp * 10 + (token - '0'); 837 | Next(); 838 | } 839 | if (expMinus) 840 | exp = -exp; 841 | } 842 | return isfloat ? handler.Double((minus ? -d : d) * Pow10(dot + exp)) : handler.Int(minus ? (int)-u : (int)u); 843 | } 844 | 845 | private string ReadString() 846 | { 847 | char symbol = (char)token; 848 | if (builder == null) 849 | builder = new StringBuilder(); 850 | else 851 | builder.Length = 0; 852 | while (true) 853 | { 854 | Next(); 855 | if (token == symbol) 856 | break; 857 | if (token == -1) 858 | return null; 859 | if (token == '\\') 860 | { 861 | Next(); 862 | switch (token) 863 | { 864 | case 'b': 865 | builder.Append('\b'); 866 | break; 867 | case 'f': 868 | builder.Append('\f'); 869 | break; 870 | case 'n': 871 | builder.Append('\n'); 872 | break; 873 | case 'r': 874 | builder.Append('\r'); 875 | break; 876 | case 't': 877 | builder.Append('\t'); 878 | break; 879 | case '"': 880 | builder.Append('"'); 881 | break; 882 | case '\'': 883 | builder.Append('\''); 884 | break; 885 | case '\\': 886 | builder.Append('\\'); 887 | break; 888 | case '/': 889 | builder.Append('/'); 890 | break; 891 | case 'u': 892 | { 893 | int unicode = 0; 894 | for (int i = 0; i < 4; ++i) 895 | { 896 | int c = Next(); 897 | if (c >= 'a') 898 | c -= 'a' - 10; 899 | else if (c >= 'A') 900 | c -= 'A' - 10; 901 | else if (c >= '0' && c <= '9') 902 | c -= '0'; 903 | else 904 | return null; 905 | unicode <<= 4; 906 | unicode |= c; 907 | } 908 | builder.Append((char)unicode); 909 | } 910 | break; 911 | default: 912 | return null; 913 | } 914 | } 915 | else 916 | { 917 | builder.Append((char)token); 918 | } 919 | } 920 | Next(); 921 | return builder.ToString(); 922 | } 923 | 924 | private bool ReadString(Handler handler) 925 | { 926 | string str = ReadString(); 927 | return str != null && handler.String(str); 928 | } 929 | 930 | private bool ReadKey(Handler handler) 931 | { 932 | if (token == '"' || token == '\'') 933 | { 934 | string str = ReadString(); 935 | return str != null && handler.Key(str); 936 | } 937 | if (token == '_' || (token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z')) 938 | { 939 | if (builder == null) 940 | builder = new StringBuilder(); 941 | else 942 | builder.Length = 0; 943 | while (true) 944 | { 945 | builder.Append((char)token); 946 | Next(); 947 | if (token == '_' || (token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z') || (token >= '0' && token <= '9')) 948 | continue; 949 | break; 950 | } 951 | return handler.Key(builder.ToString()); 952 | } 953 | return false; 954 | } 955 | 956 | private bool ReadCommentLine() 957 | { 958 | while (true) 959 | { 960 | Next(); 961 | if (token == '\n') 962 | { 963 | Next(); 964 | return true; 965 | } 966 | if (token == -1) 967 | return true; 968 | } 969 | } 970 | 971 | private bool ReadComments() 972 | { 973 | while (true) 974 | { 975 | Next(); 976 | if (token == '*') 977 | { 978 | Next(); 979 | if (token == '/') 980 | { 981 | Next(); 982 | return true; 983 | } 984 | } 985 | if (token == -1) 986 | return false; 987 | } 988 | } 989 | 990 | private bool Flush() 991 | { 992 | if (!Skip()) 993 | return false; 994 | input = null; 995 | return token == -1 || token == '\0'; 996 | } 997 | 998 | private bool Skip() 999 | { 1000 | while (token == ' ' || token == '\n' || token == '\r' || token == '\t') 1001 | { 1002 | token = input.Read(); 1003 | } 1004 | if (token == '/') 1005 | { 1006 | switch (input.Peek()) 1007 | { 1008 | case '*': 1009 | input.Read(); 1010 | while (true) 1011 | { 1012 | token = input.Read(); 1013 | if (token == -1) 1014 | return false; 1015 | if (token == '*') 1016 | { 1017 | if (input.Peek() == '/') 1018 | { 1019 | input.Read(); 1020 | token = input.Read(); 1021 | break; 1022 | } 1023 | } 1024 | } 1025 | return Skip(); 1026 | case '/': 1027 | input.Read(); 1028 | while (true) 1029 | { 1030 | token = input.Read(); 1031 | if (token == '\r' || token == '\n' || token == -1) 1032 | break; 1033 | } 1034 | return Skip(); 1035 | } 1036 | } 1037 | return true; 1038 | } 1039 | 1040 | private int Next() 1041 | { 1042 | token = input.Read(); 1043 | return token; 1044 | } 1045 | #endregion 1046 | 1047 | #region 加速Pow运算 1048 | private static readonly double[] e = 1049 | { 1050 | // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 1051 | 1e+0, 1052 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1053 | 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1054 | 1e+57, 1e+58, 1e+59, 1e+60, 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 1e+81, 1e+82, 1e+83, 1e+84, 1055 | 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112, 1056 | 1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 1057 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168, 1058 | 1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196, 1059 | 1e+197,1e+198,1e+199,1e+200,1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,1e+221,1e+222,1e+223,1e+224, 1060 | 1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252, 1061 | 1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 1062 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308, 1063 | }; 1064 | 1065 | private static double Pow10(int x) 1066 | { 1067 | if (x < -308) 1068 | return 0; 1069 | if (x > 308) 1070 | return double.PositiveInfinity; 1071 | return x >= 0 ? e[x] : 1.0 / e[-x]; 1072 | } 1073 | #endregion 1074 | 1075 | #region 默认解析生成Node 1076 | private class NodeObject : Object 1077 | { 1078 | public readonly Dictionary dict; 1079 | 1080 | public NodeObject() 1081 | { 1082 | dict = new Dictionary(); 1083 | } 1084 | 1085 | public NodeObject(Dictionary dict) 1086 | { 1087 | this.dict = dict; 1088 | } 1089 | 1090 | protected override IEnumerator Keys() 1091 | { 1092 | return new Enumerator(dict); 1093 | } 1094 | 1095 | public override Type Type(string key) 1096 | { 1097 | Value value; 1098 | return dict.TryGetValue(key, out value) ? value.Type : JSON.Type.Null; 1099 | } 1100 | 1101 | public override bool Get(string key, ref bool b) 1102 | { 1103 | Value value; 1104 | if (dict.TryGetValue(key, out value)) 1105 | { 1106 | bool? result = value.AsBool(); 1107 | if (result.HasValue) 1108 | { 1109 | b = result.Value; 1110 | return true; 1111 | } 1112 | } 1113 | return false; 1114 | } 1115 | 1116 | public override bool Get(string key, ref int i) 1117 | { 1118 | Value value; 1119 | if (dict.TryGetValue(key, out value)) 1120 | { 1121 | int? result = value.AsInt(); 1122 | if (result.HasValue) 1123 | { 1124 | i = result.Value; 1125 | return true; 1126 | } 1127 | } 1128 | return false; 1129 | } 1130 | 1131 | public override bool Get(string key, ref double d) 1132 | { 1133 | Value value; 1134 | if (dict.TryGetValue(key, out value)) 1135 | { 1136 | double? result = value.AsDouble(); 1137 | if (result.HasValue) 1138 | { 1139 | d = result.Value; 1140 | return true; 1141 | } 1142 | } 1143 | return false; 1144 | } 1145 | 1146 | public override bool Get(string key, ref string s) 1147 | { 1148 | Value value; 1149 | if (dict.TryGetValue(key, out value)) 1150 | { 1151 | string result = value.AsString(); 1152 | if (result != null) 1153 | { 1154 | s = result; 1155 | return true; 1156 | } 1157 | } 1158 | return false; 1159 | } 1160 | 1161 | public override bool Get(string key, ref Object o) 1162 | { 1163 | Value value; 1164 | if (dict.TryGetValue(key, out value)) 1165 | { 1166 | Object result = value.AsObject(); 1167 | if (result != null) 1168 | { 1169 | o = result; 1170 | return true; 1171 | } 1172 | } 1173 | return false; 1174 | } 1175 | 1176 | public override bool Get(string key, ref Array a) 1177 | { 1178 | Value value; 1179 | if (dict.TryGetValue(key, out value)) 1180 | { 1181 | Array result = value.AsArray(); 1182 | if (result != null) 1183 | { 1184 | a = result; 1185 | return true; 1186 | } 1187 | } 1188 | return false; 1189 | } 1190 | 1191 | private class Enumerator : IEnumerator 1192 | { 1193 | private readonly Dictionary dict; 1194 | private Dictionary.Enumerator enumerator; 1195 | 1196 | public Enumerator(Dictionary dict) 1197 | { 1198 | this.dict = dict; 1199 | enumerator = dict.GetEnumerator(); 1200 | } 1201 | 1202 | public void Dispose() 1203 | { 1204 | enumerator.Dispose(); 1205 | } 1206 | 1207 | public bool MoveNext() 1208 | { 1209 | return enumerator.MoveNext(); 1210 | } 1211 | 1212 | public void Reset() 1213 | { 1214 | enumerator.Dispose(); 1215 | enumerator = dict.GetEnumerator(); 1216 | } 1217 | 1218 | public string Current 1219 | { 1220 | get { return enumerator.Current.Key; } 1221 | } 1222 | 1223 | object IEnumerator.Current 1224 | { 1225 | get { return Current; } 1226 | } 1227 | } 1228 | } 1229 | 1230 | private class NodeArray : Array 1231 | { 1232 | public readonly List list; 1233 | 1234 | public NodeArray() 1235 | { 1236 | list = new List(); 1237 | } 1238 | 1239 | public NodeArray(List list) 1240 | { 1241 | this.list = list; 1242 | } 1243 | 1244 | public override int Count 1245 | { 1246 | get { return list.Count; } 1247 | } 1248 | 1249 | public override Type Type(int index) 1250 | { 1251 | return list[index].Type; 1252 | } 1253 | 1254 | public override bool Get(int index, ref bool b) 1255 | { 1256 | bool? result = list[index].AsBool(); 1257 | if (result.HasValue) 1258 | { 1259 | b = result.Value; 1260 | return true; 1261 | } 1262 | return false; 1263 | } 1264 | 1265 | public override bool Get(int index, ref int i) 1266 | { 1267 | int? result = list[index].AsInt(); 1268 | if (result.HasValue) 1269 | { 1270 | i = result.Value; 1271 | return true; 1272 | } 1273 | return false; 1274 | } 1275 | 1276 | public override bool Get(int index, ref double d) 1277 | { 1278 | double? result = list[index].AsDouble(); 1279 | if (result.HasValue) 1280 | { 1281 | d = result.Value; 1282 | return true; 1283 | } 1284 | return false; 1285 | } 1286 | 1287 | public override bool Get(int index, ref string s) 1288 | { 1289 | string result = list[index].AsString(); 1290 | if (result != null) 1291 | { 1292 | s = result; 1293 | return true; 1294 | } 1295 | return false; 1296 | } 1297 | 1298 | public override bool Get(int index, ref Object o) 1299 | { 1300 | Object result = list[index].AsObject(); 1301 | if (result != null) 1302 | { 1303 | o = result; 1304 | return true; 1305 | } 1306 | return false; 1307 | } 1308 | 1309 | public override bool Get(int index, ref Array a) 1310 | { 1311 | Array result = list[index].AsArray(); 1312 | if (result != null) 1313 | { 1314 | a = result; 1315 | return true; 1316 | } 1317 | return false; 1318 | } 1319 | } 1320 | 1321 | private class NodeHandler : Stack, Handler 1322 | { 1323 | private string key; 1324 | public Value? root; 1325 | public ValueAction result; 1326 | 1327 | private bool Value(Value value) 1328 | { 1329 | if (root == null) 1330 | { 1331 | root = value; 1332 | } 1333 | else if (Count > 0) 1334 | { 1335 | Value last = Peek(); 1336 | switch (last.Type) 1337 | { 1338 | case Type.Object: 1339 | { 1340 | NodeObject node = last.AsObject() as NodeObject; 1341 | if (node != null) 1342 | node.dict[key] = value; 1343 | } 1344 | break; 1345 | case Type.Array: 1346 | { 1347 | NodeArray node = last.AsArray() as NodeArray; 1348 | if (node != null) 1349 | node.list.Add(value); 1350 | } 1351 | break; 1352 | default: 1353 | return false; 1354 | } 1355 | } 1356 | return true; 1357 | } 1358 | 1359 | public bool StartArray() 1360 | { 1361 | NodeArray node = new NodeArray(); 1362 | if (!Value(node)) 1363 | return false; 1364 | Push(node); 1365 | return true; 1366 | } 1367 | 1368 | public bool StartTable() 1369 | { 1370 | NodeObject node = new NodeObject(); 1371 | if (!Value(node)) 1372 | return false; 1373 | Push(node); 1374 | return true; 1375 | } 1376 | 1377 | public bool EndArray() 1378 | { 1379 | try 1380 | { 1381 | Pop(); 1382 | return true; 1383 | } 1384 | catch (Exception) 1385 | { 1386 | return false; 1387 | } 1388 | } 1389 | 1390 | public bool EndTable() 1391 | { 1392 | try 1393 | { 1394 | Pop(); 1395 | return true; 1396 | } 1397 | catch (Exception) 1398 | { 1399 | return false; 1400 | } 1401 | } 1402 | 1403 | public bool Null() 1404 | { 1405 | return Value(JSON.Value.Null); 1406 | } 1407 | 1408 | public bool Key(string key) 1409 | { 1410 | this.key = key; 1411 | return true; 1412 | } 1413 | 1414 | public bool Bool(bool b) 1415 | { 1416 | return Value(b); 1417 | } 1418 | 1419 | public bool String(string s) 1420 | { 1421 | return Value(s); 1422 | } 1423 | 1424 | public bool Double(double d) 1425 | { 1426 | return Value(d); 1427 | } 1428 | 1429 | public bool Int(int i) 1430 | { 1431 | return Value(i); 1432 | } 1433 | 1434 | public bool Flush() 1435 | { 1436 | if (Count != 0) 1437 | return false; 1438 | if (result != null && root.HasValue) 1439 | result(root.Value); 1440 | return true; 1441 | } 1442 | } 1443 | #endregion 1444 | 1445 | #region 序列化实现 1446 | private class Buffer : Handler 1447 | { 1448 | public bool escape; 1449 | public TextWriter writer; 1450 | protected bool empty; 1451 | protected int depth; 1452 | protected bool table; 1453 | 1454 | public Buffer() 1455 | { 1456 | escape = false; 1457 | empty = true; 1458 | depth = 0; 1459 | } 1460 | 1461 | private void WriteString(string s) 1462 | { 1463 | writer.Write('"'); 1464 | for (int i = 0, j = s.Length; i < j; ++i) 1465 | { 1466 | char c = s[i]; 1467 | if (c < 128) 1468 | { 1469 | char esc = escapes[c]; 1470 | if (esc == '#') 1471 | { 1472 | writer.Write(c); 1473 | } 1474 | else if (esc == 'u') 1475 | { 1476 | writer.Write("\\u00"); 1477 | writer.Write(((uint)c).ToString("X2", CultureInfo.InvariantCulture)); 1478 | } 1479 | else 1480 | { 1481 | writer.Write('\\'); 1482 | writer.Write(esc); 1483 | } 1484 | } 1485 | else if (escape) 1486 | { 1487 | writer.Write("\\u"); 1488 | writer.Write(((uint)c).ToString("X4", CultureInfo.InvariantCulture)); 1489 | } 1490 | else 1491 | { 1492 | writer.Write(c); 1493 | } 1494 | } 1495 | writer.Write('"'); 1496 | } 1497 | 1498 | protected virtual void Prefix() 1499 | { 1500 | if (depth > 0) 1501 | { 1502 | if (!table) 1503 | { 1504 | if (!empty) 1505 | WriteComma(); 1506 | WriteIndent(); 1507 | } 1508 | } 1509 | } 1510 | 1511 | public override string ToString() 1512 | { 1513 | return writer.ToString(); 1514 | } 1515 | 1516 | public virtual void Reset() 1517 | { 1518 | empty = true; 1519 | depth = 0; 1520 | } 1521 | 1522 | public virtual bool StartArray() 1523 | { 1524 | Prefix(); 1525 | ++depth; 1526 | empty = true; 1527 | table = false; 1528 | writer.Write('['); 1529 | return true; 1530 | } 1531 | 1532 | public virtual bool EndArray() 1533 | { 1534 | --depth; 1535 | if (!empty) 1536 | WriteIndent(); 1537 | empty = false; 1538 | writer.Write(']'); 1539 | return true; 1540 | } 1541 | 1542 | public virtual bool StartTable() 1543 | { 1544 | Prefix(); 1545 | ++depth; 1546 | empty = true; 1547 | table = false; 1548 | writer.Write('{'); 1549 | return true; 1550 | } 1551 | 1552 | public virtual bool EndTable() 1553 | { 1554 | --depth; 1555 | if (!empty) 1556 | WriteIndent(); 1557 | empty = false; 1558 | writer.Write('}'); 1559 | return true; 1560 | } 1561 | 1562 | public virtual bool Key(string s) 1563 | { 1564 | table = true; 1565 | if (!empty) 1566 | WriteComma(); 1567 | WriteIndent(); 1568 | WriteString(s); 1569 | WriteColon(); 1570 | return true; 1571 | } 1572 | 1573 | public bool Null() 1574 | { 1575 | Prefix(); 1576 | empty = false; 1577 | table = false; 1578 | writer.Write("null"); 1579 | return true; 1580 | } 1581 | 1582 | public bool Bool(bool b) 1583 | { 1584 | Prefix(); 1585 | empty = false; 1586 | table = false; 1587 | writer.Write(b ? "true" : "false"); 1588 | return true; 1589 | } 1590 | 1591 | public bool String(string s) 1592 | { 1593 | Prefix(); 1594 | empty = false; 1595 | table = false; 1596 | WriteString(s); 1597 | return true; 1598 | } 1599 | 1600 | public bool Double(double d) 1601 | { 1602 | Prefix(); 1603 | empty = false; 1604 | table = false; 1605 | writer.Write(d.ToString(CultureInfo.InvariantCulture)); 1606 | return true; 1607 | } 1608 | 1609 | public bool Int(int i) 1610 | { 1611 | Prefix(); 1612 | empty = false; 1613 | table = false; 1614 | writer.Write(i.ToString(CultureInfo.InvariantCulture)); 1615 | return true; 1616 | } 1617 | 1618 | public bool Flush() 1619 | { 1620 | return depth == 0; 1621 | } 1622 | 1623 | protected virtual void WriteIndent() 1624 | { 1625 | } 1626 | 1627 | protected virtual void WriteComma() 1628 | { 1629 | writer.Write(','); 1630 | } 1631 | 1632 | protected virtual void WriteColon() 1633 | { 1634 | writer.Write(':'); 1635 | } 1636 | } 1637 | 1638 | private class PrettyBuffer : Buffer 1639 | { 1640 | protected override void WriteColon() 1641 | { 1642 | writer.Write(" : "); 1643 | } 1644 | 1645 | protected override void WriteIndent() 1646 | { 1647 | writer.Write('\n'); 1648 | for (int i = 0, j = depth; i < j; ++i) 1649 | { 1650 | writer.Write('\t'); 1651 | } 1652 | } 1653 | } 1654 | #endregion 1655 | 1656 | #region 转义字符表 1657 | private static readonly char[] escapes = 1658 | { 1659 | /* 1660 | This array maps the 128 ASCII characters into character escape. 1661 | 'u' indicate must transform to \u00xx. 1662 | */ 1663 | 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', 1664 | 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 1665 | '#', '#', '"', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 1666 | '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 1667 | '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 1668 | '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '\\', '#', '#', '#', 1669 | '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 1670 | '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 1671 | }; 1672 | 1673 | #endregion 1674 | 1675 | #region 默认序列化行为 1676 | private class NodeWriter : Writer 1677 | { 1678 | private readonly Value root; 1679 | private readonly Dictionary writed; 1680 | 1681 | public NodeWriter(Value value) 1682 | { 1683 | root = value; 1684 | writed = new Dictionary(); 1685 | } 1686 | 1687 | public bool Write(Handler handler) 1688 | { 1689 | return Write(handler, root) && handler.Flush(); 1690 | } 1691 | 1692 | private bool Write(Handler handler, Value value) 1693 | { 1694 | switch (value.Type) 1695 | { 1696 | case Type.Null: 1697 | return handler.Null(); 1698 | case Type.Bool: 1699 | return handler.Bool((bool)value); 1700 | case Type.Int: 1701 | return handler.Int((int)value); 1702 | case Type.Double: 1703 | return handler.Double((double)value); 1704 | case Type.String: 1705 | return handler.String((string)value); 1706 | case Type.Array: 1707 | { 1708 | Array arr = (Array)value; 1709 | if (writed.ContainsKey(arr)) 1710 | return false; 1711 | writed.Add(arr, true); 1712 | if (!handler.StartArray()) 1713 | return false; 1714 | for (int i = 0, j = arr.Count; i < j; ++i) 1715 | { 1716 | if (!Write(handler, arr[i])) 1717 | return false; 1718 | } 1719 | return handler.EndArray(); 1720 | } 1721 | case Type.Object: 1722 | { 1723 | Object obj = (Object)value; 1724 | if (writed.ContainsKey(obj)) 1725 | return false; 1726 | writed.Add(obj, true); 1727 | if (!handler.StartTable()) 1728 | return false; 1729 | foreach (string key in obj) 1730 | { 1731 | if (!handler.Key(key)) 1732 | return false; 1733 | if (!Write(handler, obj[key])) 1734 | return false; 1735 | } 1736 | return handler.EndTable(); 1737 | } 1738 | } 1739 | return false; 1740 | } 1741 | } 1742 | 1743 | private class ActionWriter : Writer 1744 | { 1745 | private readonly WriteAction func; 1746 | 1747 | public ActionWriter(WriteAction func) 1748 | { 1749 | this.func = func; 1750 | } 1751 | 1752 | public bool Write(Handler handler) 1753 | { 1754 | return func(handler); 1755 | } 1756 | } 1757 | #endregion 1758 | 1759 | public interface Readable 1760 | { 1761 | bool Read(Object o); 1762 | } 1763 | 1764 | public interface Writeable 1765 | { 1766 | Object Write(); 1767 | } 1768 | 1769 | public static bool Read(Object o, ref T value) where T : Readable, new() 1770 | { 1771 | T tmp = new T(); 1772 | if (!tmp.Read(o)) 1773 | return false; 1774 | value = tmp; 1775 | return true; 1776 | } 1777 | 1778 | public static Object Write(ref T value) where T : Writeable 1779 | { 1780 | return value.Write(); 1781 | } 1782 | 1783 | public static Object Write(T value) where T : Writeable 1784 | { 1785 | return Write(ref value); 1786 | } 1787 | } 1788 | 1789 | public static partial class JSONExt 1790 | { 1791 | public static bool Convert(this JSON.Object o, ref T value) where T : JSON.Readable, new() 1792 | { 1793 | return JSON.Read(o, ref value); 1794 | } 1795 | 1796 | public static T Convert(this JSON.Object o) where T : JSON.Readable, new() 1797 | { 1798 | T value = default(T); 1799 | if (JSON.Read(o, ref value)) 1800 | return value; 1801 | throw new FormatException(); 1802 | } 1803 | 1804 | public static JSON.Object Convert(this T value) where T : JSON.Writeable 1805 | { 1806 | return JSON.Write(ref value); 1807 | } 1808 | 1809 | public static bool Get(this JSON.Object o, string key, ref byte value) 1810 | { 1811 | int tmp = default(int); 1812 | if (!o.Get(key, ref tmp)) 1813 | return false; 1814 | if (tmp < byte.MinValue || tmp > byte.MaxValue) 1815 | return false; 1816 | value = (byte)tmp; 1817 | return true; 1818 | } 1819 | 1820 | public static bool Get(this JSON.Object o, string key, ref sbyte value) 1821 | { 1822 | int tmp = default(int); 1823 | if (!o.Get(key, ref tmp)) 1824 | return false; 1825 | if (tmp < sbyte.MinValue || tmp > sbyte.MaxValue) 1826 | return false; 1827 | value = (sbyte)tmp; 1828 | return true; 1829 | } 1830 | 1831 | public static bool Get(this JSON.Object o, string key, ref short value) 1832 | { 1833 | int tmp = default(int); 1834 | if (!o.Get(key, ref tmp)) 1835 | return false; 1836 | if (tmp < short.MinValue || tmp > short.MaxValue) 1837 | return false; 1838 | value = (short)tmp; 1839 | return true; 1840 | } 1841 | 1842 | public static bool Get(this JSON.Object o, string key, ref ushort value) 1843 | { 1844 | int tmp = default(int); 1845 | if (!o.Get(key, ref tmp)) 1846 | return false; 1847 | if (tmp < ushort.MinValue || tmp > ushort.MaxValue) 1848 | return false; 1849 | value = (ushort)tmp; 1850 | return true; 1851 | } 1852 | 1853 | public static bool Get(this JSON.Object o, string key, ref uint value) 1854 | { 1855 | int tmpi = default(int); 1856 | if (o.Get(key, ref tmpi)) 1857 | { 1858 | if (tmpi < 0) 1859 | return false; 1860 | value = (uint)tmpi; 1861 | return true; 1862 | } 1863 | double tmpd = default(double); 1864 | if (o.Get(key, ref tmpd)) 1865 | { 1866 | double r = Math.Round(tmpd); 1867 | if (Math.Abs(tmpd - r) < double.Epsilon && r >= uint.MinValue && r <= uint.MaxValue) 1868 | { 1869 | value = (uint)r; 1870 | return true; 1871 | } 1872 | } 1873 | return false; 1874 | } 1875 | 1876 | public static bool Get(this JSON.Object o, string key, ref float value) 1877 | { 1878 | double tmp = default(double); 1879 | if (!o.Get(key, ref tmp)) 1880 | return false; 1881 | if (tmp < float.MinValue || tmp > float.MaxValue) 1882 | return false; 1883 | value = (float)tmp; 1884 | return true; 1885 | } 1886 | 1887 | public static bool Get(this JSON.Object o, string key, ref decimal value) 1888 | { 1889 | double tmp = default(double); 1890 | if (!o.Get(key, ref tmp)) 1891 | return false; 1892 | try 1893 | { 1894 | value = (decimal)tmp; 1895 | return true; 1896 | } 1897 | catch (Exception) 1898 | { 1899 | return false; 1900 | } 1901 | } 1902 | 1903 | public static bool Get(this JSON.Object o, string key, ref JSON.Value value) 1904 | { 1905 | value = o[key]; 1906 | return true; 1907 | } 1908 | 1909 | public static bool Get(this JSON.Object o, string key, ref T value) where T : JSON.Readable, new() 1910 | { 1911 | if (typeof(T).IsEnum) 1912 | { 1913 | string tmp = default(string); 1914 | if (!o.Get(key, ref tmp)) 1915 | return false; 1916 | try 1917 | { 1918 | value = (T)Enum.Parse(typeof(T), tmp); 1919 | return true; 1920 | } 1921 | catch (Exception) 1922 | { 1923 | return false; 1924 | } 1925 | } 1926 | else 1927 | { 1928 | JSON.Object tmp = default(JSON.Object); 1929 | return o.Get(key, ref tmp) && JSON.Read(tmp, ref value); 1930 | } 1931 | } 1932 | 1933 | public static bool Get(this JSON.Object o, string key, ref bool? value) 1934 | { 1935 | if (o.Type(key) == JSON.Type.Null) 1936 | { 1937 | value = null; 1938 | return true; 1939 | } 1940 | bool tmp = default(bool); 1941 | if (!o.Get(key, ref tmp)) 1942 | return false; 1943 | value = tmp; 1944 | return true; 1945 | } 1946 | 1947 | public static bool Get(this JSON.Object o, string key, ref bool[] value) 1948 | { 1949 | JSON.Array array = default(JSON.Array); 1950 | if (!o.Get(key, ref array)) 1951 | return false; 1952 | bool[] result = new bool[array.Count]; 1953 | for (int i = 0; i < result.Length; ++i) 1954 | { 1955 | if (!array.Get(i, ref result[i])) 1956 | return false; 1957 | } 1958 | value = result; 1959 | return true; 1960 | } 1961 | 1962 | public static bool Get(this JSON.Object o, string key, ref byte? value) 1963 | { 1964 | if (o.Type(key) == JSON.Type.Null) 1965 | { 1966 | value = null; 1967 | return true; 1968 | } 1969 | byte tmp = default(byte); 1970 | if (!o.Get(key, ref tmp)) 1971 | return false; 1972 | value = tmp; 1973 | return true; 1974 | } 1975 | 1976 | public static bool Get(this JSON.Object o, string key, ref byte[] value) 1977 | { 1978 | JSON.Array array = default(JSON.Array); 1979 | if (!o.Get(key, ref array)) 1980 | return false; 1981 | byte[] result = new byte[array.Count]; 1982 | for (int i = 0; i < result.Length; ++i) 1983 | { 1984 | if (!array.Get(i, ref result[i])) 1985 | return false; 1986 | } 1987 | value = result; 1988 | return true; 1989 | } 1990 | 1991 | public static bool Get(this JSON.Object o, string key, ref sbyte? value) 1992 | { 1993 | if (o.Type(key) == JSON.Type.Null) 1994 | { 1995 | value = null; 1996 | return true; 1997 | } 1998 | sbyte tmp = default(sbyte); 1999 | if (!o.Get(key, ref tmp)) 2000 | return false; 2001 | value = tmp; 2002 | return true; 2003 | } 2004 | 2005 | public static bool Get(this JSON.Object o, string key, ref sbyte[] value) 2006 | { 2007 | JSON.Array array = default(JSON.Array); 2008 | if (!o.Get(key, ref array)) 2009 | return false; 2010 | sbyte[] result = new sbyte[array.Count]; 2011 | for (int i = 0; i < result.Length; ++i) 2012 | { 2013 | if (!array.Get(i, ref result[i])) 2014 | return false; 2015 | } 2016 | value = result; 2017 | return true; 2018 | } 2019 | 2020 | public static bool Get(this JSON.Object o, string key, ref short? value) 2021 | { 2022 | if (o.Type(key) == JSON.Type.Null) 2023 | { 2024 | value = null; 2025 | return true; 2026 | } 2027 | short tmp = default(short); 2028 | if (!o.Get(key, ref tmp)) 2029 | return false; 2030 | value = tmp; 2031 | return true; 2032 | } 2033 | 2034 | public static bool Get(this JSON.Object o, string key, ref short[] value) 2035 | { 2036 | JSON.Array array = default(JSON.Array); 2037 | if (!o.Get(key, ref array)) 2038 | return false; 2039 | short[] result = new short[array.Count]; 2040 | for (int i = 0; i < result.Length; ++i) 2041 | { 2042 | if (!array.Get(i, ref result[i])) 2043 | return false; 2044 | } 2045 | value = result; 2046 | return true; 2047 | } 2048 | 2049 | public static bool Get(this JSON.Object o, string key, ref ushort? value) 2050 | { 2051 | if (o.Type(key) == JSON.Type.Null) 2052 | { 2053 | value = null; 2054 | return true; 2055 | } 2056 | ushort tmp = default(ushort); 2057 | if (!o.Get(key, ref tmp)) 2058 | return false; 2059 | value = tmp; 2060 | return true; 2061 | } 2062 | 2063 | public static bool Get(this JSON.Object o, string key, ref ushort[] value) 2064 | { 2065 | JSON.Array array = default(JSON.Array); 2066 | if (!o.Get(key, ref array)) 2067 | return false; 2068 | ushort[] result = new ushort[array.Count]; 2069 | for (int i = 0; i < result.Length; ++i) 2070 | { 2071 | if (!array.Get(i, ref result[i])) 2072 | return false; 2073 | } 2074 | value = result; 2075 | return true; 2076 | } 2077 | 2078 | public static bool Get(this JSON.Object o, string key, ref int? value) 2079 | { 2080 | if (o.Type(key) == JSON.Type.Null) 2081 | { 2082 | value = null; 2083 | return true; 2084 | } 2085 | int tmp = default(int); 2086 | if (!o.Get(key, ref tmp)) 2087 | return false; 2088 | value = tmp; 2089 | return true; 2090 | } 2091 | 2092 | public static bool Get(this JSON.Object o, string key, ref int[] value) 2093 | { 2094 | JSON.Array array = default(JSON.Array); 2095 | if (!o.Get(key, ref array)) 2096 | return false; 2097 | int[] result = new int[array.Count]; 2098 | for (int i = 0; i < result.Length; ++i) 2099 | { 2100 | if (!array.Get(i, ref result[i])) 2101 | return false; 2102 | } 2103 | value = result; 2104 | return true; 2105 | } 2106 | 2107 | public static bool Get(this JSON.Object o, string key, ref uint? value) 2108 | { 2109 | if (o.Type(key) == JSON.Type.Null) 2110 | { 2111 | value = null; 2112 | return true; 2113 | } 2114 | uint tmp = default(uint); 2115 | if (!o.Get(key, ref tmp)) 2116 | return false; 2117 | value = tmp; 2118 | return true; 2119 | } 2120 | 2121 | public static bool Get(this JSON.Object o, string key, ref uint[] value) 2122 | { 2123 | JSON.Array array = default(JSON.Array); 2124 | if (!o.Get(key, ref array)) 2125 | return false; 2126 | uint[] result = new uint[array.Count]; 2127 | for (int i = 0; i < result.Length; ++i) 2128 | { 2129 | if (!array.Get(i, ref result[i])) 2130 | return false; 2131 | } 2132 | value = result; 2133 | return true; 2134 | } 2135 | 2136 | public static bool Get(this JSON.Object o, string key, ref float? value) 2137 | { 2138 | if (o.Type(key) == JSON.Type.Null) 2139 | { 2140 | value = null; 2141 | return true; 2142 | } 2143 | float tmp = default(float); 2144 | if (!o.Get(key, ref tmp)) 2145 | return false; 2146 | value = tmp; 2147 | return true; 2148 | } 2149 | 2150 | public static bool Get(this JSON.Object o, string key, ref float[] value) 2151 | { 2152 | JSON.Array array = default(JSON.Array); 2153 | if (!o.Get(key, ref array)) 2154 | return false; 2155 | float[] result = new float[array.Count]; 2156 | for (int i = 0; i < result.Length; ++i) 2157 | { 2158 | if (!array.Get(i, ref result[i])) 2159 | return false; 2160 | } 2161 | value = result; 2162 | return true; 2163 | } 2164 | 2165 | public static bool Get(this JSON.Object o, string key, ref decimal? value) 2166 | { 2167 | if (o.Type(key) == JSON.Type.Null) 2168 | { 2169 | value = null; 2170 | return true; 2171 | } 2172 | decimal tmp = default(decimal); 2173 | if (!o.Get(key, ref tmp)) 2174 | return false; 2175 | value = tmp; 2176 | return true; 2177 | } 2178 | 2179 | public static bool Get(this JSON.Object o, string key, ref decimal[] value) 2180 | { 2181 | JSON.Array array = default(JSON.Array); 2182 | if (!o.Get(key, ref array)) 2183 | return false; 2184 | decimal[] result = new decimal[array.Count]; 2185 | for (int i = 0; i < result.Length; ++i) 2186 | { 2187 | if (!array.Get(i, ref result[i])) 2188 | return false; 2189 | } 2190 | value = result; 2191 | return true; 2192 | } 2193 | 2194 | public static bool Get(this JSON.Object o, string key, ref double? value) 2195 | { 2196 | if (o.Type(key) == JSON.Type.Null) 2197 | { 2198 | value = null; 2199 | return true; 2200 | } 2201 | double tmp = default(double); 2202 | if (!o.Get(key, ref tmp)) 2203 | return false; 2204 | value = tmp; 2205 | return true; 2206 | } 2207 | 2208 | public static bool Get(this JSON.Object o, string key, ref double[] value) 2209 | { 2210 | JSON.Array array = default(JSON.Array); 2211 | if (!o.Get(key, ref array)) 2212 | return false; 2213 | double[] result = new double[array.Count]; 2214 | for (int i = 0; i < result.Length; ++i) 2215 | { 2216 | if (!array.Get(i, ref result[i])) 2217 | return false; 2218 | } 2219 | value = result; 2220 | return true; 2221 | } 2222 | 2223 | public static bool Get(this JSON.Object o, string key, ref string[] value) 2224 | { 2225 | JSON.Array array = default(JSON.Array); 2226 | if (!o.Get(key, ref array)) 2227 | return false; 2228 | string[] result = new string[array.Count]; 2229 | for (int i = 0; i < result.Length; ++i) 2230 | { 2231 | if (!array.Get(i, ref result[i])) 2232 | return false; 2233 | } 2234 | value = result; 2235 | return true; 2236 | } 2237 | 2238 | public static bool Get(this JSON.Object o, string key, ref JSON.Object[] value) 2239 | { 2240 | JSON.Array array = default(JSON.Array); 2241 | if (!o.Get(key, ref array)) 2242 | return false; 2243 | JSON.Object[] result = new JSON.Object[array.Count]; 2244 | for (int i = 0; i < result.Length; ++i) 2245 | { 2246 | if (!array.Get(i, ref result[i])) 2247 | return false; 2248 | } 2249 | value = result; 2250 | return true; 2251 | } 2252 | 2253 | public static bool Get(this JSON.Object o, string key, ref JSON.Array[] value) 2254 | { 2255 | JSON.Array array = default(JSON.Array); 2256 | if (!o.Get(key, ref array)) 2257 | return false; 2258 | JSON.Array[] result = new JSON.Array[array.Count]; 2259 | for (int i = 0; i < result.Length; ++i) 2260 | { 2261 | if (!array.Get(i, ref result[i])) 2262 | return false; 2263 | } 2264 | value = result; 2265 | return true; 2266 | } 2267 | 2268 | public static bool Get(this JSON.Object o, string key, ref JSON.Value? value) 2269 | { 2270 | if (o.Type(key) == JSON.Type.Null) 2271 | { 2272 | value = null; 2273 | return true; 2274 | } 2275 | JSON.Value tmp = default(JSON.Value); 2276 | if (!o.Get(key, ref tmp)) 2277 | return false; 2278 | value = tmp; 2279 | return true; 2280 | } 2281 | 2282 | public static bool Get(this JSON.Object o, string key, ref JSON.Value[] value) 2283 | { 2284 | JSON.Array array = default(JSON.Array); 2285 | if (!o.Get(key, ref array)) 2286 | return false; 2287 | JSON.Value[] result = new JSON.Value[array.Count]; 2288 | for (int i = 0; i < result.Length; ++i) 2289 | { 2290 | if (!array.Get(i, ref result[i])) 2291 | return false; 2292 | } 2293 | value = result; 2294 | return true; 2295 | } 2296 | 2297 | public static bool Get(this JSON.Object o, string key, ref T? value) where T : struct, JSON.Readable 2298 | { 2299 | if (o.Type(key) == JSON.Type.Null) 2300 | { 2301 | value = null; 2302 | return true; 2303 | } 2304 | T tmp = default(T); 2305 | if (!Get(o, key, ref tmp)) 2306 | return false; 2307 | value = tmp; 2308 | return true; 2309 | } 2310 | 2311 | public static bool Get(this JSON.Object o, string key, ref T[] value) where T : JSON.Readable, new() 2312 | { 2313 | JSON.Array array = default(JSON.Array); 2314 | if (!o.Get(key, ref array)) 2315 | return false; 2316 | T[] result = new T[array.Count]; 2317 | for (int i = 0; i < result.Length; ++i) 2318 | { 2319 | if (!array.Get(i, ref result[i])) 2320 | return false; 2321 | } 2322 | value = result; 2323 | return true; 2324 | } 2325 | 2326 | public static bool Get(this JSON.Array a, int index, ref byte value) 2327 | { 2328 | int tmp = default(int); 2329 | if (!a.Get(index, ref tmp)) 2330 | return false; 2331 | if (tmp < byte.MinValue || tmp > byte.MaxValue) 2332 | return false; 2333 | value = (byte)tmp; 2334 | return true; 2335 | } 2336 | 2337 | public static bool Get(this JSON.Array a, int index, ref sbyte value) 2338 | { 2339 | int tmp = default(int); 2340 | if (!a.Get(index, ref tmp)) 2341 | return false; 2342 | if (tmp < sbyte.MinValue || tmp > sbyte.MaxValue) 2343 | return false; 2344 | value = (sbyte)tmp; 2345 | return true; 2346 | } 2347 | 2348 | public static bool Get(this JSON.Array a, int index, ref short value) 2349 | { 2350 | int tmp = default(int); 2351 | if (!a.Get(index, ref tmp)) 2352 | return false; 2353 | if (tmp < short.MinValue || tmp > short.MaxValue) 2354 | return false; 2355 | value = (short)tmp; 2356 | return true; 2357 | } 2358 | 2359 | public static bool Get(this JSON.Array a, int index, ref ushort value) 2360 | { 2361 | int tmp = default(int); 2362 | if (!a.Get(index, ref tmp)) 2363 | return false; 2364 | if (tmp < ushort.MinValue || tmp > ushort.MaxValue) 2365 | return false; 2366 | value = (ushort)tmp; 2367 | return true; 2368 | } 2369 | 2370 | public static bool Get(this JSON.Array a, int index, ref uint value) 2371 | { 2372 | int tmpi = default(int); 2373 | if (a.Get(index, ref tmpi)) 2374 | { 2375 | if (tmpi < 0) 2376 | return false; 2377 | value = (uint)tmpi; 2378 | return true; 2379 | } 2380 | double tmpd = default(double); 2381 | if (a.Get(index, ref tmpd)) 2382 | { 2383 | double r = Math.Round(tmpd); 2384 | if (Math.Abs(tmpd - r) < double.Epsilon && r >= uint.MinValue && r <= uint.MaxValue) 2385 | { 2386 | value = (uint)r; 2387 | return true; 2388 | } 2389 | } 2390 | return false; 2391 | } 2392 | 2393 | public static bool Get(this JSON.Array a, int index, ref float value) 2394 | { 2395 | double tmp = default(double); 2396 | if (!a.Get(index, ref tmp)) 2397 | return false; 2398 | if (tmp < float.MinValue || tmp > float.MaxValue) 2399 | return false; 2400 | value = (float)tmp; 2401 | return true; 2402 | } 2403 | 2404 | public static bool Get(this JSON.Array a, int index, ref decimal value) 2405 | { 2406 | double tmp = default(double); 2407 | if (!a.Get(index, ref tmp)) 2408 | return false; 2409 | try 2410 | { 2411 | value = (decimal)tmp; 2412 | return true; 2413 | } 2414 | catch (Exception) 2415 | { 2416 | return false; 2417 | } 2418 | } 2419 | 2420 | public static bool Get(this JSON.Array a, int index, ref JSON.Value value) 2421 | { 2422 | value = a[index]; 2423 | return true; 2424 | } 2425 | 2426 | public static bool Get(this JSON.Array a, int index, ref T value) where T : JSON.Readable, new() 2427 | { 2428 | if (typeof(T).IsEnum) 2429 | { 2430 | string tmp = default(string); 2431 | if (!a.Get(index, ref tmp)) 2432 | return false; 2433 | try 2434 | { 2435 | value = (T)Enum.Parse(typeof(T), tmp); 2436 | return true; 2437 | } 2438 | catch (Exception) 2439 | { 2440 | return false; 2441 | } 2442 | } 2443 | else 2444 | { 2445 | JSON.Object tmp = default(JSON.Object); 2446 | return a.Get(index, ref tmp) && JSON.Read(tmp, ref value); 2447 | } 2448 | } 2449 | 2450 | public static bool Get(this JSON.Array a, int index, ref bool? value) 2451 | { 2452 | if (a.Type(index) == JSON.Type.Null) 2453 | { 2454 | value = null; 2455 | return true; 2456 | } 2457 | bool tmp = default(bool); 2458 | if (!a.Get(index, ref tmp)) 2459 | return false; 2460 | value = tmp; 2461 | return true; 2462 | } 2463 | 2464 | public static bool Get(this JSON.Array a, int index, ref bool[] value) 2465 | { 2466 | JSON.Array array = default(JSON.Array); 2467 | if (!a.Get(index, ref array)) 2468 | return false; 2469 | bool[] result = new bool[array.Count]; 2470 | for (int i = 0; i < result.Length; ++i) 2471 | { 2472 | if (!array.Get(i, ref result[i])) 2473 | return false; 2474 | } 2475 | value = result; 2476 | return true; 2477 | } 2478 | 2479 | public static bool Get(this JSON.Array a, int index, ref byte? value) 2480 | { 2481 | if (a.Type(index) == JSON.Type.Null) 2482 | { 2483 | value = null; 2484 | return true; 2485 | } 2486 | byte tmp = default(byte); 2487 | if (!a.Get(index, ref tmp)) 2488 | return false; 2489 | value = tmp; 2490 | return true; 2491 | } 2492 | 2493 | public static bool Get(this JSON.Array a, int index, ref byte[] value) 2494 | { 2495 | JSON.Array array = default(JSON.Array); 2496 | if (!a.Get(index, ref array)) 2497 | return false; 2498 | byte[] result = new byte[array.Count]; 2499 | for (int i = 0; i < result.Length; ++i) 2500 | { 2501 | if (!array.Get(i, ref result[i])) 2502 | return false; 2503 | } 2504 | value = result; 2505 | return true; 2506 | } 2507 | 2508 | public static bool Get(this JSON.Array a, int index, ref sbyte? value) 2509 | { 2510 | if (a.Type(index) == JSON.Type.Null) 2511 | { 2512 | value = null; 2513 | return true; 2514 | } 2515 | sbyte tmp = default(sbyte); 2516 | if (!a.Get(index, ref tmp)) 2517 | return false; 2518 | value = tmp; 2519 | return true; 2520 | } 2521 | 2522 | public static bool Get(this JSON.Array a, int index, ref sbyte[] value) 2523 | { 2524 | JSON.Array array = default(JSON.Array); 2525 | if (!a.Get(index, ref array)) 2526 | return false; 2527 | sbyte[] result = new sbyte[array.Count]; 2528 | for (int i = 0; i < result.Length; ++i) 2529 | { 2530 | if (!array.Get(i, ref result[i])) 2531 | return false; 2532 | } 2533 | value = result; 2534 | return true; 2535 | } 2536 | 2537 | public static bool Get(this JSON.Array a, int index, ref short? value) 2538 | { 2539 | if (a.Type(index) == JSON.Type.Null) 2540 | { 2541 | value = null; 2542 | return true; 2543 | } 2544 | short tmp = default(short); 2545 | if (!a.Get(index, ref tmp)) 2546 | return false; 2547 | value = tmp; 2548 | return true; 2549 | } 2550 | 2551 | public static bool Get(this JSON.Array a, int index, ref short[] value) 2552 | { 2553 | JSON.Array array = default(JSON.Array); 2554 | if (!a.Get(index, ref array)) 2555 | return false; 2556 | short[] result = new short[array.Count]; 2557 | for (int i = 0; i < result.Length; ++i) 2558 | { 2559 | if (!array.Get(i, ref result[i])) 2560 | return false; 2561 | } 2562 | value = result; 2563 | return true; 2564 | } 2565 | 2566 | public static bool Get(this JSON.Array a, int index, ref ushort? value) 2567 | { 2568 | if (a.Type(index) == JSON.Type.Null) 2569 | { 2570 | value = null; 2571 | return true; 2572 | } 2573 | ushort tmp = default(ushort); 2574 | if (!a.Get(index, ref tmp)) 2575 | return false; 2576 | value = tmp; 2577 | return true; 2578 | } 2579 | 2580 | public static bool Get(this JSON.Array a, int index, ref ushort[] value) 2581 | { 2582 | JSON.Array array = default(JSON.Array); 2583 | if (!a.Get(index, ref array)) 2584 | return false; 2585 | ushort[] result = new ushort[array.Count]; 2586 | for (int i = 0; i < result.Length; ++i) 2587 | { 2588 | if (!array.Get(i, ref result[i])) 2589 | return false; 2590 | } 2591 | value = result; 2592 | return true; 2593 | } 2594 | 2595 | public static bool Get(this JSON.Array a, int index, ref int? value) 2596 | { 2597 | if (a.Type(index) == JSON.Type.Null) 2598 | { 2599 | value = null; 2600 | return true; 2601 | } 2602 | int tmp = default(int); 2603 | if (!a.Get(index, ref tmp)) 2604 | return false; 2605 | value = tmp; 2606 | return true; 2607 | } 2608 | 2609 | public static bool Get(this JSON.Array a, int index, ref int[] value) 2610 | { 2611 | JSON.Array array = default(JSON.Array); 2612 | if (!a.Get(index, ref array)) 2613 | return false; 2614 | int[] result = new int[array.Count]; 2615 | for (int i = 0; i < result.Length; ++i) 2616 | { 2617 | if (!array.Get(i, ref result[i])) 2618 | return false; 2619 | } 2620 | value = result; 2621 | return true; 2622 | } 2623 | 2624 | public static bool Get(this JSON.Array a, int index, ref uint? value) 2625 | { 2626 | if (a.Type(index) == JSON.Type.Null) 2627 | { 2628 | value = null; 2629 | return true; 2630 | } 2631 | uint tmp = default(uint); 2632 | if (!a.Get(index, ref tmp)) 2633 | return false; 2634 | value = tmp; 2635 | return true; 2636 | } 2637 | 2638 | public static bool Get(this JSON.Array a, int index, ref uint[] value) 2639 | { 2640 | JSON.Array array = default(JSON.Array); 2641 | if (!a.Get(index, ref array)) 2642 | return false; 2643 | uint[] result = new uint[array.Count]; 2644 | for (int i = 0; i < result.Length; ++i) 2645 | { 2646 | if (!array.Get(i, ref result[i])) 2647 | return false; 2648 | } 2649 | value = result; 2650 | return true; 2651 | } 2652 | 2653 | public static bool Get(this JSON.Array a, int index, ref float? value) 2654 | { 2655 | if (a.Type(index) == JSON.Type.Null) 2656 | { 2657 | value = null; 2658 | return true; 2659 | } 2660 | float tmp = default(float); 2661 | if (!a.Get(index, ref tmp)) 2662 | return false; 2663 | value = tmp; 2664 | return true; 2665 | } 2666 | 2667 | public static bool Get(this JSON.Array a, int index, ref float[] value) 2668 | { 2669 | JSON.Array array = default(JSON.Array); 2670 | if (!a.Get(index, ref array)) 2671 | return false; 2672 | float[] result = new float[array.Count]; 2673 | for (int i = 0; i < result.Length; ++i) 2674 | { 2675 | if (!array.Get(i, ref result[i])) 2676 | return false; 2677 | } 2678 | value = result; 2679 | return true; 2680 | } 2681 | 2682 | public static bool Get(this JSON.Array a, int index, ref decimal? value) 2683 | { 2684 | if (a.Type(index) == JSON.Type.Null) 2685 | { 2686 | value = null; 2687 | return true; 2688 | } 2689 | decimal tmp = default(decimal); 2690 | if (!a.Get(index, ref tmp)) 2691 | return false; 2692 | value = tmp; 2693 | return true; 2694 | } 2695 | 2696 | public static bool Get(this JSON.Array a, int index, ref decimal[] value) 2697 | { 2698 | JSON.Array array = default(JSON.Array); 2699 | if (!a.Get(index, ref array)) 2700 | return false; 2701 | decimal[] result = new decimal[array.Count]; 2702 | for (int i = 0; i < result.Length; ++i) 2703 | { 2704 | if (!array.Get(i, ref result[i])) 2705 | return false; 2706 | } 2707 | value = result; 2708 | return true; 2709 | } 2710 | 2711 | public static bool Get(this JSON.Array a, int index, ref double? value) 2712 | { 2713 | if (a.Type(index) == JSON.Type.Null) 2714 | { 2715 | value = null; 2716 | return true; 2717 | } 2718 | double tmp = default(double); 2719 | if (!a.Get(index, ref tmp)) 2720 | return false; 2721 | value = tmp; 2722 | return true; 2723 | } 2724 | 2725 | public static bool Get(this JSON.Array a, int index, ref double[] value) 2726 | { 2727 | JSON.Array array = default(JSON.Array); 2728 | if (!a.Get(index, ref array)) 2729 | return false; 2730 | double[] result = new double[array.Count]; 2731 | for (int i = 0; i < result.Length; ++i) 2732 | { 2733 | if (!array.Get(i, ref result[i])) 2734 | return false; 2735 | } 2736 | value = result; 2737 | return true; 2738 | } 2739 | 2740 | public static bool Get(this JSON.Array a, int index, ref string[] value) 2741 | { 2742 | JSON.Array array = default(JSON.Array); 2743 | if (!a.Get(index, ref array)) 2744 | return false; 2745 | string[] result = new string[array.Count]; 2746 | for (int i = 0; i < result.Length; ++i) 2747 | { 2748 | if (!array.Get(i, ref result[i])) 2749 | return false; 2750 | } 2751 | value = result; 2752 | return true; 2753 | } 2754 | 2755 | public static bool Get(this JSON.Array a, int index, ref JSON.Object[] value) 2756 | { 2757 | JSON.Array array = default(JSON.Array); 2758 | if (!a.Get(index, ref array)) 2759 | return false; 2760 | JSON.Object[] result = new JSON.Object[array.Count]; 2761 | for (int i = 0; i < result.Length; ++i) 2762 | { 2763 | if (!array.Get(i, ref result[i])) 2764 | return false; 2765 | } 2766 | value = result; 2767 | return true; 2768 | } 2769 | 2770 | public static bool Get(this JSON.Array a, int index, ref JSON.Array[] value) 2771 | { 2772 | JSON.Array array = default(JSON.Array); 2773 | if (!a.Get(index, ref array)) 2774 | return false; 2775 | JSON.Array[] result = new JSON.Array[array.Count]; 2776 | for (int i = 0; i < result.Length; ++i) 2777 | { 2778 | if (!array.Get(i, ref result[i])) 2779 | return false; 2780 | } 2781 | value = result; 2782 | return true; 2783 | } 2784 | 2785 | public static bool Get(this JSON.Array a, int index, ref JSON.Value? value) 2786 | { 2787 | if (a.Type(index) == JSON.Type.Null) 2788 | { 2789 | value = null; 2790 | return true; 2791 | } 2792 | JSON.Value tmp = default(JSON.Value); 2793 | if (!a.Get(index, ref tmp)) 2794 | return false; 2795 | value = tmp; 2796 | return true; 2797 | } 2798 | 2799 | public static bool Get(this JSON.Array a, int index, ref JSON.Value[] value) 2800 | { 2801 | JSON.Array array = default(JSON.Array); 2802 | if (!a.Get(index, ref array)) 2803 | return false; 2804 | JSON.Value[] result = new JSON.Value[array.Count]; 2805 | for (int i = 0; i < result.Length; ++i) 2806 | { 2807 | if (!array.Get(i, ref result[i])) 2808 | return false; 2809 | } 2810 | value = result; 2811 | return true; 2812 | } 2813 | 2814 | public static bool Get(this JSON.Array a, int index, ref T? value) where T : struct, JSON.Readable 2815 | { 2816 | if (a.Type(index) == JSON.Type.Null) 2817 | { 2818 | value = null; 2819 | return true; 2820 | } 2821 | T tmp = default(T); 2822 | if (!Get(a, index, ref tmp)) 2823 | return false; 2824 | value = tmp; 2825 | return true; 2826 | } 2827 | 2828 | public static bool Get(this JSON.Array a, int index, ref T[] value) where T : JSON.Readable, new() 2829 | { 2830 | JSON.Array array = default(JSON.Array); 2831 | if (!a.Get(index, ref array)) 2832 | return false; 2833 | T[] result = new T[array.Count]; 2834 | for (int i = 0; i < result.Length; ++i) 2835 | { 2836 | if (!array.Get(i, ref result[i])) 2837 | return false; 2838 | } 2839 | value = result; 2840 | return true; 2841 | } 2842 | } 2843 | } 2844 | --------------------------------------------------------------------------------