This commit is contained in:
JamesNK
2007-09-08 08:59:38 +00:00
commit e65bc2becd
43 changed files with 13240 additions and 0 deletions
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,70 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Tests
{
[TestFixture]
public class AspNetAjaxDateTimeConverterTest
{
public class DateTimeTestClass
{
public string PreField;
public DateTime DateTimeField;
public string PostField;
}
[Test]
public void Serialize()
{
DateTimeTestClass c = new DateTimeTestClass();
c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 12);
c.PreField = "Pre";
c.PostField = "Post";
string json = JavaScriptConvert.SerializeObject(c, new AspNetAjaxDateTimeConverter());
Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""@1229083932012@"",""PostField"":""Post""}", json);
}
[Test]
public void DeSerialize()
{
DateTimeTestClass c =
JavaScriptConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""@1229083932012@"",""PostField"":""Post""}", new AspNetAjaxDateTimeConverter());
Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 12), c.DateTimeField);
Assert.AreEqual("Pre", c.PreField);
Assert.AreEqual("Post", c.PostField);
}
}
}
+220
View File
@@ -0,0 +1,220 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
namespace Newtonsoft.Json.Tests
{
[TestFixture]
public class JsonReaderTest
{
[Test]
public void YahooFinance()
{
string input = @"{
""matches"" : [
{""t"":""C"", ""n"":""Citigroup Inc."", ""e"":""NYSE"", ""id"":""662713""}
,{""t"":""CHL"", ""n"":""China Mobile Ltd. (ADR)"", ""e"":""NYSE"", ""id"":""660998""}
,{""t"":""PTR"", ""n"":""PetroChina Company Limited (ADR)"", ""e"":""NYSE"", ""id"":""664536""}
,{""t"":""RIO"", ""n"":""Companhia Vale do Rio Doce (ADR)"", ""e"":""NYSE"", ""id"":""671472""}
,{""t"":""RIOPR"", ""n"":""Companhia Vale do Rio Doce (ADR)"", ""e"":""NYSE"", ""id"":""3512643""}
,{""t"":""CSCO"", ""n"":""Cisco Systems, Inc."", ""e"":""NASDAQ"", ""id"":""99624""}
,{""t"":""CVX"", ""n"":""Chevron Corporation"", ""e"":""NYSE"", ""id"":""667226""}
,{""t"":""TM"", ""n"":""Toyota Motor Corporation (ADR)"", ""e"":""NYSE"", ""id"":""655880""}
,{""t"":""JPM"", ""n"":""JPMorgan Chase \x26 Co."", ""e"":""NYSE"", ""id"":""665639""}
,{""t"":""COP"", ""n"":""ConocoPhillips"", ""e"":""NYSE"", ""id"":""1691168""}
,{""t"":""LFC"", ""n"":""China Life Insurance Company Ltd. (ADR)"", ""e"":""NYSE"", ""id"":""688679""}
,{""t"":""NOK"", ""n"":""Nokia Corporation (ADR)"", ""e"":""NYSE"", ""id"":""657729""}
,{""t"":""KO"", ""n"":""The Coca-Cola Company"", ""e"":""NYSE"", ""id"":""6550""}
,{""t"":""VZ"", ""n"":""Verizon Communications Inc."", ""e"":""NYSE"", ""id"":""664887""}
,{""t"":""AMX"", ""n"":""America Movil S.A.B de C.V. (ADR)"", ""e"":""NYSE"", ""id"":""665834""}],
""all"" : false
}
";
using (JsonReader jsonReader = new JsonReader(new StringReader(input)))
{
while (jsonReader.Read())
{
Console.WriteLine(jsonReader.Value);
}
}
}
[Test]
public void ReadingIndented()
{
string input = @"{
CPU: 'Intel',
Drives: [
'DVD read/writer',
""500 gigabyte hard drive""
]
}";
StringReader sr = new StringReader(input);
using (JsonReader jsonReader = new JsonReader(sr))
{
Assert.AreEqual(jsonReader.TokenType, JsonToken.None);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
Assert.AreEqual(jsonReader.Value, "CPU");
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
Assert.AreEqual(jsonReader.Value, "Intel");
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
Assert.AreEqual(jsonReader.Value, "Drives");
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
Assert.AreEqual(jsonReader.Value, "DVD read/writer");
Assert.AreEqual(jsonReader.QuoteChar, '\'');
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive");
Assert.AreEqual(jsonReader.QuoteChar, '"');
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
}
}
[Test]
public void ReadingEscapedStrings()
{
string input = "{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}";
StringReader sr = new StringReader(input);
using (JsonReader jsonReader = new JsonReader(sr))
{
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
Assert.AreEqual(jsonReader.Value, "Purple\r \n monkey's:\tdishwasher");
Assert.AreEqual(jsonReader.QuoteChar, '\'');
jsonReader.Read();
Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
}
}
[Test]
public void ReadNewlineLastCharacter()
{
string input = @"{
CPU: 'Intel',
Drives: [
'DVD read/writer',
""500 gigabyte hard drive""
]
}" + '\n';
object o = JavaScriptConvert.DeserializeObject(input);
}
[Test]
public void WriteReadWrite()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
jsonWriter.WriteStartArray();
jsonWriter.WriteValue(true);
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("integer");
jsonWriter.WriteValue(99);
jsonWriter.WritePropertyName("string");
jsonWriter.WriteValue("how now brown cow?");
jsonWriter.WritePropertyName("array");
jsonWriter.WriteStartArray();
for (int i = 0; i < 5; i++)
{
jsonWriter.WriteValue(i);
}
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("decimal");
jsonWriter.WriteValue(990.00990099m);
jsonWriter.WriteEndObject();
jsonWriter.WriteValue(5);
jsonWriter.WriteEndArray();
jsonWriter.WriteEndObject();
jsonWriter.WriteValue("This is a string.");
jsonWriter.WriteNull();
jsonWriter.WriteNull();
jsonWriter.WriteEndArray();
}
string json = sb.ToString();
JsonSerializer serializer = new JsonSerializer();
object jsonObject = serializer.Deserialize(new JsonReader(new StringReader(json)));
sb = new StringBuilder();
sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
serializer.Serialize(sw, jsonObject);
}
Assert.AreEqual(json, sb.ToString());
}
}
}
@@ -0,0 +1,529 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
namespace Newtonsoft.Json.Tests
{
public class Product
{
public string Name;
public DateTime Expiry;
public decimal Price;
public string[] Sizes;
}
public class Store
{
public StoreColor Color = StoreColor.Yellow;
public DateTime Establised = new DateTime(2010, 1, 22);
public double Width = 1.1;
public int Employees = 999;
public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public bool Open = false;
public char Symbol = '@';
public List<string> Mottos = new List<string>();
public decimal Cost = 100980.1M;
public string Escape = "\r\n\t\f\b?{\\r\\n\"\'";
public List<Product> product = new List<Product>();
public Store()
{
Mottos.Add("Hello World");
Mottos.Add("öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~");
Mottos.Add(null);
Mottos.Add(" ");
Product rocket = new Product();
rocket.Name = "Rocket";
rocket.Expiry = new DateTime(2000, 2, 2, 23, 1, 30);
Product alien = new Product();
alien.Name = "Alien";
product.Add(rocket);
product.Add(alien);
}
}
public enum StoreColor
{
Black,
Red,
Yellow,
White
}
[TestFixture]
public class JsonSerializerTest
{
[Test]
public void PersonTypedObjectDeserialization()
{
Store store = new Store();
string jsonText = JavaScriptConvert.SerializeObject(store);
Store deserializedStore = (Store)JavaScriptConvert.DeserializeObject(jsonText, typeof(Store));
Console.WriteLine(jsonText);
}
[Test]
public void TypedObjectDeserialization()
{
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JavaScriptConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Expiry": new Date(1230422400000),
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = (Product)JavaScriptConvert.DeserializeObject(output, typeof(Product));
Assert.AreEqual("Apple", deserializedProduct.Name);
Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.Expiry);
Assert.AreEqual(3.99, deserializedProduct.Price);
Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
}
[Test]
public void JavaScriptConvertSerializer()
{
string value = @"{""Name"":""Orange"", ""Price"":3.99, ""Expiry"":""01/24/2010 12:00:00""}";
Product p = JavaScriptConvert.DeserializeObject(value, typeof(Product)) as Product;
Assert.AreEqual("Orange", p.Name);
Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.Expiry);
Assert.AreEqual(3.99, p.Price);
}
[Test]
public void DeserializeJavaScriptDate()
{
DateTime dateValue = new DateTime(2000, 3, 30);
Dictionary<string, object> testDictionary = new Dictionary<string, object>();
testDictionary["date"] = dateValue;
string jsonText = JavaScriptConvert.SerializeObject(testDictionary);
Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>)JavaScriptConvert.DeserializeObject(jsonText, typeof(Dictionary<string, object>));
DateTime deserializedDate = (DateTime)deserializedDictionary["date"];
Assert.AreEqual(dateValue, deserializedDate);
Console.WriteLine("DeserializeJavaScriptDate");
Console.WriteLine(jsonText);
Console.WriteLine();
Console.WriteLine(jsonText);
}
public class MethodExecutorObject
{
public string serverClassName;
public object[] serverMethodParams;
public string clientGetResultFunction;
}
[Test]
public void TestMethodExecutorObject()
{
MethodExecutorObject executorObject = new MethodExecutorObject();
executorObject.serverClassName = "BanSubs";
executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" };
executorObject.clientGetResultFunction = "ClientBanSubsCB";
string output = JavaScriptConvert.SerializeObject(executorObject);
MethodExecutorObject executorObject2 = JavaScriptConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject;
Assert.AreNotSame(executorObject, executorObject2);
Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
Assert.Contains("101", executorObject2.serverMethodParams);
Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
}
[Test]
public void HashtableDeserialization()
{
string value = @"{""Name"":""Orange"", ""Price"":3.99, ""Expiry"":""01/24/2010 12:00:00""}";
Hashtable p = JavaScriptConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable;
Assert.AreEqual("Orange", p["Name"].ToString());
}
public class TypedSubHashtable
{
public string Name;
public Hashtable Hash;
}
[Test]
public void TypedHashtableDeserialization()
{
string value = @"{""Name"":""Orange"", ""Hash"":{""Expiry"":""01/24/2010 12:00:00""}}";
TypedSubHashtable p = JavaScriptConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable;
Assert.AreEqual("01/24/2010 12:00:00", p.Hash["Expiry"].ToString());
}
public class GetOnlyPropertyClass
{
public string Field = "Field";
public string GetOnlyProperty
{
get { return "GetOnlyProperty"; }
}
}
[Test]
public void SerializeDeserializeGetOnlyProperty()
{
string value = JavaScriptConvert.SerializeObject(new GetOnlyPropertyClass());
GetOnlyPropertyClass c = JavaScriptConvert.DeserializeObject<GetOnlyPropertyClass>(value);
Assert.AreEqual(c.Field, "Field");
Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
}
public class SetOnlyPropertyClass
{
public string Field = "Field";
public string SetOnlyProperty
{
set { }
}
}
[Test]
public void SerializeDeserializeSetOnlyProperty()
{
string value = JavaScriptConvert.SerializeObject(new SetOnlyPropertyClass());
SetOnlyPropertyClass c = JavaScriptConvert.DeserializeObject<SetOnlyPropertyClass>(value);
Assert.AreEqual(c.Field, "Field");
}
public class JsonIgnoreAttributeTestClass
{
private int _property = 21;
private int _ignoredProperty = 12;
public int Field;
public int Property
{
get { return _property; }
}
[JsonIgnore]
public int IgnoredField;
[JsonIgnore]
public int IgnoredProperty
{
get { return _ignoredProperty; }
}
}
[Test]
public void JsonIgnoreAttributeTest()
{
string json = JavaScriptConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
JsonIgnoreAttributeTestClass c = JavaScriptConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1}");
Assert.AreEqual(0, c.IgnoredField);
Assert.AreEqual(99, c.Field);
}
[Test]
public void GoogleSearchAPI()
{
string json = @"{
results:
[
{
GsearchResultClass:""GwebSearch"",
unescapedUrl : ""http://www.google.com/"",
url : ""http://www.google.com/"",
visibleUrl : ""www.google.com"",
cacheUrl :
""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
title : ""Google"",
titleNoFormatting : ""Google"",
content : ""Enables users to search the Web, Usenet, and
images. Features include PageRank, caching and translation of
results, and an option to find similar pages.""
},
{
GsearchResultClass:""GwebSearch"",
unescapedUrl : ""http://news.google.com/"",
url : ""http://news.google.com/"",
visibleUrl : ""news.google.com"",
cacheUrl :
""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
title : ""Google News"",
titleNoFormatting : ""Google News"",
content : ""Aggregated headlines and a search engine of many of the world's news sources.""
},
{
GsearchResultClass:""GwebSearch"",
unescapedUrl : ""http://groups.google.com/"",
url : ""http://groups.google.com/"",
visibleUrl : ""groups.google.com"",
cacheUrl :
""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
title : ""Google Groups"",
titleNoFormatting : ""Google Groups"",
content : ""Enables users to search and browse the Usenet
archives which consist of over 700 million messages, and post new
comments.""
},
{
GsearchResultClass:""GwebSearch"",
unescapedUrl : ""http://maps.google.com/"",
url : ""http://maps.google.com/"",
visibleUrl : ""maps.google.com"",
cacheUrl :
""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
title : ""Google Maps"",
titleNoFormatting : ""Google Maps"",
content : ""Provides directions, interactive maps, and
satellite/aerial imagery of the United States. Can also search by
keyword such as type of business.""
}
],
adResults:
[
{
GsearchResultClass:""GwebSearch.ad"",
title : ""Gartner Symposium/ITxpo"",
content1 : ""Meet brilliant Gartner IT analysts"",
content2 : ""20-23 May 2007- Barcelona, Spain"",
url :
""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="",
impressionUrl :
""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"",
unescapedUrl :
""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="",
visibleUrl : ""www.gartner.com""
}
]
}
";
object o = JavaScriptConvert.DeserializeObject(json);
string s = string.Empty;
s += s;
}
[Test]
public void TorrentDeserializeTest()
{
string jsonText = @"{
"""":"""",
""label"": [
[""SomeName"",6]
],
""torrents"": [
[""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
],
""torrentc"": ""1816000723""
}";
JavaScriptObject o = (JavaScriptObject)JavaScriptConvert.DeserializeObject(jsonText);
Assert.AreEqual(4, o.Count);
JavaScriptArray torrentsArray = (JavaScriptArray)o["torrents"];
JavaScriptArray nestedTorrentsArray = (JavaScriptArray)torrentsArray[0];
Assert.AreEqual(nestedTorrentsArray.Count, 19);
}
public class JsonPropertyClass
{
[JsonProperty("pie")]
public string Pie = "Yum";
[JsonIgnore]
public string pie = "No pie for you!";
public string pie1 = "PieChart!";
private int _sweetCakesCount;
[JsonProperty("sweet_cakes_count")]
public int SweetCakesCount
{
get { return _sweetCakesCount; }
set { _sweetCakesCount = value; }
}
}
[Test]
public void JsonPropertyClassSerialize()
{
JsonPropertyClass test = new JsonPropertyClass();
test.Pie = "Delicious";
test.SweetCakesCount = int.MaxValue;
string jsonText = JavaScriptConvert.SerializeObject(test);
Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
JsonPropertyClass test2 = JavaScriptConvert.DeserializeObject<JsonPropertyClass>(jsonText);
Assert.AreEqual(test.Pie, test2.Pie);
Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
}
public class BadJsonPropertyClass
{
[JsonProperty("pie")]
public string Pie = "Yum";
public string pie = "PieChart!";
}
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"A member with the name 'pie' already exists on Newtonsoft.Json.Tests.JsonSerializerTest+BadJsonPropertyClass. Use the JsonPropertyAttribute to specify another name.")]
public void BadJsonPropertyClassSerialize()
{
JavaScriptConvert.SerializeObject(new BadJsonPropertyClass());
}
public class Article
{
public string Name;
public Article()
{
}
public Article(string name)
{
Name = name;
}
}
public class ArticleCollection : List<Article>
{
}
[Test]
public void InheritedListSerialize()
{
Article a1 = new Article("a1");
Article a2 = new Article("a2");
ArticleCollection articles1 = new ArticleCollection();
articles1.Add(a1);
articles1.Add(a2);
string jsonText = JavaScriptConvert.SerializeObject(articles1);
ArticleCollection articles2 = JavaScriptConvert.DeserializeObject<ArticleCollection>(jsonText);
Assert.AreEqual(articles1.Count, articles2.Count);
Assert.AreEqual(articles1[0].Name, articles2[0].Name);
}
[Test]
public void ReadOnlyCollectionSerialize()
{
ReadOnlyCollection<int> r1 = new ReadOnlyCollection<int>(new int[] {0, 1, 2, 3, 4});
string jsonText = JavaScriptConvert.SerializeObject(r1);
ReadOnlyCollection<int> r2 = JavaScriptConvert.DeserializeObject<ReadOnlyCollection<int>>(jsonText);
CollectionAssert.AreEqual(r1, r2);
}
//public abstract class Foo
//{
//}
//public class Baz : Foo
//{
//}
//public class Bar : Foo
//{
//}
//public class BazJsonConverter : JsonConverter
//{
// public override bool CanConvert(Type objectType)
// {
// throw new Exception("The method or operation is not implemented.");
// }
//}
//public class BarJsonConverter : JsonConverter
//{
// public override bool CanConvert(Type objectType)
// {
// throw new Exception("The method or operation is not implemented.");
// }
//}
}
}
+176
View File
@@ -0,0 +1,176 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
namespace Newtonsoft.Json.Tests
{
[TestFixture]
public class JsonWriterTest
{
[Test]
public void ValueFormatting()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
jsonWriter.WriteStartArray();
jsonWriter.WriteValue('@');
jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'");
jsonWriter.WriteValue(true);
jsonWriter.WriteValue(10);
jsonWriter.WriteValue(10.99);
jsonWriter.WriteValue(0.99);
jsonWriter.WriteValue(0.000000000000000001d);
jsonWriter.WriteValue(0.000000000000000001m);
jsonWriter.WriteValue(null);
jsonWriter.WriteValue("This is a string.");
jsonWriter.WriteNull();
jsonWriter.WriteUndefined();
jsonWriter.WriteEndArray();
}
string expected = @"[""@"",""\r\n\t\f\b?{\\r\\n\""'"",true,10,10.99,0.99,1E-18,0.000000000000000001,"""",""This is a string."",null,undefined]";
string result = sb.ToString();
Console.WriteLine("ValueFormatting");
Console.WriteLine(result);
Assert.AreEqual(expected, result);
}
[Test]
public void StringEscaping()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
jsonWriter.WriteStartArray();
jsonWriter.WriteValue(@"""These pretzels are making me thirsty!""");
jsonWriter.WriteValue("Jeff's house was burninated.");
jsonWriter.WriteValue(@"1. You don't talk about fight club.
2. You don't talk about fight club.");
jsonWriter.WriteValue("35% of\t statistics\n are made\r up.");
jsonWriter.WriteEndArray();
}
string expected = @"[""\""These pretzels are making me thirsty!\"""",""Jeff's house was burninated."",""1. You don't talk about fight club.\r\n2. You don't talk about fight club."",""35% of\t statistics\n are made\r up.""]";
string result = sb.ToString();
Console.WriteLine("StringEscaping");
Console.WriteLine(result);
Assert.AreEqual(expected, result);
}
[Test]
public void Indenting()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("CPU");
jsonWriter.WriteValue("Intel");
jsonWriter.WritePropertyName("PSU");
jsonWriter.WriteValue("500W");
jsonWriter.WritePropertyName("Drives");
jsonWriter.WriteStartArray();
jsonWriter.WriteValue("DVD read/writer");
jsonWriter.WriteComment("(broken)");
jsonWriter.WriteValue("500 gigabyte hard drive");
jsonWriter.WriteValue("200 gigabype hard drive");
jsonWriter.WriteEnd();
jsonWriter.WriteEndObject();
}
string expected = @"{
""CPU"": ""Intel"",
""PSU"": ""500W"",
""Drives"": [
""DVD read/writer""
/*(broken)*/,
""500 gigabyte hard drive"",
""200 gigabype hard drive""
]
}";
string result = sb.ToString();
Console.WriteLine("Indenting");
Console.WriteLine(result);
Assert.AreEqual(expected, result);
}
[Test]
public void State()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
jsonWriter.WriteStartObject();
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
jsonWriter.WritePropertyName("CPU");
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
jsonWriter.WriteValue("Intel");
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
jsonWriter.WritePropertyName("Drives");
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
jsonWriter.WriteStartArray();
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
jsonWriter.WriteValue("DVD read/writer");
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
jsonWriter.WriteEnd();
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
jsonWriter.WriteEndObject();
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
}
}
}
}
@@ -0,0 +1,69 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3E6E2335-B079-4B5B-A65A-9D586914BCBB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Newtonsoft.Json.Tests</RootNamespace>
<AssemblyName>Newtonsoft.Json.Tests</AssemblyName>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AspNetAjaxDateTimeConverterTest.cs" />
<Compile Include="JsonReaderTest.cs" />
<Compile Include="JsonSerializerTest.cs" />
<Compile Include="JsonWriterTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XmlNodeConverterTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.csproj">
<Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
<Name>Newtonsoft.Json</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Newtonsoft Json.NET Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyProduct("Newtonsoft Json.NET Test")]
[assembly: AssemblyCopyright("Copyright © Newtonsoft 2006")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("0be3d72b-d2ef-409c-985c-d3ede89a25f1")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
@@ -0,0 +1,342 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using NUnit.Framework;
using Newtonsoft.Json;
using System.IO;
using System.Xml;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json.Tests
{
[TestFixture]
public class XmlNodeConverterTest
{
[Test]
public void DocumentSerializeIndented()
{
string xml = @"<?xml version=""1.0"" standalone=""no""?>
<?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
<span class=""vevent"">
<a class=""url"" href=""http://www.web2con.com/"">
<span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
<abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
<abbr class=""dtend"" title=""2005-10-08"">7</abbr>
<span class=""location"">Argent Hotel, San Francisco, CA</span>
</a>
</span>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
StringWriter sw = new StringWriter();
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
JsonSerializer jsonSerializer = new JsonSerializer();
jsonSerializer.Converters.Add(new XmlNodeConverter());
jsonSerializer.Serialize(jsonWriter, doc);
}
string jsonText = sw.ToString();
string expected = @"{
""?xml"": {
""@version"": ""1.0"",
""@standalone"": ""no""
},
""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
""span"": {
""@class"": ""vevent"",
""a"": {
""@class"": ""url"",
""@href"": ""http://www.web2con.com/"",
""span"": [
{
""@class"": ""summary"",
""#text"": ""Web 2.0 Conference"",
""#cdata-section"": ""my escaped text""
},
{
""@class"": ""location"",
""#text"": ""Argent Hotel, San Francisco, CA""
}
],
""abbr"": [
{
""@class"": ""dtstart"",
""@title"": ""2005-10-05"",
""#text"": ""October 5""
},
{
""@class"": ""dtend"",
""@title"": ""2005-10-08"",
""#text"": ""7""
}
]
}
}
}";
Assert.AreEqual(expected, jsonText);
Console.WriteLine("DocumentSerializeIndented");
Console.WriteLine(jsonText);
Console.WriteLine();
}
[Test]
public void SerializeNodeTypes()
{
XmlDocument doc = new XmlDocument();
string jsonText;
Console.WriteLine("SerializeNodeTypes");
// XmlAttribute
XmlAttribute attribute = doc.CreateAttribute("msdata:IsDataSet");
attribute.Value = "true";
jsonText = JavaScriptConvert.SerializeXmlNode(attribute);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
// XmlProcessingInstruction
XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
jsonText = JavaScriptConvert.SerializeXmlNode(instruction);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
// XmlProcessingInstruction
XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
jsonText = JavaScriptConvert.SerializeXmlNode(cDataSection);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
// XmlElement
XmlElement element = doc.CreateElement("xs:Choice");
element.SetAttributeNode(attribute);
element.AppendChild(instruction);
element.AppendChild(cDataSection);
jsonText = JavaScriptConvert.SerializeXmlNode(element);
Console.WriteLine(jsonText);
Assert.AreEqual(@"{""xs:Choice"":{""@msdata:IsDataSet"":""true"",""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\"""",""#cdata-section"":""<Kiwi>true</Kiwi>""}}", jsonText);
}
[Test]
public void DocumentFragmentSerialize()
{
XmlDocument doc = new XmlDocument();
XmlDocumentFragment fragement = doc.CreateDocumentFragment();
fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
string jsonText = JavaScriptConvert.SerializeXmlNode(fragement);
string expected = @"{""Item"":[""widget"",""widget""]}";
Assert.AreEqual(expected, jsonText);
Console.WriteLine("DocumentFragmentSerialize");
Console.WriteLine(jsonText);
Console.WriteLine();
}
[Test]
public void NamespaceSerializeDeserialize()
{
string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<xs:schema xs:id=""SomeID""
xmlns=""""
xmlns:xs=""http://www.w3.org/2001/XMLSchema""
xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
<xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
<xs:complexType>
<xs:choice maxOccurs=""unbounded"">
<xs:element name=""customers"" >
<xs:complexType >
<xs:sequence>
<xs:element name=""CustomerID"" type=""xs:integer""
minOccurs=""0"" />
<xs:element name=""CompanyName"" type=""xs:string""
minOccurs=""0"" />
<xs:element name=""Phone"" type=""xs:string"" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
XmlDocument deserializedDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
Console.WriteLine("NamespaceSerializeDeserialize");
Console.WriteLine(jsonText);
Console.WriteLine(deserializedDoc.InnerXml);
Console.WriteLine();
}
[Test]
public void DocumentDeserialize()
{
string jsonText = @"{
""?xml"": {
""@version"": ""1.0"",
""@standalone"": ""no""
},
""span"": {
""@class"": ""vevent"",
""a"": {
""@class"": ""url"",
""@href"": ""http://www.web2con.com/"",
""span"": {
""@class"": ""summary"",
""#text"": ""Web 2.0 Conference"",
""#cdata-section"": ""my escaped text""
}
}
}
}";
XmlDocument doc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
string expected = @"<?xml version=""1.0"" standalone=""no""?>
<span class=""vevent"">
<a class=""url"" href=""http://www.web2con.com/"">
<span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
</a>
</span>";
string formattedXml = GetIndentedInnerXml(doc);
Console.WriteLine("DocumentDeserialize");
Console.WriteLine(formattedXml);
Console.WriteLine();
Assert.AreEqual(expected, formattedXml);
}
private string GetIndentedInnerXml(XmlNode node)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
StringWriter sw = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
node.WriteTo(writer);
}
return sw.ToString();
}
[Test]
public void SingleTextNode()
{
string xml = @"<?xml version=""1.0"" standalone=""no""?>
<root>
<person id=""1"">
<name>Alan</name>
<url>http://www.google.com</url>
</person>
<person id=""2"">
<name>Louis</name>
<url>http://www.yahoo.com</url>
</person>
</root>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
}
[Test]
public void EmptyNode()
{
string xml = @"<?xml version=""1.0"" standalone=""no""?>
<root>
<person id=""1"">
<name>Alan</name>
<url />
</person>
<person id=""2"">
<name>Louis</name>
<url>http://www.yahoo.com</url>
</person>
</root>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
Console.WriteLine(jsonText);
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
}
[Test]
public void OtherElementDataTypes()
{
string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":new Date(954374400000)}]}}";
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
string expected = @"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><Float>2.5</Float><Integer>99</Integer></person><person id=""2""><Boolean>true</Boolean><date>2000-03-30T00:00:00.0000000+12:00</date></person></root>";
Assert.AreEqual(expected, newDoc.InnerXml);
}
}
}
+44
View File
@@ -0,0 +1,44 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json", "Newtonsoft.Json\Newtonsoft.Json.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{620042D9-2753-48F5-BEDE-3905248781D2}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(SolutionItems) = preProject
Lib\nunit.framework.dll = Lib\nunit.framework.dll
Lib\nunit.framework.xml = Lib\nunit.framework.xml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.csproj", "{3E6E2335-B079-4B5B-A65A-9D586914BCBB}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
{3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,59 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace Newtonsoft.Json.Converters
{
public class AspNetAjaxDateTimeConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value)
{
DateTime dateTime = (DateTime)value;
long javaScriptTicks = JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(dateTime);
writer.WriteValue("@" + javaScriptTicks.ToString(null, CultureInfo.InvariantCulture) + "@");
}
public override object ReadJson(JsonReader reader, Type objectType)
{
string dateTimeText = (string)reader.Value;
dateTimeText = dateTimeText.Substring(1, dateTimeText.Length - 2);
long javaScriptTicks = Convert.ToInt64(dateTimeText);
return JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
}
public override bool CanConvert(Type valueType)
{
return typeof(DateTime).IsAssignableFrom(valueType);
}
}
}
@@ -0,0 +1,45 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace Newtonsoft.Json.Converters
{
public class HtmlColorConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value)
{
writer.WriteValue(ColorTranslator.ToHtml((Color)value));
}
public override bool CanConvert(Type valueType)
{
return typeof(Color).IsAssignableFrom(valueType);
}
}
}
@@ -0,0 +1,472 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Xml;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Converters
{
public class XmlNodeConverter : JsonConverter
{
private const string TextName = "#text";
private const string CommentName = "#comment";
private const string CDataName = "#cdata-section";
private const string WhitespaceName = "#whitespace";
private const string SignificantWhitespaceName = "#significant-whitespace";
private const string DeclarationName = "?xml";
#region Writing
public override void WriteJson(JsonWriter writer, object value)
{
XmlNode node = value as XmlNode;
if (node == null)
throw new ArgumentException("Value must be an XmlNode", "value");
writer.WriteStartObject();
SerializeNode(writer, node, true);
writer.WriteEndObject();
}
private string GetPropertyName(XmlNode node)
{
switch (node.NodeType)
{
case XmlNodeType.Attribute:
return "@" + node.Name;
case XmlNodeType.CDATA:
return CDataName;
case XmlNodeType.Comment:
return CommentName;
case XmlNodeType.Element:
return node.Name;
case XmlNodeType.ProcessingInstruction:
return "?" + node.Name;
case XmlNodeType.XmlDeclaration:
return DeclarationName;
case XmlNodeType.SignificantWhitespace:
return SignificantWhitespaceName;
case XmlNodeType.Text:
return TextName;
case XmlNodeType.Whitespace:
return WhitespaceName;
default:
throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType);
}
}
private void SerializeGroupedNodes(JsonWriter writer, XmlNode node)
{
// group nodes together by name
Dictionary<string, List<XmlNode>> nodesGroupedByName = new Dictionary<string, List<XmlNode>>();
for (int i = 0; i < node.ChildNodes.Count; i++)
{
XmlNode childNode = node.ChildNodes[i];
string nodeName = GetPropertyName(childNode);
List<XmlNode> nodes;
if (!nodesGroupedByName.TryGetValue(nodeName, out nodes))
{
nodes = new List<XmlNode>();
nodesGroupedByName.Add(nodeName, nodes);
}
nodes.Add(childNode);
}
// loop through grouped nodes. write single name instances as normal,
// write multiple names together in an array
foreach (KeyValuePair<string, List<XmlNode>> nodeNameGroup in nodesGroupedByName)
{
List<XmlNode> groupedNodes = nodeNameGroup.Value;
if (groupedNodes.Count == 1)
{
SerializeNode(writer, groupedNodes[0], true);
}
else
{
writer.WritePropertyName(nodeNameGroup.Key);
writer.WriteStartArray();
for (int i = 0; i < groupedNodes.Count; i++)
{
SerializeNode(writer, groupedNodes[i], false);
}
writer.WriteEndArray();
}
}
}
private void SerializeNode(JsonWriter writer, XmlNode node, bool writePropertyName)
{
switch (node.NodeType)
{
case XmlNodeType.Document:
case XmlNodeType.DocumentFragment:
SerializeGroupedNodes(writer, node);
break;
case XmlNodeType.Element:
if (writePropertyName)
writer.WritePropertyName(node.Name);
if (CollectionUtils.IsNullOrEmpty(node.Attributes) && node.ChildNodes.Count == 1
&& node.ChildNodes[0].NodeType == XmlNodeType.Text)
{
// write elements with a single text child as a name value pair
writer.WriteValue(node.ChildNodes[0].Value);
}
else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
{
// empty element
writer.WriteNull();
}
else
{
writer.WriteStartObject();
for (int i = 0; i < node.Attributes.Count; i++)
{
SerializeNode(writer, node.Attributes[i], true);
}
SerializeGroupedNodes(writer, node);
writer.WriteEndObject();
}
break;
case XmlNodeType.Comment:
if (writePropertyName)
writer.WriteComment(node.Value);
break;
case XmlNodeType.Attribute:
case XmlNodeType.Text:
case XmlNodeType.CDATA:
case XmlNodeType.ProcessingInstruction:
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
if (writePropertyName)
writer.WritePropertyName(GetPropertyName(node));
writer.WriteValue(node.Value);
break;
case XmlNodeType.XmlDeclaration:
XmlDeclaration declaration = (XmlDeclaration)node;
writer.WritePropertyName(GetPropertyName(node));
writer.WriteStartObject();
if (!string.IsNullOrEmpty(declaration.Version))
{
writer.WritePropertyName("@version");
writer.WriteValue(declaration.Version);
}
if (!string.IsNullOrEmpty(declaration.Encoding))
{
writer.WritePropertyName("@encoding");
writer.WriteValue(declaration.Encoding);
}
if (!string.IsNullOrEmpty(declaration.Standalone))
{
writer.WritePropertyName("@standalone");
writer.WriteValue(declaration.Standalone);
}
writer.WriteEndObject();
break;
default:
throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
}
}
#endregion
#region Reading
public override object ReadJson(JsonReader reader, Type objectType)
{
// maybe have CanReader and a CanWrite methods so this sort of test wouldn't be necessary
if (objectType != typeof(XmlDocument))
throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments");
XmlDocument document = new XmlDocument();
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
reader.Read();
DeserializeNode(reader, document, manager, document);
return document;
}
private void DeserializeValue(JsonReader reader, XmlDocument document, XmlNamespaceManager manager, string propertyName, XmlNode currentNode)
{
switch (propertyName)
{
case TextName:
currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
break;
case CDataName:
currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
break;
case WhitespaceName:
currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
break;
case SignificantWhitespaceName:
currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
break;
default:
// processing instructions and the xml declaration start with ?
if (propertyName[0] == '?')
{
if (propertyName == DeclarationName)
{
string version = null;
string encoding = null;
string standalone = null;
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
{
switch (reader.Value.ToString())
{
case "@version":
reader.Read();
version = reader.Value.ToString();
break;
case "@encoding":
reader.Read();
encoding = reader.Value.ToString();
break;
case "@standalone":
reader.Read();
standalone = reader.Value.ToString();
break;
default:
throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
}
}
XmlDeclaration declaration = document.CreateXmlDeclaration(version, encoding, standalone);
currentNode.AppendChild(declaration);
}
else
{
XmlProcessingInstruction instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
currentNode.AppendChild(instruction);
}
}
else
{
// deserialize xml element
bool finishedAttributes = false;
bool finishedElement = false;
string elementPrefix = GetPrefix(propertyName);
Dictionary<string, string> attributeNameValues = new Dictionary<string, string>();
// a string token means the element only has a single text child
if (reader.TokenType != JsonToken.String
&& reader.TokenType != JsonToken.Null
&& reader.TokenType != JsonToken.Boolean
&& reader.TokenType != JsonToken.Integer
&& reader.TokenType != JsonToken.Float
&& reader.TokenType != JsonToken.Date)
{
// read properties until first non-attribute is encountered
while (!finishedAttributes && !finishedElement && reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string attributeName = reader.Value.ToString();
if (attributeName[0] == '@')
{
attributeName = attributeName.Substring(1);
reader.Read();
string attributeValue = reader.Value.ToString();
attributeNameValues.Add(attributeName, attributeValue);
string namespacePrefix;
if (IsNamespaceAttribute(attributeName, out namespacePrefix))
{
manager.AddNamespace(namespacePrefix, attributeValue);
}
}
else
{
finishedAttributes = true;
}
break;
case JsonToken.EndObject:
finishedElement = true;
break;
default:
throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
}
}
}
// have to wait until attributes have been parsed before creating element
// attributes may contain namespace info used by the element
XmlElement element = (!string.IsNullOrEmpty(elementPrefix))
? document.CreateElement(propertyName, manager.LookupNamespace(elementPrefix))
: document.CreateElement(propertyName);
currentNode.AppendChild(element);
// add attributes to newly created element
foreach (KeyValuePair<string, string> nameValue in attributeNameValues)
{
string attributePrefix = GetPrefix(nameValue.Key);
XmlAttribute attribute = (!string.IsNullOrEmpty(attributePrefix))
? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix))
: document.CreateAttribute(nameValue.Key);
attribute.Value = nameValue.Value;
element.SetAttributeNode(attribute);
}
if (reader.TokenType == JsonToken.String)
{
element.AppendChild(document.CreateTextNode(reader.Value.ToString()));
}
else if (reader.TokenType == JsonToken.Integer)
{
element.AppendChild(document.CreateTextNode(XmlConvert.ToString((long)reader.Value)));
}
else if (reader.TokenType == JsonToken.Float)
{
element.AppendChild(document.CreateTextNode(XmlConvert.ToString((double)reader.Value)));
}
else if (reader.TokenType == JsonToken.Boolean)
{
element.AppendChild(document.CreateTextNode(XmlConvert.ToString((bool)reader.Value)));
}
else if (reader.TokenType == JsonToken.Date)
{
element.AppendChild(document.CreateTextNode(XmlConvert.ToString((DateTime)reader.Value)));
}
else if (reader.TokenType == JsonToken.Null)
{
// empty element. do nothing
}
else
{
// finished element will have no children to deserialize
if (!finishedElement)
{
manager.PushScope();
DeserializeNode(reader, document, manager, element);
manager.PopScope();
}
}
}
break;
}
}
private void DeserializeNode(JsonReader reader, XmlDocument document, XmlNamespaceManager manager, XmlNode currentNode)
{
do
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string propertyName = reader.Value.ToString();
reader.Read();
if (reader.TokenType == JsonToken.StartArray)
{
while (reader.Read() && reader.TokenType != JsonToken.EndArray)
{
DeserializeValue(reader, document, manager, propertyName, currentNode);
}
}
else
{
DeserializeValue(reader, document, manager, propertyName, currentNode);
}
break;
//case JsonToken.String:
// DeserializeValue(reader, document, manager, TextName, currentNode);
// break;
case JsonToken.EndObject:
case JsonToken.EndArray:
return;
default:
throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
}
} while (reader.TokenType == JsonToken.PropertyName || reader.Read());
// don't read if current token is a property. token was already read when parsing element attributes
}
/// <summary>
/// Checks if the attributeName is a namespace attribute.
/// </summary>
/// <param name="attributeName">Attribute name to test.</param>
/// <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
/// <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
private bool IsNamespaceAttribute(string attributeName, out string prefix)
{
if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
{
if (attributeName.Length == 5)
{
prefix = string.Empty;
return true;
}
else if (attributeName[5] == ':')
{
prefix = attributeName.Substring(6, attributeName.Length - 6);
return true;
}
}
prefix = null;
return false;
}
private string GetPrefix(string qualifiedName)
{
int colonPosition = qualifiedName.IndexOf(':');
if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition)
return string.Empty;
else
return qualifiedName.Substring(0, colonPosition);
}
#endregion
public override bool CanConvert(Type valueType)
{
return typeof(XmlNode).IsAssignableFrom(valueType);
}
}
}
+102
View File
@@ -0,0 +1,102 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Newtonsoft.Json
{
public class Identifier
{
private string _name;
public string Name
{
get { return _name; }
}
public Identifier(string name)
{
_name = name;
}
private static bool IsAsciiLetter(char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
public override bool Equals(object obj)
{
Identifier function = obj as Identifier;
return Equals(function);
}
public bool Equals(Identifier function)
{
return (_name == function.Name);
}
public static bool Equals(Identifier a, Identifier b)
{
if (a == b)
return true;
if (a != null && b != null)
return a.Equals(b);
return false;
}
public override int GetHashCode()
{
return _name.GetHashCode();
}
public override string ToString()
{
return _name;
}
public static bool operator ==(Identifier a, Identifier b)
{
return Identifier.Equals(a, b);
}
public static bool operator !=(Identifier a, Identifier b)
{
return !Identifier.Equals(a, b);
}
}
}
+64
View File
@@ -0,0 +1,64 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Represents a JavaScript array.
/// </summary>
public class JavaScriptArray : List<object>
{
/// <summary>
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class.
/// </summary>
public JavaScriptArray()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JavaScriptArray"/> class that
/// contains elements copied from the specified collection.
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new array.</param>
public JavaScriptArray(IEnumerable<object> collection)
: base(collection)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JavaScriptArray"/> class that
/// is empty and has the specified initial capacity.
/// </summary>
/// <param name="capacity">The number of elements that the new array can initially store.</param>
public JavaScriptArray(int capacity)
: base(capacity)
{
}
}
}
@@ -0,0 +1,81 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Represents a JavaScript constructor.
/// </summary>
public class JavaScriptConstructor
{
private string _name;
private JavaScriptParameters _parameters;
public JavaScriptParameters Parameters
{
get { return _parameters; }
}
public string Name
{
get { return _name; }
}
public JavaScriptConstructor(string name, JavaScriptParameters parameters)
{
if (name == null)
throw new ArgumentNullException("name");
if (name.Length == 0)
throw new ArgumentException("Constructor name cannot be empty.", "name");
_name = name;
_parameters = parameters ?? JavaScriptParameters.Empty;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("new ");
sb.Append(_name);
sb.Append("(");
if (_parameters != null)
{
for (int i = 0; i < _parameters.Count; i++)
{
sb.Append(_parameters[i]);
}
}
sb.Append(")");
return sb.ToString();
}
}
}
+448
View File
@@ -0,0 +1,448 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Web.UI.WebControls;
using System.Collections;
using System.IO;
using System.Globalization;
using System.Runtime.Serialization;
using System.Reflection;
using System.Data.SqlTypes;
using Newtonsoft.Json.Utilities;
using System.Xml;
using Newtonsoft.Json.Converters;
namespace Newtonsoft.Json
{
/// <summary>
/// Provides methods for converting between common language runtime types and JavaScript types.
/// </summary>
public static class JavaScriptConvert
{
/// <summary>
/// Represents JavaScript's boolean value true as a string. This field is read-only.
/// </summary>
public static readonly string True;
/// <summary>
/// Represents JavaScript's boolean value false as a string. This field is read-only.
/// </summary>
public static readonly string False;
/// <summary>
/// Represents JavaScript's null as a string. This field is read-only.
/// </summary>
public static readonly string Null;
/// <summary>
/// Represents JavaScript's undefined as a string. This field is read-only.
/// </summary>
public static readonly string Undefined;
internal static long InitialJavaScriptDateTicks;
internal static DateTime MinimumJavaScriptDate;
static JavaScriptConvert()
{
True = "true";
False = "false";
Null = "null";
Undefined = "undefined";
InitialJavaScriptDateTicks = (new DateTime(1970, 1, 1)).Ticks;
MinimumJavaScriptDate = new DateTime(100, 1, 1);
}
/// <summary>
/// Converts the <see cref="DateTime"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="DateTime"/>.</returns>
public static string ToString(DateTime value)
{
long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value);
return "new Date(" + javaScriptTicks + ")";
}
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
{
if (dateTime < MinimumJavaScriptDate)
dateTime = MinimumJavaScriptDate;
long javaScriptTicks = (dateTime.Ticks - InitialJavaScriptDateTicks) / (long)10000;
return javaScriptTicks;
}
internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
{
DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks);
return dateTime;
}
/// <summary>
/// Converts the <see cref="Boolean"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Boolean"/>.</returns>
public static string ToString(bool value)
{
return (value) ? True : False;
}
/// <summary>
/// Converts the <see cref="Char"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Char"/>.</returns>
public static string ToString(char value)
{
return ToString(char.ToString(value));
}
/// <summary>
/// Converts the <see cref="Enum"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Enum"/>.</returns>
public static string ToString(Enum value)
{
return value.ToString();
}
/// <summary>
/// Converts the <see cref="Int32"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Int32"/>.</returns>
public static string ToString(int value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Int16"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Int16"/>.</returns>
public static string ToString(short value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="UInt16"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="UInt16"/>.</returns>
public static string ToString(ushort value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="UInt32"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="UInt32"/>.</returns>
public static string ToString(uint value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Int64"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Int64"/>.</returns>
public static string ToString(long value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="UInt64"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="UInt64"/>.</returns>
public static string ToString(ulong value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Single"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Single"/>.</returns>
public static string ToString(float value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Double"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Double"/>.</returns>
public static string ToString(double value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Byte"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Byte"/>.</returns>
public static string ToString(byte value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="SByte"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="SByte"/>.</returns>
public static string ToString(sbyte value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Decimal"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="SByte"/>.</returns>
public static string ToString(decimal value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the <see cref="Guid"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Guid"/>.</returns>
public static string ToString(Guid value)
{
return '"' + value.ToString("D", CultureInfo.InvariantCulture) + '"';
}
/// <summary>
/// Converts the <see cref="String"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="String"/>.</returns>
public static string ToString(string value)
{
return ToString(value, '"');
}
/// <summary>
/// Converts the <see cref="String"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <param name="delimter">The string delimiter character.</param>
/// <returns>A Json string representation of the <see cref="String"/>.</returns>
public static string ToString(string value, char delimter)
{
return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, true);
}
/// <summary>
/// Converts the <see cref="Object"/> to it's JavaScript string representation.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>A Json string representation of the <see cref="Object"/>.</returns>
public static string ToString(object value)
{
if (value == null)
{
return Null;
}
else if (value is IConvertible)
{
IConvertible convertible = value as IConvertible;
switch (convertible.GetTypeCode())
{
case TypeCode.String:
return ToString((string)convertible);
case TypeCode.Char:
return ToString((char)convertible);
case TypeCode.Boolean:
return ToString((bool)convertible);
case TypeCode.SByte:
return ToString((sbyte)convertible);
case TypeCode.Int16:
return ToString((short)convertible);
case TypeCode.UInt16:
return ToString((ushort)convertible);
case TypeCode.Int32:
return ToString((int)convertible);
case TypeCode.Byte:
return ToString((byte)convertible);
case TypeCode.UInt32:
return ToString((uint)convertible);
case TypeCode.Int64:
return ToString((long)convertible);
case TypeCode.UInt64:
return ToString((ulong)convertible);
case TypeCode.Single:
return ToString((float)convertible);
case TypeCode.Double:
return ToString((double)convertible);
case TypeCode.DateTime:
return ToString((DateTime)convertible);
case TypeCode.Decimal:
return ToString((decimal)convertible);
}
}
throw new ArgumentException(string.Format("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.", value.GetType()));
}
/// <summary>
/// Serializes the specified object to a Json object.
/// </summary>
/// <param name="value">The object to serialize.</param>
/// <returns>A Json string representation of the object.</returns>
public static string SerializeObject(object value)
{
return SerializeObject(value, null);
}
public static string SerializeObject(object value, params JsonConverter[] converters)
{
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
JsonSerializer jsonSerializer = new JsonSerializer();
if (!CollectionUtils.IsNullOrEmpty<JsonConverter>(converters))
{
for (int i = 0; i < converters.Length; i++)
{
jsonSerializer.Converters.Add(converters[i]);
}
}
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
//jsonWriter.Formatting = Formatting.Indented;
jsonSerializer.Serialize(jsonWriter, value);
}
return sw.ToString();
}
/// <summary>
/// Deserializes the specified object to a Json object.
/// </summary>
/// <param name="value">The object to deserialize.</param>
/// <returns>The deserialized object from the Json string.</returns>
public static object DeserializeObject(string value)
{
return DeserializeObject(value, null, null);
}
/// <summary>
/// Deserializes the specified object to a Json object.
/// </summary>
/// <param name="value">The object to deserialize.</param>
/// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
/// <returns>The deserialized object from the Json string.</returns>
public static object DeserializeObject(string value, Type type)
{
return DeserializeObject(value, type, null);
}
/// <summary>
/// Deserializes the specified object to a Json object.
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="value">The object to deserialize.</param>
/// <returns>The deserialized object from the Json string.</returns>
public static T DeserializeObject<T>(string value)
{
return DeserializeObject<T>(value, null);
}
/// <summary>
/// Deserializes the specified object to a Json object.
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="value">The object to deserialize.</param>
/// <param name="converters">Converters to use while deserializing.</param>
/// <returns>The deserialized object from the Json string.</returns>
public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
{
return (T)DeserializeObject(value, typeof(T), converters);
}
public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
{
StringReader sr = new StringReader(value);
JsonSerializer jsonSerializer = new JsonSerializer();
if (!CollectionUtils.IsNullOrEmpty<JsonConverter>(converters))
{
for (int i = 0; i < converters.Length; i++)
{
jsonSerializer.Converters.Add(converters[i]);
}
}
object deserializedValue;
using (JsonReader jsonReader = new JsonReader(sr))
{
deserializedValue = jsonSerializer.Deserialize(jsonReader, type);
}
return deserializedValue;
}
public static string SerializeXmlNode(XmlNode node)
{
XmlNodeConverter converter = new XmlNodeConverter();
return SerializeObject(node, converter);
}
public static XmlNode DeerializeXmlNode(string value)
{
XmlNodeConverter converter = new XmlNodeConverter();
return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), converter);
}
}
}
+55
View File
@@ -0,0 +1,55 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Represents a JavaScript object.
/// </summary>
public class JavaScriptObject : Dictionary<string, object>
{
/// <summary>
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class.
/// </summary>
public JavaScriptObject()
: base(EqualityComparer<string>.Default)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JavaScriptObject"/> class that
/// contains values copied from the specified <see cref="JavaScriptObject"/>.
/// </summary>
/// <param name="javaScriptObject">The <see cref="JavaScriptObject"/> whose elements are copied to the new object.</param>
public JavaScriptObject(JavaScriptObject javaScriptObject)
: base(javaScriptObject, EqualityComparer<string>.Default)
{
}
}
}
@@ -0,0 +1,42 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace Newtonsoft.Json
{
public class JavaScriptParameters : ReadOnlyCollection<object>
{
public static readonly JavaScriptParameters Empty = new JavaScriptParameters(new List<object>());
public JavaScriptParameters(IList<object> list)
: base(list)
{
}
}
}
+48
View File
@@ -0,0 +1,48 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
public abstract class JsonConverter
{
public virtual void WriteJson(JsonWriter writer, object value)
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, value);
}
public virtual object ReadJson(JsonReader reader, Type objectType)
{
throw new NotImplementedException(string.Format("{0} has not overriden FromJson method.", GetType().Name));
}
public abstract bool CanConvert(Type objectType);
}
}
@@ -0,0 +1,36 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace Newtonsoft.Json
{
public class JsonConverterCollection : Collection<JsonConverter>
{
}
}
+63
View File
@@ -0,0 +1,63 @@
using System;
using System.Web;
using System.Web.Caching;
using System.Xml;
using System.Text;
using System.Security.Principal;
namespace Newtonsoft.Json
{
public abstract class JsonHandler : HandlerBase, IHttpHandler
{
public event EventHandler Error;
protected abstract void WriteResult(JsonWriter writer);
public static void JsonResponse(HttpResponse response, Action<JsonWriter> writeAction)
{
response.ClearHeaders();
response.ClearContent();
JsonWriter writer = new JsonWriter(response.Output);
writeAction(writer);
writer.Flush();
}
protected virtual void OnError(EventArgs e)
{
if (Error != null)
{
Error(this, e);
}
}
void IHttpHandler.ProcessRequest(HttpContext context)
{
if (context == null)
throw new ArgumentNullException("context");
Context = context;
try
{
JsonHandler.JsonResponse(context.Response, new Action<JsonWriter>(WriteResult));
}
catch (Exception exception)
{
context.AddError(exception);
OnError(EventArgs.Empty);
if (context.Error != null)
{
throw new HttpUnhandledException("blah", exception);
}
}
}
bool IHttpHandler.IsReusable
{
get { return false; }
}
}
}
@@ -0,0 +1,36 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public sealed class JsonIgnoreAttribute : Attribute
{
}
}
@@ -0,0 +1,21 @@
using System;
namespace Newtonsoft.Json
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public sealed class JsonPropertyAttribute : Attribute
{
private string _propertyName;
public string PropertyName
{
get { return _propertyName; }
set { _propertyName = value; }
}
public JsonPropertyAttribute(string propertyName)
{
_propertyName = propertyName;
}
}
}
+897
View File
@@ -0,0 +1,897 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Globalization;
namespace Newtonsoft.Json
{
/// <summary>
/// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
/// </summary>
public class JsonReader : IDisposable
{
private enum State
{
Start,
Complete,
Property,
ObjectStart,
Object,
ArrayStart,
Array,
Closed,
PostValue,
Constructor,
ConstructorEnd,
Error,
Finished
}
private TextReader _reader;
private char _currentChar;
// current Token data
private JsonToken _token;
private object _value;
private Type _valueType;
private char _quoteChar;
private StringBuffer _buffer;
//private StringBuilder _testBuffer;
private State _currentState;
private int _top;
private List<JsonType> _stack;
/// <summary>
/// Gets the quotation mark character used to enclose the value of a string.
/// </summary>
public char QuoteChar
{
get { return _quoteChar; }
}
/// <summary>
/// Gets the type of the current Json token.
/// </summary>
public JsonToken TokenType
{
get { return _token; }
}
/// <summary>
/// Gets the text value of the current Json token.
/// </summary>
public object Value
{
get { return _value; }
}
/// <summary>
/// Gets The Common Language Runtime (CLR) type for the current Json token.
/// </summary>
public Type ValueType
{
get { return _valueType; }
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
/// </summary>
/// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
public JsonReader(TextReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
_reader = reader;
_buffer = new StringBuffer(4096);
//_testBuffer = new StringBuilder();
_currentState = State.Start;
_stack = new List<JsonType>();
_top = 0;
Push(JsonType.None);
}
private void Push(JsonType value)
{
_stack.Add(value);
_top++;
}
private JsonType Pop()
{
JsonType value = Peek();
_stack.RemoveAt(_stack.Count - 1);
_top--;
return value;
}
private JsonType Peek()
{
return _stack[_top - 1];
}
private void ParseString(char quote)
{
bool stringTerminated = false;
while (!stringTerminated && MoveNext())
{
switch (_currentChar)
{
//case 0:
//case 0x0A:
//case 0x0D:
// throw new JsonReaderException("Unterminated string");
case '\\':
if (MoveNext())
{
switch (_currentChar)
{
case 'b':
_buffer.Append('\b');
break;
case 't':
_buffer.Append('\t');
break;
case 'n':
_buffer.Append('\n');
break;
case 'f':
_buffer.Append('\f');
break;
case 'r':
_buffer.Append('\r');
break;
case 'u':
//_buffer.Append((char) Integer.parseInt(next(4), 16));
break;
case 'x':
//_buffer.Append((char) Integer.parseInt(next(2), 16));
break;
default:
_buffer.Append(_currentChar);
break;
}
}
else
{
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
}
break;
case '"':
case '\'':
if (_currentChar == quote)
stringTerminated = true;
else
goto default;
break;
default:
_buffer.Append(_currentChar);
break;
}
}
if (!stringTerminated)
throw new JsonReaderException("Unterminated string. Expected delimiter: " + quote);
ClearCurrentChar();
_currentState = State.PostValue;
_token = JsonToken.String;
_value = _buffer.ToString();
_buffer.Position = 0;
_valueType = typeof(string);
_quoteChar = quote;
}
private bool MoveNext()
{
int value = _reader.Read();
if (value != -1)
{
_currentChar = (char)value;
//_testBuffer.Append(_currentChar);
return true;
}
else
{
return false;
}
}
private bool HasNext()
{
return (_reader.Peek() != -1);
}
private char PeekNext()
{
return (char)_reader.Peek();
}
private void ClearCurrentChar()
{
_currentChar = '\0';
}
private bool MoveTo(char value)
{
while (MoveNext())
{
if (_currentChar == value)
return true;
}
return false;
}
/// <summary>
/// Reads the next Json token from the stream.
/// </summary>
/// <returns></returns>
public bool Read()
{
while (true)
{
if (_currentChar == '\0')
{
if (!MoveNext())
return false;
}
switch (_currentState)
{
case State.Start:
case State.Property:
case State.Array:
case State.ArrayStart:
return ParseValue();
case State.Complete:
break;
case State.Object:
case State.ObjectStart:
return ParseObject();
case State.PostValue:
// returns true if it hits
// end of object or array
if (ParsePostValue())
return true;
break;
case State.Closed:
break;
case State.Error:
break;
default:
throw new JsonReaderException("Unexpected state: " + _currentState);
}
}
}
private bool ParsePostValue()
{
do
{
switch (_currentChar)
{
case '}':
SetToken(JsonToken.EndObject);
ClearCurrentChar();
return true;
case ']':
SetToken(JsonToken.EndArray);
ClearCurrentChar();
return true;
case '/':
ParseComment();
return true;
case ',':
// finished paring
SetStateBasedOnCurrent();
ClearCurrentChar();
return false;
default:
if (char.IsWhiteSpace(_currentChar))
{
// eat whitespace
ClearCurrentChar();
}
else
{
throw new JsonReaderException("After parsing a value an unexpected character was encoutered: " + _currentChar);
}
break;
}
} while (MoveNext());
return false;
}
private bool ParseObject()
{
do
{
switch (_currentChar)
{
case '}':
SetToken(JsonToken.EndObject);
return true;
case '/':
ParseComment();
return true;
case ',':
SetToken(JsonToken.Undefined);
return true;
default:
if (char.IsWhiteSpace(_currentChar))
{
// eat
}
else
{
return ParseProperty();
}
break;
}
} while (MoveNext());
return false;
}
private bool ParseProperty()
{
if (ValidIdentifierChar(_currentChar))
{
ParseUnquotedProperty();
}
else if (_currentChar == '"' || _currentChar == '\'')
{
ParseQuotedProperty(_currentChar);
}
else
{
throw new JsonReaderException("Invalid property identifier character: " + _currentChar);
}
// finished property. move to colon
if (_currentChar != ':')
{
MoveTo(':');
}
SetToken(JsonToken.PropertyName, _buffer.ToString());
_buffer.Position = 0;
return true;
}
private void ParseQuotedProperty(char quoteChar)
{
// parse property name until quoted char is hit
while (MoveNext())
{
if (_currentChar == quoteChar)
{
return;
}
else
{
_buffer.Append(_currentChar);
}
}
throw new JsonReaderException("Unclosed quoted property. Expected: " + quoteChar);
}
private bool ValidIdentifierChar(char value)
{
return (char.IsLetterOrDigit(_currentChar) || _currentChar == '_' || _currentChar == '$');
}
private void ParseUnquotedProperty()
{
// parse unquoted property name until whitespace or colon
_buffer.Append(_currentChar);
while (MoveNext())
{
if (char.IsWhiteSpace(_currentChar) || _currentChar == ':')
{
break;
}
else if (ValidIdentifierChar(_currentChar))
{
_buffer.Append(_currentChar);
}
else
{
throw new JsonReaderException("Invalid JavaScript property identifier character: " + _currentChar);
}
}
}
private void SetToken(JsonToken newToken)
{
SetToken(newToken, null);
}
private void SetToken(JsonToken newToken, object value)
{
_token = newToken;
switch (newToken)
{
case JsonToken.StartObject:
_currentState = State.ObjectStart;
Push(JsonType.Object);
ClearCurrentChar();
break;
case JsonToken.StartArray:
_currentState = State.ArrayStart;
Push(JsonType.Array);
ClearCurrentChar();
break;
case JsonToken.EndObject:
ValidateEnd(JsonToken.EndObject);
ClearCurrentChar();
_currentState = State.PostValue;
break;
case JsonToken.EndArray:
ValidateEnd(JsonToken.EndArray);
ClearCurrentChar();
_currentState = State.PostValue;
break;
case JsonToken.PropertyName:
_currentState = State.Property;
ClearCurrentChar();
break;
case JsonToken.Undefined:
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Constructor:
case JsonToken.Date:
_currentState = State.PostValue;
break;
}
if (value != null)
{
_value = value;
_valueType = value.GetType();
}
else
{
_value = null;
_valueType = null;
}
}
private bool ParseValue()
{
do
{
switch (_currentChar)
{
case '"':
case '\'':
ParseString(_currentChar);
return true;
case 't':
ParseTrue();
return true;
case 'f':
ParseFalse();
return true;
case 'n':
if (HasNext())
{
char next = PeekNext();
if (next == 'u')
ParseNull();
else if (next == 'e')
ParseConstructor();
else
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
}
else
{
throw new JsonReaderException("Unexpected end");
}
return true;
case '/':
ParseComment();
return true;
case 'u':
ParseUndefined();
return true;
case '{':
SetToken(JsonToken.StartObject);
return true;
case '[':
SetToken(JsonToken.StartArray);
return true;
case '}':
SetToken(JsonToken.EndObject);
return true;
case ']':
SetToken(JsonToken.EndArray);
return true;
case ',':
SetToken(JsonToken.Undefined);
//ClearCurrentChar();
return true;
case ')':
if (_currentState == State.Constructor)
{
_currentState = State.ConstructorEnd;
return false;
}
else
{
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
}
default:
if (char.IsWhiteSpace(_currentChar))
{
// eat
}
else if (char.IsNumber(_currentChar) || _currentChar == '-' || _currentChar == '.')
{
ParseNumber();
return true;
}
else
{
throw new JsonReaderException("Unexpected character encountered while parsing value: " + _currentChar);
}
break;
}
} while (MoveNext());
return false;
}
private bool EatWhitespace(bool oneOrMore)
{
bool whitespace = false;
while (char.IsWhiteSpace(_currentChar))
{
whitespace = true;
MoveNext();
}
return (!oneOrMore || whitespace);
}
private void ParseConstructor()
{
if (MatchValue("new", true))
{
if (EatWhitespace(true))
{
while (char.IsLetter(_currentChar))
{
_buffer.Append(_currentChar);
MoveNext();
}
string constructorName = _buffer.ToString();
_buffer.Position = 0;
List<object> parameters = new List<object>();
EatWhitespace(false);
if (_currentChar == '(' && MoveNext())
{
_currentState = State.Constructor;
while (ParseValue())
{
parameters.Add(_value);
_currentState = State.Constructor;
}
if (string.CompareOrdinal(constructorName, "Date") == 0)
{
long javaScriptTicks = Convert.ToInt64(parameters[0]);
DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
SetToken(JsonToken.Date, date);
}
else
{
JavaScriptConstructor constructor = new JavaScriptConstructor(constructorName, new JavaScriptParameters(parameters));
if (_currentState == State.ConstructorEnd)
{
SetToken(JsonToken.Constructor, constructor);
}
}
// move past ')'
MoveNext();
}
}
}
}
private void ParseNumber()
{
// parse until seperator character or end
bool end = false;
do
{
if (CurrentIsSeperator())
end = true;
else
_buffer.Append(_currentChar);
} while (!end && MoveNext());
string number = _buffer.ToString();
object numberValue;
JsonToken numberType;
if (number.IndexOf('.') == -1)
{
numberValue = Convert.ToInt64(_buffer.ToString(), CultureInfo.InvariantCulture);
numberType = JsonToken.Integer;
}
else
{
numberValue = Convert.ToDouble(_buffer.ToString(), CultureInfo.InvariantCulture);
numberType = JsonToken.Float;
}
_buffer.Position = 0;
SetToken(numberType, numberValue);
}
private void ValidateEnd(JsonToken endToken)
{
JsonType currentObject = Pop();
if (GetTypeForCloseToken(endToken) != currentObject)
throw new JsonReaderException(string.Format("JsonToken {0} is not valid for closing JsonType {1}.", endToken, currentObject));
}
private void SetStateBasedOnCurrent()
{
JsonType currentObject = Peek();
switch (currentObject)
{
case JsonType.Object:
_currentState = State.Object;
break;
case JsonType.Array:
_currentState = State.Array;
break;
case JsonType.None:
_currentState = State.Finished;
break;
default:
throw new JsonReaderException("While setting the reader state back to current object an unexpected JsonType was encountered: " + currentObject);
}
}
private JsonType GetTypeForCloseToken(JsonToken token)
{
switch (token)
{
case JsonToken.EndObject:
return JsonType.Object;
case JsonToken.EndArray:
return JsonType.Array;
default:
throw new JsonReaderException("Not a valid close JsonToken: " + token);
}
}
private void ParseComment()
{
// should have already parsed / character before reaching this method
MoveNext();
if (_currentChar == '*')
{
while (MoveNext())
{
if (_currentChar == '*')
{
if (MoveNext())
{
if (_currentChar == '/')
{
break;
}
else
{
_buffer.Append('*');
_buffer.Append(_currentChar);
}
}
}
else
{
_buffer.Append(_currentChar);
}
}
}
else
{
throw new JsonReaderException("Error parsing comment. Expected: *");
}
SetToken(JsonToken.Comment, _buffer.ToString());
_buffer.Position = 0;
ClearCurrentChar();
}
private bool MatchValue(string value)
{
int i = 0;
do
{
if (_currentChar != value[i])
{
break;
}
i++;
}
while (i < value.Length && MoveNext());
return (i == value.Length);
}
private bool MatchValue(string value, bool noTrailingNonSeperatorCharacters)
{
// will match value and then move to the next character, checking that it is a seperator character
bool match = MatchValue(value);
if (!noTrailingNonSeperatorCharacters)
return match;
else
return (match && (!MoveNext() || CurrentIsSeperator()));
}
private bool CurrentIsSeperator()
{
switch (_currentChar)
{
case '}':
case ']':
case ',':
return true;
case '/':
// check next character to see if start of a comment
return (HasNext() && PeekNext() == '*');
case ')':
if (_currentState == State.Constructor)
return true;
break;
default:
if (char.IsWhiteSpace(_currentChar))
return true;
break;
}
return false;
}
private void ParseTrue()
{
// check characters equal 'true'
// and that it is followed by either a seperator character
// or the text ends
if (MatchValue(JavaScriptConvert.True, true))
{
SetToken(JsonToken.Boolean, true);
}
else
{
throw new JsonReaderException("Error parsing boolean value.");
}
}
private void ParseNull()
{
if (MatchValue(JavaScriptConvert.Null, true))
{
SetToken(JsonToken.Null);
}
else
{
throw new JsonReaderException("Error parsing null value.");
}
}
private void ParseUndefined()
{
if (MatchValue(JavaScriptConvert.Undefined, true))
{
SetToken(JsonToken.Undefined);
}
else
{
throw new JsonReaderException("Error parsing undefined value.");
}
}
private void ParseFalse()
{
if (MatchValue(JavaScriptConvert.False, true))
{
SetToken(JsonToken.Boolean, false);
}
else
{
throw new JsonReaderException("Error parsing boolean value.");
}
}
void IDisposable.Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (_currentState != State.Closed && disposing)
Close();
}
/// <summary>
/// Changes the <see cref="State"/> to Closed.
/// </summary>
public void Close()
{
_currentState = State.Closed;
_token = JsonToken.None;
_value = null;
_valueType = null;
if (_reader != null)
_reader.Close();
if (_buffer != null)
_buffer.Clear();
}
}
}
@@ -0,0 +1,65 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// The exception thrown when an error occurs while reading Json text.
/// </summary>
public class JsonReaderException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class.
/// </summary>
public JsonReaderException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class
/// with a specified error message.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public JsonReaderException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonReaderException"/> class
/// with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public JsonReaderException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}
@@ -0,0 +1,65 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// The exception thrown when an error occurs during Json serialization or deserialization.
/// </summary>
public class JsonSerializationException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonSerializationException"/> class.
/// </summary>
public JsonSerializationException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonSerializationException"/> class
/// with a specified error message.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public JsonSerializationException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonSerializationException"/> class
/// with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public JsonSerializationException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}
+649
View File
@@ -0,0 +1,649 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
using Newtonsoft.Json.Utilities;
using System.Globalization;
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies reference loop handling options for the <see cref="JsonWriter"/>.
/// </summary>
public enum ReferenceLoopHandling
{
/// <summary>
/// Throw a <see cref="JsonSerializationException"/> when a loop is encountered.
/// </summary>
Error = 0,
/// <summary>
/// Ignore loop references and do not serialize.
/// </summary>
Ignore = 1,
/// <summary>
/// Serialize loop references.
/// </summary>
Serialize = 2
}
/// <summary>
/// Serializes and deserializes objects into and from the Json format.
/// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into Json.
/// </summary>
public class JsonSerializer
{
private ReferenceLoopHandling _referenceLoopHandling;
private int _level;
private JsonConverterCollection _converters;
private Dictionary<Type, MemberMappingCollection> _typeMemberMappings;
/// <summary>
/// Get or set how reference loops (e.g. a class referencing itself) is handled.
/// </summary>
public ReferenceLoopHandling ReferenceLoopHandling
{
get { return _referenceLoopHandling; }
set
{
if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
{
throw new ArgumentOutOfRangeException("value");
}
_referenceLoopHandling = value;
}
}
public JsonConverterCollection Converters
{
get
{
if (_converters == null)
_converters = new JsonConverterCollection();
return _converters;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonSerializer"/> class.
/// </summary>
public JsonSerializer()
{
_referenceLoopHandling = ReferenceLoopHandling.Error;
}
#region Deserialize
/// <summary>
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> that contains the Json structure to deserialize.</param>
/// <returns>The <see cref="Object"/> being deserialized.</returns>
public object Deserialize(JsonReader reader)
{
return Deserialize(reader, null);
}
/// <summary>
/// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
/// into an instance of the specified type.
/// </summary>
/// <param name="reader">The type of object to create.</param>
/// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
/// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
public object Deserialize(JsonReader reader, Type objectType)
{
if (reader == null)
throw new ArgumentNullException("reader");
if (!reader.Read())
return null;
return GetObject(reader, objectType);
}
private JavaScriptArray PopulateJavaScriptArray(JsonReader reader)
{
JavaScriptArray jsArray = new JavaScriptArray();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.EndArray:
return jsArray;
case JsonToken.Comment:
break;
default:
object value = GetObject(reader, null);
jsArray.Add(value);
break;
}
}
throw new JsonSerializationException("Unexpected end while deserializing array.");
}
private JavaScriptObject PopulateJavaScriptObject(JsonReader reader)
{
JavaScriptObject jsObject = new JavaScriptObject();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string memberName = reader.Value.ToString();
// move to the value token. skip comments
do
{
if (!reader.Read())
throw new JsonSerializationException("Unexpected end while deserializing object.");
} while (reader.TokenType == JsonToken.Comment);
object value = GetObject(reader, null);
jsObject[memberName] = value;
break;
case JsonToken.EndObject:
return jsObject;
case JsonToken.Comment:
break;
default:
throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType);
}
}
throw new JsonSerializationException("Unexpected end while deserializing object.");
}
private object GetObject(JsonReader reader, Type objectType)
{
_level++;
object value;
JsonConverter converter;
if (HasMatchingConverter(objectType, out converter))
{
return converter.ReadJson(reader, objectType);
}
else
{
switch (reader.TokenType)
{
// populate a typed object or generic dictionary/array
// depending upon whether an objectType was supplied
case JsonToken.StartObject:
value = (objectType != null) ? PopulateObject(reader, objectType) : PopulateJavaScriptObject(reader);
break;
case JsonToken.StartArray:
value = (objectType != null) ? PopulateList(reader, objectType) : PopulateJavaScriptArray(reader);
break;
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Date:
value = EnsureType(reader.Value, objectType);
break;
case JsonToken.Constructor:
value = reader.Value.ToString();
break;
case JsonToken.Null:
case JsonToken.Undefined:
value = null;
break;
default:
throw new JsonSerializationException("Unexpected token whil deserializing object: " + reader.TokenType);
}
}
_level--;
return value;
}
private object EnsureType(object value, Type targetType)
{
// do something about null value when the targetType is a valuetype?
if (value == null)
return null;
if (targetType == null)
return value;
Type valueType = value.GetType();
// type of value and type of target don't match
// attempt to convert value's type to target's type
if (valueType != targetType)
{
TypeConverter targetConverter = TypeDescriptor.GetConverter(targetType);
if (!targetConverter.CanConvertFrom(valueType))
{
if (targetConverter.CanConvertFrom(typeof(string)))
{
string valueString = TypeDescriptor.GetConverter(value).ConvertToInvariantString(value);
return targetConverter.ConvertFromInvariantString(valueString);
}
if (!targetType.IsAssignableFrom(valueType))
throw new InvalidOperationException(string.Format("Cannot convert object of type '{0}' to type '{1}'", value.GetType(), targetType));
return value;
}
return targetConverter.ConvertFrom(null, CultureInfo.InvariantCulture, value);
}
else
{
return value;
}
}
private MemberMappingCollection GetMemberMappings(Type objectType)
{
if (_typeMemberMappings == null)
_typeMemberMappings = new Dictionary<Type, MemberMappingCollection>();
MemberMappingCollection memberMappings;
if (_typeMemberMappings.TryGetValue(objectType, out memberMappings))
return memberMappings;
memberMappings = CreateMemberMappings(objectType);
_typeMemberMappings[objectType] = memberMappings;
return memberMappings;
}
private MemberMappingCollection CreateMemberMappings(Type objectType)
{
List<MemberInfo> members = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.Instance);
MemberMappingCollection memberMappings = new MemberMappingCollection();
foreach (MemberInfo member in members)
{
string mappedName;
JsonPropertyAttribute propertyAttribute = ReflectionUtils.GetAttribute<JsonPropertyAttribute>(member, true);
if (propertyAttribute != null)
mappedName = propertyAttribute.PropertyName;
else
mappedName = member.Name;
bool ignored = member.IsDefined(typeof (JsonIgnoreAttribute), true);
bool readable = ReflectionUtils.CanReadMemberValue(member);
bool writable = ReflectionUtils.CanSetMemberValue(member);
MemberMapping memberMapping = new MemberMapping(mappedName, member, ignored, readable, writable);
memberMappings.AddMapping(memberMapping);
}
return memberMappings;
}
private void SetObjectMember(JsonReader reader, object target, Type targetType, string memberName)
{
if (!reader.Read())
throw new JsonSerializationException(string.Format("Unexpected end when setting {0}'s value.", memberName));
MemberMappingCollection memberMappings = GetMemberMappings(targetType);
Type memberType;
object value;
// test if a member with memberName exists on the type
// otherwise test if target is a dictionary and assign value with the key if it is
if (memberMappings.Contains(memberName))
{
MemberMapping memberMapping = memberMappings[memberName];
if (memberMapping.Ignored)
return;
// ignore member if it is readonly
if (!memberMapping.Writable)
return;
// get the member's underlying type
memberType = ReflectionUtils.GetMemberUnderlyingType(memberMapping.Member);
value = GetObject(reader, memberType);
ReflectionUtils.SetMemberValue(memberMapping.Member, target, value);
}
else if (typeof(IDictionary).IsAssignableFrom(targetType))
{
// attempt to get the IDictionary's type
memberType = ReflectionUtils.GetDictionaryValueType(target.GetType());
value = GetObject(reader, memberType);
((IDictionary)target).Add(memberName, value);
}
else
{
throw new JsonSerializationException(string.Format("Could not find member '{0}' on object of type '{1}'", memberName, targetType.GetType().Name));
}
}
private object PopulateList(JsonReader reader, Type objectType)
{
Type elementType = ReflectionUtils.GetListItemType(objectType);
IList populatedList = CollectionUtils.CreateAndPopulateList(objectType, delegate(IList list)
{
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.EndArray:
return;
case JsonToken.Comment:
break;
default:
object value = GetObject(reader, elementType);
list.Add(value);
break;
}
}
throw new JsonSerializationException("Unexpected end when deserializing array.");
});
return populatedList;
}
private object PopulateObject(JsonReader reader, Type objectType)
{
object newObject = Activator.CreateInstance(objectType);
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.PropertyName:
string memberName = reader.Value.ToString();
SetObjectMember(reader, newObject, objectType, memberName);
break;
case JsonToken.EndObject:
return newObject;
default:
throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
}
}
throw new JsonSerializationException("Unexpected end when deserializing object.");
}
#endregion
#region Serialize
/// <summary>
/// Serializes the specified <see cref="Object"/> and writes the Json structure
/// to a <c>Stream</c> using the specified <see cref="TextWriter"/>.
/// </summary>
/// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
/// <param name="value">The <see cref="Object"/> to serialize.</param>
public void Serialize(TextWriter textWriter, object value)
{
Serialize(new JsonWriter(textWriter), value);
}
/// <summary>
/// Serializes the specified <see cref="Object"/> and writes the Json structure
/// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>.
/// </summary>
/// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
/// <param name="value">The <see cref="Object"/> to serialize.</param>
public void Serialize(JsonWriter jsonWriter, object value)
{
if (jsonWriter == null)
throw new ArgumentNullException("jsonWriter");
if (value == null)
throw new ArgumentNullException("value");
SerializeValue(jsonWriter, value);
}
private void SerializeValue(JsonWriter writer, object value)
{
JsonConverter converter;
if (value == null)
{
writer.WriteNull();
}
else if (HasMatchingConverter(value.GetType(), out converter))
{
converter.WriteJson(writer, value);
}
else if (value is IConvertible)
{
IConvertible convertible = value as IConvertible;
switch (convertible.GetTypeCode())
{
case TypeCode.String:
writer.WriteValue((string)convertible);
break;
case TypeCode.Char:
writer.WriteValue((char)convertible);
break;
case TypeCode.Boolean:
writer.WriteValue((bool)convertible);
break;
case TypeCode.SByte:
writer.WriteValue((sbyte)convertible);
break;
case TypeCode.Int16:
writer.WriteValue((short)convertible);
break;
case TypeCode.UInt16:
writer.WriteValue((ushort)convertible);
break;
case TypeCode.Int32:
writer.WriteValue((int)convertible);
break;
case TypeCode.Byte:
writer.WriteValue((byte)convertible);
break;
case TypeCode.UInt32:
writer.WriteValue((uint)convertible);
break;
case TypeCode.Int64:
writer.WriteValue((long)convertible);
break;
case TypeCode.UInt64:
writer.WriteValue((ulong)convertible);
break;
case TypeCode.Single:
writer.WriteValue((float)convertible);
break;
case TypeCode.Double:
writer.WriteValue((double)convertible);
break;
case TypeCode.DateTime:
writer.WriteValue((DateTime)convertible);
break;
case TypeCode.Decimal:
writer.WriteValue((decimal)convertible);
break;
default:
SerializeObject(writer, value);
break;
}
}
else if (value is IList)
{
SerializeList(writer, (IList)value);
}
else if (value is IDictionary)
{
SerializeDictionary(writer, (IDictionary)value);
}
else if (value is ICollection)
{
SerializeCollection(writer, (ICollection)value);
}
else if (value is Identifier)
{
writer.WriteRaw(value.ToString());
}
else
{
SerializeObject(writer, value);
}
}
private bool HasMatchingConverter(Type type, out JsonConverter matchingConverter)
{
if (_converters != null)
{
for (int i = 0; i < _converters.Count; i++)
{
JsonConverter converter = _converters[i];
if (converter.CanConvert(type))
{
matchingConverter = converter;
return true;
}
}
}
matchingConverter = null;
return false;
}
private void WriteMemberInfoProperty(JsonWriter writer, object value, MemberInfo member, string propertyName)
{
if (!ReflectionUtils.IsIndexedProperty(member))
{
object memberValue = ReflectionUtils.GetMemberValue(member, value);
if (writer.SerializeStack.IndexOf(memberValue) != -1)
{
switch (_referenceLoopHandling)
{
case ReferenceLoopHandling.Error:
throw new JsonSerializationException("Self referencing loop");
case ReferenceLoopHandling.Ignore:
// return from method
return;
case ReferenceLoopHandling.Serialize:
// continue
break;
default:
throw new InvalidOperationException(string.Format("Unexpected ReferenceLoopHandling value: '{0}'", _referenceLoopHandling));
}
}
writer.WritePropertyName(propertyName ?? member.Name);
SerializeValue(writer, memberValue);
}
}
private void SerializeObject(JsonWriter writer, object value)
{
Type objectType = value.GetType();
TypeConverter converter = TypeDescriptor.GetConverter(objectType);
// use the objectType's TypeConverter if it has one and can convert to a string
if (converter != null && !(converter is ComponentConverter) && converter.GetType() != typeof(TypeConverter))
{
if (converter.CanConvertTo(typeof(string)))
{
writer.WriteValue(converter.ConvertToInvariantString(value));
return;
}
}
writer.SerializeStack.Add(value);
writer.WriteStartObject();
MemberMappingCollection memberMappings = GetMemberMappings(objectType);
foreach (MemberMapping memberMapping in memberMappings)
{
if (!memberMapping.Ignored && memberMapping.Readable)
WriteMemberInfoProperty(writer, value, memberMapping.Member, memberMapping.MappingName);
}
writer.WriteEndObject();
writer.SerializeStack.Remove(value);
}
private void SerializeCollection(JsonWriter writer, ICollection values)
{
object[] collectionValues = new object[values.Count];
values.CopyTo(collectionValues, 0);
SerializeList(writer, collectionValues);
}
private void SerializeList(JsonWriter writer, IList values)
{
writer.WriteStartArray();
for (int i = 0; i < values.Count; i++)
{
SerializeValue(writer, values[i]);
}
writer.WriteEndArray();
}
private void SerializeDictionary(JsonWriter writer, IDictionary values)
{
writer.WriteStartObject();
foreach (DictionaryEntry entry in values)
{
writer.WritePropertyName(entry.Key.ToString());
SerializeValue(writer, entry.Value);
}
writer.WriteEndObject();
}
#endregion
}
}
+98
View File
@@ -0,0 +1,98 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies the type of Json token.
/// </summary>
public enum JsonToken
{
/// <summary>
/// This is returned by the <see cref="JsonReader"/> if a <see cref="JsonReader.Read"/> method has not been called.
/// </summary>
None,
/// <summary>
/// An object start token.
/// </summary>
StartObject,
/// <summary>
/// An array start token.
/// </summary>
StartArray,
/// <summary>
/// An object property name.
/// </summary>
PropertyName,
/// <summary>
/// A comment.
/// </summary>
Comment,
/// <summary>
/// An interger.
/// </summary>
Integer,
/// <summary>
/// A float.
/// </summary>
Float,
/// <summary>
/// A string.
/// </summary>
String,
/// <summary>
/// A boolean.
/// </summary>
Boolean,
/// <summary>
/// A null token.
/// </summary>
Null,
/// <summary>
/// An undefined token.
/// </summary>
Undefined,
/// <summary>
/// An object end token.
/// </summary>
EndObject,
/// <summary>
/// An array end token.
/// </summary>
EndArray,
/// <summary>
/// A JavaScript object constructor.
/// </summary>
Constructor,
/// <summary>
/// A Date.
/// </summary>
Date
}
}
+732
View File
@@ -0,0 +1,732 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json
{
internal enum JsonType
{
Object,
Array,
None
}
/// <summary>
/// Specifies the state of the <see cref="JsonWriter"/>.
/// </summary>
public enum WriteState
{
/// <summary>
/// An exception has been thrown, which has left the <see cref="JsonWriter"/> in an invalid state.
/// You may call the <see cref="JsonWriter.Close"/> method to put the <see cref="JsonWriter"/> in the <c>Closed</c> state.
/// Any other <see cref="JsonWriter"/> method calls results in an <see cref="InvalidOperationException"/> being thrown.
/// </summary>
Error,
/// <summary>
/// The <see cref="JsonWriter.Close"/> method has been called.
/// </summary>
Closed,
/// <summary>
/// An object is being written.
/// </summary>
Object,
/// <summary>
/// A array is being written.
/// </summary>
Array,
/// <summary>
/// A property is being written.
/// </summary>
Property,
/// <summary>
/// A write method has not been called.
/// </summary>
Start
}
/// <summary>
/// Specifies formatting options for the <see cref="JsonWriter"/>.
/// </summary>
public enum Formatting
{
/// <summary>
/// No special formatting is applied. This is the default.
/// </summary>
None,
/// <summary>
/// Causes child objects to be indented according to the <see cref="JsonWriter.Indentation"/> and <see cref="JsonWriter.IndentChar"/> settings.
/// </summary>
Indented
}
/// <summary>
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
/// </summary>
public class JsonWriter : IDisposable
{
private enum State
{
Start,
Property,
ObjectStart,
Object,
ArrayStart,
Array,
Closed,
Error
}
// array that gives a new state based on the current state an the token being written
private static readonly State[,] stateArray = {
// Start PropertyName ObjectStart Object ArrayStart Array Closed Error
//
/* None */{ State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error },
/* StartObject */{ State.ObjectStart, State.ObjectStart, State.Error, State.Error, State.ObjectStart, State.ObjectStart, State.Error, State.Error },
/* StartArray */{ State.ArrayStart, State.ArrayStart, State.Error, State.Error, State.ArrayStart, State.ArrayStart, State.Error, State.Error },
/* StartProperty */{ State.Error, State.Error, State.Property, State.Property, State.Error, State.Error, State.Error, State.Error },
/* Comment */{ State.Error, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Error, State.Error },
/* Value */{ State.Error, State.Object, State.Error, State.Error, State.Array, State.Array, State.Error, State.Error },
};
private int _top;
private List<JsonType> _stack;
private List<object> _serializeStack;
private TextWriter _writer;
private Formatting _formatting;
private char _indentChar;
private int _indentation;
private char _quoteChar;
private bool _quoteName;
private State _currentState;
internal List<object> SerializeStack
{
get
{
if (_serializeStack == null)
_serializeStack = new List<object>();
return _serializeStack;
}
}
/// <summary>
/// Gets the state of the writer.
/// </summary>
public WriteState WriteState
{
get
{
switch (_currentState)
{
case State.Error:
return WriteState.Error;
case State.Closed:
return WriteState.Closed;
case State.Object:
case State.ObjectStart:
return WriteState.Object;
case State.Array:
case State.ArrayStart:
return WriteState.Array;
case State.Property:
return WriteState.Property;
case State.Start:
return WriteState.Start;
default:
throw new JsonWriterException("Invalid state: " + _currentState);
}
}
}
/// <summary>
/// Indicates how the output is formatted.
/// </summary>
public Formatting Formatting
{
get { return _formatting; }
set { _formatting = value; }
}
/// <summary>
/// Gets or sets how many IndentChars to write for each level in the hierarchy when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
/// </summary>
public int Indentation
{
get { return _indentation; }
set
{
if (value < 0)
throw new ArgumentException("Indentation value must be greater than 0.");
_indentation = value;
}
}
/// <summary>
/// Gets or sets which character to use to quote attribute values.
/// </summary>
public char QuoteChar
{
get { return _quoteChar; }
set
{
if (value != '"' && value != '\'')
throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
_quoteChar = value;
}
}
/// <summary>
/// Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
/// </summary>
public char IndentChar
{
get { return _indentChar; }
set { _indentChar = value; }
}
/// <summary>
/// Gets or sets a value indicating whether object names will be surrounded with quotes.
/// </summary>
public bool QuoteName
{
get { return _quoteName; }
set { _quoteName = value; }
}
/// <summary>
/// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>.
/// </summary>
/// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
public JsonWriter(TextWriter textWriter)
{
if (textWriter == null)
throw new ArgumentNullException("textWriter");
_writer = textWriter;
_quoteChar = '"';
_quoteName = true;
_indentChar = ' ';
_indentation = 2;
_formatting = Formatting.None;
_stack = new List<JsonType>(1);
_stack.Add(JsonType.None);
_currentState = State.Start;
}
private void Push(JsonType value)
{
_top++;
if (_stack.Count <= _top)
_stack.Add(value);
else
_stack[_top] = value;
}
private JsonType Pop()
{
JsonType value = Peek();
_top--;
return value;
}
private JsonType Peek()
{
return _stack[_top];
}
/// <summary>
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
/// </summary>
public void Flush()
{
_writer.Flush();
}
/// <summary>
/// Closes this stream and the underlying stream.
/// </summary>
public void Close()
{
AutoCompleteAll();
_writer.Close();
}
/// <summary>
/// Writes the beginning of a Json object.
/// </summary>
public void WriteStartObject()
{
AutoComplete(JsonToken.StartObject);
Push(JsonType.Object);
_writer.Write("{");
}
/// <summary>
/// Writes the end of a Json object.
/// </summary>
public void WriteEndObject()
{
AutoCompleteClose(JsonToken.EndObject);
}
/// <summary>
/// Writes the beginning of a Json array.
/// </summary>
public void WriteStartArray()
{
AutoComplete(JsonToken.StartArray);
Push(JsonType.Array);
_writer.Write("[");
}
/// <summary>
/// Writes the end of an array.
/// </summary>
public void WriteEndArray()
{
AutoCompleteClose(JsonToken.EndArray);
}
/// <summary>
/// Writes the property name of a name/value pair on a Json object.
/// </summary>
/// <param name="name"></param>
public void WritePropertyName(string name)
{
//_objectStack.Push(new JsonObjectInfo(JsonType.Property));
AutoComplete(JsonToken.PropertyName);
if (_quoteName)
_writer.Write(_quoteChar);
_writer.Write(name);
if (_quoteName)
_writer.Write(_quoteChar);
_writer.Write(':');
}
/// <summary>
/// Writes the end of the current Json object or array.
/// </summary>
public void WriteEnd()
{
WriteEnd(Peek());
}
private void WriteEnd(JsonType type)
{
switch (type)
{
case JsonType.Object:
WriteEndObject();
break;
case JsonType.Array:
WriteEndArray();
break;
default:
throw new JsonWriterException("Unexpected type when writing end: " + type);
}
}
private void AutoCompleteAll()
{
while (_top > 0)
{
WriteEnd();
}
}
private JsonType GetTypeForCloseToken(JsonToken token)
{
switch (token)
{
case JsonToken.EndObject:
return JsonType.Object;
case JsonToken.EndArray:
return JsonType.Array;
default:
throw new JsonWriterException("No type for token: " + token);
}
}
private JsonToken GetCloseTokenForType(JsonType type)
{
switch (type)
{
case JsonType.Object:
return JsonToken.EndObject;
case JsonType.Array:
return JsonToken.EndArray;
default:
throw new JsonWriterException("No close token for type: " + type);
}
}
private void AutoCompleteClose(JsonToken tokenBeingClosed)
{
// write closing symbol and calculate new state
int levelsToComplete = 0;
for (int i = 0; i < _top; i++)
{
int currentLevel = _top - i;
if (_stack[currentLevel] == GetTypeForCloseToken(tokenBeingClosed))
{
levelsToComplete = i + 1;
break;
}
}
if (levelsToComplete == 0)
throw new JsonWriterException("No token to close.");
for (int i = 0; i < levelsToComplete; i++)
{
JsonToken token = GetCloseTokenForType(Pop());
if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
WriteIndent();
switch (token)
{
case JsonToken.EndObject:
_writer.Write("}");
break;
case JsonToken.EndArray:
_writer.Write("]");
break;
default:
throw new JsonWriterException("Invalid JsonToken: " + token);
}
}
JsonType currentLevelType = Peek();
switch (currentLevelType)
{
case JsonType.Object:
_currentState = State.Object;
break;
case JsonType.Array:
_currentState = State.Array;
break;
case JsonType.None:
_currentState = State.Start;
break;
default:
throw new JsonWriterException("Unknown JsonType: " + currentLevelType);
}
}
private void WriteIndent()
{
if (_formatting == Formatting.Indented)
{
_writer.Write(Environment.NewLine);
// for each level of object...
for (int i = 0; i < _top; i++)
{
// ...write the indent char the specified number of times
for (int j = 0; j < _indentation; j++)
{
_writer.Write(_indentChar);
}
}
}
}
private void AutoComplete(JsonToken tokenBeingWritten)
{
int token;
switch (tokenBeingWritten)
{
default:
token = (int)tokenBeingWritten;
break;
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
// a value is being written
token = 5;
break;
}
// gets new state based on the current state and what is being written
State newState = stateArray[token, (int)_currentState];
if (newState == State.Error)
throw new JsonWriterException(string.Format("Token {0} in state {1} would result in an invalid JavaScript object.", tokenBeingWritten.ToString(), _currentState.ToString()));
if ((_currentState == State.Object || _currentState == State.Array) && tokenBeingWritten != JsonToken.Comment)
{
_writer.Write(',');
}
else if (_currentState == State.Property)
{
if (_formatting == Formatting.Indented)
_writer.Write(' ');
}
if (tokenBeingWritten == JsonToken.PropertyName ||
(WriteState == WriteState.Array))
{
WriteIndent();
}
_currentState = newState;
}
private void WriteValueInternal(string value, JsonToken token)
{
AutoComplete(token);
_writer.Write(value);
}
#region WriteValue methods
/// <summary>
/// Writes a null value.
/// </summary>
public void WriteNull()
{
WriteValueInternal(JavaScriptConvert.Null, JsonToken.Null);
}
/// <summary>
/// Writes an undefined value.
/// </summary>
public void WriteUndefined()
{
WriteValueInternal(JavaScriptConvert.Undefined, JsonToken.Undefined);
}
/// <summary>
/// Writes raw JavaScript manually.
/// </summary>
/// <param name="javaScript">The raw JavaScript to write.</param>
public void WriteRaw(string javaScript)
{
// hack. some 'raw' or 'other' token perhaps?
WriteValueInternal(javaScript, JsonToken.Undefined);
}
/// <summary>
/// Writes a <see cref="String"/> value.
/// </summary>
/// <param name="value">The <see cref="String"/> value to write.</param>
public void WriteValue(string value)
{
WriteValueInternal(JavaScriptConvert.ToString(value, _quoteChar), JsonToken.String);
}
/// <summary>
/// Writes a <see cref="Int32"/> value.
/// </summary>
/// <param name="value">The <see cref="Int32"/> value to write.</param>
public void WriteValue(int value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="UInt32"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
public void WriteValue(uint value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="Int64"/> value.
/// </summary>
/// <param name="value">The <see cref="Int64"/> value to write.</param>
public void WriteValue(long value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="UInt64"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
public void WriteValue(ulong value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="Single"/> value.
/// </summary>
/// <param name="value">The <see cref="Single"/> value to write.</param>
public void WriteValue(float value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
}
/// <summary>
/// Writes a <see cref="Double"/> value.
/// </summary>
/// <param name="value">The <see cref="Double"/> value to write.</param>
public void WriteValue(double value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
}
/// <summary>
/// Writes a <see cref="Boolean"/> value.
/// </summary>
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
public void WriteValue(bool value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Boolean);
}
/// <summary>
/// Writes a <see cref="Int16"/> value.
/// </summary>
/// <param name="value">The <see cref="Int16"/> value to write.</param>
public void WriteValue(short value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="UInt16"/> value.
/// </summary>
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
public void WriteValue(ushort value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="Char"/> value.
/// </summary>
/// <param name="value">The <see cref="Char"/> value to write.</param>
public void WriteValue(char value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="Byte"/> value.
/// </summary>
/// <param name="value">The <see cref="Byte"/> value to write.</param>
public void WriteValue(byte value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="SByte"/> value.
/// </summary>
/// <param name="value">The <see cref="SByte"/> value to write.</param>
public void WriteValue(sbyte value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Integer);
}
/// <summary>
/// Writes a <see cref="Decimal"/> value.
/// </summary>
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
public void WriteValue(decimal value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Float);
}
/// <summary>
/// Writes a <see cref="DateTime"/> value.
/// </summary>
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
public void WriteValue(DateTime value)
{
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
}
#endregion
/// <summary>
/// Writes out a comment <code>/*...*/</code> containing the specified text.
/// </summary>
/// <param name="text">Text to place inside the comment.</param>
public void WriteComment(string text)
{
AutoComplete(JsonToken.Comment);
_writer.Write("/*");
_writer.Write(text);
_writer.Write("*/");
}
/// <summary>
/// Writes out the given white space.
/// </summary>
/// <param name="ws">The string of white space characters.</param>
public void WriteWhitespace(string ws)
{
if (ws != null)
{
if (!StringUtils.IsWhiteSpace(ws))
throw new JsonWriterException("Only white space characters should be used.");
_writer.Write(ws);
}
}
void IDisposable.Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (WriteState != WriteState.Closed)
Close();
}
}
}
@@ -0,0 +1,65 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// The exception thrown when an error occurs while reading Json text.
/// </summary>
public class JsonWriterException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="JsonWriterException"/> class.
/// </summary>
public JsonWriterException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonWriterException"/> class
/// with a specified error message.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
public JsonWriterException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonWriterException"/> class
/// with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public JsonWriterException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}
+50
View File
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace Newtonsoft.Json
{
internal struct MemberMapping
{
private readonly string _mappingName;
private readonly MemberInfo _member;
private readonly bool _ignored;
private readonly bool _readable;
private readonly bool _writable;
public MemberMapping(string mappingName, MemberInfo member, bool ignored, bool readable, bool writable)
{
_mappingName = mappingName;
_member = member;
_ignored = ignored;
_readable = readable;
_writable = writable;
}
public string MappingName
{
get { return _mappingName; }
}
public MemberInfo Member
{
get { return _member; }
}
public bool Ignored
{
get { return _ignored; }
}
public bool Readable
{
get { return _readable; }
}
public bool Writable
{
get { return _writable; }
}
}
}
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
namespace Newtonsoft.Json
{
internal class MemberMappingCollection : KeyedCollection<string, MemberMapping>
{
protected override string GetKeyForItem(MemberMapping item)
{
return item.MappingName;
}
public void AddMapping(MemberMapping memberMapping)
{
if (Contains(memberMapping.MappingName))
{
// don't overwrite existing mapping with ignored mapping
if (memberMapping.Ignored)
return;
MemberMapping existingMemberMapping = this[memberMapping.MappingName];
if (!existingMemberMapping.Ignored)
{
throw new JsonSerializationException(
string.Format(
"A member with the name '{0}' already exists on {1}. Use the JsonPropertyAttribute to specify another name.",
memberMapping.MappingName, memberMapping.Member.DeclaringType));
}
else
{
// remove ignored mapping so it can be replaced in collection
Remove(existingMemberMapping);
}
}
Add(memberMapping);
}
}
}
@@ -0,0 +1,84 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Newtonsoft.Json</RootNamespace>
<AssemblyName>Newtonsoft.Json</AssemblyName>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\Newtonsoft.Json.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Newtonsoft.Json.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Converters\AspNetAjaxDateTimeConverter.cs" />
<Compile Include="Converters\XmlNodeConverter.cs" />
<Compile Include="Converters\HtmlColorConverter.cs" />
<Compile Include="JavaScriptParameters.cs" />
<Compile Include="JavaScriptConstructor.cs" />
<Compile Include="JsonPropertyAttribute.cs" />
<Compile Include="JsonIgnoreAttribute.cs" />
<Compile Include="JsonWriterException.cs" />
<Compile Include="JsonReaderException.cs" />
<Compile Include="Identifier.cs" />
<Compile Include="JavaScriptArray.cs" />
<Compile Include="JavaScriptObject.cs" />
<Compile Include="JsonConverter.cs" />
<Compile Include="JsonConverterCollection.cs" />
<Compile Include="JsonReader.cs" />
<Compile Include="JavaScriptConvert.cs" />
<Compile Include="JsonSerializationException.cs" />
<Compile Include="JsonSerializer.cs" />
<Compile Include="MemberMapping.cs" />
<Compile Include="MemberMappingCollection.cs" />
<Compile Include="Utilities\JavaScriptUtils.cs" />
<Compile Include="JsonToken.cs" />
<Compile Include="JsonWriter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StringBuffer.cs" />
<Compile Include="Utilities\CollectionUtils.cs" />
<Compile Include="Utilities\MathUtils.cs" />
<Compile Include="Utilities\MiscellaneousUtils.cs" />
<Compile Include="Utilities\ReflectionUtils.cs" />
<Compile Include="Utilities\StringUtils.cs" />
<Compile Include="Utilities\ValidationUtils.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,57 @@
#region License
// Copyright 2006 James Newton-King
// http://www.newtonsoft.com
//
// This work is licensed under the Creative Commons Attribution 2.5 License
// http://creativecommons.org/licenses/by/2.5/
//
// You are free:
// * to copy, distribute, display, and perform the work
// * to make derivative works
// * to make commercial use of the work
//
// Under the following conditions:
// * You must attribute the work in the manner specified by the author or licensor:
// - If you find this component useful a link to http://www.newtonsoft.com would be appreciated.
// * For any reuse or distribution, you must make clear to others the license terms of this work.
// * Any of these conditions can be waived if you get permission from the copyright holder.
#endregion
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Newtonsoft Json.NET")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyProduct("Newtonsoft Json.NET")]
[assembly: AssemblyCopyright("Copyright © Newtonsoft 2006")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AllowPartiallyTrustedCallers]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM componenets. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
+90
View File
@@ -0,0 +1,90 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json
{
/// <summary>
/// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer.
/// </summary>
internal class StringBuffer
{
private char[] _buffer;
private int _position;
private static char[] _emptyBuffer = new char[0];
public int Position
{
get { return _position; }
set { _position = value; }
}
public StringBuffer()
{
_buffer = _emptyBuffer;
}
public StringBuffer(int initalSize)
{
_buffer = new char[initalSize];
}
public void Append(char value)
{
// test if the buffer array is large enough to take the value
if (_position + 1 > _buffer.Length)
{
EnsureSize(1);
}
// set value and increment poisition
_buffer[_position++] = value;
}
public void Clear()
{
_buffer = _emptyBuffer;
_position = 0;
}
private void EnsureSize(int appendLength)
{
char[] newBuffer = new char[_position + appendLength * 2];
Array.Copy(_buffer, newBuffer, _position);
_buffer = newBuffer;
}
public override string ToString()
{
return new string(_buffer, 0, _position);
}
}
}
@@ -0,0 +1,419 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Text;
using System.Collections;
namespace Newtonsoft.Json.Utilities
{
internal static class CollectionUtils
{
public static List<T> CreateList<T>(params T[] values)
{
return new List<T>(values);
}
/// <summary>
/// Determines whether the collection is null or empty.
/// </summary>
/// <param name="collection">The collection.</param>
/// <returns>
/// <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
/// </returns>
public static bool IsNullOrEmpty(ICollection collection)
{
if (collection != null)
{
return (collection.Count == 0);
}
return true;
}
/// <summary>
/// Determines whether the collection is null or empty.
/// </summary>
/// <param name="collection">The collection.</param>
/// <returns>
/// <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
/// </returns>
public static bool IsNullOrEmpty<T>(ICollection<T> collection)
{
if (collection != null)
{
return (collection.Count == 0);
}
return true;
}
/// <summary>
/// Determines whether the collection is null, empty or its contents are uninitialized values.
/// </summary>
/// <param name="list">The list.</param>
/// <returns>
/// <c>true</c> if the collection is null or empty or its contents are uninitialized values; otherwise, <c>false</c>.
/// </returns>
public static bool IsNullOrEmptyOrDefault<T>(IList<T> list)
{
if (IsNullOrEmpty<T>(list))
return true;
return ReflectionUtils.ItemsUnitializedValue<T>(list);
}
/// <summary>
/// Makes a slice of the specified list in between the start and end indexes.
/// </summary>
/// <param name="list">The list.</param>
/// <param name="start">The start index.</param>
/// <param name="end">The end index.</param>
/// <returns>A slice of the list.</returns>
public static IList<T> Slice<T>(IList<T> list, int? start, int? end)
{
return Slice<T>(list, start, end, null);
}
/// <summary>
/// Makes a slice of the specified list in between the start and end indexes,
/// getting every so many items based upon the step.
/// </summary>
/// <param name="list">The list.</param>
/// <param name="start">The start index.</param>
/// <param name="end">The end index.</param>
/// <param name="step">The step.</param>
/// <returns>A slice of the list.</returns>
public static IList<T> Slice<T>(IList<T> list, int? start, int? end, int? step)
{
if (list == null)
throw new ArgumentNullException("list");
if (step == 0)
throw new ArgumentException("Step cannot be zero.", "step");
List<T> slicedList = new List<T>();
// nothing to slice
if (list.Count == 0)
return slicedList;
// set defaults for null arguments
int s = step ?? 1;
int startIndex = start ?? 0;
int endIndex = end ?? list.Count;
// start from the end of the list if start is negitive
startIndex = (startIndex < 0) ? list.Count + startIndex : startIndex;
// end from the start of the list if end is negitive
endIndex = (endIndex < 0) ? list.Count + endIndex : endIndex;
// ensure indexes keep within collection bounds
startIndex = Math.Max(startIndex, 0);
endIndex = Math.Min(endIndex, list.Count - 1);
// loop between start and end indexes, incrementing by the step
for (int i = startIndex; i < endIndex; i += s)
{
slicedList.Add(list[i]);
}
return slicedList;
}
/// <summary>
/// Group the collection using a function which returns the key.
/// </summary>
/// <param name="source">The source collection to group.</param>
/// <param name="keySelector">The key selector.</param>
/// <returns>A Dictionary with each key relating to a list of objects in a list grouped under it.</returns>
public static Dictionary<K, List<V>> GroupBy<K, V>(ICollection<V> source, Func<V, K> keySelector)
{
if (keySelector == null)
throw new ArgumentNullException("keySelector");
Dictionary<K, List<V>> groupedValues = new Dictionary<K, List<V>>();
foreach (V value in source)
{
// using delegate to get the value's key
K key = keySelector(value);
List<V> groupedValueList;
// add a list for grouped values if the key is not already in Dictionary
if (!groupedValues.TryGetValue(key, out groupedValueList))
{
groupedValueList = new List<V>();
groupedValues.Add(key, groupedValueList);
}
groupedValueList.Add(value);
}
return groupedValues;
}
/// <summary>
/// Adds the elements of the specified collection to the specified generic IList.
/// </summary>
/// <param name="initial">The list to add to.</param>
/// <param name="collection">The collection of elements to add.</param>
public static void AddRange<T>(IList<T> initial, IEnumerable<T> collection)
{
if (initial == null)
throw new ArgumentNullException("initial");
if (collection == null)
return;
foreach (T value in collection)
{
initial.Add(value);
}
}
public static List<T> Distinct<T>(List<T> collection)
{
List<T> distinctList = new List<T>();
foreach (T value in collection)
{
if (!distinctList.Contains(value))
distinctList.Add(value);
}
return distinctList;
}
public static List<List<T>> Flatten<T>(params IList<T>[] lists)
{
List<List<T>> flattened = new List<List<T>>();
Dictionary<int, T> currentList = new Dictionary<int, T>();
Recurse<T>(new List<IList<T>>(lists), 0, currentList, flattened);
return flattened;
}
private static void Recurse<T>(IList<IList<T>> global, int current, Dictionary<int, T> currentSet, List<List<T>> flattenedResult)
{
IList<T> currentArray = global[current];
for (int i = 0; i < currentArray.Count; i++)
{
currentSet[current] = currentArray[i];
if (current == global.Count - 1)
{
List<T> items = new List<T>();
for (int k = 0; k < currentSet.Count; k++)
{
items.Add(currentSet[k]);
}
flattenedResult.Add(items);
}
else
{
Recurse(global, current + 1, currentSet, flattenedResult);
}
}
}
public static List<T> CreateList<T>(ICollection collection)
{
if (collection == null)
throw new ArgumentNullException("collection");
T[] array = new T[collection.Count];
collection.CopyTo(array, 0);
return new List<T>(array);
}
public static bool ListEquals<T>(IList<T> a, IList<T> b)
{
if (a == null || b == null)
return (a == null && b == null);
if (a.Count != b.Count)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a.Count; i++)
{
if (!comparer.Equals(a[i], b[i]))
return false;
}
return true;
}
#region GetSingleItem
public static bool TryGetSingleItem<T>(IList<T> list, out T value)
{
return TryGetSingleItem<T>(list, false, out value);
}
public static bool TryGetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty, out T value)
{
return MiscellaneousUtils.TryAction<T>(delegate { return GetSingleItem(list, returnDefaultIfEmpty); }, out value);
}
public static T GetSingleItem<T>(IList<T> list)
{
return GetSingleItem<T>(list, false);
}
public static T GetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty)
{
if (list.Count == 1)
return list[0];
else if (returnDefaultIfEmpty && list.Count == 0)
return default(T);
else
throw new Exception(string.Format("Expected single {0} in list but got {1}.", typeof(T), list.Count));
}
#endregion
public static IList<T> Minus<T>(IList<T> list, IList<T> minus)
{
ValidationUtils.ArgumentNotNull(list, "list");
List<T> result = new List<T>(list.Count);
foreach (T t in list)
{
if (minus == null || !minus.Contains(t))
result.Add(t);
}
return result;
}
public static T[] CreateArray<T>(IEnumerable<T> enumerable)
{
ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
if (enumerable is T[])
return (T[])enumerable;
List<T> tempList = new List<T>(enumerable);
return tempList.ToArray();
}
public static object CreateGenericList(Type listType)
{
ValidationUtils.ArgumentNotNull(listType, "listType");
return ReflectionUtils.CreateGeneric(typeof(List<>), listType);
}
public static bool IsListType(Type type)
{
ValidationUtils.ArgumentNotNull(type, "listType");
if (type.IsArray)
return true;
else if (typeof(IList).IsAssignableFrom(type))
return true;
else if (ReflectionUtils.IsSubClass(type, typeof(IList<>)))
return true;
else
return false;
}
public static IList CreateAndPopulateList(Type listType, Action<IList> populateList)
{
ValidationUtils.ArgumentNotNull(listType, "listType");
ValidationUtils.ArgumentNotNull(populateList, "populateList");
IList list;
Type readOnlyCollectionType;
bool isReadOnlyOrFixedSize = false;
if (listType.IsArray)
{
// have to use an arraylist when creating array
// there is no way to know the size until it is finised
list = new ArrayList();
isReadOnlyOrFixedSize = true;
}
else if (ReflectionUtils.IsSubClass(listType, typeof(ReadOnlyCollection<>), out readOnlyCollectionType))
{
Type readOnlyCollectionContentsType = readOnlyCollectionType.GetGenericArguments()[0];
Type genericEnumerable = ReflectionUtils.MakeGenericType(typeof(IEnumerable<>), readOnlyCollectionContentsType);
bool suitableConstructor = false;
foreach (ConstructorInfo constructor in listType.GetConstructors())
{
IList<ParameterInfo> parameters = constructor.GetParameters();
if (parameters.Count == 1)
{
if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
{
suitableConstructor = true;
break;
}
}
}
if (!suitableConstructor)
throw new Exception(string.Format("Readonly type {0} does not have a public constructor that takes a type that implements {1}.", listType, genericEnumerable));
// can't add or modify a readonly list
// use List<T> and convert once populated
list = (IList)CreateGenericList(readOnlyCollectionContentsType);
isReadOnlyOrFixedSize = true;
}
else if (typeof(IList).IsAssignableFrom(listType) && ReflectionUtils.IsInstantiatableType(listType))
{
list = (IList)Activator.CreateInstance(listType);
}
else
{
throw new Exception(string.Format("Cannot create and populate list type {0}.", listType));
}
populateList(list);
// create readonly and fixed sized collections using the temporary list
if (isReadOnlyOrFixedSize)
{
if (listType.IsArray)
list = ((ArrayList)list).ToArray(ReflectionUtils.GetListItemType(listType));
else if (ReflectionUtils.IsSubClass(listType, typeof(ReadOnlyCollection<>)))
list = (IList)Activator.CreateInstance(listType, list);
}
return list;
}
}
}
@@ -0,0 +1,137 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Newtonsoft.Json.Utilities
{
internal static class JavaScriptUtils
{
public static string GetCallbackEventFunction(Page page, Control control)
{
string script = page.ClientScript.GetCallbackEventReference(control, "eventArgument", "eventCallback", "context", "errorCallback", true);
script = "function(eventArgument,eventCallback,context,errorCallback){" + script + "}";
return script;
}
public static string GetCallbackEventFunction(Page page, Control control, string argument)
{
string script = page.ClientScript.GetCallbackEventReference(control, "'" + argument + "'", "eventCallback", "context", "errorCallback", true);
script = "function(eventCallback,context,errorCallback){" + script + "}";
return script;
}
public static void WriteEscapedJavaScriptChar(TextWriter writer, char c, char delimiter)
{
switch (c)
{
case '\t':
writer.Write(@"\t");
break;
case '\n':
writer.Write(@"\n");
break;
case '\r':
writer.Write(@"\r");
break;
case '\f':
writer.Write(@"\f");
break;
case '\b':
writer.Write(@"\b");
break;
case '\\':
writer.Write(@"\\");
break;
//case '<':
//case '>':
//case '\'':
// StringUtils.WriteCharAsUnicode(writer, c);
// break;
case '"':
// only escape if this charater is being used as the delimiter
writer.Write((delimiter == '"') ? "\\\"" : null);
break;
default:
if (c > '\u001f')
writer.Write(c);
else
StringUtils.WriteCharAsUnicode(writer, c);
break;
}
}
public static void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter, bool appendDelimiters)
{
// leading delimiter
if (appendDelimiters)
writer.Write(delimiter);
if (value != null)
{
for (int i = 0; i < value.Length; i++)
{
WriteEscapedJavaScriptChar(writer, value[i], delimiter);
}
}
// trailing delimiter
if (appendDelimiters)
writer.Write(delimiter);
}
public static string ToEscapedJavaScriptString(string value)
{
return ToEscapedJavaScriptString(value, '"', true);
}
public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters)
{
using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16))
{
WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters);
return w.ToString();
}
}
}
}
@@ -0,0 +1,60 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json.Utilities
{
internal class MathUtils
{
public static int HexToInt(char h)
{
if ((h >= '0') && (h <= '9'))
{
return (h - '0');
}
if ((h >= 'a') && (h <= 'f'))
{
return ((h - 'a') + 10);
}
if ((h >= 'A') && (h <= 'F'))
{
return ((h - 'A') + 10);
}
return -1;
}
public static char IntToHex(int n)
{
if (n <= 9)
{
return (char)(n + 48);
}
return (char)((n - 10) + 97);
}
}
}
@@ -0,0 +1,84 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
namespace Newtonsoft.Json.Utilities
{
internal delegate void Action();
internal delegate T Creator<T>();
internal delegate T Func<A0, T>(A0 arg0);
internal delegate T Func<A0, A1, T>(A0 arg0, A1 arg1);
internal delegate T Func<A0, A1, A2, T>(A0 arg0, A1 arg1, A2 arg2);
internal static class MiscellaneousUtils
{
public static bool TryAction<T>(Creator<T> creator, out T output)
{
ValidationUtils.ArgumentNotNull(creator, "creator");
try
{
output = creator();
return true;
}
catch
{
output = default(T);
return false;
}
}
public static bool TryGetDescription(object value, out string description)
{
return TryAction<string>(delegate { return GetDescription(value); }, out description);
}
public static string GetDescription(object o)
{
ValidationUtils.ArgumentNotNull(o, "o");
ICustomAttributeProvider attributeProvider = o as ICustomAttributeProvider;
// object passed in isn't an attribute provider
// if value is an enum value, get value field member, otherwise get values type
if (attributeProvider == null)
{
Type valueType = o.GetType();
if (valueType.IsEnum)
attributeProvider = valueType.GetField(o.ToString());
else
attributeProvider = valueType;
}
DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute<DescriptionAttribute>(attributeProvider);
if (descriptionAttribute != null)
return descriptionAttribute.Description;
else
throw new Exception(string.Format("No DescriptionAttribute on '{0}'.", o.GetType()));
}
public static IList<string> GetDescriptions(IList values)
{
ValidationUtils.ArgumentNotNull(values, "values");
string[] descriptions = new string[values.Count];
for (int i = 0; i < values.Count; i++)
{
descriptions[i] = GetDescription(values[i]);
}
return descriptions;
}
public static string ToString(object value)
{
return (value != null) ? value.ToString() : "{null}";
}
}
}
@@ -0,0 +1,524 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
namespace Newtonsoft.Json.Utilities
{
internal static class ReflectionUtils
{
public static Type GetObjectType(object v)
{
return (v != null) ? v.GetType() : null;
}
public static bool IsInstantiatableType(Type t)
{
ValidationUtils.ArgumentNotNull(t, "t");
if (t.IsAbstract || t.IsInterface || t.IsArray || t.IsGenericTypeDefinition || t == typeof(void))
return false;
if (!HasDefaultConstructor(t))
return false;
return true;
}
public static bool HasDefaultConstructor(Type t)
{
ValidationUtils.ArgumentNotNull(t, "t");
if (t.IsValueType)
return true;
return (t.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null) != null);
}
public static bool IsNullable(Type t)
{
ValidationUtils.ArgumentNotNull(t, "t");
if (t.IsValueType)
return IsNullableType(t);
return true;
}
public static bool IsNullableType(Type t)
{
ValidationUtils.ArgumentNotNull(t, "t");
return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
}
//public static bool IsValueTypeUnitializedValue(ValueType value)
//{
// if (value == null)
// return true;
// return value.Equals(CreateUnitializedValue(value.GetType()));
//}
public static bool IsUnitializedValue(object value)
{
if (value == null)
{
return true;
}
else
{
object unitializedValue = CreateUnitializedValue(value.GetType());
return value.Equals(unitializedValue);
}
}
public static object CreateUnitializedValue(Type type)
{
ValidationUtils.ArgumentNotNull(type, "type");
if (type.IsGenericTypeDefinition)
throw new ArgumentException(string.Format("Type {0} is a generic type definition and cannot be instantiated.", type), "type");
if (type.IsClass || type.IsInterface || type == typeof(void))
return null;
else if (type.IsValueType)
return Activator.CreateInstance(type);
else
throw new ArgumentException(string.Format("Type {0} cannot be instantiated.", type), "type");
}
public static bool IsPropertyIndexed(PropertyInfo property)
{
ValidationUtils.ArgumentNotNull(property, "property");
return !CollectionUtils.IsNullOrEmpty<ParameterInfo>(property.GetIndexParameters());
}
public static bool IsSubClass(Type type, Type check)
{
Type implementingType;
return IsSubClass(type, check, out implementingType);
}
public static bool IsSubClass(Type type, Type check, out Type implementingType)
{
ValidationUtils.ArgumentNotNull(type, "type");
ValidationUtils.ArgumentNotNull(check, "check");
return IsSubClassInternal(type, type, check, out implementingType);
}
private static bool IsSubClassInternal(Type initialType, Type currentType, Type check, out Type implementingType)
{
if (currentType == check)
{
implementingType = currentType;
return true;
}
// don't get interfaces for an interface unless the initial type is an interface
if (check.IsInterface && (initialType.IsInterface || currentType == initialType))
{
foreach (Type t in currentType.GetInterfaces())
{
if (IsSubClassInternal(initialType, t, check, out implementingType))
{
// don't return the interface itself, return it's implementor
if (check == implementingType)
implementingType = currentType;
return true;
}
}
}
if (currentType.IsGenericType && !currentType.IsGenericTypeDefinition)
{
if (IsSubClassInternal(initialType, currentType.GetGenericTypeDefinition(), check, out implementingType))
{
implementingType = currentType;
return true;
}
}
if (currentType.BaseType == null)
{
implementingType = null;
return false;
}
return IsSubClassInternal(initialType, currentType.BaseType, check, out implementingType);
}
/// <summary>
/// Gets the type of the typed list's items.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>The type of the typed list's items.</returns>
public static Type GetListItemType(Type type)
{
ValidationUtils.ArgumentNotNull(type, "type");
Type genericListType;
if (type.IsArray)
{
return type.GetElementType();
}
else if (IsSubClass(type, typeof(IList<>), out genericListType))
{
if (genericListType.IsGenericTypeDefinition)
throw new Exception(string.Format("Type {0} is not a list.", type));
return genericListType.GetGenericArguments()[0];
}
else if (typeof(IList).IsAssignableFrom(type))
{
return null;
}
else
{
throw new Exception(string.Format("Type {0} is not a list.", type));
}
}
public static Type GetDictionaryValueType(Type type)
{
ValidationUtils.ArgumentNotNull(type, "type");
Type genericDictionaryType;
if (IsSubClass(type, typeof(IDictionary<,>), out genericDictionaryType))
{
if (genericDictionaryType.IsGenericTypeDefinition)
throw new Exception(string.Format("Type {0} is not a dictionary.", type));
return genericDictionaryType.GetGenericArguments()[1];
}
else if (typeof(IDictionary).IsAssignableFrom(type))
{
return null;
}
else
{
throw new Exception(string.Format("Type {0} is not a dictionary.", type));
}
}
/// <summary>
/// Tests whether the list's items are their unitialized value.
/// </summary>
/// <param name="list">The list.</param>
/// <returns>Whether the list's items are their unitialized value</returns>
public static bool ItemsUnitializedValue<T>(IList<T> list)
{
ValidationUtils.ArgumentNotNull(list, "list");
Type elementType = GetListItemType(list.GetType());
if (elementType.IsValueType)
{
object unitializedValue = CreateUnitializedValue(elementType);
for (int i = 0; i < list.Count; i++)
{
if (!list[i].Equals(unitializedValue))
return false;
}
}
else if (elementType.IsClass)
{
for (int i = 0; i < list.Count; i++)
{
object value = list[i];
if (value != null)
return false;
}
}
else
{
throw new Exception(string.Format("Type {0} is neither a ValueType or a Class.", elementType));
}
return true;
}
/// <summary>
/// Gets the member's underlying type.
/// </summary>
/// <param name="member">The member.</param>
/// <returns>The underlying type of the member.</returns>
public static Type GetMemberUnderlyingType(MemberInfo member)
{
ValidationUtils.ArgumentNotNull(member, "member");
switch (member.MemberType)
{
case MemberTypes.Field:
return ((FieldInfo)member).FieldType;
case MemberTypes.Property:
return ((PropertyInfo)member).PropertyType;
case MemberTypes.Event:
return ((EventInfo)member).EventHandlerType;
default:
throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", "member");
}
}
/// <summary>
/// Determines whether the member is an indexed property.
/// </summary>
/// <param name="member">The member.</param>
/// <returns>
/// <c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
/// </returns>
public static bool IsIndexedProperty(MemberInfo member)
{
ValidationUtils.ArgumentNotNull(member, "member");
PropertyInfo propertyInfo = member as PropertyInfo;
if (propertyInfo != null)
return IsIndexedProperty(propertyInfo);
else
return false;
}
/// <summary>
/// Determines whether the property is an indexed property.
/// </summary>
/// <param name="property">The property.</param>
/// <returns>
/// <c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
/// </returns>
public static bool IsIndexedProperty(PropertyInfo property)
{
ValidationUtils.ArgumentNotNull(property, "property");
return (property.GetIndexParameters().Length > 0);
}
public static MemberInfo GetMember(Type type, string name, MemberTypes memberTypes)
{
return GetMember(type, name, memberTypes, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
}
public static MemberInfo GetMember(Type type, string name, MemberTypes memberTypes, BindingFlags bindingAttr)
{
ValidationUtils.ArgumentNotNull(type, "type");
ValidationUtils.ArgumentNotNull(name, "name");
MemberInfo[] result = type.GetMember(name, memberTypes, bindingAttr);
return CollectionUtils.GetSingleItem<MemberInfo>(result);
}
/// <summary>
/// Gets the member's value on the object.
/// </summary>
/// <param name="member">The member.</param>
/// <param name="target">The target object.</param>
/// <returns>The member's value on the object.</returns>
public static object GetMemberValue(MemberInfo member, object target)
{
ValidationUtils.ArgumentNotNull(member, "member");
ValidationUtils.ArgumentNotNull(target, "target");
switch (member.MemberType)
{
case MemberTypes.Field:
return ((FieldInfo)member).GetValue(target);
case MemberTypes.Property:
try
{
return ((PropertyInfo)member).GetValue(target, null);
}
catch (TargetParameterCountException e)
{
throw new ArgumentException(string.Format("MemberInfo '{0}' has index parameters", member.Name), "member", e);
}
default:
throw new ArgumentException(string.Format("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo", member.Name), "member");
}
}
/// <summary>
/// Sets the member's value on the target object.
/// </summary>
/// <param name="member">The member.</param>
/// <param name="target">The target.</param>
/// <param name="value">The value.</param>
public static void SetMemberValue(MemberInfo member, object target, object value)
{
ValidationUtils.ArgumentNotNull(member, "member");
ValidationUtils.ArgumentNotNull(target, "target");
switch (member.MemberType)
{
case MemberTypes.Field:
((FieldInfo)member).SetValue(target, value);
break;
case MemberTypes.Property:
((PropertyInfo)member).SetValue(target, value, null);
break;
default:
throw new ArgumentException(string.Format("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo", member.Name), "member");
}
}
/// <summary>
/// Determines whether the specified MemberInfo can be read.
/// </summary>
/// <param name="member">The MemberInfo to determine whether can be read.</param>
/// <returns>
/// <c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
/// </returns>
public static bool CanReadMemberValue(MemberInfo member)
{
switch (member.MemberType)
{
case MemberTypes.Field:
return true;
case MemberTypes.Property:
return ((PropertyInfo)member).CanRead;
default:
return false;
}
}
/// <summary>
/// Determines whether the specified MemberInfo can be set.
/// </summary>
/// <param name="member">The MemberInfo to determine whether can be set.</param>
/// <returns>
/// <c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
/// </returns>
public static bool CanSetMemberValue(MemberInfo member)
{
switch (member.MemberType)
{
case MemberTypes.Field:
return true;
case MemberTypes.Property:
return ((PropertyInfo)member).CanWrite;
default:
return false;
}
}
public static List<MemberInfo> GetFieldsAndProperties<T>(BindingFlags bindingAttr)
{
return GetFieldsAndProperties(typeof(T), bindingAttr);
}
public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
{
List<MemberInfo> targetMembers = new List<MemberInfo>();
targetMembers.AddRange(type.GetFields(bindingAttr));
targetMembers.AddRange(type.GetProperties(bindingAttr));
return targetMembers;
}
public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
{
return GetAttribute<T>(attributeProvider, true);
}
public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
{
T[] attributes = GetAttributes<T>(attributeProvider, inherit);
return CollectionUtils.GetSingleItem(attributes, true);
}
public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
{
ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
}
public static string GetNameAndAssessmblyName(Type t)
{
ValidationUtils.ArgumentNotNull(t, "t");
return t.FullName + ", " + t.Assembly.GetName().Name;
}
public static List<MemberInfo> FindMembers(Type targetType, MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
{
ValidationUtils.ArgumentNotNull(targetType, "targetType");
List<MemberInfo> memberInfos = new List<MemberInfo>(targetType.FindMembers(memberType, bindingAttr, filter, filterCriteria));
// fix weirdness with FieldInfos only being returned for the current Type
// find base type fields and add them to result
if ((memberType & MemberTypes.Field) != 0
&& (bindingAttr & BindingFlags.NonPublic) != 0)
{
// modify flags to not search for public fields
BindingFlags nonPublicBindingAttr = bindingAttr ^ BindingFlags.Public;
while ((targetType = targetType.BaseType) != null)
{
memberInfos.AddRange(targetType.FindMembers(MemberTypes.Field, nonPublicBindingAttr, filter, filterCriteria));
}
}
return memberInfos;
}
public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
{
ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition, "genericTypeDefinition", string.Format("Type {0} is not a generic type definition.", genericTypeDefinition));
return genericTypeDefinition.MakeGenericType(innerTypes);
}
public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
{
return CreateGeneric(genericTypeDefinition, new Type[] { innerType }, args);
}
public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
{
ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
Type specificType = MakeGenericType(genericTypeDefinition, CollectionUtils.CreateArray(innerTypes));
return Activator.CreateInstance(specificType, args);
}
}
}
@@ -0,0 +1,396 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace Newtonsoft.Json.Utilities
{
internal static class StringUtils
{
public const string CarriageReturnLineFeed = "\r\n";
public const string Empty = "";
public const char CarriageReturn = '\r';
public const char LineFeed = '\n';
public const char Tab = '\t';
/// <summary>
/// Determines whether the string contains white space.
/// </summary>
/// <param name="s">The string to test for white space.</param>
/// <returns>
/// <c>true</c> if the string contains white space; otherwise, <c>false</c>.
/// </returns>
public static bool ContainsWhiteSpace(string s)
{
if (s == null)
throw new ArgumentNullException("s");
for (int i = 0; i < s.Length; i++)
{
if (char.IsWhiteSpace(s[i]))
return true;
}
return false;
}
/// <summary>
/// Determines whether the string is all white space. Empty string will return false.
/// </summary>
/// <param name="s">The string to test whether it is all white space.</param>
/// <returns>
/// <c>true</c> if the string is all white space; otherwise, <c>false</c>.
/// </returns>
public static bool IsWhiteSpace(string s)
{
if (s == null)
throw new ArgumentNullException("s");
if (s.Length == 0)
return false;
for (int i = 0; i < s.Length; i++)
{
if (!char.IsWhiteSpace(s[i]))
return false;
}
return true;
}
/// <summary>
/// Ensures the target string ends with the specified string.
/// </summary>
/// <param name="target">The target.</param>
/// <param name="value">The value.</param>
/// <returns>The target string with the value string at the end.</returns>
public static string EnsureEndsWith(string target, string value)
{
if (target == null)
throw new ArgumentNullException("target");
if (value == null)
throw new ArgumentNullException("value");
if (target.Length >= value.Length)
{
if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) ==
0)
return target;
string trimmedString = target.TrimEnd(null);
if (string.Compare(trimmedString, trimmedString.Length - value.Length, value, 0, value.Length,
StringComparison.OrdinalIgnoreCase) == 0)
return target;
}
return target + value;
}
/// <summary>
/// Determines whether the SqlString is null or empty.
/// </summary>
/// <param name="s">The string.</param>
/// <returns>
/// <c>true</c> if the SqlString is null or empty; otherwise, <c>false</c>.
/// </returns>
public static bool IsNullOrEmpty(SqlString s)
{
if (s.IsNull)
return true;
else
return string.IsNullOrEmpty(s.Value);
}
public static bool IsNullOrEmptyOrWhiteSpace(string s)
{
if (string.IsNullOrEmpty(s))
return true;
else if (IsWhiteSpace(s))
return true;
else
return false;
}
/// <summary>
/// Perform an action if the string is not null or empty.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="action">The action to perform.</param>
public static void IfNotNullOrEmpty(string value, Action<string> action)
{
IfNotNullOrEmpty(value, action, null);
}
private static void IfNotNullOrEmpty(string value, Action<string> trueAction, Action<string> falseAction)
{
if (!string.IsNullOrEmpty(value))
{
if (trueAction != null)
trueAction(value);
}
else
{
if (falseAction != null)
falseAction(value);
}
}
/// <summary>
/// Indents the specified string.
/// </summary>
/// <param name="s">The string to indent.</param>
/// <param name="indentation">The number of characters to indent by.</param>
/// <returns></returns>
public static string Indent(string s, int indentation)
{
return Indent(s, indentation, ' ');
}
/// <summary>
/// Indents the specified string.
/// </summary>
/// <param name="s">The string to indent.</param>
/// <param name="indentation">The number of characters to indent by.</param>
/// <param name="indentChar">The indent character.</param>
/// <returns></returns>
public static string Indent(string s, int indentation, char indentChar)
{
if (s == null)
throw new ArgumentNullException("s");
if (indentation <= 0)
throw new ArgumentException("Must be greater than zero.", "indentation");
StringReader sr = new StringReader(s);
StringWriter sw = new StringWriter();
ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
{
tw.Write(new string(indentChar, indentation));
tw.Write(line);
});
return sw.ToString();
}
private delegate void ActionLine(TextWriter textWriter, string line);
private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction)
{
string line;
bool firstLine = true;
while ((line = textReader.ReadLine()) != null)
{
if (!firstLine)
textWriter.WriteLine();
else
firstLine = false;
lineAction(textWriter, line);
}
}
/// <summary>
/// Numbers the lines.
/// </summary>
/// <param name="s">The string to number.</param>
/// <returns></returns>
public static string NumberLines(string s)
{
if (s == null)
throw new ArgumentNullException("s");
StringReader sr = new StringReader(s);
StringWriter sw = new StringWriter();
int lineNumber = 1;
ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
{
tw.Write(lineNumber.ToString().PadLeft(4));
tw.Write(". ");
tw.Write(line);
lineNumber++;
});
return sw.ToString();
}
/// <summary>
/// Nulls an empty string.
/// </summary>
/// <param name="s">The string.</param>
/// <returns>Null if the string was null, otherwise the string unchanged.</returns>
public static string NullEmptyString(string s)
{
return (string.IsNullOrEmpty(s)) ? null : s;
}
public static string ReplaceNewLines(string s, string replacement)
{
StringReader sr = new StringReader(s);
StringBuilder sb = new StringBuilder();
bool first = true;
string line;
while ((line = sr.ReadLine()) != null)
{
if (first)
first = false;
else
sb.Append(replacement);
sb.Append(line);
}
return sb.ToString();
}
public static string RemoveHtml(string s)
{
return RemoveHtmlInternal(s, null);
}
public static string RemoveHtml(string s, IList<string> removeTags)
{
if (removeTags == null)
throw new ArgumentNullException("removeTags");
return RemoveHtmlInternal(s, removeTags);
}
private static string RemoveHtmlInternal(string s, IList<string> removeTags)
{
List<string> removeTagsUpper = null;
if (removeTags != null)
{
removeTagsUpper = new List<string>(removeTags.Count);
foreach (string tag in removeTags)
{
removeTagsUpper.Add(tag.ToUpperInvariant());
}
}
Regex anyTag = new Regex(@"<[/]{0,1}\s*(?<tag>\w*)\s*(?<attr>.*?=['""].*?[""'])*?\s*[/]{0,1}>", RegexOptions.Compiled);
return anyTag.Replace(s, delegate(Match match)
{
string tag = match.Groups["tag"].Value.ToUpperInvariant();
if (removeTagsUpper == null)
return string.Empty;
else if (removeTagsUpper.Contains(tag))
return string.Empty;
else
return match.Value;
});
}
public static string Truncate(string s, int maximumLength)
{
return Truncate(s, maximumLength, "...");
}
public static string Truncate(string s, int maximumLength, string suffix)
{
if (suffix == null)
throw new ArgumentNullException("suffix");
if (maximumLength <= 0)
throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength");
int subStringLength = maximumLength - suffix.Length;
if (subStringLength <= 0)
throw new ArgumentException("Length of suffix string is greater or equal to maximumLength");
if (s != null && s.Length > maximumLength)
{
string truncatedString = s.Substring(0, subStringLength);
// incase the last character is a space
truncatedString = truncatedString.Trim();
truncatedString += suffix;
return truncatedString;
}
else
{
return s;
}
}
public static StringWriter CreateStringWriter(int capacity)
{
StringBuilder sb = new StringBuilder(capacity);
StringWriter sw = new StringWriter(sb);
return sw;
}
public static int? GetLength(string value)
{
if (value == null)
return null;
else
return value.Length;
}
public static string ToCharAsUnicode(char c)
{
using (StringWriter w = new StringWriter())
{
WriteCharAsUnicode(w, c);
return w.ToString();
}
}
public static void WriteCharAsUnicode(TextWriter writer, char c)
{
ValidationUtils.ArgumentNotNull(writer, "writer");
char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
char h4 = MathUtils.IntToHex(c & '\x000f');
writer.Write('\\');
writer.Write('u');
writer.Write(h1);
writer.Write(h2);
writer.Write(h3);
writer.Write(h4);
}
}
}
@@ -0,0 +1,148 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Newtonsoft.Json.Utilities
{
internal static class ValidationUtils
{
public const string EmailAddressRegex = @"^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$";
public const string CurrencyRegex = @"(^\$?(?!0,?\d)\d{1,3}(,?\d{3})*(\.\d\d)?)$";
public const string DateRegex =
@"^(((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$";
public const string NumericRegex = @"\d*";
public static void ArgumentNotNullOrEmpty(string value, string parameterName)
{
if (value == null)
throw new ArgumentNullException(parameterName);
if (value.Length == 0)
throw new ArgumentException(string.Format("'{0}' cannot be empty.", parameterName), parameterName);
}
public static void ArgumentNotNullOrEmptyOrWhitespace(string value, string parameterName)
{
ArgumentNotNullOrEmpty(value, parameterName);
if (StringUtils.IsWhiteSpace(value))
throw new ArgumentException(string.Format("'{0}' cannot only be whitespace.", parameterName), parameterName);
}
public static void ArgumentTypeIsEnum(Type enumType, string parameterName)
{
ArgumentNotNull(enumType, "enumType");
if (!enumType.IsEnum)
throw new ArgumentException(string.Format("Type {0} is not an Enum.", enumType), parameterName);
}
public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName)
{
ArgumentNotNullOrEmpty<T>(collection, parameterName, string.Format("Collection '{0}' cannot be empty.", parameterName));
}
public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName, string message)
{
if (collection == null)
throw new ArgumentNullException(parameterName);
if (collection.Count == 0)
throw new ArgumentException(message, parameterName);
}
public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName)
{
ArgumentNotNullOrEmpty(collection, parameterName, string.Format("Collection '{0}' cannot be empty.", parameterName));
}
public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName, string message)
{
if (collection == null)
throw new ArgumentNullException(parameterName);
if (collection.Count == 0)
throw new ArgumentException(message, parameterName);
}
public static void ArgumentNotNull(object value, string parameterName)
{
if (value == null)
throw new ArgumentNullException(parameterName);
}
public static void ArgumentNotNegative(int value, string parameterName)
{
if (value <= 0)
throw new ArgumentOutOfRangeException(parameterName, value, "Argument cannot be negative.");
}
public static void ArgumentNotNegative(int value, string parameterName, string message)
{
if (value <= 0)
throw new ArgumentOutOfRangeException(parameterName, value, message);
}
public static void ArgumentNotZero(int value, string parameterName)
{
if (value == 0)
throw new ArgumentOutOfRangeException(parameterName, value, "Argument cannot be zero.");
}
public static void ArgumentNotZero(int value, string parameterName, string message)
{
if (value == 0)
throw new ArgumentOutOfRangeException(parameterName, value, message);
}
public static void ArgumentIsPositive<T>(T value, string parameterName) where T : struct, IComparable<T>
{
if (value.CompareTo(default(T)) != 1)
throw new ArgumentOutOfRangeException(parameterName, value, "Positive number required.");
}
public static void ArgumentIsPositive(int value, string parameterName, string message)
{
if (value > 0)
throw new ArgumentOutOfRangeException(parameterName, value, message);
}
public static void ObjectNotDisposed(bool disposed, Type objectType)
{
if (disposed)
throw new ObjectDisposedException(objectType.Name);
}
public static void ArgumentConditionTrue(bool condition, string parameterName, string message)
{
if (!condition)
throw new ArgumentException(message, parameterName);
}
}
}