コミットメタ情報

リビジョンd69ddad1e24ea6f1525298d6fdeda54fb9a03e12 (tree)
日時2018-03-24 19:41:25
作者Kazuhiro Fujieda <fujieda@user...>
コミッターKazuhiro Fujieda

ログメッセージ

JSONオブジェクトのメンバー順を保存する

変更サマリ

差分

--- a/KancolleSniffer.Test/JsonTest.cs
+++ b/KancolleSniffer.Test/JsonTest.cs
@@ -231,6 +231,18 @@ namespace KancolleSniffer.Test
231231 }
232232
233233 [TestMethod]
234+ public void PropertyOrder()
235+ {
236+ const int count = 100;
237+ var json = "{" + string.Join(",", Enumerable.Range(0, count).Select(n => $"\"{"a" + n}\":{n}")) + "}";
238+ var obj = (dynamic)JsonParser.Parse(json);
239+ var list = new List<int>();
240+ foreach (KeyValuePair<string, dynamic> kv in obj)
241+ list.Add((int)kv.Value);
242+ Assert.IsTrue(list.SequenceEqual(Enumerable.Range(0, count)));
243+ }
244+
245+ [TestMethod]
234246 public void CastArrayToPrimitivetArray()
235247 {
236248 var bary = (bool[])(dynamic)JsonParser.Parse("[true,false,true]");
--- a/KancolleSniffer/JsonParser.cs
+++ b/KancolleSniffer/JsonParser.cs
@@ -1,6 +1,7 @@
11 using System;
22 using System.Collections;
33 using System.Collections.Generic;
4+using System.Collections.Specialized;
45 using System.Dynamic;
56 using System.Linq;
67 using System.Reflection;
@@ -187,7 +188,7 @@ namespace KancolleSniffer
187188 private JsonObject ParseObject()
188189 {
189190 Consume();
190- var dict = new Dictionary<string, JsonObject>();
191+ var dict = new OrderedDictionary();
191192 while (true)
192193 {
193194 var ch = NextChar();
@@ -250,11 +251,11 @@ namespace KancolleSniffer
250251 private readonly double _number;
251252 private readonly string _string;
252253 private readonly List<JsonObject> _array;
253- private readonly Dictionary<string, JsonObject> _dict;
254+ private readonly OrderedDictionary _dict;
254255
255256 public bool IsArray => _type == JsonType.Array;
256257 public bool IsObject => _type == JsonType.Object;
257- public bool IsDefined(string attr) => IsObject && _dict.ContainsKey(attr);
258+ public bool IsDefined(string attr) => IsObject && _dict.Contains(attr);
258259
259260 public JsonObject(bool b)
260261 {
@@ -280,7 +281,7 @@ namespace KancolleSniffer
280281 _array = ary;
281282 }
282283
283- public JsonObject(Dictionary<string, JsonObject> dict)
284+ public JsonObject(OrderedDictionary dict)
284285 {
285286 _type = JsonType.Object;
286287 _dict = dict;
@@ -291,15 +292,15 @@ namespace KancolleSniffer
291292 result = null;
292293 if (_type != JsonType.Object)
293294 return false;
294- if (!_dict.TryGetValue(binder.Name, out var dict))
295+ if (!_dict.Contains(binder.Name))
295296 return false;
296- result = dict?.Value;
297+ result = ((JsonObject)_dict[binder.Name])?.Value;
297298 return true;
298299 }
299300
300301 public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
301302 {
302- result = _type == JsonType.Object && _dict.ContainsKey(binder.Name);
303+ result = _type == JsonType.Object && _dict.Contains(binder.Name);
303304 return true;
304305 }
305306
@@ -311,7 +312,7 @@ namespace KancolleSniffer
311312 result = _array[(int)indexes[0]]?.Value;
312313 return true;
313314 case JsonType.Object:
314- result = _dict[(string)indexes[0]]?.Value;
315+ result = ((JsonObject)_dict[(string)indexes[0]])?.Value;
315316 return true;
316317 }
317318 result = null;
@@ -328,7 +329,7 @@ namespace KancolleSniffer
328329 result = _array.Select(x => x.Value);
329330 return true;
330331 case JsonType.Object:
331- result = _dict.Select(x => new KeyValuePair<string, dynamic>(x.Key, x.Value));
332+ result = _dict.Cast<DictionaryEntry>().Select(x => new KeyValuePair<string, dynamic>((string)x.Key, x.Value));
332333 return true;
333334 default:
334335 result = null;
@@ -419,8 +420,10 @@ namespace KancolleSniffer
419420 case IEnumerable arry:
420421 return new JsonObject(arry.Cast<object>().Select(CreateJsonObject).ToList());
421422 case object obj:
422- return new JsonObject(obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
423- .ToDictionary(prop => prop.Name, prop => CreateJsonObject(prop.GetValue(obj))));
423+ var dict = new OrderedDictionary();
424+ foreach (var prop in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
425+ dict.Add(prop.Name, CreateJsonObject(prop.GetValue(obj)));
426+ return new JsonObject(dict);
424427 }
425428 return null;
426429 }
@@ -491,7 +494,7 @@ namespace KancolleSniffer
491494 case JsonType.Object:
492495 sb.Append("{");
493496 delimiter = "";
494- foreach (var entry in _dict)
497+ foreach (DictionaryEntry entry in _dict)
495498 {
496499 sb.Append(delimiter);
497500 sb.Append("\"");
@@ -503,7 +506,7 @@ namespace KancolleSniffer
503506 }
504507 else
505508 {
506- entry.Value.ConvertToString(sb);
509+ ((JsonObject)entry.Value).ConvertToString(sb);
507510 }
508511 delimiter = ",";
509512 }
旧リポジトリブラウザで表示