├── .gitignore ├── JsonFx ├── History.txt ├── JsonFx.Json.UnitTests │ ├── JsonFx.Json.UnitTests.csproj │ ├── JsonFx.Json.UnitTests.pidb │ ├── License.txt │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── AssemblyVersion.cs │ ├── UnitTests │ │ ├── JsonText.cs │ │ ├── ReadMe.txt │ │ └── StronglyTyped.cs │ └── bin │ │ ├── Debug │ │ ├── JsonFx.Json.UnitTests.exe │ │ ├── JsonFx.Json.UnitTests.exe.mdb │ │ ├── JsonFx.Json.dll │ │ ├── JsonFx.Json.dll.mdb │ │ ├── License.txt │ │ ├── Readme.txt │ │ └── UnitTests │ │ │ └── ReadMe.txt │ │ └── Release │ │ ├── JsonFx.Json.UnitTests.exe │ │ ├── JsonFx.Json.dll │ │ ├── License.txt │ │ ├── Readme.txt │ │ └── UnitTests │ │ └── ReadMe.txt ├── JsonFx.Json.sln ├── JsonFx.Json.userprefs ├── JsonFx.Json │ ├── About.cs │ ├── DataReaderProvider.cs │ ├── DataWriterProvider.cs │ ├── EcmaScriptIdentifier.cs │ ├── EcmaScriptWriter.cs │ ├── IDataReader.cs │ ├── IDataWriter.cs │ ├── IJsonSerializable.cs │ ├── JsonDataReader.cs │ ├── JsonDataWriter.cs │ ├── JsonFx.Json.csproj │ ├── JsonFx.Json.pidb │ ├── JsonIgnoreAttribute.cs │ ├── JsonMemberAttribute.cs │ ├── JsonNameAttribute.cs │ ├── JsonOptInAttribute.cs │ ├── JsonReader.cs │ ├── JsonReaderSettings.cs │ ├── JsonSerializationException.cs │ ├── JsonSpecifiedPropertyAttribute.cs │ ├── JsonToken.cs │ ├── JsonWriter.cs │ ├── JsonWriterSettings.cs │ ├── License.txt │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── AssemblyVersion.cs │ ├── Readme.txt │ ├── Scripts │ │ └── json2.js │ ├── TypeCoercionUtility.cs │ ├── XmlDataReader.cs │ └── XmlDataWriter.cs └── TODO.txt └── Unity Examples ├── JsonConverters.cs └── JsonFxDemo.cs /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | *.suo 3 | JsonFx/JsonFx.Json/bin 4 | JsonFx/JsonFx.Json/obj 5 | JsonFx/JsonFx.Json.UnitTests/bin 6 | JsonFx/JsonFx.Json.UnitTests/obj 7 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/JsonFx.Json.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {9F616133-A5C3-48C7-95F3-2DCC01F8B03F} 9 | Exe 10 | Properties 11 | JsonFx.Json 12 | JsonFx.Json.UnitTests 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | v2.0 22 | 23 | 24 | 25 | 26 | 2.0 27 | publish\ 28 | true 29 | Disk 30 | false 31 | Foreground 32 | 7 33 | Days 34 | false 35 | false 36 | true 37 | 0 38 | 1.0.0.%2a 39 | false 40 | false 41 | true 42 | 43 | 44 | true 45 | full 46 | false 47 | bin\Debug\ 48 | DEBUG;TRACE 49 | prompt 50 | 4 51 | 52 | 53 | pdbonly 54 | true 55 | bin\Release\ 56 | TRACE 57 | prompt 58 | 4 59 | false 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Code 72 | 73 | 74 | 75 | 76 | Always 77 | 78 | 79 | Always 80 | 81 | 82 | 83 | 84 | False 85 | .NET Framework 3.5 SP1 Client Profile 86 | false 87 | 88 | 89 | False 90 | .NET Framework 3.5 SP1 91 | true 92 | 93 | 94 | False 95 | Windows Installer 3.1 96 | true 97 | 98 | 99 | 100 | 101 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB} 102 | JsonFx.Json 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/JsonFx.Json.UnitTests.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/JsonFx.Json.UnitTests.pidb -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/License.txt: -------------------------------------------------------------------------------- 1 | Distributed under the terms of an MIT-style license: 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2006-2009 Stephen M. McKamey 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/Program.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2008 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Text; 34 | using System.Diagnostics; 35 | 36 | using JsonFx.Json; 37 | 38 | namespace JsonFx.Json.Test 39 | { 40 | class Program 41 | { 42 | #region Constants 43 | 44 | private const string ReportPath = "{0:yyyy-MM-dd-HHmmss}_Report.txt"; 45 | private const string UnitTestsFolder = @".\UnitTests\"; 46 | private const string OutputFolder = @".\Output\"; 47 | private const string HeaderMessage = 48 | "NOTE: JsonFx.Json accepts all valid JSON and can recover from many minor errors.\r\n\r\n"+ 49 | "Unit Test Report ({0:yyyy-MM-dd @ HH:mm:ss})"; 50 | 51 | #endregion Constants 52 | 53 | #region Program Entry 54 | 55 | static void Main(string[] args) 56 | { 57 | DateTime now = DateTime.Now; 58 | string reportPath = String.Format(ReportPath, now); 59 | const int Count = 100; 60 | double total = 0; 61 | 62 | for (int i=0; i 0) 59 | { 60 | JsonReaderSettings readerSettings = new JsonReaderSettings(); 61 | readerSettings.TypeHintName = StronglyTyped.MyTypeHintName; 62 | readerSettings.AllowNullValueTypes = true; 63 | readerSettings.AllowUnquotedObjectKeys = true; 64 | 65 | JsonWriterSettings writerSettings = new JsonWriterSettings(); 66 | writerSettings.TypeHintName = StronglyTyped.MyTypeHintName; 67 | writerSettings.PrettyPrint = false; 68 | writerSettings.MaxDepth = 100; 69 | 70 | writer.WriteLine(JsonText.Seperator); 71 | writer.WriteLine("JsonReaderSettings:"); 72 | new JsonWriter(writer).Write(readerSettings); 73 | 74 | writer.WriteLine(JsonText.Seperator); 75 | writer.WriteLine("JsonWriterSettings:"); 76 | new JsonWriter(writer).Write(writerSettings); 77 | 78 | foreach (string unitTest in unitTests) 79 | { 80 | string source = String.Empty; 81 | 82 | try 83 | { 84 | writer.WriteLine(JsonText.Seperator); 85 | 86 | source = File.ReadAllText(unitTest); 87 | JsonReader jsonReader = new JsonReader(source, readerSettings); 88 | 89 | object obj, obj2; 90 | obj2 = obj = jsonReader.Deserialize(); 91 | 92 | do 93 | { 94 | writer.WriteLine("READ: {0}", unitTest.Replace(unitTestsFolder, "")); 95 | writer.WriteLine("Result: {0}", (obj == null) ? "null" : obj.GetType().FullName); 96 | 97 | obj = jsonReader.Deserialize(); 98 | } while (obj != null); 99 | 100 | string outputFile = unitTest.Replace(unitTestsFolder, outputFolder); 101 | string outputDir = Path.GetDirectoryName(outputFile); 102 | if (!Directory.Exists(outputDir)) 103 | { 104 | Directory.CreateDirectory(outputDir); 105 | } 106 | using (JsonWriter jsonWriter = new JsonWriter(outputFile, writerSettings)) 107 | { 108 | jsonWriter.Write(obj2); 109 | } 110 | } 111 | catch (JsonDeserializationException ex) 112 | { 113 | int col, line; 114 | ex.GetLineAndColumn(source, out line, out col); 115 | 116 | writer.WriteLine("ERROR: {0}", unitTest.Replace(unitTestsFolder, "")); 117 | writer.WriteLine("-- \"{0}\" ({1}, {2})", ex.Message, line, col); 118 | continue; 119 | } 120 | catch (Exception ex) 121 | { 122 | writer.WriteLine("ERROR: {0}", unitTest.Replace(unitTestsFolder, "")); 123 | writer.WriteLine("-- \"{0}\"", ex.Message); 124 | continue; 125 | } 126 | } 127 | } 128 | else 129 | { 130 | writer.WriteLine(ErrorMessage); 131 | } 132 | } 133 | 134 | #endregion Methods 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/UnitTests/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Any *.json file in this folder will be processed. 2 | 3 | Download http://www.json.org/JSON_checker/test.zip and place contents into this folder. 4 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/UnitTests/StronglyTyped.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2008 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.ComponentModel; 34 | using System.Collections; 35 | using System.Collections.Generic; 36 | using System.Collections.Specialized; 37 | using System.Text; 38 | 39 | using JsonFx.Json; 40 | 41 | namespace JsonFx.Json.Test.UnitTests 42 | { 43 | /* A set of objects used to test strongly-typed serialization */ 44 | 45 | public class StronglyTyped 46 | { 47 | #region Constants 48 | 49 | public const string MyTypeHintName = "__type"; 50 | 51 | #endregion Constants 52 | 53 | #region Methods 54 | 55 | public static void RunTest(TextWriter writer, string unitTestsFolder, string outputFolder) 56 | { 57 | JsonReaderSettings readerSettings = new JsonReaderSettings(); 58 | readerSettings.TypeHintName = StronglyTyped.MyTypeHintName; 59 | readerSettings.AllowNullValueTypes = true; 60 | readerSettings.AllowUnquotedObjectKeys = false; 61 | 62 | JsonWriterSettings writerSettings = new JsonWriterSettings(); 63 | writerSettings.TypeHintName = StronglyTyped.MyTypeHintName; 64 | writerSettings.PrettyPrint = true; 65 | writerSettings.MaxDepth = 100; 66 | 67 | writer.WriteLine(JsonText.Seperator); 68 | writer.WriteLine("JsonReaderSettings:"); 69 | new JsonWriter(writer).Write(readerSettings); 70 | 71 | writer.WriteLine(JsonText.Seperator); 72 | writer.WriteLine("JsonWriterSettings:"); 73 | new JsonWriter(writer).Write(writerSettings); 74 | 75 | #region Simple Root Types 76 | 77 | SerializeDeserialize(writer, unitTestsFolder, "RootEnum.json", BlahBlah.Three, readerSettings, writerSettings); 78 | 79 | SerializeDeserialize(writer, unitTestsFolder, "RootInt64.json", 42678L, readerSettings, writerSettings); 80 | 81 | SerializeDeserialize(writer, unitTestsFolder, "RootDateTime.json", DateTime.Now, readerSettings, writerSettings); 82 | 83 | #endregion Simple Root Types 84 | 85 | #region Strongly Typed Object Graph Test 86 | 87 | ComplexObject collectionTest = new ComplexObject(); 88 | 89 | collectionTest.MyNested = new NestedObject(); 90 | collectionTest.MyNested.Items = new Dictionary(); 91 | collectionTest.MyNested.Items["First"] = 3.14159; 92 | collectionTest.MyNested.Items["Second"] = "Hello World"; 93 | collectionTest.MyNested.Items["Third"] = 42; 94 | collectionTest.MyNested.Items["Fourth"] = true; 95 | 96 | collectionTest.MyNested.Hash = new Hashtable(collectionTest.MyNested.Items); 97 | 98 | collectionTest.MyNested.Hybrid = new HybridDictionary(); 99 | foreach (string key in collectionTest.MyNested.Items.Keys) 100 | { 101 | collectionTest.MyNested.Hybrid[key] = collectionTest.MyNested.Items[key]; 102 | } 103 | 104 | // populate with an Array 105 | collectionTest.MyArray = new SimpleObject[]{ 106 | new SimpleObject(BlahBlah.Four), 107 | new SimpleObject(BlahBlah.Three), 108 | new SimpleObject(BlahBlah.Two), 109 | new SimpleObject(BlahBlah.One), 110 | new SimpleObject() 111 | }; 112 | 113 | // duplicate for ArrayList 114 | collectionTest.MyArrayList = new ArrayList(collectionTest.MyArray); 115 | 116 | // duplicate for List 117 | collectionTest.MyList = new List(collectionTest.MyArray); 118 | 119 | // duplicate for LinkedList 120 | collectionTest.MyLinkedList = new LinkedList(collectionTest.MyArray); 121 | 122 | // duplicate for Stack 123 | collectionTest.MyStack = new Stack(collectionTest.MyArray); 124 | 125 | // duplicate for Queue 126 | collectionTest.MyQueue = new Queue(collectionTest.MyArray); 127 | 128 | SerializeDeserialize(writer, unitTestsFolder, "StronglyTyped.json", collectionTest, readerSettings, writerSettings); 129 | 130 | #endregion Strongly Typed Object Graph Test 131 | 132 | #region Non-IDictionary, IDictionary Test 133 | 134 | NotIDictionary notIDictionary = new NotIDictionary(); 135 | notIDictionary["This Collection"] = "is not an IDictionary"; 136 | notIDictionary["But It is"] = "an IDictionary"; 137 | 138 | SerializeDeserialize(writer, unitTestsFolder, "NotIDictionary.json", notIDictionary, readerSettings, writerSettings); 139 | 140 | #endregion Non-IDictionary ,IDictionary Test 141 | } 142 | 143 | private static void SerializeDeserialize(TextWriter writer, string unitTestsFolder, string unitTestFile, object obj, JsonReaderSettings readerSettings, JsonWriterSettings writerSettings) 144 | { 145 | writer.WriteLine(JsonText.Seperator); 146 | 147 | string source = String.Empty; 148 | try 149 | { 150 | using (JsonWriter jsonWriter = new JsonWriter(unitTestsFolder+unitTestFile, writerSettings)) 151 | { 152 | jsonWriter.Write(obj); 153 | } 154 | 155 | source = File.ReadAllText(unitTestsFolder+unitTestFile); 156 | 157 | obj = new JsonReader(source, readerSettings).Deserialize((obj == null) ? null : obj.GetType()); 158 | writer.WriteLine("READ: "+unitTestFile); 159 | writer.WriteLine("Result: {0}", (obj == null) ? "null" : obj.GetType().FullName); 160 | } 161 | catch (JsonDeserializationException ex) 162 | { 163 | int col, line; 164 | writer.WriteLine("ERROR: "+unitTestFile); 165 | ex.GetLineAndColumn(source, out line, out col); 166 | writer.WriteLine("-- \"{0}\" ({1}, {2})", ex.Message, line, col); 167 | } 168 | catch (Exception ex) 169 | { 170 | writer.WriteLine("ERROR: "+unitTestFile); 171 | writer.WriteLine("-- \"{0}\"", ex.Message); 172 | } 173 | } 174 | 175 | #endregion Methods 176 | } 177 | 178 | public class ComplexObject 179 | { 180 | #region Fields 181 | 182 | private Decimal myDecimal = 0.12345678901234567890123456789m; 183 | private Guid myGuid = Guid.NewGuid(); 184 | private TimeSpan myTimeSpan = new TimeSpan(5, 4, 3, 2, 1); 185 | private Version myVersion = new Version(1, 2, 3, 4); 186 | private Uri myUri = new Uri("http://jsonfx.net/BuildTools"); 187 | private DateTime myDateTime = DateTime.UtcNow; 188 | private Nullable myNullableInt32 = null; 189 | private Nullable myNullableInt64a = null; 190 | private Nullable myNullableInt64b = 42; 191 | private Nullable myNullableDateTime = DateTime.Now; 192 | private SimpleObject[] myArray = null; 193 | private ArrayList myArrayList = null; 194 | private List myList = null; 195 | private LinkedList myLinkedList = null; 196 | private Stack myStack = null; 197 | private Queue myQueue = null; 198 | private NestedObject myNested = null; 199 | 200 | #endregion Fields 201 | 202 | #region Properties 203 | 204 | [JsonName("AnArbitraryRenameForMyNestedProperty")] 205 | public NestedObject MyNested 206 | { 207 | get { return this.myNested; } 208 | set { this.myNested = value; } 209 | } 210 | 211 | public Decimal MyDecimal 212 | { 213 | get { return this.myDecimal; } 214 | set { this.myDecimal = value; } 215 | } 216 | 217 | public Guid MyGuid 218 | { 219 | get { return this.myGuid; } 220 | set { this.myGuid = value; } 221 | } 222 | 223 | public TimeSpan MyTimeSpan 224 | { 225 | get { return this.myTimeSpan; } 226 | set { this.myTimeSpan = value; } 227 | } 228 | 229 | public Version MyVersion 230 | { 231 | get { return this.myVersion; } 232 | set { this.myVersion = value; } 233 | } 234 | 235 | public Uri MyUri 236 | { 237 | get { return this.myUri; } 238 | set { this.myUri = value; } 239 | } 240 | 241 | public DateTime MyDateTime 242 | { 243 | get { return this.myDateTime; } 244 | set { this.myDateTime = value; } 245 | } 246 | 247 | public Nullable MyNullableInt32 248 | { 249 | get { return this.myNullableInt32; } 250 | set { this.myNullableInt32 = value; } 251 | } 252 | 253 | public Nullable MyNullableDateTime 254 | { 255 | get { return this.myNullableDateTime; } 256 | set { this.myNullableDateTime = value; } 257 | } 258 | 259 | [DefaultValue(null)] 260 | public Nullable MyNullableInt64a 261 | { 262 | get { return this.myNullableInt64a; } 263 | set { this.myNullableInt64a = value; } 264 | } 265 | 266 | [DefaultValue(null)] 267 | public Nullable MyNullableInt64b 268 | { 269 | get { return this.myNullableInt64b; } 270 | set { this.myNullableInt64b = value; } 271 | } 272 | 273 | public SimpleObject[] MyArray 274 | { 275 | get { return this.myArray; } 276 | set { this.myArray = value; } 277 | } 278 | 279 | public ArrayList MyArrayList 280 | { 281 | get { return this.myArrayList; } 282 | set { this.myArrayList = value; } 283 | } 284 | 285 | public List MyList 286 | { 287 | get { return this.myList; } 288 | set { this.myList = value; } 289 | } 290 | 291 | [JsonSpecifiedProperty("SerializeMyStack")] 292 | public Stack MyStack 293 | { 294 | get { return this.myStack; } 295 | set { this.myStack = value; } 296 | } 297 | 298 | [JsonIgnore] 299 | public bool SerializeMyStack 300 | { 301 | get { return false; } 302 | set { /* do nothing */ } 303 | } 304 | 305 | public LinkedList MyLinkedList 306 | { 307 | get { return this.myLinkedList; } 308 | set { this.myLinkedList = value; } 309 | } 310 | 311 | public Queue MyQueue 312 | { 313 | get { return this.myQueue; } 314 | set { this.myQueue = value; } 315 | } 316 | 317 | #endregion Properties 318 | } 319 | 320 | public class NotIDictionary : IDictionary 321 | { 322 | #region Fields 323 | 324 | private IDictionary dictionary = new Dictionary(); 325 | 326 | #endregion Fields 327 | 328 | #region IDictionary Members 329 | 330 | public object this[string key] 331 | { 332 | get { return this.dictionary[key]; } 333 | set { this.dictionary[key] = value; } 334 | } 335 | 336 | void IDictionary.Add(string key, object value) 337 | { 338 | this.dictionary.Add(key, value); 339 | } 340 | 341 | bool IDictionary.ContainsKey(string key) 342 | { 343 | return this.dictionary.ContainsKey(key); 344 | } 345 | 346 | ICollection IDictionary.Keys 347 | { 348 | get { return this.dictionary.Keys; } 349 | } 350 | 351 | bool IDictionary.Remove(string key) 352 | { 353 | return this.dictionary.Remove(key); 354 | } 355 | 356 | bool IDictionary.TryGetValue(string key, out object value) 357 | { 358 | return this.dictionary.TryGetValue(key, out value); 359 | } 360 | 361 | ICollection IDictionary.Values 362 | { 363 | get { return this.dictionary.Values; } 364 | } 365 | 366 | #endregion IDictionary Members 367 | 368 | #region ICollection> Members 369 | 370 | void ICollection>.Add(KeyValuePair item) 371 | { 372 | ((ICollection>)this.dictionary).Add(item); 373 | } 374 | 375 | void ICollection>.Clear() 376 | { 377 | ((ICollection>)this.dictionary).Clear(); 378 | } 379 | 380 | bool ICollection>.Contains(KeyValuePair item) 381 | { 382 | return ((ICollection>)this.dictionary).Contains(item); 383 | } 384 | 385 | void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) 386 | { 387 | ((ICollection>)this.dictionary).CopyTo(array, arrayIndex); 388 | } 389 | 390 | int ICollection>.Count 391 | { 392 | get { return ((ICollection>)this.dictionary).Count; } 393 | } 394 | 395 | bool ICollection>.IsReadOnly 396 | { 397 | get { return ((ICollection>)this.dictionary).IsReadOnly; } 398 | } 399 | 400 | bool ICollection>.Remove(KeyValuePair item) 401 | { 402 | return ((ICollection>)this.dictionary).Remove(item); 403 | } 404 | 405 | #endregion ICollection> Members 406 | 407 | #region IEnumerable> Members 408 | 409 | IEnumerator> IEnumerable>.GetEnumerator() 410 | { 411 | return ((IEnumerable>)this.dictionary).GetEnumerator(); 412 | } 413 | 414 | #endregion IEnumerable> Members 415 | 416 | #region IEnumerable Members 417 | 418 | IEnumerator IEnumerable.GetEnumerator() 419 | { 420 | return ((IEnumerable)this.dictionary).GetEnumerator(); 421 | } 422 | 423 | #endregion IEnumerable Members 424 | } 425 | 426 | public class NestedObject 427 | { 428 | #region Fields 429 | 430 | private Dictionary items = null; 431 | private Hashtable hash = null; 432 | private HybridDictionary hybrid = null; 433 | 434 | #endregion Fields 435 | 436 | #region Properties 437 | 438 | public Dictionary Items 439 | { 440 | get { return this.items; } 441 | set { this.items = value; } 442 | } 443 | 444 | public Hashtable Hash 445 | { 446 | get { return this.hash; } 447 | set { this.hash = value; } 448 | } 449 | 450 | public HybridDictionary Hybrid 451 | { 452 | get { return this.hybrid; } 453 | set { this.hybrid = value; } 454 | } 455 | 456 | #endregion Properties 457 | } 458 | 459 | public class SimpleObject 460 | { 461 | #region Constants 462 | 463 | private static readonly Random Rand = new Random(); 464 | 465 | #endregion Constants 466 | 467 | #region Fields 468 | 469 | double random; 470 | BlahBlah blah = BlahBlah.None; 471 | 472 | #endregion Fields 473 | 474 | #region Init 475 | 476 | /// 477 | /// Ctor 478 | /// 479 | public SimpleObject() 480 | { 481 | this.random = Rand.NextDouble(); 482 | } 483 | 484 | /// 485 | /// Ctor 486 | /// 487 | public SimpleObject(BlahBlah blah) : this() 488 | { 489 | this.Blah = blah; 490 | } 491 | 492 | #endregion Init 493 | 494 | #region Properties 495 | 496 | public BlahBlah Blah 497 | { 498 | get { return this.blah; } 499 | set { this.blah = value; } 500 | } 501 | 502 | public double Random 503 | { 504 | get { return this.random; } 505 | set { this.random = value; } 506 | } 507 | 508 | #endregion Properties 509 | 510 | #region Object Overrides 511 | 512 | public override string ToString() 513 | { 514 | return String.Format( 515 | "SimpleObject: {0}, {1}", 516 | this.Blah, 517 | this.Random); 518 | } 519 | 520 | #endregion Object Overrides 521 | } 522 | 523 | public enum BlahBlah 524 | { 525 | None, 526 | One, 527 | Two, 528 | Three, 529 | Four 530 | } 531 | 532 | public class ErrorProneSimpleObject : SimpleObject 533 | { 534 | #region Init 535 | 536 | /// 537 | /// Ctor 538 | /// 539 | public ErrorProneSimpleObject() 540 | { 541 | throw new NotImplementedException("ErrorProneSimpleObject always throws an error in the constructor."); 542 | } 543 | 544 | #endregion Init 545 | } 546 | } 547 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.UnitTests.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.UnitTests.exe -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.UnitTests.exe.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.UnitTests.exe.mdb -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.dll -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Debug/JsonFx.Json.dll.mdb -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/License.txt: -------------------------------------------------------------------------------- 1 | Distributed under the terms of an MIT-style license: 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2006-2009 Stephen M. McKamey 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/Readme.txt: -------------------------------------------------------------------------------- 1 | JsonFx.NET - JSON Serializer 2 | 3 | The JsonFx.NET JSON parser/serializer functions similarly to the XmlSerializer in .NET 4 | 5 | Serializes and deserializes any Dictionary and IDictionary with 6 | String keys directly as a JSON object 7 | 8 | Serializes and deserializes any List, ArrayList, LinkedList, Queue and 9 | many other IEnumerable types directly as JSON arrays 10 | 11 | Serializes and deserializes DateTime, Enum, Nullable, Guid and other 12 | common .NET Types directly as JSON primitives 13 | 14 | Serializes and deserializes strongly-typed custom classes (similarly to XML 15 | Serialization in .NET Framework) 16 | 17 | Serializes C# 3.0 Anonymous Types directly as JSON objects 18 | 19 | Serializes C# 3.0 LINQ Queries as JSON arrays of objects (by enumerating the results) 20 | 21 | Follows Postel's Law ("Be conservative in what you do; be liberal in what you accept from others.") 22 | by accepting handling many non-JSON JavaScript concepts: 23 | - Common literals such as "Infinity", "NaN", and "undefined" 24 | - Ignores block and line comments when deserializing 25 | 26 | This version has been modified to work better with Unity3D, especially when building for the iPhone. 27 | No additional .dll dependencies (such as System.Xml) are required. Additional in the sense that Unity does not include them per default. 28 | 29 | Optional ability to control serialization via attributes/interfaces: 30 | 31 | JsonFx.Json.IJsonSerializable: 32 | Interface which allows classes to control their own JSON serialization 33 | 34 | JsonFx.Json.JsonIgnoreAttribute: 35 | Attribute which designates a property or field to not be serialized 36 | 37 | System.ComponentModel.DefaultValueAttribute: 38 | Member does not serialize if the value matches the DefaultValue attribute 39 | 40 | JsonFx.Json.JsonNameAttribute: 41 | Attribute which specifies the naming to use for a property or field when serializing 42 | 43 | JsonFx.Json.JsonSpecifiedPropertyAttribute: 44 | Attribute which specifies the name of the property which specifies if member should be serialized 45 | 46 | JsonFx.Json.JsonOptIn: 47 | Attribute which specifies that all members of the class must be explicitly declared to be included in the serialization (see next) 48 | 49 | JsonFx.Json.JsonMember: 50 | Attribute which explicitly declares the member to be included in the serialization. 51 | 52 | Optional Type-Hinting improves deserializing to strongly-typed objects 53 | 54 | JsonFx.Json.JsonWriter.TypeHintName & JsonFx.Json.JsonReader.TypeHintName: 55 | Property designates the name of the type hint property (e.g. "__type") and enables type hinting 56 | 57 | Optional PrettyPrint mode helps with debugging / human-readability 58 | 59 | JsonFx.Json.JsonWriter.PrettyPrint 60 | 61 | Optional custom DateTime serialization override 62 | 63 | JsonFx.Json.JsonWriter.DateTimeSerializer 64 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Debug/UnitTests/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Any *.json file in this folder will be processed. 2 | 3 | Download http://www.json.org/JSON_checker/test.zip and place contents into this folder. 4 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Release/JsonFx.Json.UnitTests.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Release/JsonFx.Json.UnitTests.exe -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Release/JsonFx.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json.UnitTests/bin/Release/JsonFx.Json.dll -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Release/License.txt: -------------------------------------------------------------------------------- 1 | Distributed under the terms of an MIT-style license: 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2006-2009 Stephen M. McKamey 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Release/Readme.txt: -------------------------------------------------------------------------------- 1 | JsonFx.NET - JSON Serializer 2 | 3 | The JsonFx.NET JSON parser/serializer functions similarly to the XmlSerializer in .NET 4 | 5 | Serializes and deserializes any Dictionary and IDictionary with 6 | String keys directly as a JSON object 7 | 8 | Serializes and deserializes any List, ArrayList, LinkedList, Queue and 9 | many other IEnumerable types directly as JSON arrays 10 | 11 | Serializes and deserializes DateTime, Enum, Nullable, Guid and other 12 | common .NET Types directly as JSON primitives 13 | 14 | Serializes and deserializes strongly-typed custom classes (similarly to XML 15 | Serialization in .NET Framework) 16 | 17 | Serializes C# 3.0 Anonymous Types directly as JSON objects 18 | 19 | Serializes C# 3.0 LINQ Queries as JSON arrays of objects (by enumerating the results) 20 | 21 | Follows Postel's Law ("Be conservative in what you do; be liberal in what you accept from others.") 22 | by accepting handling many non-JSON JavaScript concepts: 23 | - Common literals such as "Infinity", "NaN", and "undefined" 24 | - Ignores block and line comments when deserializing 25 | 26 | This version has been modified to work better with Unity3D, especially when building for the iPhone. 27 | No additional .dll dependencies (such as System.Xml) are required. Additional in the sense that Unity does not include them per default. 28 | 29 | Optional ability to control serialization via attributes/interfaces: 30 | 31 | JsonFx.Json.IJsonSerializable: 32 | Interface which allows classes to control their own JSON serialization 33 | 34 | JsonFx.Json.JsonIgnoreAttribute: 35 | Attribute which designates a property or field to not be serialized 36 | 37 | System.ComponentModel.DefaultValueAttribute: 38 | Member does not serialize if the value matches the DefaultValue attribute 39 | 40 | JsonFx.Json.JsonNameAttribute: 41 | Attribute which specifies the naming to use for a property or field when serializing 42 | 43 | JsonFx.Json.JsonSpecifiedPropertyAttribute: 44 | Attribute which specifies the name of the property which specifies if member should be serialized 45 | 46 | JsonFx.Json.JsonOptIn: 47 | Attribute which specifies that all members of the class must be explicitly declared to be included in the serialization (see next) 48 | 49 | JsonFx.Json.JsonMember: 50 | Attribute which explicitly declares the member to be included in the serialization. 51 | 52 | Optional Type-Hinting improves deserializing to strongly-typed objects 53 | 54 | JsonFx.Json.JsonWriter.TypeHintName & JsonFx.Json.JsonReader.TypeHintName: 55 | Property designates the name of the type hint property (e.g. "__type") and enables type hinting 56 | 57 | Optional PrettyPrint mode helps with debugging / human-readability 58 | 59 | JsonFx.Json.JsonWriter.PrettyPrint 60 | 61 | Optional custom DateTime serialization override 62 | 63 | JsonFx.Json.JsonWriter.DateTimeSerializer 64 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.UnitTests/bin/Release/UnitTests/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Any *.json file in this folder will be processed. 2 | 3 | Download http://www.json.org/JSON_checker/test.zip and place contents into this folder. 4 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JsonFx.Json.UnitTests", "JsonFx.Json.UnitTests\JsonFx.Json.UnitTests.csproj", "{9F616133-A5C3-48C7-95F3-2DCC01F8B03F}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JsonFx.Json", "JsonFx.Json\JsonFx.Json.csproj", "{ABA23F14-7E47-43FE-A3E7-1FF97840C3FB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9F616133-A5C3-48C7-95F3-2DCC01F8B03F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9F616133-A5C3-48C7-95F3-2DCC01F8B03F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9F616133-A5C3-48C7-95F3-2DCC01F8B03F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9F616133-A5C3-48C7-95F3-2DCC01F8B03F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | GlobalSection(MonoDevelopProperties) = preSolution 27 | StartupItem = JsonFx.Json\JsonFx.csproj 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/About.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Reflection; 33 | 34 | namespace JsonFx 35 | { 36 | /// 37 | /// JsonFx metadata 38 | /// 39 | public sealed class About 40 | { 41 | #region Fields 42 | 43 | public static readonly About Fx = new About(typeof(About).Assembly); 44 | 45 | public readonly Version Version; 46 | public readonly string FullName; 47 | public readonly string Name; 48 | public readonly string Configuration; 49 | public readonly string Copyright; 50 | public readonly string Title; 51 | public readonly string Description; 52 | public readonly string Company; 53 | 54 | #endregion Fields 55 | 56 | #region Init 57 | 58 | /// 59 | /// Ctor 60 | /// 61 | public About(Assembly assembly) 62 | { 63 | AssemblyName name = assembly.GetName(); 64 | 65 | this.FullName = assembly.FullName; 66 | this.Version = name.Version; 67 | this.Name = name.Name; 68 | 69 | AssemblyCopyrightAttribute copyright = Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute)) as AssemblyCopyrightAttribute; 70 | this.Copyright = (copyright != null) ? copyright.Copyright : String.Empty; 71 | 72 | AssemblyDescriptionAttribute description = Attribute.GetCustomAttribute(assembly, typeof(AssemblyDescriptionAttribute)) as AssemblyDescriptionAttribute; 73 | this.Description = (description != null) ? description.Description : String.Empty; 74 | 75 | AssemblyTitleAttribute title = Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute)) as AssemblyTitleAttribute; 76 | this.Title = (title != null) ? title.Title : String.Empty; 77 | 78 | AssemblyCompanyAttribute company = Attribute.GetCustomAttribute(assembly, typeof(AssemblyCompanyAttribute)) as AssemblyCompanyAttribute; 79 | this.Company = (company != null) ? company.Company : String.Empty; 80 | 81 | AssemblyConfigurationAttribute config = Attribute.GetCustomAttribute(assembly, typeof(AssemblyConfigurationAttribute)) as AssemblyConfigurationAttribute; 82 | this.Configuration = (config != null) ? config.Configuration : String.Empty; 83 | } 84 | 85 | #endregion Init 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/DataReaderProvider.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Collections.Generic; 33 | 34 | namespace JsonFx.Json 35 | { 36 | public interface IDataReaderProvider 37 | { 38 | IDataReader Find(string contentTypeHeader); 39 | } 40 | 41 | /// 42 | /// Provides lookup capabilities for finding an IDataReader 43 | /// 44 | public class DataReaderProvider : IDataReaderProvider 45 | { 46 | #region Fields 47 | 48 | private readonly IDictionary ReadersByMime = new Dictionary(StringComparer.OrdinalIgnoreCase); 49 | 50 | #endregion Fields 51 | 52 | #region Init 53 | 54 | /// 55 | /// Ctor 56 | /// 57 | /// inject with all possible readers 58 | public DataReaderProvider(IEnumerable readers) 59 | { 60 | if (readers != null) 61 | { 62 | foreach (IDataReader reader in readers) 63 | { 64 | if (!String.IsNullOrEmpty(reader.ContentType)) 65 | { 66 | this.ReadersByMime[reader.ContentType] = reader; 67 | } 68 | } 69 | } 70 | } 71 | 72 | #endregion Init 73 | 74 | #region Methods 75 | 76 | /// 77 | /// Finds an IDataReader by content-type header 78 | /// 79 | /// 80 | /// 81 | public IDataReader Find(string contentTypeHeader) 82 | { 83 | string type = DataWriterProvider.ParseMediaType(contentTypeHeader); 84 | 85 | if (this.ReadersByMime.ContainsKey(type)) 86 | { 87 | return ReadersByMime[type]; 88 | } 89 | 90 | return null; 91 | } 92 | 93 | #endregion Methods 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/DataWriterProvider.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Collections.Generic; 33 | using System.IO; 34 | 35 | namespace JsonFx.Json 36 | { 37 | public interface IDataWriterProvider 38 | { 39 | IDataWriter DefaultDataWriter { get; } 40 | 41 | IDataWriter Find(string extension); 42 | 43 | IDataWriter Find(string acceptHeader, string contentTypeHeader); 44 | } 45 | 46 | /// 47 | /// Provides lookup capabilities for finding an IDataWriter 48 | /// 49 | public class DataWriterProvider : IDataWriterProvider 50 | { 51 | #region Fields 52 | 53 | private readonly IDataWriter DefaultWriter; 54 | private readonly IDictionary WritersByExt = new Dictionary(StringComparer.OrdinalIgnoreCase); 55 | private readonly IDictionary WritersByMime = new Dictionary(StringComparer.OrdinalIgnoreCase); 56 | 57 | #endregion Fields 58 | 59 | #region Init 60 | 61 | /// 62 | /// Ctor 63 | /// 64 | /// inject with all possible writers 65 | public DataWriterProvider(IEnumerable writers) 66 | { 67 | if (writers != null) 68 | { 69 | foreach (IDataWriter writer in writers) 70 | { 71 | if (this.DefaultWriter == null) 72 | { 73 | // TODO: decide less arbitrary way to choose default 74 | // without hardcoding value into IDataWriter 75 | this.DefaultWriter = writer; 76 | } 77 | 78 | if (!String.IsNullOrEmpty(writer.ContentType)) 79 | { 80 | this.WritersByMime[writer.ContentType] = writer; 81 | } 82 | 83 | if (!String.IsNullOrEmpty(writer.ContentType)) 84 | { 85 | string ext = DataWriterProvider.NormalizeExtension(writer.FileExtension); 86 | this.WritersByExt[ext] = writer; 87 | } 88 | } 89 | } 90 | } 91 | 92 | #endregion Init 93 | 94 | #region Properties 95 | 96 | public IDataWriter DefaultDataWriter 97 | { 98 | get { return this.DefaultWriter; } 99 | } 100 | 101 | #endregion Properties 102 | 103 | #region Methods 104 | 105 | public IDataWriter Find(string extension) 106 | { 107 | extension = DataWriterProvider.NormalizeExtension(extension); 108 | 109 | if (this.WritersByExt.ContainsKey(extension)) 110 | { 111 | return WritersByExt[extension]; 112 | } 113 | 114 | return null; 115 | } 116 | 117 | public IDataWriter Find(string acceptHeader, string contentTypeHeader) 118 | { 119 | foreach (string type in DataWriterProvider.ParseHeaders(acceptHeader, contentTypeHeader)) 120 | { 121 | if (this.WritersByMime.ContainsKey(type)) 122 | { 123 | return WritersByMime[type]; 124 | } 125 | } 126 | 127 | return null; 128 | } 129 | 130 | #endregion Methods 131 | 132 | #region Utility Methods 133 | 134 | /// 135 | /// Parses HTTP headers for Media-Types 136 | /// 137 | /// HTTP Accept header 138 | /// HTTP Content-Type header 139 | /// sequence of Media-Types 140 | /// 141 | /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 142 | /// 143 | public static IEnumerable ParseHeaders(string accept, string contentType) 144 | { 145 | string mime; 146 | 147 | // check for a matching accept type 148 | foreach (string type in DataWriterProvider.SplitTrim(accept, ',')) 149 | { 150 | mime = DataWriterProvider.ParseMediaType(type); 151 | if (!String.IsNullOrEmpty(mime)) 152 | { 153 | yield return mime; 154 | } 155 | } 156 | 157 | // fallback on content-type 158 | mime = DataWriterProvider.ParseMediaType(contentType); 159 | if (!String.IsNullOrEmpty(mime)) 160 | { 161 | yield return mime; 162 | } 163 | } 164 | 165 | /// 166 | /// 167 | /// 168 | /// 169 | /// 170 | public static string ParseMediaType(string type) 171 | { 172 | foreach (string mime in DataWriterProvider.SplitTrim(type, ';')) 173 | { 174 | // only return first part 175 | return mime; 176 | } 177 | 178 | // if no parts then was empty 179 | return String.Empty; 180 | } 181 | 182 | private static IEnumerable SplitTrim(string source, char ch) 183 | { 184 | if (String.IsNullOrEmpty(source)) 185 | { 186 | yield break; 187 | } 188 | 189 | int length = source.Length; 190 | for (int prev=0, next=0; prev=0; prev=next+1) 191 | { 192 | next = source.IndexOf(ch, prev); 193 | if (next < 0) 194 | { 195 | next = length; 196 | } 197 | 198 | string part = source.Substring(prev, next-prev).Trim(); 199 | if (part.Length > 0) 200 | { 201 | yield return part; 202 | } 203 | } 204 | } 205 | 206 | private static string NormalizeExtension(string extension) 207 | { 208 | if (String.IsNullOrEmpty(extension)) 209 | { 210 | return String.Empty; 211 | } 212 | 213 | // ensure is only extension with leading dot 214 | return Path.GetExtension(extension); 215 | } 216 | 217 | #endregion Utility Methods 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/EcmaScriptIdentifier.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | 33 | namespace JsonFx.Json 34 | { 35 | /// 36 | /// Represents an ECMAScript identifier for serialization. 37 | /// 38 | public class EcmaScriptIdentifier : IJsonSerializable 39 | { 40 | #region Fields 41 | 42 | private readonly string identifier; 43 | 44 | #endregion Fields 45 | 46 | #region Init 47 | 48 | /// 49 | /// Ctor 50 | /// 51 | public EcmaScriptIdentifier() 52 | : this(null) 53 | { 54 | } 55 | 56 | /// 57 | /// Ctor 58 | /// 59 | public EcmaScriptIdentifier(string ident) 60 | { 61 | this.identifier = String.IsNullOrEmpty(ident) ? String.Empty : 62 | EcmaScriptIdentifier.EnsureValidIdentifier(ident, true); 63 | } 64 | 65 | #endregion Init 66 | 67 | #region Properties 68 | 69 | /// 70 | /// Gets the ECMAScript identifier represented by this instance. 71 | /// 72 | public string Identifier 73 | { 74 | get { return this.identifier; } 75 | } 76 | 77 | #endregion Properties 78 | 79 | #region Methods 80 | 81 | /// 82 | /// Ensures is a valid EcmaScript variable expression. 83 | /// 84 | /// the variable expression 85 | /// varExpr 86 | public static string EnsureValidIdentifier(string varExpr, bool nested) 87 | { 88 | return EcmaScriptIdentifier.EnsureValidIdentifier(varExpr, nested, true); 89 | } 90 | 91 | /// 92 | /// Ensures is a valid EcmaScript variable expression. 93 | /// 94 | /// the variable expression 95 | /// varExpr 96 | public static string EnsureValidIdentifier(string varExpr, bool nested, bool throwOnEmpty) 97 | { 98 | if (String.IsNullOrEmpty(varExpr)) 99 | { 100 | if (throwOnEmpty) 101 | { 102 | throw new ArgumentException("Variable expression is empty."); 103 | } 104 | return String.Empty; 105 | } 106 | 107 | varExpr = varExpr.Replace(" ", ""); 108 | 109 | if (!EcmaScriptIdentifier.IsValidIdentifier(varExpr, nested)) 110 | { 111 | throw new ArgumentException("Variable expression \""+varExpr+"\" is not supported."); 112 | } 113 | 114 | return varExpr; 115 | } 116 | 117 | /// 118 | /// Verifies is a valid EcmaScript variable expression. 119 | /// 120 | /// the variable expression 121 | /// varExpr 122 | /// 123 | /// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 124 | /// 125 | /// IdentifierName = 126 | /// IdentifierStart | IdentifierName IdentifierPart 127 | /// IdentifierStart = 128 | /// Letter | '$' | '_' 129 | /// IdentifierPart = 130 | /// IdentifierStart | Digit 131 | /// 132 | public static bool IsValidIdentifier(string varExpr, bool nested) 133 | { 134 | if (String.IsNullOrEmpty(varExpr)) 135 | { 136 | return false; 137 | } 138 | 139 | if (nested) 140 | { 141 | string[] parts = varExpr.Split('.'); 142 | foreach (string part in parts) 143 | { 144 | if (!EcmaScriptIdentifier.IsValidIdentifier(part, false)) 145 | { 146 | return false; 147 | } 148 | } 149 | return true; 150 | } 151 | 152 | if (EcmaScriptIdentifier.IsReservedWord(varExpr)) 153 | { 154 | return false; 155 | } 156 | 157 | bool indentPart = false; 158 | foreach (char ch in varExpr) 159 | { 160 | if (indentPart && Char.IsDigit(ch)) 161 | { 162 | // digits are only allowed after first char 163 | continue; 164 | } 165 | 166 | // can be start or part 167 | if (Char.IsLetter(ch) || ch == '_' || ch == '$') 168 | { 169 | indentPart = true; 170 | continue; 171 | } 172 | 173 | return false; 174 | } 175 | 176 | return true; 177 | } 178 | 179 | private static bool IsReservedWord(string varExpr) 180 | { 181 | // TODO: investigate doing this like Rhino does (switch on length check first letter or two) 182 | switch (varExpr) 183 | { 184 | // literals 185 | case "null": 186 | case "false": 187 | case "true": 188 | 189 | // ES5 Keywords 190 | case "break": 191 | case "case": 192 | case "catch": 193 | case "continue": 194 | case "debugger": 195 | case "default": 196 | case "delete": 197 | case "do": 198 | case "else": 199 | case "finally": 200 | case "for": 201 | case "function": 202 | case "if": 203 | case "in": 204 | case "instanceof": 205 | case "new": 206 | case "return": 207 | case "switch": 208 | case "this": 209 | case "throw": 210 | case "try": 211 | case "typeof": 212 | case "var": 213 | case "void": 214 | case "while": 215 | case "with": 216 | 217 | // ES5 Future Reserved Words 218 | case "abstract": 219 | case "boolean": 220 | case "byte": 221 | case "char": 222 | case "class": 223 | case "const": 224 | case "double": 225 | case "enum": 226 | case "export": 227 | case "extends": 228 | case "final": 229 | case "float": 230 | case "goto": 231 | case "implements": 232 | case "import": 233 | case "int": 234 | case "interface": 235 | case "long": 236 | case "native": 237 | case "package": 238 | case "private": 239 | case "protected": 240 | case "public": 241 | case "short": 242 | case "static": 243 | case "super": 244 | case "synchronized": 245 | case "throws": 246 | case "transient": 247 | case "volatile": 248 | 249 | // ES5 Possible Reserved Words 250 | case "let": 251 | case "yield": 252 | { 253 | return true; 254 | } 255 | default: 256 | { 257 | return false; 258 | } 259 | } 260 | } 261 | 262 | /// 263 | /// Trivial conversion method. Essentially performs a cast. 264 | /// 265 | /// 266 | /// 267 | /// 268 | /// Supports conversion via System.Web.UI.PropertyConverter.ObjectFromString(Type, MemberInfo, string) 269 | /// 270 | public static EcmaScriptIdentifier Parse(string value) 271 | { 272 | return new EcmaScriptIdentifier(value); 273 | } 274 | 275 | #endregion Methods 276 | 277 | #region Operators 278 | 279 | /// 280 | /// Implicit type conversion allows to be used directly as a String 281 | /// 282 | /// valid ECMAScript identifier 283 | /// 284 | public static implicit operator string(EcmaScriptIdentifier ident) 285 | { 286 | if (ident == null) 287 | { 288 | return String.Empty; 289 | } 290 | return ident.identifier; 291 | } 292 | 293 | /// 294 | /// Implicit type conversion allows to be used directly with Strings 295 | /// 296 | /// valid ECMAScript identifier 297 | /// 298 | public static implicit operator EcmaScriptIdentifier(string ident) 299 | { 300 | return new EcmaScriptIdentifier(ident); 301 | } 302 | 303 | #endregion Operators 304 | 305 | #region IJsonSerializable Members 306 | 307 | void IJsonSerializable.ReadJson(JsonReader reader) 308 | { 309 | throw new NotImplementedException("The method or operation is not implemented."); 310 | } 311 | 312 | void IJsonSerializable.WriteJson(JsonWriter writer) 313 | { 314 | if (String.IsNullOrEmpty(this.identifier)) 315 | { 316 | writer.TextWriter.Write("null"); 317 | } 318 | else 319 | { 320 | // TODO: determine if this should output parens around identifier 321 | writer.TextWriter.Write(this.identifier); 322 | } 323 | } 324 | 325 | #endregion IJsonSerializable Members 326 | 327 | #region Object Overrides 328 | 329 | /// 330 | /// Compares the identifiers. 331 | /// 332 | /// 333 | /// 334 | public override bool Equals(object obj) 335 | { 336 | EcmaScriptIdentifier that = obj as EcmaScriptIdentifier; 337 | if (that == null) 338 | { 339 | return base.Equals(obj); 340 | } 341 | 342 | if (String.IsNullOrEmpty(this.identifier) && String.IsNullOrEmpty(that.identifier)) 343 | { 344 | // null and String.Empty are equivalent 345 | return true; 346 | } 347 | 348 | return StringComparer.Ordinal.Equals(this.identifier, that.identifier); 349 | } 350 | 351 | /// 352 | /// Returns the identifier. 353 | /// 354 | /// 355 | public override string ToString() 356 | { 357 | return this.identifier; 358 | } 359 | 360 | /// 361 | /// Returns the hash code for this identifier. 362 | /// 363 | /// 364 | public override int GetHashCode() 365 | { 366 | if (this.identifier == null) 367 | { 368 | return 0; 369 | } 370 | 371 | return this.identifier.GetHashCode(); 372 | } 373 | 374 | #endregion Object Overrides 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/EcmaScriptWriter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2010 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Collections.Generic; 33 | using System.IO; 34 | using System.Text; 35 | using System.Text.RegularExpressions; 36 | 37 | namespace JsonFx.Json 38 | { 39 | /// 40 | /// Writes data as full ECMAScript objects, rather than the limited set of JSON objects. 41 | /// 42 | public class EcmaScriptWriter : JsonWriter 43 | { 44 | #region Constants 45 | 46 | private static readonly DateTime EcmaScriptEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 47 | private const string EcmaScriptDateCtor1 = "new Date({0})"; 48 | private const string EcmaScriptDateCtor7 = "new Date({0:0000},{1},{2},{3},{4},{5},{6})"; 49 | private const string EmptyRegExpLiteral = "(?:)"; 50 | private const char RegExpLiteralDelim = '/'; 51 | private const char OperatorCharEscape = '\\'; 52 | 53 | private const string NamespaceDelim = "."; 54 | private static readonly char[] NamespaceDelims = { '.' }; 55 | 56 | private const string RootDeclarationDebug = 57 | @" 58 | /* namespace {1} */ 59 | var {0};"; 60 | 61 | private const string RootDeclaration = @"var {0};"; 62 | 63 | private const string NamespaceCheck = 64 | @"if(""undefined""===typeof {0}){{{0}={{}};}}"; 65 | private const string NamespaceCheckDebug = 66 | @" 67 | if (""undefined"" === typeof {0}) {{ 68 | {0} = {{}}; 69 | }}"; 70 | private static readonly IList BrowserObjects = new List(new string[] 71 | { 72 | "console", 73 | "document", 74 | "event", 75 | "frames", 76 | "history", 77 | "location", 78 | "navigator", 79 | "opera", 80 | "screen", 81 | "window" 82 | }); 83 | 84 | #endregion Constants 85 | 86 | #region Init 87 | 88 | /// 89 | /// Ctor 90 | /// 91 | /// TextWriter for writing 92 | public EcmaScriptWriter(TextWriter output) 93 | : base(output) 94 | { 95 | } 96 | 97 | /// 98 | /// Ctor 99 | /// 100 | /// Stream for writing 101 | public EcmaScriptWriter(Stream output) 102 | : base(output) 103 | { 104 | } 105 | 106 | /// 107 | /// Ctor 108 | /// 109 | /// File name for writing 110 | public EcmaScriptWriter(string outputFileName) 111 | : base(outputFileName) 112 | { 113 | } 114 | 115 | /// 116 | /// Ctor 117 | /// 118 | /// StringBuilder for appending 119 | public EcmaScriptWriter(StringBuilder output) 120 | : base(output) 121 | { 122 | } 123 | 124 | #endregion Init 125 | 126 | #region Static Methods 127 | 128 | /// 129 | /// A helper method for serializing an object to EcmaScript 130 | /// 131 | /// 132 | /// 133 | public static new string Serialize(object value) 134 | { 135 | StringBuilder output = new StringBuilder(); 136 | 137 | using (EcmaScriptWriter writer = new EcmaScriptWriter(output)) 138 | { 139 | writer.Write(value); 140 | } 141 | 142 | return output.ToString(); 143 | } 144 | 145 | /// 146 | /// Returns a block of script for ensuring that a namespace is declared. 147 | /// 148 | /// the output writer 149 | /// the namespace to ensure 150 | /// list of namespaces already emitted 151 | /// determines if should emit pretty-printed 152 | /// if was a nested identifier 153 | public static bool WriteNamespaceDeclaration(TextWriter writer, string ident, List namespaces, bool isDebug) 154 | { 155 | if (String.IsNullOrEmpty(ident)) 156 | { 157 | return false; 158 | } 159 | 160 | if (namespaces == null) 161 | { 162 | namespaces = new List(); 163 | } 164 | 165 | string[] nsParts = ident.Split(EcmaScriptWriter.NamespaceDelims, StringSplitOptions.RemoveEmptyEntries); 166 | string ns = nsParts[0]; 167 | 168 | bool isNested = false; 169 | for (int i=0; i 0) 174 | { 175 | ns += EcmaScriptWriter.NamespaceDelim; 176 | ns += nsParts[i]; 177 | } 178 | 179 | if (namespaces.Contains(ns) || 180 | EcmaScriptWriter.BrowserObjects.Contains(ns)) 181 | { 182 | // don't emit multiple checks for same namespace 183 | continue; 184 | } 185 | 186 | // make note that we've emitted this namespace before 187 | namespaces.Add(ns); 188 | 189 | if (i == 0) 190 | { 191 | if (isDebug) 192 | { 193 | writer.Write(EcmaScriptWriter.RootDeclarationDebug, ns, 194 | String.Join(NamespaceDelim, nsParts, 0, nsParts.Length-1)); 195 | } 196 | else 197 | { 198 | writer.Write(EcmaScriptWriter.RootDeclaration, ns); 199 | } 200 | } 201 | 202 | if (isDebug) 203 | { 204 | writer.WriteLine(EcmaScriptWriter.NamespaceCheckDebug, ns); 205 | } 206 | else 207 | { 208 | writer.Write(EcmaScriptWriter.NamespaceCheck, ns); 209 | } 210 | } 211 | 212 | if (isDebug && isNested) 213 | { 214 | writer.WriteLine(); 215 | } 216 | 217 | return isNested; 218 | } 219 | 220 | #endregion Static Methods 221 | 222 | #region Writer Methods 223 | 224 | /// 225 | /// Writes dates as ECMAScript Date constructors 226 | /// 227 | /// 228 | public override void Write(DateTime value) 229 | { 230 | EcmaScriptWriter.WriteEcmaScriptDate(this, value); 231 | } 232 | 233 | /// 234 | /// Writes out all Single values including NaN, Infinity, -Infinity 235 | /// 236 | /// Single 237 | public override void Write(float value) 238 | { 239 | this.TextWriter.Write(value.ToString("r")); 240 | } 241 | 242 | /// 243 | /// Writes out all Double values including NaN, Infinity, -Infinity 244 | /// 245 | /// Double 246 | public override void Write(double value) 247 | { 248 | this.TextWriter.Write(value.ToString("r")); 249 | } 250 | 251 | protected override void Write(object value, bool isProperty) 252 | { 253 | if (value is Regex) 254 | { 255 | if (isProperty && this.Settings.PrettyPrint) 256 | { 257 | this.TextWriter.Write(' '); 258 | } 259 | EcmaScriptWriter.WriteEcmaScriptRegExp(this, (Regex)value); 260 | return; 261 | } 262 | 263 | base.Write(value, isProperty); 264 | } 265 | 266 | protected override void WriteObjectPropertyName(string name) 267 | { 268 | if (EcmaScriptIdentifier.IsValidIdentifier(name, false)) 269 | { 270 | // write out without quoting 271 | this.TextWriter.Write(name); 272 | } 273 | else 274 | { 275 | // write out as an escaped string 276 | base.WriteObjectPropertyName(name); 277 | } 278 | } 279 | 280 | public static void WriteEcmaScriptDate(JsonWriter writer, DateTime value) 281 | { 282 | if (value.Kind == DateTimeKind.Unspecified) 283 | { 284 | // unknown timezones serialize directly to become browser-local 285 | writer.TextWriter.Write( 286 | EcmaScriptWriter.EcmaScriptDateCtor7, 287 | value.Year, // yyyy 288 | value.Month-1, // 0-11 289 | value.Day, // 1-31 290 | value.Hour, // 0-23 291 | value.Minute, // 0-60 292 | value.Second, // 0-60 293 | value.Millisecond); // 0-999 294 | return; 295 | } 296 | 297 | if (value.Kind == DateTimeKind.Local) 298 | { 299 | // convert server-local to UTC 300 | value = value.ToUniversalTime(); 301 | } 302 | 303 | // find the time since Jan 1, 1970 304 | TimeSpan duration = value.Subtract(EcmaScriptWriter.EcmaScriptEpoch); 305 | 306 | // get the total milliseconds 307 | long ticks = (long)duration.TotalMilliseconds; 308 | 309 | // write out as a Date constructor 310 | writer.TextWriter.Write( 311 | EcmaScriptWriter.EcmaScriptDateCtor1, 312 | ticks); 313 | } 314 | 315 | /// 316 | /// Outputs a .NET Regex as an ECMAScript RegExp literal. 317 | /// Defaults to global matching off. 318 | /// 319 | /// 320 | /// 321 | /// 322 | /// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 323 | /// 324 | public static void WriteEcmaScriptRegExp(JsonWriter writer, Regex regex) 325 | { 326 | EcmaScriptWriter.WriteEcmaScriptRegExp(writer, regex, false); 327 | } 328 | 329 | /// 330 | /// Outputs a .NET Regex as an ECMAScript RegExp literal. 331 | /// 332 | /// 333 | /// 334 | /// 335 | /// 336 | /// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 337 | /// 338 | public static void WriteEcmaScriptRegExp(JsonWriter writer, Regex regex, bool isGlobal) 339 | { 340 | if (regex == null) 341 | { 342 | writer.TextWriter.Write(JsonReader.LiteralNull); 343 | return; 344 | } 345 | 346 | // Regex.ToString() returns the original pattern 347 | string pattern = regex.ToString(); 348 | if (String.IsNullOrEmpty(pattern)) 349 | { 350 | // must output something otherwise becomes a code comment 351 | pattern = EcmaScriptWriter.EmptyRegExpLiteral; 352 | } 353 | 354 | string modifiers = isGlobal ? "g" : ""; 355 | switch (regex.Options & (RegexOptions.IgnoreCase|RegexOptions.Multiline)) 356 | { 357 | case RegexOptions.IgnoreCase: 358 | { 359 | modifiers += "i"; 360 | break; 361 | } 362 | case RegexOptions.Multiline: 363 | { 364 | modifiers += "m"; 365 | break; 366 | } 367 | case RegexOptions.IgnoreCase|RegexOptions.Multiline: 368 | { 369 | modifiers += "im"; 370 | break; 371 | } 372 | } 373 | 374 | writer.TextWriter.Write(EcmaScriptWriter.RegExpLiteralDelim); 375 | 376 | int length = pattern.Length; 377 | int start = 0; 378 | 379 | for (int i = start; i < length; i++) 380 | { 381 | switch (pattern[i]) 382 | { 383 | case EcmaScriptWriter.RegExpLiteralDelim: 384 | { 385 | writer.TextWriter.Write(pattern.Substring(start, i - start)); 386 | start = i + 1; 387 | writer.TextWriter.Write(EcmaScriptWriter.OperatorCharEscape); 388 | writer.TextWriter.Write(pattern[i]); 389 | break; 390 | } 391 | } 392 | } 393 | 394 | writer.TextWriter.Write(pattern.Substring(start, length - start)); 395 | writer.TextWriter.Write(EcmaScriptWriter.RegExpLiteralDelim); 396 | writer.TextWriter.Write(modifiers); 397 | } 398 | 399 | #endregion Writer Methods 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/IDataReader.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Text; 34 | 35 | namespace JsonFx.Json 36 | { 37 | /// 38 | /// A common interface for data deserializers 39 | /// 40 | public interface IDataReader 41 | { 42 | #region Properties 43 | 44 | /// 45 | /// Gets the content type of the serialized data 46 | /// 47 | string ContentType 48 | { 49 | get; 50 | } 51 | 52 | #endregion Properties 53 | 54 | #region Methods 55 | 56 | /// 57 | /// Serializes the data to the given output 58 | /// 59 | /// 60 | /// 61 | object Deserialize(TextReader input, Type data); 62 | 63 | #endregion Methods 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/IDataWriter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Text; 34 | 35 | namespace JsonFx.Json 36 | { 37 | /// 38 | /// A common interface for data serializers 39 | /// 40 | public interface IDataWriter 41 | { 42 | #region Properties 43 | 44 | /// 45 | /// Gets the content encoding for the serialized data 46 | /// 47 | Encoding ContentEncoding 48 | { 49 | get; 50 | } 51 | 52 | /// 53 | /// Gets the content type for the serialized data 54 | /// 55 | string ContentType 56 | { 57 | get; 58 | } 59 | 60 | /// 61 | /// Gets the file extension for the serialized data 62 | /// 63 | string FileExtension 64 | { 65 | get; 66 | } 67 | 68 | #endregion Properties 69 | 70 | #region Methods 71 | 72 | /// 73 | /// Serializes the data to the given output 74 | /// 75 | /// 76 | /// 77 | void Serialize(TextWriter output, object data); 78 | 79 | #endregion Methods 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/IJsonSerializable.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | 33 | namespace JsonFx.Json 34 | { 35 | /// 36 | /// Allows classes to control their own JSON serialization 37 | /// 38 | public interface IJsonSerializable 39 | { 40 | void ReadJson(JsonReader reader); 41 | void WriteJson(JsonWriter writer); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonDataReader.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Text; 34 | 35 | namespace JsonFx.Json 36 | { 37 | /// 38 | /// An adapter for 39 | /// 40 | public class JsonDataReader : IDataReader 41 | { 42 | #region Constants 43 | 44 | public const string JsonMimeType = JsonWriter.JsonMimeType; 45 | public const string JsonFileExtension = JsonWriter.JsonFileExtension; 46 | 47 | #endregion Constants 48 | 49 | #region Fields 50 | 51 | private readonly JsonReaderSettings Settings; 52 | 53 | #endregion Fields 54 | 55 | #region Init 56 | 57 | /// 58 | /// Ctor 59 | /// 60 | /// JsonWriterSettings 61 | public JsonDataReader(JsonReaderSettings settings) 62 | { 63 | if (settings == null) 64 | { 65 | throw new ArgumentNullException("settings"); 66 | } 67 | this.Settings = settings; 68 | } 69 | 70 | #endregion Init 71 | 72 | #region IDataReader Members 73 | 74 | /// 75 | /// Gets the content type 76 | /// 77 | public string ContentType 78 | { 79 | get { return JsonDataReader.JsonMimeType; } 80 | } 81 | 82 | /// 83 | /// Deserializes a data object of Type type from the input 84 | /// 85 | /// 86 | /// 87 | public object Deserialize(TextReader input, Type type) 88 | { 89 | return new JsonReader(input, this.Settings).Deserialize(type); 90 | } 91 | 92 | #endregion IDataReader Members 93 | 94 | #region Methods 95 | 96 | /// 97 | /// Builds a common settings objects 98 | /// 99 | /// 100 | /// 101 | public static JsonReaderSettings CreateSettings(bool allowNullValueTypes) 102 | { 103 | JsonReaderSettings settings = new JsonReaderSettings(); 104 | 105 | settings.AllowNullValueTypes = allowNullValueTypes; 106 | 107 | return settings; 108 | } 109 | 110 | #endregion Methods 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonDataWriter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Text; 34 | 35 | namespace JsonFx.Json 36 | { 37 | /// 38 | /// An adapter for 39 | /// 40 | public class JsonDataWriter : IDataWriter 41 | { 42 | #region Constants 43 | 44 | public const string JsonMimeType = JsonWriter.JsonMimeType; 45 | public const string JsonFileExtension = JsonWriter.JsonFileExtension; 46 | 47 | #endregion Constants 48 | 49 | #region Fields 50 | 51 | private readonly JsonWriterSettings Settings; 52 | 53 | #endregion Fields 54 | 55 | #region Init 56 | 57 | /// 58 | /// Ctor 59 | /// 60 | /// JsonWriterSettings 61 | public JsonDataWriter(JsonWriterSettings settings) 62 | { 63 | if (settings == null) 64 | { 65 | throw new ArgumentNullException("settings"); 66 | } 67 | this.Settings = settings; 68 | } 69 | 70 | #endregion Init 71 | 72 | #region IDataSerializer Members 73 | 74 | /// 75 | /// Gets the content encoding 76 | /// 77 | public Encoding ContentEncoding 78 | { 79 | get { return Encoding.UTF8; } 80 | } 81 | 82 | /// 83 | /// Gets the content type 84 | /// 85 | public string ContentType 86 | { 87 | get { return JsonDataWriter.JsonMimeType; } 88 | } 89 | 90 | /// 91 | /// Gets the file extension 92 | /// 93 | public string FileExtension 94 | { 95 | get { return JsonDataWriter.JsonFileExtension; } 96 | } 97 | 98 | /// 99 | /// Serializes the data object to the output 100 | /// 101 | /// 102 | /// 103 | public void Serialize(TextWriter output, object data) 104 | { 105 | new JsonWriter(output, this.Settings).Write(data); 106 | } 107 | 108 | #endregion IDataSerializer Members 109 | 110 | #region Methods 111 | 112 | /// 113 | /// Builds a common settings objects 114 | /// 115 | /// 116 | /// 117 | public static JsonWriterSettings CreateSettings(bool prettyPrint) 118 | { 119 | JsonWriterSettings settings = new JsonWriterSettings(); 120 | 121 | settings.PrettyPrint = prettyPrint; 122 | 123 | return settings; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonFx.Json.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {ABA23F14-7E47-43FE-A3E7-1FF97840C3FB} 9 | Library 10 | Properties 11 | JsonFx 12 | JsonFx.Json 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | v2.0 22 | 23 | 24 | 25 | 26 | 2.0 27 | 28 | 29 | True 30 | full 31 | False 32 | bin\Debug\ 33 | DEBUG;TRACE;UNITY3D 34 | prompt 35 | 4 36 | false 37 | bin\Debug\JsonFx.Json.XML 38 | 1570,1571,1572,1573,1591,1592 39 | 40 | 41 | pdbonly 42 | True 43 | bin\Release\ 44 | TRACE;UNITY3D 45 | prompt 46 | 4 47 | false 48 | bin\Release\JsonFx.Json.XML 49 | 1570,1571,1572,1573,1591,1592 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Always 84 | 85 | 86 | Always 87 | 88 | 89 | 90 | 97 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonFx.Json.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/piplay-fork/jsonfx-for-unity3d/b4bf550cf81fab69448d97c12efed78a50d3c538/JsonFx/JsonFx.Json/JsonFx.Json.pidb -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Reflection; 33 | #if !UNITY3D 34 | using System.Xml.Serialization; 35 | #endif 36 | 37 | namespace JsonFx.Json 38 | { 39 | /// 40 | /// Designates a property or field to not be serialized. 41 | /// 42 | [AttributeUsage(AttributeTargets.All, AllowMultiple=false)] 43 | public sealed class JsonIgnoreAttribute : Attribute 44 | { 45 | #region Methods 46 | 47 | /// 48 | /// Gets a value which indicates if should be ignored in Json serialization. 49 | /// 50 | /// 51 | /// 52 | public static bool IsJsonIgnore(object value) 53 | { 54 | if (value == null) 55 | { 56 | return false; 57 | } 58 | 59 | Type type = value.GetType(); 60 | 61 | ICustomAttributeProvider provider = null; 62 | if (type.IsEnum) 63 | { 64 | provider = type.GetField(Enum.GetName(type, value)); 65 | } 66 | else 67 | { 68 | provider = value as ICustomAttributeProvider; 69 | } 70 | 71 | if (provider == null) 72 | { 73 | throw new ArgumentException(); 74 | } 75 | 76 | return provider.IsDefined(typeof(JsonIgnoreAttribute), true); 77 | } 78 | 79 | /// 80 | /// Gets a value which indicates if should be ignored in Json serialization. 81 | /// 82 | /// 83 | /// 84 | public static bool IsXmlIgnore(object value) 85 | { 86 | if (value == null) 87 | { 88 | return false; 89 | } 90 | 91 | Type type = value.GetType(); 92 | 93 | ICustomAttributeProvider provider = null; 94 | if (type.IsEnum) 95 | { 96 | provider = type.GetField(Enum.GetName(type, value)); 97 | } 98 | else 99 | { 100 | provider = value as ICustomAttributeProvider; 101 | } 102 | 103 | if (provider == null) 104 | { 105 | throw new ArgumentException(); 106 | } 107 | 108 | #if !UNITY3D 109 | return provider.IsDefined(typeof(XmlIgnoreAttribute), true); 110 | #else 111 | return false; 112 | #endif 113 | } 114 | 115 | #endregion Methods 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonMemberAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace JsonFx.Json 3 | { 4 | /** Explicitly declare this member to be serialized. 5 | * \see JsonOptInAttribute 6 | */ 7 | public class JsonMemberAttribute : Attribute 8 | { 9 | public JsonMemberAttribute () 10 | { 11 | } 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonNameAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Reflection; 33 | 34 | namespace JsonFx.Json 35 | { 36 | /// 37 | /// Specifies the naming to use for a property or field when serializing 38 | /// 39 | [AttributeUsage(AttributeTargets.All, AllowMultiple=false)] 40 | public class JsonNameAttribute : Attribute 41 | { 42 | #region Fields 43 | 44 | private string jsonName = null; 45 | 46 | #endregion Fields 47 | 48 | #region Init 49 | 50 | /// 51 | /// Ctor 52 | /// 53 | public JsonNameAttribute() 54 | { 55 | } 56 | 57 | /// 58 | /// Ctor 59 | /// 60 | /// 61 | public JsonNameAttribute(string jsonName) 62 | { 63 | this.jsonName = EcmaScriptIdentifier.EnsureValidIdentifier(jsonName, false); 64 | } 65 | 66 | #endregion Init 67 | 68 | #region Properties 69 | 70 | /// 71 | /// Gets and sets the name to be used in JSON 72 | /// 73 | public string Name 74 | { 75 | get { return this.jsonName; } 76 | set { this.jsonName = EcmaScriptIdentifier.EnsureValidIdentifier(value, false); } 77 | } 78 | 79 | #endregion Properties 80 | 81 | #region Methods 82 | 83 | /// 84 | /// Gets the name specified for use in Json serialization. 85 | /// 86 | /// 87 | /// 88 | public static string GetJsonName(object value) 89 | { 90 | if (value == null) 91 | { 92 | return null; 93 | } 94 | 95 | Type type = value.GetType(); 96 | MemberInfo memberInfo = null; 97 | 98 | if (type.IsEnum) 99 | { 100 | string name = Enum.GetName(type, value); 101 | if (String.IsNullOrEmpty(name)) 102 | { 103 | return null; 104 | } 105 | memberInfo = type.GetField(name); 106 | } 107 | else 108 | { 109 | memberInfo = value as MemberInfo; 110 | } 111 | 112 | if (memberInfo == null) 113 | { 114 | throw new ArgumentException(); 115 | } 116 | 117 | if (!Attribute.IsDefined(memberInfo, typeof(JsonNameAttribute))) 118 | { 119 | return null; 120 | } 121 | JsonNameAttribute attribute = (JsonNameAttribute)Attribute.GetCustomAttribute(memberInfo, typeof(JsonNameAttribute)); 122 | 123 | return attribute.Name; 124 | } 125 | 126 | ///// 127 | ///// Gets the name specified for use in Json serialization. 128 | ///// 129 | ///// 130 | ///// 131 | //public static string GetXmlName(object value) 132 | //{ 133 | // if (value == null) 134 | // { 135 | // return null; 136 | // } 137 | 138 | // Type type = value.GetType(); 139 | // ICustomAttributeProvider memberInfo = null; 140 | 141 | // if (type.IsEnum) 142 | // { 143 | // string name = Enum.GetName(type, value); 144 | // if (String.IsNullOrEmpty(name)) 145 | // { 146 | // return null; 147 | // } 148 | // memberInfo = type.GetField(name); 149 | // } 150 | // else 151 | // { 152 | // memberInfo = value as ICustomAttributeProvider; 153 | // } 154 | 155 | // if (memberInfo == null) 156 | // { 157 | // throw new ArgumentException(); 158 | // } 159 | 160 | // XmlAttributes xmlAttributes = new XmlAttributes(memberInfo); 161 | // if (xmlAttributes.XmlElements.Count == 1 && 162 | // !String.IsNullOrEmpty(xmlAttributes.XmlElements[0].ElementName)) 163 | // { 164 | // return xmlAttributes.XmlElements[0].ElementName; 165 | // } 166 | // if (xmlAttributes.XmlAttribute != null && 167 | // !String.IsNullOrEmpty(xmlAttributes.XmlAttribute.AttributeName)) 168 | // { 169 | // return xmlAttributes.XmlAttribute.AttributeName; 170 | // } 171 | 172 | // return null; 173 | //} 174 | 175 | #endregion Methods 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonOptInAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace JsonFx.Json 3 | { 4 | /** Specifies that members of this class that should be serialized must be explicitly specified. 5 | * Classes that this attribute is applied to need to explicitly 6 | * declare every member that should be serialized with the JsonMemberAttribute. 7 | * \see JsonMemberAttribute 8 | */ 9 | public class JsonOptInAttribute : Attribute 10 | { 11 | public JsonOptInAttribute () 12 | { 13 | 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonReaderSettings.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Collections.Generic; 33 | 34 | namespace JsonFx.Json 35 | { 36 | /// 37 | /// Controls the deserialization settings for JsonReader 38 | /// 39 | public class JsonReaderSettings 40 | { 41 | #region Fields 42 | 43 | internal readonly TypeCoercionUtility Coercion = new TypeCoercionUtility(); 44 | private bool allowUnquotedObjectKeys = false; 45 | private string typeHintName; 46 | 47 | #endregion Fields 48 | 49 | #region Properties 50 | 51 | /// 52 | /// Gets and sets if ValueTypes can accept values of null 53 | /// 54 | /// 55 | /// Only affects deserialization: if a ValueType is assigned the 56 | /// value of null, it will receive the value default(TheType). 57 | /// Setting this to false, throws an exception if null is 58 | /// specified for a ValueType member. 59 | /// 60 | public bool AllowNullValueTypes 61 | { 62 | get { return this.Coercion.AllowNullValueTypes; } 63 | set { this.Coercion.AllowNullValueTypes = value; } 64 | } 65 | 66 | /// 67 | /// Gets and sets if objects can have unquoted property names 68 | /// 69 | public bool AllowUnquotedObjectKeys 70 | { 71 | get { return this.allowUnquotedObjectKeys; } 72 | set { this.allowUnquotedObjectKeys = value; } 73 | } 74 | 75 | /// 76 | /// Gets and sets the property name used for type hinting. 77 | /// 78 | public string TypeHintName 79 | { 80 | get { return this.typeHintName; } 81 | set { this.typeHintName = value; } 82 | } 83 | 84 | #endregion Properties 85 | 86 | #region Methods 87 | 88 | /// 89 | /// Determines if the specified name is the TypeHint property 90 | /// 91 | /// 92 | /// 93 | internal bool IsTypeHintName(string name) 94 | { 95 | return 96 | !String.IsNullOrEmpty(name) && 97 | !String.IsNullOrEmpty(this.typeHintName) && 98 | StringComparer.Ordinal.Equals(this.typeHintName, name); 99 | } 100 | 101 | protected List converters = new List(); 102 | 103 | public virtual JsonConverter GetConverter (Type type) { 104 | for (int i=0;i 88 | /// Gets the character position in the stream where the error occurred. 89 | /// 90 | public int Index 91 | { 92 | get { return this.index; } 93 | } 94 | 95 | #endregion Properties 96 | 97 | #region Methods 98 | 99 | /// 100 | /// Helper method which converts the index into Line and Column numbers 101 | /// 102 | /// 103 | /// 104 | /// 105 | public void GetLineAndColumn(string source, out int line, out int col) 106 | { 107 | if (source == null) 108 | { 109 | throw new ArgumentNullException(); 110 | } 111 | 112 | col = 1; 113 | line = 1; 114 | 115 | bool foundLF = false; 116 | int i = Math.Min(this.index, source.Length); 117 | for (; i>0; i--) 118 | { 119 | if (!foundLF) 120 | { 121 | col++; 122 | } 123 | if (source[i-1] == '\n') 124 | { 125 | line++; 126 | foundLF = true; 127 | } 128 | } 129 | } 130 | 131 | #endregion Methods 132 | } 133 | 134 | public class JsonTypeCoercionException : ArgumentException 135 | { 136 | #region Init 137 | 138 | public JsonTypeCoercionException() : base() { } 139 | 140 | public JsonTypeCoercionException(string message) : base(message) { } 141 | 142 | public JsonTypeCoercionException(string message, Exception innerException) : base(message, innerException) { } 143 | 144 | public JsonTypeCoercionException( 145 | System.Runtime.Serialization.SerializationInfo info, 146 | System.Runtime.Serialization.StreamingContext context) 147 | : base(info, context) 148 | { 149 | } 150 | 151 | #endregion Init 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonSpecifiedPropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Reflection; 33 | 34 | namespace JsonFx.Json 35 | { 36 | /// 37 | /// Specifies the name of the property which specifies if member should be serialized. 38 | /// 39 | [AttributeUsage(AttributeTargets.Property|AttributeTargets.Field, AllowMultiple=false)] 40 | public class JsonSpecifiedPropertyAttribute : Attribute 41 | { 42 | #region Fields 43 | 44 | private string specifiedProperty = null; 45 | 46 | #endregion Fields 47 | 48 | #region Init 49 | 50 | /// 51 | /// Ctor 52 | /// 53 | /// the name of the property which controls serialization for this member 54 | public JsonSpecifiedPropertyAttribute(string propertyName) 55 | { 56 | this.specifiedProperty = propertyName; 57 | } 58 | 59 | #endregion Init 60 | 61 | #region Properties 62 | 63 | /// 64 | /// Gets and sets the name of the property which 65 | /// specifies if member should be serialized 66 | /// 67 | public string SpecifiedProperty 68 | { 69 | get { return this.specifiedProperty; } 70 | set { this.specifiedProperty = value; } 71 | } 72 | 73 | #endregion Properties 74 | 75 | #region Methods 76 | 77 | /// 78 | /// Gets the name specified for use in Json serialization. 79 | /// 80 | /// 81 | /// 82 | public static string GetJsonSpecifiedProperty(MemberInfo memberInfo) 83 | { 84 | if (memberInfo == null || 85 | !Attribute.IsDefined(memberInfo, typeof(JsonSpecifiedPropertyAttribute))) 86 | { 87 | return null; 88 | } 89 | 90 | JsonSpecifiedPropertyAttribute attribute = (JsonSpecifiedPropertyAttribute)Attribute.GetCustomAttribute(memberInfo, typeof(JsonSpecifiedPropertyAttribute)); 91 | return attribute.SpecifiedProperty; 92 | } 93 | 94 | #endregion Methods 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonToken.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | 33 | namespace JsonFx.Json 34 | { 35 | /// 36 | /// Parse Tokens 37 | /// 38 | internal enum JsonToken 39 | { 40 | End, 41 | Undefined, 42 | Null, 43 | False, 44 | True, 45 | NaN, 46 | PositiveInfinity, 47 | NegativeInfinity, 48 | Number, 49 | String, 50 | ArrayStart, 51 | ArrayEnd, 52 | ObjectStart, 53 | ObjectEnd, 54 | NameDelim, 55 | ValueDelim, 56 | UnquotedName 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/JsonWriterSettings.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.IO; 33 | using System.Collections.Generic; 34 | 35 | namespace JsonFx.Json 36 | { 37 | /// 38 | /// Represents a proxy method for serialization of types which do not implement IJsonSerializable 39 | /// 40 | /// the type for this proxy 41 | /// the JsonWriter to serialize to 42 | /// the value to serialize 43 | public delegate void WriteDelegate(JsonWriter writer, T value); 44 | 45 | /// 46 | /// Controls the serialization settings for JsonWriter 47 | /// 48 | public class JsonWriterSettings 49 | { 50 | #region Fields 51 | 52 | private WriteDelegate dateTimeSerializer; 53 | private int maxDepth = 25; 54 | private string newLine = Environment.NewLine; 55 | private bool prettyPrint; 56 | private string tab = "\t"; 57 | private string typeHintName; 58 | private bool useXmlSerializationAttributes; 59 | 60 | #endregion Fields 61 | 62 | #region Properties 63 | 64 | /// 65 | /// Gets and sets the property name used for type hinting. 66 | /// 67 | public virtual string TypeHintName 68 | { 69 | get { return this.typeHintName; } 70 | set { this.typeHintName = value; } 71 | } 72 | 73 | /// 74 | /// Gets and sets if JSON will be formatted for human reading. 75 | /// 76 | public virtual bool PrettyPrint 77 | { 78 | get { return this.prettyPrint; } 79 | set { this.prettyPrint = value; } 80 | } 81 | 82 | /// 83 | /// Gets and sets the string to use for indentation 84 | /// 85 | public virtual string Tab 86 | { 87 | get { return this.tab; } 88 | set { this.tab = value; } 89 | } 90 | 91 | /// 92 | /// Gets and sets the line terminator string 93 | /// 94 | public virtual string NewLine 95 | { 96 | get { return this.newLine; } 97 | set { this.newLine = value; } 98 | } 99 | 100 | /// 101 | /// Gets and sets the maximum depth to be serialized. 102 | /// 103 | public virtual int MaxDepth 104 | { 105 | get { return this.maxDepth; } 106 | set 107 | { 108 | if (value < 1) 109 | { 110 | throw new ArgumentOutOfRangeException("MaxDepth must be a positive integer as it controls the maximum nesting level of serialized objects."); 111 | } 112 | this.maxDepth = value; 113 | } 114 | } 115 | 116 | /// 117 | /// Gets and sets if should use XmlSerialization Attributes. 118 | /// 119 | /// 120 | /// Respects XmlIgnoreAttribute, ... 121 | /// 122 | public virtual bool UseXmlSerializationAttributes 123 | { 124 | get { return this.useXmlSerializationAttributes; } 125 | set { this.useXmlSerializationAttributes = value; } 126 | } 127 | 128 | /// 129 | /// Gets and sets a proxy formatter to use for DateTime serialization 130 | /// 131 | public virtual WriteDelegate DateTimeSerializer 132 | { 133 | get { return this.dateTimeSerializer; } 134 | set { this.dateTimeSerializer = value; } 135 | } 136 | 137 | /** Enables more debugging messages. 138 | * E.g about why some members are not serialized. 139 | * The number of debugging messages are in no way exhaustive 140 | */ 141 | public virtual bool DebugMode { get; set; } 142 | 143 | protected List converters = new List(); 144 | 145 | /** Returns the converter for the specified type */ 146 | public virtual JsonConverter GetConverter (Type type) { 147 | for (int i=0;i dict = WriteJson (type,value); 171 | writer.Write (dict); 172 | } 173 | 174 | public object Read (JsonReader reader, Type type, Dictionary value) { 175 | return ReadJson (type, value); 176 | } 177 | 178 | public float CastFloat (object o) { 179 | if (o==null)return 0.0F; 180 | try { 181 | return System.Convert.ToSingle(o); 182 | } catch(System.Exception e) { 183 | throw new JsonDeserializationException ("Cannot cast object to float. Expected float, got "+o.GetType(),e,0); 184 | } 185 | } 186 | 187 | public double CastDouble (object o) { 188 | if (o==null)return 0.0; 189 | try { 190 | return System.Convert.ToDouble(o); 191 | } catch(System.Exception e) { 192 | throw new JsonDeserializationException ("Cannot cast object to double. Expected double, got "+o.GetType(),e,0); 193 | } 194 | } 195 | 196 | public abstract Dictionary WriteJson (Type type, object value); 197 | public abstract object ReadJson (Type type, Dictionary value); 198 | } 199 | 200 | } -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/License.txt: -------------------------------------------------------------------------------- 1 | Distributed under the terms of an MIT-style license: 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2006-2009 Stephen M. McKamey 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System.Reflection; 32 | using System.Runtime.CompilerServices; 33 | using System.Runtime.InteropServices; 34 | 35 | [assembly: AssemblyTitle("JsonFx for Unity3D")] 36 | [assembly: AssemblyDescription("JsonFx.NET JSON Serialization")] 37 | [assembly: AssemblyProduct("JsonFx.NET.Unity3D")] 38 | [assembly: AssemblyCopyright("Copyright © 2006-2009 Stephen M. McKamey. All rights reserved.")] 39 | [assembly: AssemblyCompany("http://jsonfx.net")] 40 | 41 | #if DEBUG 42 | [assembly: AssemblyConfiguration("Debug")] 43 | #elif STRONG 44 | [assembly: AssemblyConfiguration("Signed")] 45 | #else 46 | [assembly: AssemblyConfiguration("Release")] 47 | #endif 48 | [assembly: ComVisible(false)] 49 | [assembly: Guid("a3a74921-2901-456c-84f2-b0d83994d33a")] 50 | [assembly: ObfuscateAssembly(false, StripAfterObfuscation=false)] 51 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/Properties/AssemblyVersion.cs: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------*\ 2 | This is auto-generated code. All changes will be overwritten. 3 | \*------------------------------------------------------------------*/ 4 | 5 | #region 1.4.1003.3009 6 | 7 | using System.Reflection; 8 | 9 | [assembly: AssemblyVersion("1.4.1003.3009")] 10 | [assembly: AssemblyFileVersion("1.4.1003.3009")] 11 | 12 | #endregion 1.4.1003.3009 13 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/Readme.txt: -------------------------------------------------------------------------------- 1 | JsonFx.NET - JSON Serializer 2 | 3 | The JsonFx.NET JSON parser/serializer functions similarly to the XmlSerializer in .NET 4 | 5 | Serializes and deserializes any Dictionary and IDictionary with 6 | String keys directly as a JSON object 7 | 8 | Serializes and deserializes any List, ArrayList, LinkedList, Queue and 9 | many other IEnumerable types directly as JSON arrays 10 | 11 | Serializes and deserializes DateTime, Enum, Nullable, Guid and other 12 | common .NET Types directly as JSON primitives 13 | 14 | Serializes and deserializes strongly-typed custom classes (similarly to XML 15 | Serialization in .NET Framework) 16 | 17 | Serializes C# 3.0 Anonymous Types directly as JSON objects 18 | 19 | Serializes C# 3.0 LINQ Queries as JSON arrays of objects (by enumerating the results) 20 | 21 | Follows Postel's Law ("Be conservative in what you do; be liberal in what you accept from others.") 22 | by accepting handling many non-JSON JavaScript concepts: 23 | - Common literals such as "Infinity", "NaN", and "undefined" 24 | - Ignores block and line comments when deserializing 25 | 26 | This version has been modified to work better with Unity3D, especially when building for the iPhone. 27 | No additional .dll dependencies (such as System.Xml) are required. Additional in the sense that Unity does not include them per default. 28 | 29 | Optional ability to control serialization via attributes/interfaces: 30 | 31 | JsonFx.Json.IJsonSerializable: 32 | Interface which allows classes to control their own JSON serialization 33 | 34 | JsonFx.Json.JsonIgnoreAttribute: 35 | Attribute which designates a property or field to not be serialized 36 | 37 | System.ComponentModel.DefaultValueAttribute: 38 | Member does not serialize if the value matches the DefaultValue attribute 39 | 40 | JsonFx.Json.JsonNameAttribute: 41 | Attribute which specifies the naming to use for a property or field when serializing 42 | 43 | JsonFx.Json.JsonSpecifiedPropertyAttribute: 44 | Attribute which specifies the name of the property which specifies if member should be serialized 45 | 46 | JsonFx.Json.JsonOptIn: 47 | Attribute which specifies that all members of the class must be explicitly declared to be included in the serialization (see next) 48 | 49 | JsonFx.Json.JsonMember: 50 | Attribute which explicitly declares the member to be included in the serialization. 51 | 52 | Optional Type-Hinting improves deserializing to strongly-typed objects 53 | 54 | JsonFx.Json.JsonWriter.TypeHintName & JsonFx.Json.JsonReader.TypeHintName: 55 | Property designates the name of the type hint property (e.g. "__type") and enables type hinting 56 | 57 | Optional PrettyPrint mode helps with debugging / human-readability 58 | 59 | JsonFx.Json.JsonWriter.PrettyPrint 60 | 61 | Optional custom DateTime serialization override 62 | 63 | JsonFx.Json.JsonWriter.DateTimeSerializer 64 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/Scripts/json2.js: -------------------------------------------------------------------------------- 1 | /* 2 | http://www.JSON.org/json2.js 3 | 2010-03-20 4 | 5 | Public Domain. 6 | 7 | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 8 | 9 | See http://www.JSON.org/js.html 10 | 11 | 12 | This code should be minified before deployment. 13 | See http://javascript.crockford.com/jsmin.html 14 | 15 | USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO 16 | NOT CONTROL. 17 | 18 | 19 | This file creates a global JSON object containing two methods: stringify 20 | and parse. 21 | 22 | JSON.stringify(value, replacer, space) 23 | value any JavaScript value, usually an object or array. 24 | 25 | replacer an optional parameter that determines how object 26 | values are stringified for objects. It can be a 27 | function or an array of strings. 28 | 29 | space an optional parameter that specifies the indentation 30 | of nested structures. If it is omitted, the text will 31 | be packed without extra whitespace. If it is a number, 32 | it will specify the number of spaces to indent at each 33 | level. If it is a string (such as '\t' or ' '), 34 | it contains the characters used to indent at each level. 35 | 36 | This method produces a JSON text from a JavaScript value. 37 | 38 | When an object value is found, if the object contains a toJSON 39 | method, its toJSON method will be called and the result will be 40 | stringified. A toJSON method does not serialize: it returns the 41 | value represented by the name/value pair that should be serialized, 42 | or undefined if nothing should be serialized. The toJSON method 43 | will be passed the key associated with the value, and this will be 44 | bound to the value 45 | 46 | For example, this would serialize Dates as ISO strings. 47 | 48 | Date.prototype.toJSON = function (key) { 49 | function f(n) { 50 | // Format integers to have at least two digits. 51 | return n < 10 ? '0' + n : n; 52 | } 53 | 54 | return this.getUTCFullYear() + '-' + 55 | f(this.getUTCMonth() + 1) + '-' + 56 | f(this.getUTCDate()) + 'T' + 57 | f(this.getUTCHours()) + ':' + 58 | f(this.getUTCMinutes()) + ':' + 59 | f(this.getUTCSeconds()) + 'Z'; 60 | }; 61 | 62 | You can provide an optional replacer method. It will be passed the 63 | key and value of each member, with this bound to the containing 64 | object. The value that is returned from your method will be 65 | serialized. If your method returns undefined, then the member will 66 | be excluded from the serialization. 67 | 68 | If the replacer parameter is an array of strings, then it will be 69 | used to select the members to be serialized. It filters the results 70 | such that only members with keys listed in the replacer array are 71 | stringified. 72 | 73 | Values that do not have JSON representations, such as undefined or 74 | functions, will not be serialized. Such values in objects will be 75 | dropped; in arrays they will be replaced with null. You can use 76 | a replacer function to replace those with JSON values. 77 | JSON.stringify(undefined) returns undefined. 78 | 79 | The optional space parameter produces a stringification of the 80 | value that is filled with line breaks and indentation to make it 81 | easier to read. 82 | 83 | If the space parameter is a non-empty string, then that string will 84 | be used for indentation. If the space parameter is a number, then 85 | the indentation will be that many spaces. 86 | 87 | Example: 88 | 89 | text = JSON.stringify(['e', {pluribus: 'unum'}]); 90 | // text is '["e",{"pluribus":"unum"}]' 91 | 92 | 93 | text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); 94 | // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' 95 | 96 | text = JSON.stringify([new Date()], function (key, value) { 97 | return this[key] instanceof Date ? 98 | 'Date(' + this[key] + ')' : value; 99 | }); 100 | // text is '["Date(---current time---)"]' 101 | 102 | 103 | JSON.parse(text, reviver) 104 | This method parses a JSON text to produce an object or array. 105 | It can throw a SyntaxError exception. 106 | 107 | The optional reviver parameter is a function that can filter and 108 | transform the results. It receives each of the keys and values, 109 | and its return value is used instead of the original value. 110 | If it returns what it received, then the structure is not modified. 111 | If it returns undefined then the member is deleted. 112 | 113 | Example: 114 | 115 | // Parse the text. Values that look like ISO date strings will 116 | // be converted to Date objects. 117 | 118 | myData = JSON.parse(text, function (key, value) { 119 | var a; 120 | if (typeof value === 'string') { 121 | a = 122 | /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 123 | if (a) { 124 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], 125 | +a[5], +a[6])); 126 | } 127 | } 128 | return value; 129 | }); 130 | 131 | myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { 132 | var d; 133 | if (typeof value === 'string' && 134 | value.slice(0, 5) === 'Date(' && 135 | value.slice(-1) === ')') { 136 | d = new Date(value.slice(5, -1)); 137 | if (d) { 138 | return d; 139 | } 140 | } 141 | return value; 142 | }); 143 | 144 | 145 | This is a reference implementation. You are free to copy, modify, or 146 | redistribute. 147 | */ 148 | 149 | /*jslint evil: true, strict: false */ 150 | 151 | 152 | // Create a JSON object only if one does not already exist. We create the 153 | // methods in a closure to avoid creating global variables. 154 | 155 | if (!this.JSON) { 156 | this.JSON = {}; 157 | } 158 | 159 | (function () { 160 | 161 | function f(n) { 162 | // Format integers to have at least two digits. 163 | return n < 10 ? '0' + n : n; 164 | } 165 | 166 | if (typeof Date.prototype.toJSON !== 'function') { 167 | 168 | Date.prototype.toJSON = function (key) { 169 | 170 | return isFinite(this.valueOf()) ? 171 | this.getUTCFullYear() + '-' + 172 | f(this.getUTCMonth() + 1) + '-' + 173 | f(this.getUTCDate()) + 'T' + 174 | f(this.getUTCHours()) + ':' + 175 | f(this.getUTCMinutes()) + ':' + 176 | f(this.getUTCSeconds()) + 'Z' : null; 177 | }; 178 | 179 | String.prototype.toJSON = 180 | Number.prototype.toJSON = 181 | Boolean.prototype.toJSON = function (key) { 182 | return this.valueOf(); 183 | }; 184 | } 185 | 186 | var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 187 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 188 | gap, 189 | indent, 190 | meta = { // table of character substitutions 191 | '\b': '\\b', 192 | '\t': '\\t', 193 | '\n': '\\n', 194 | '\f': '\\f', 195 | '\r': '\\r', 196 | '"' : '\\"', 197 | '\\': '\\\\' 198 | }, 199 | rep; 200 | 201 | 202 | function quote(string) { 203 | 204 | // If the string contains no control characters, no quote characters, and no 205 | // backslash characters, then we can safely slap some quotes around it. 206 | // Otherwise we must also replace the offending characters with safe escape 207 | // sequences. 208 | 209 | escapable.lastIndex = 0; 210 | return escapable.test(string) ? 211 | '"' + string.replace(escapable, function (a) { 212 | var c = meta[a]; 213 | return typeof c === 'string' ? c : 214 | '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 215 | }) + '"' : 216 | '"' + string + '"'; 217 | } 218 | 219 | 220 | function str(key, holder) { 221 | 222 | // Produce a string from holder[key]. 223 | 224 | var i, // The loop counter. 225 | k, // The member key. 226 | v, // The member value. 227 | length, 228 | mind = gap, 229 | partial, 230 | value = holder[key]; 231 | 232 | // If the value has a toJSON method, call it to obtain a replacement value. 233 | 234 | if (value && typeof value === 'object' && 235 | typeof value.toJSON === 'function') { 236 | value = value.toJSON(key); 237 | } 238 | 239 | // If we were called with a replacer function, then call the replacer to 240 | // obtain a replacement value. 241 | 242 | if (typeof rep === 'function') { 243 | value = rep.call(holder, key, value); 244 | } 245 | 246 | // What happens next depends on the value's type. 247 | 248 | switch (typeof value) { 249 | case 'string': 250 | return quote(value); 251 | 252 | case 'number': 253 | 254 | // JSON numbers must be finite. Encode non-finite numbers as null. 255 | 256 | return isFinite(value) ? String(value) : 'null'; 257 | 258 | case 'boolean': 259 | case 'null': 260 | 261 | // If the value is a boolean or null, convert it to a string. Note: 262 | // typeof null does not produce 'null'. The case is included here in 263 | // the remote chance that this gets fixed someday. 264 | 265 | return String(value); 266 | 267 | // If the type is 'object', we might be dealing with an object or an array or 268 | // null. 269 | 270 | case 'object': 271 | 272 | // Due to a specification blunder in ECMAScript, typeof null is 'object', 273 | // so watch out for that case. 274 | 275 | if (!value) { 276 | return 'null'; 277 | } 278 | 279 | // Make an array to hold the partial results of stringifying this object value. 280 | 281 | gap += indent; 282 | partial = []; 283 | 284 | // Is the value an array? 285 | 286 | if (Object.prototype.toString.apply(value) === '[object Array]') { 287 | 288 | // The value is an array. Stringify every element. Use null as a placeholder 289 | // for non-JSON values. 290 | 291 | length = value.length; 292 | for (i = 0; i < length; i += 1) { 293 | partial[i] = str(i, value) || 'null'; 294 | } 295 | 296 | // Join all of the elements together, separated with commas, and wrap them in 297 | // brackets. 298 | 299 | v = partial.length === 0 ? '[]' : 300 | gap ? '[\n' + gap + 301 | partial.join(',\n' + gap) + '\n' + 302 | mind + ']' : 303 | '[' + partial.join(',') + ']'; 304 | gap = mind; 305 | return v; 306 | } 307 | 308 | // If the replacer is an array, use it to select the members to be stringified. 309 | 310 | if (rep && typeof rep === 'object') { 311 | length = rep.length; 312 | for (i = 0; i < length; i += 1) { 313 | k = rep[i]; 314 | if (typeof k === 'string') { 315 | v = str(k, value); 316 | if (v) { 317 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 318 | } 319 | } 320 | } 321 | } else { 322 | 323 | // Otherwise, iterate through all of the keys in the object. 324 | 325 | for (k in value) { 326 | if (Object.hasOwnProperty.call(value, k)) { 327 | v = str(k, value); 328 | if (v) { 329 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 330 | } 331 | } 332 | } 333 | } 334 | 335 | // Join all of the member texts together, separated with commas, 336 | // and wrap them in braces. 337 | 338 | v = partial.length === 0 ? '{}' : 339 | gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + 340 | mind + '}' : '{' + partial.join(',') + '}'; 341 | gap = mind; 342 | return v; 343 | } 344 | } 345 | 346 | // If the JSON object does not yet have a stringify method, give it one. 347 | 348 | if (typeof JSON.stringify !== 'function') { 349 | JSON.stringify = function (value, replacer, space) { 350 | 351 | // The stringify method takes a value and an optional replacer, and an optional 352 | // space parameter, and returns a JSON text. The replacer can be a function 353 | // that can replace values, or an array of strings that will select the keys. 354 | // A default replacer method can be provided. Use of the space parameter can 355 | // produce text that is more easily readable. 356 | 357 | var i; 358 | gap = ''; 359 | indent = ''; 360 | 361 | // If the space parameter is a number, make an indent string containing that 362 | // many spaces. 363 | 364 | if (typeof space === 'number') { 365 | for (i = 0; i < space; i += 1) { 366 | indent += ' '; 367 | } 368 | 369 | // If the space parameter is a string, it will be used as the indent string. 370 | 371 | } else if (typeof space === 'string') { 372 | indent = space; 373 | } 374 | 375 | // If there is a replacer, it must be a function or an array. 376 | // Otherwise, throw an error. 377 | 378 | rep = replacer; 379 | if (replacer && typeof replacer !== 'function' && 380 | (typeof replacer !== 'object' || 381 | typeof replacer.length !== 'number')) { 382 | throw new Error('JSON.stringify'); 383 | } 384 | 385 | // Make a fake root object containing our value under the key of ''. 386 | // Return the result of stringifying the value. 387 | 388 | return str('', {'': value}); 389 | }; 390 | } 391 | 392 | 393 | // If the JSON object does not yet have a parse method, give it one. 394 | 395 | if (typeof JSON.parse !== 'function') { 396 | JSON.parse = function (text, reviver) { 397 | 398 | // The parse method takes a text and an optional reviver function, and returns 399 | // a JavaScript value if the text is a valid JSON text. 400 | 401 | var j; 402 | 403 | function walk(holder, key) { 404 | 405 | // The walk method is used to recursively walk the resulting structure so 406 | // that modifications can be made. 407 | 408 | var k, v, value = holder[key]; 409 | if (value && typeof value === 'object') { 410 | for (k in value) { 411 | if (Object.hasOwnProperty.call(value, k)) { 412 | v = walk(value, k); 413 | if (v !== undefined) { 414 | value[k] = v; 415 | } else { 416 | delete value[k]; 417 | } 418 | } 419 | } 420 | } 421 | return reviver.call(holder, key, value); 422 | } 423 | 424 | 425 | // Parsing happens in four stages. In the first stage, we replace certain 426 | // Unicode characters with escape sequences. JavaScript handles many characters 427 | // incorrectly, either silently deleting them, or treating them as line endings. 428 | 429 | text = String(text); 430 | cx.lastIndex = 0; 431 | if (cx.test(text)) { 432 | text = text.replace(cx, function (a) { 433 | return '\\u' + 434 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 435 | }); 436 | } 437 | 438 | // In the second stage, we run the text against regular expressions that look 439 | // for non-JSON patterns. We are especially concerned with '()' and 'new' 440 | // because they can cause invocation, and '=' because it can cause mutation. 441 | // But just to be safe, we want to reject all unexpected forms. 442 | 443 | // We split the second stage into 4 regexp operations in order to work around 444 | // crippling inefficiencies in IE's and Safari's regexp engines. First we 445 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 446 | // replace all simple value tokens with ']' characters. Third, we delete all 447 | // open brackets that follow a colon or comma or that begin the text. Finally, 448 | // we look to see that the remaining characters are only whitespace or ']' or 449 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 450 | 451 | if (/^[\],:{}\s]*$/. 452 | test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). 453 | replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). 454 | replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 455 | 456 | // In the third stage we use the eval function to compile the text into a 457 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 458 | // in JavaScript: it can begin a block or an object literal. We wrap the text 459 | // in parens to eliminate the ambiguity. 460 | 461 | j = eval('(' + text + ')'); 462 | 463 | // In the optional fourth stage, we recursively walk the new structure, passing 464 | // each name/value pair to a reviver function for possible transformation. 465 | 466 | return typeof reviver === 'function' ? 467 | walk({'': j}, '') : j; 468 | } 469 | 470 | // If the text is not JSON parseable, then a SyntaxError is thrown. 471 | 472 | throw new SyntaxError('JSON.parse'); 473 | }; 474 | } 475 | }()); 476 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/TypeCoercionUtility.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | using System; 32 | using System.Collections; 33 | using System.Collections.Generic; 34 | using System.ComponentModel; 35 | using System.Globalization; 36 | using System.Reflection; 37 | 38 | namespace JsonFx.Json 39 | { 40 | /// 41 | /// Utility for forcing conversion between types 42 | /// 43 | internal class TypeCoercionUtility 44 | { 45 | #region Constants 46 | 47 | private const string ErrorNullValueType = "{0} does not accept null as a value"; 48 | private const string ErrorDefaultCtor = "Only objects with default constructors can be deserialized. ({0})"; 49 | private const string ErrorCannotInstantiate = "Interfaces, Abstract classes, and unsupported ValueTypes cannot be deserialized. ({0})"; 50 | 51 | #endregion Constants 52 | 53 | #region Fields 54 | 55 | private Dictionary> memberMapCache; 56 | private bool allowNullValueTypes = true; 57 | 58 | #endregion Fields 59 | 60 | #region Properties 61 | 62 | private Dictionary> MemberMapCache 63 | { 64 | get 65 | { 66 | if (this.memberMapCache == null) 67 | { 68 | // instantiate space for cache 69 | this.memberMapCache = new Dictionary>(); 70 | } 71 | return this.memberMapCache; 72 | } 73 | } 74 | 75 | /// 76 | /// Gets and sets if ValueTypes can accept values of null 77 | /// 78 | /// 79 | /// Only affects deserialization: if a ValueType is assigned the 80 | /// value of null, it will receive the value default(TheType). 81 | /// Setting this to false, throws an exception if null is 82 | /// specified for a ValueType member. 83 | /// 84 | public bool AllowNullValueTypes 85 | { 86 | get { return this.allowNullValueTypes; } 87 | set { this.allowNullValueTypes = value; } 88 | } 89 | 90 | #endregion Properties 91 | 92 | #region Object Methods 93 | 94 | /// 95 | /// If a Type Hint is present then this method attempts to 96 | /// use it and move any previously parsed data over. 97 | /// 98 | /// the previous result 99 | /// the type info string to use 100 | /// reference to the objectType 101 | /// reference to the memberMap 102 | /// 103 | internal object ProcessTypeHint( 104 | IDictionary result, 105 | string typeInfo, 106 | out Type objectType, 107 | out Dictionary memberMap) 108 | { 109 | if (String.IsNullOrEmpty(typeInfo)) 110 | { 111 | objectType = null; 112 | memberMap = null; 113 | return result; 114 | } 115 | 116 | Type hintedType = Type.GetType(typeInfo, false); 117 | if (hintedType == null) 118 | { 119 | objectType = null; 120 | memberMap = null; 121 | return result; 122 | } 123 | 124 | objectType = hintedType; 125 | return this.CoerceType(hintedType, result, out memberMap); 126 | } 127 | 128 | internal Object InstantiateObject(Type objectType, out Dictionary memberMap) 129 | { 130 | if (objectType.IsInterface || objectType.IsAbstract || objectType.IsValueType) 131 | { 132 | throw new JsonTypeCoercionException( 133 | String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName)); 134 | } 135 | 136 | ConstructorInfo ctor = objectType.GetConstructor(Type.EmptyTypes); 137 | if (ctor == null) 138 | { 139 | throw new JsonTypeCoercionException( 140 | String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName)); 141 | } 142 | Object result; 143 | try 144 | { 145 | // always try-catch Invoke() to expose real exception 146 | result = ctor.Invoke(null); 147 | } 148 | catch (TargetInvocationException ex) 149 | { 150 | if (ex.InnerException != null) 151 | { 152 | throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); 153 | } 154 | throw new JsonTypeCoercionException("Error instantiating " + objectType.FullName, ex); 155 | } 156 | 157 | memberMap = GetMemberMap (objectType); 158 | 159 | return result; 160 | } 161 | 162 | /** Returns a member map if suitable for the object type. 163 | * Dictionary types will make this method return null 164 | */ 165 | public Dictionary GetMemberMap (Type objectType) { 166 | // don't incurr the cost of member map for dictionaries 167 | if (typeof(IDictionary).IsAssignableFrom(objectType)) 168 | { 169 | return null; 170 | } 171 | else 172 | { 173 | return this.CreateMemberMap(objectType); 174 | } 175 | } 176 | 177 | /** Creates a member map for the type */ 178 | private Dictionary CreateMemberMap(Type objectType) 179 | { 180 | if (this.MemberMapCache.ContainsKey(objectType)) 181 | { 182 | // map was stored in cache 183 | return this.MemberMapCache[objectType]; 184 | } 185 | 186 | // create a new map 187 | Dictionary memberMap = new Dictionary(); 188 | 189 | // load properties into property map 190 | PropertyInfo[] properties = objectType.GetProperties(); 191 | foreach (PropertyInfo info in properties) 192 | { 193 | if (!info.CanRead || !info.CanWrite) 194 | { 195 | continue; 196 | } 197 | 198 | if (JsonIgnoreAttribute.IsJsonIgnore(info)) 199 | { 200 | continue; 201 | } 202 | 203 | string jsonName = JsonNameAttribute.GetJsonName(info); 204 | if (String.IsNullOrEmpty(jsonName)) 205 | { 206 | memberMap[info.Name] = info; 207 | } 208 | else 209 | { 210 | memberMap[jsonName] = info; 211 | } 212 | } 213 | 214 | // load public fields into property map 215 | FieldInfo[] fields = objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 216 | foreach (FieldInfo info in fields) 217 | { 218 | if (JsonIgnoreAttribute.IsJsonIgnore(info)) 219 | { 220 | continue; 221 | } 222 | 223 | string jsonName = JsonNameAttribute.GetJsonName(info); 224 | if (String.IsNullOrEmpty(jsonName)) 225 | { 226 | memberMap[info.Name] = info; 227 | } 228 | else 229 | { 230 | memberMap[jsonName] = info; 231 | } 232 | } 233 | 234 | // store in cache for repeated usage 235 | this.MemberMapCache[objectType] = memberMap; 236 | 237 | return memberMap; 238 | } 239 | 240 | internal static Type GetMemberInfo( 241 | Dictionary memberMap, 242 | string memberName, 243 | out MemberInfo memberInfo) 244 | { 245 | if (memberMap != null && 246 | memberMap.ContainsKey(memberName)) 247 | { 248 | // Check properties for object member 249 | memberInfo = memberMap[memberName]; 250 | 251 | if (memberInfo is PropertyInfo) 252 | { 253 | // maps to public property 254 | return ((PropertyInfo)memberInfo).PropertyType; 255 | } 256 | else if (memberInfo is FieldInfo) 257 | { 258 | // maps to public field 259 | return ((FieldInfo)memberInfo).FieldType; 260 | } 261 | } 262 | 263 | memberInfo = null; 264 | return null; 265 | } 266 | 267 | /// 268 | /// Helper method to set value of either property or field 269 | /// 270 | /// 271 | /// 272 | /// 273 | /// 274 | internal void SetMemberValue(Object result, Type memberType, MemberInfo memberInfo, object value) 275 | { 276 | if (memberInfo is PropertyInfo) 277 | { 278 | // set value of public property 279 | ((PropertyInfo)memberInfo).SetValue( 280 | result, 281 | this.CoerceType(memberType, value), 282 | null); 283 | } 284 | else if (memberInfo is FieldInfo) 285 | { 286 | // set value of public field 287 | ((FieldInfo)memberInfo).SetValue( 288 | result, 289 | this.CoerceType(memberType, value)); 290 | } 291 | 292 | // all other values are ignored 293 | } 294 | 295 | #endregion Object Methods 296 | 297 | #region Type Methods 298 | 299 | internal object CoerceType(Type targetType, object value) 300 | { 301 | bool isNullable = TypeCoercionUtility.IsNullable(targetType); 302 | if (value == null) 303 | { 304 | if (!allowNullValueTypes && 305 | targetType.IsValueType && 306 | !isNullable) 307 | { 308 | throw new JsonTypeCoercionException(String.Format(TypeCoercionUtility.ErrorNullValueType, targetType.FullName)); 309 | } 310 | return value; 311 | } 312 | 313 | if (isNullable) 314 | { 315 | // nullable types have a real underlying struct 316 | Type[] genericArgs = targetType.GetGenericArguments(); 317 | if (genericArgs.Length == 1) 318 | { 319 | targetType = genericArgs[0]; 320 | } 321 | } 322 | 323 | Type actualType = value.GetType(); 324 | if (targetType.IsAssignableFrom(actualType)) 325 | { 326 | return value; 327 | } 328 | 329 | if (targetType.IsEnum) 330 | { 331 | if (value is String) 332 | { 333 | if (!Enum.IsDefined(targetType, value)) 334 | { 335 | // if isn't a defined value perhaps it is the JsonName 336 | foreach (FieldInfo field in targetType.GetFields()) 337 | { 338 | string jsonName = JsonNameAttribute.GetJsonName(field); 339 | if (((string)value).Equals(jsonName)) 340 | { 341 | value = field.Name; 342 | break; 343 | } 344 | } 345 | } 346 | 347 | return Enum.Parse(targetType, (string)value); 348 | } 349 | else 350 | { 351 | value = this.CoerceType(Enum.GetUnderlyingType(targetType), value); 352 | return Enum.ToObject(targetType, value); 353 | } 354 | } 355 | 356 | if (value is IDictionary) 357 | { 358 | Dictionary memberMap; 359 | return this.CoerceType(targetType, (IDictionary)value, out memberMap); 360 | } 361 | 362 | if (typeof(IEnumerable).IsAssignableFrom(targetType) && 363 | typeof(IEnumerable).IsAssignableFrom(actualType)) 364 | { 365 | return this.CoerceList(targetType, actualType, (IEnumerable)value); 366 | } 367 | 368 | if (value is String) 369 | { 370 | if (targetType == typeof(DateTime)) 371 | { 372 | DateTime date; 373 | if (DateTime.TryParse( 374 | (string)value, 375 | DateTimeFormatInfo.InvariantInfo, 376 | DateTimeStyles.RoundtripKind | DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault, 377 | out date)) 378 | { 379 | return date; 380 | } 381 | } 382 | else if (targetType == typeof(Guid)) 383 | { 384 | // try-catch is pointless since will throw upon generic conversion 385 | return new Guid((string)value); 386 | } 387 | else if (targetType == typeof(Char)) 388 | { 389 | if (((string)value).Length == 1) 390 | { 391 | return ((string)value)[0]; 392 | } 393 | } 394 | else if (targetType == typeof(Uri)) 395 | { 396 | Uri uri; 397 | if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out uri)) 398 | { 399 | return uri; 400 | } 401 | } 402 | else if (targetType == typeof(Version)) 403 | { 404 | // try-catch is pointless since will throw upon generic conversion 405 | return new Version((string)value); 406 | } 407 | } 408 | else if (targetType == typeof(TimeSpan)) 409 | { 410 | return new TimeSpan((long)this.CoerceType(typeof(Int64), value)); 411 | } 412 | 413 | TypeConverter converter = TypeDescriptor.GetConverter(targetType); 414 | if (converter.CanConvertFrom(actualType)) 415 | { 416 | return converter.ConvertFrom(value); 417 | } 418 | 419 | converter = TypeDescriptor.GetConverter(actualType); 420 | if (converter.CanConvertTo(targetType)) 421 | { 422 | return converter.ConvertTo(value, targetType); 423 | } 424 | 425 | try 426 | { 427 | // fall back to basics 428 | return Convert.ChangeType(value, targetType); 429 | } 430 | catch (Exception ex) 431 | { 432 | throw new JsonTypeCoercionException( 433 | String.Format("Error converting {0} to {1}", value.GetType().FullName, targetType.FullName), ex); 434 | } 435 | } 436 | 437 | private object CoerceType(Type targetType, IDictionary value, out Dictionary memberMap) 438 | { 439 | object newValue = this.InstantiateObject(targetType, out memberMap); 440 | if (memberMap != null) 441 | { 442 | // copy any values into new object 443 | foreach (object key in value.Keys) 444 | { 445 | MemberInfo memberInfo; 446 | Type memberType = TypeCoercionUtility.GetMemberInfo(memberMap, key as String, out memberInfo); 447 | this.SetMemberValue(newValue, memberType, memberInfo, value[key]); 448 | } 449 | } 450 | return newValue; 451 | } 452 | 453 | private object CoerceList(Type targetType, Type arrayType, IEnumerable value) 454 | { 455 | if (targetType.IsArray) 456 | { 457 | return this.CoerceArray(targetType.GetElementType(), value); 458 | } 459 | 460 | // targetType serializes as a JSON array but is not an array 461 | // assume is an ICollection / IEnumerable with AddRange, Add, 462 | // or custom Constructor with which we can populate it 463 | 464 | // many ICollection types take an IEnumerable or ICollection 465 | // as a constructor argument. look through constructors for 466 | // a compatible match. 467 | ConstructorInfo[] ctors = targetType.GetConstructors(); 468 | ConstructorInfo defaultCtor = null; 469 | foreach (ConstructorInfo ctor in ctors) 470 | { 471 | ParameterInfo[] paramList = ctor.GetParameters(); 472 | if (paramList.Length == 0) 473 | { 474 | // save for in case cannot find closer match 475 | defaultCtor = ctor; 476 | continue; 477 | } 478 | 479 | if (paramList.Length == 1 && 480 | paramList[0].ParameterType.IsAssignableFrom(arrayType)) 481 | { 482 | try 483 | { 484 | // invoke first constructor that can take this value as an argument 485 | return ctor.Invoke( 486 | new object[] { value } 487 | ); 488 | } 489 | catch 490 | { 491 | // there might exist a better match 492 | continue; 493 | } 494 | } 495 | } 496 | 497 | if (defaultCtor == null) 498 | { 499 | throw new JsonTypeCoercionException( 500 | String.Format(TypeCoercionUtility.ErrorDefaultCtor, targetType.FullName)); 501 | } 502 | object collection; 503 | try 504 | { 505 | // always try-catch Invoke() to expose real exception 506 | collection = defaultCtor.Invoke(null); 507 | } 508 | catch (TargetInvocationException ex) 509 | { 510 | if (ex.InnerException != null) 511 | { 512 | throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); 513 | } 514 | throw new JsonTypeCoercionException("Error instantiating " + targetType.FullName, ex); 515 | } 516 | 517 | // many ICollection types have an AddRange method 518 | // which adds all items at once 519 | MethodInfo method = targetType.GetMethod("AddRange"); 520 | ParameterInfo[] parameters = (method == null) ? 521 | null : method.GetParameters(); 522 | Type paramType = (parameters == null || parameters.Length != 1) ? 523 | null : parameters[0].ParameterType; 524 | if (paramType != null && 525 | paramType.IsAssignableFrom(arrayType)) 526 | { 527 | try 528 | { 529 | // always try-catch Invoke() to expose real exception 530 | // add all members in one method 531 | method.Invoke( 532 | collection, 533 | new object[] { value }); 534 | } 535 | catch (TargetInvocationException ex) 536 | { 537 | if (ex.InnerException != null) 538 | { 539 | throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); 540 | } 541 | throw new JsonTypeCoercionException("Error calling AddRange on " + targetType.FullName, ex); 542 | } 543 | return collection; 544 | } 545 | else 546 | { 547 | // many ICollection types have an Add method 548 | // which adds items one at a time 549 | method = targetType.GetMethod("Add"); 550 | parameters = (method == null) ? 551 | null : method.GetParameters(); 552 | paramType = (parameters == null || parameters.Length != 1) ? 553 | null : parameters[0].ParameterType; 554 | if (paramType != null) 555 | { 556 | // loop through adding items to collection 557 | foreach (object item in value) 558 | { 559 | try 560 | { 561 | // always try-catch Invoke() to expose real exception 562 | method.Invoke( 563 | collection, 564 | new object[] { 565 | this.CoerceType(paramType, item) 566 | }); 567 | } 568 | catch (TargetInvocationException ex) 569 | { 570 | if (ex.InnerException != null) 571 | { 572 | throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); 573 | } 574 | throw new JsonTypeCoercionException("Error calling Add on " + targetType.FullName, ex); 575 | } 576 | } 577 | return collection; 578 | } 579 | } 580 | 581 | try 582 | { 583 | // fall back to basics 584 | return Convert.ChangeType(value, targetType); 585 | } 586 | catch (Exception ex) 587 | { 588 | throw new JsonTypeCoercionException(String.Format("Error converting {0} to {1}", value.GetType().FullName, targetType.FullName), ex); 589 | } 590 | } 591 | 592 | private Array CoerceArray(Type elementType, IEnumerable value) 593 | { 594 | ArrayList target = new ArrayList(); 595 | 596 | foreach (object item in value) 597 | { 598 | target.Add(this.CoerceType(elementType, item)); 599 | } 600 | 601 | return target.ToArray(elementType); 602 | } 603 | 604 | private static bool IsNullable(Type type) 605 | { 606 | return type.IsGenericType && (typeof(Nullable<>) == type.GetGenericTypeDefinition()); 607 | } 608 | 609 | #endregion Type Methods 610 | } 611 | } 612 | -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/XmlDataReader.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | #if !UNITY3D 32 | using System; 33 | using System.IO; 34 | using System.Xml; 35 | using System.Xml.Serialization; 36 | 37 | using JsonFx.Json; 38 | 39 | namespace JsonFx.Xml 40 | { 41 | /// 42 | /// An adapter for 43 | /// 44 | public class XmlDataReader : IDataReader 45 | { 46 | #region Constants 47 | 48 | public const string XmlMimeType = XmlDataWriter.XmlMimeType; 49 | 50 | #endregion Constants 51 | 52 | #region Fields 53 | 54 | private readonly XmlReaderSettings Settings; 55 | private readonly XmlSerializerNamespaces Namespaces; 56 | 57 | #endregion Fields 58 | 59 | #region Init 60 | 61 | /// 62 | /// Ctor 63 | /// 64 | /// 65 | /// 66 | public XmlDataReader(XmlReaderSettings settings, XmlSerializerNamespaces namespaces) 67 | { 68 | if (settings == null) 69 | { 70 | throw new ArgumentNullException("settings"); 71 | } 72 | this.Settings = settings; 73 | 74 | if (namespaces == null) 75 | { 76 | namespaces = new XmlSerializerNamespaces(); 77 | namespaces.Add(String.Empty, String.Empty);// tricks the serializer into not emitting default xmlns attributes 78 | } 79 | this.Namespaces = namespaces; 80 | } 81 | 82 | #endregion Init 83 | 84 | #region IDataSerializer Members 85 | 86 | /// 87 | /// Gets the content type 88 | /// 89 | public string ContentType 90 | { 91 | get { return XmlDataWriter.XmlMimeType; } 92 | } 93 | 94 | /// 95 | /// Deserializes a data object from the given input 96 | /// 97 | /// 98 | /// 99 | /// 100 | public object Deserialize(TextReader input, Type type) 101 | { 102 | XmlReader reader = XmlReader.Create(input, this.Settings); 103 | 104 | // skip DocType / processing instructions 105 | reader.MoveToContent(); 106 | 107 | // serialize feed 108 | XmlSerializer serializer = new XmlSerializer(type); 109 | return serializer.Deserialize(reader); 110 | } 111 | 112 | #endregion IDataSerializer Members 113 | 114 | #region Methods 115 | 116 | /// 117 | /// Builds a common settings objects 118 | /// 119 | /// 120 | public static XmlReaderSettings CreateSettings() 121 | { 122 | // setup document formatting 123 | XmlReaderSettings settings = new XmlReaderSettings(); 124 | settings.CloseInput = false; 125 | settings.ConformanceLevel = ConformanceLevel.Auto; 126 | settings.IgnoreComments = true; 127 | settings.IgnoreWhitespace = true; 128 | settings.IgnoreProcessingInstructions = true; 129 | return settings; 130 | } 131 | 132 | #endregion Methods 133 | } 134 | } 135 | #endif -------------------------------------------------------------------------------- /JsonFx/JsonFx.Json/XmlDataWriter.cs: -------------------------------------------------------------------------------- 1 | #region License 2 | /*---------------------------------------------------------------------------------*\ 3 | 4 | Distributed under the terms of an MIT-style license: 5 | 6 | The MIT License 7 | 8 | Copyright (c) 2006-2009 Stephen M. McKamey 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | \*---------------------------------------------------------------------------------*/ 29 | #endregion License 30 | 31 | #if !UNITY3D 32 | using System; 33 | using System.IO; 34 | using System.Text; 35 | using System.Xml; 36 | using System.Xml.Serialization; 37 | 38 | using JsonFx.Json; 39 | 40 | namespace JsonFx.Xml 41 | { 42 | /// 43 | /// An adapter for 44 | /// 45 | public class XmlDataWriter : IDataWriter 46 | { 47 | #region Constants 48 | 49 | public const string XmlMimeType = "application/xml"; 50 | public const string XmlFileExtension = ".xml"; 51 | 52 | #endregion Constants 53 | 54 | #region Fields 55 | 56 | private readonly XmlWriterSettings Settings; 57 | private readonly XmlSerializerNamespaces Namespaces; 58 | 59 | #endregion Fields 60 | 61 | #region Init 62 | 63 | /// 64 | /// Ctor 65 | /// 66 | /// 67 | /// 68 | public XmlDataWriter(XmlWriterSettings settings, XmlSerializerNamespaces namespaces) 69 | { 70 | if (settings == null) 71 | { 72 | throw new ArgumentNullException("settings"); 73 | } 74 | this.Settings = settings; 75 | 76 | if (namespaces == null) 77 | { 78 | namespaces = new XmlSerializerNamespaces(); 79 | namespaces.Add(String.Empty, String.Empty);// tricks the serializer into not emitting default xmlns attributes 80 | } 81 | this.Namespaces = namespaces; 82 | } 83 | 84 | #endregion Init 85 | 86 | #region IDataSerializer Members 87 | 88 | /// 89 | /// Gets the content encoding 90 | /// 91 | public Encoding ContentEncoding 92 | { 93 | get { return this.Settings.Encoding ?? Encoding.UTF8; } 94 | } 95 | 96 | /// 97 | /// Gets the content type 98 | /// 99 | public string ContentType 100 | { 101 | get { return XmlDataWriter.XmlMimeType; } 102 | } 103 | 104 | /// 105 | /// Gets the file extension 106 | /// 107 | public string FileExtension 108 | { 109 | get { return XmlDataWriter.XmlFileExtension; } 110 | } 111 | 112 | /// 113 | /// Serializes the data object to the given output 114 | /// 115 | /// 116 | /// 117 | public void Serialize(TextWriter output, object data) 118 | { 119 | if (data == null) 120 | { 121 | return; 122 | } 123 | 124 | if (this.Settings.Encoding == null) 125 | { 126 | this.Settings.Encoding = this.ContentEncoding; 127 | } 128 | XmlWriter writer = XmlWriter.Create(output, this.Settings); 129 | 130 | // serialize feed 131 | XmlSerializer serializer = new XmlSerializer(data.GetType()); 132 | serializer.Serialize(writer, data, this.Namespaces); 133 | } 134 | 135 | #endregion IDataSerializer Members 136 | 137 | #region Methods 138 | 139 | /// 140 | /// Builds a common settings objects 141 | /// 142 | /// 143 | /// 144 | /// 145 | public static XmlWriterSettings CreateSettings(Encoding encoding, bool prettyPrint) 146 | { 147 | // setup document formatting 148 | XmlWriterSettings settings = new XmlWriterSettings(); 149 | settings.CheckCharacters = true; 150 | settings.CloseOutput = false; 151 | settings.ConformanceLevel = ConformanceLevel.Auto; 152 | settings.Encoding = encoding; 153 | settings.OmitXmlDeclaration = true; 154 | 155 | if (prettyPrint) 156 | { 157 | // make human readable 158 | settings.Indent = true; 159 | settings.IndentChars = "\t"; 160 | } 161 | else 162 | { 163 | // compact 164 | settings.Indent = false; 165 | settings.NewLineChars = String.Empty; 166 | } 167 | settings.NewLineHandling = NewLineHandling.Replace; 168 | 169 | return settings; 170 | } 171 | 172 | #endregion Methods 173 | } 174 | } 175 | #endif -------------------------------------------------------------------------------- /JsonFx/TODO.txt: -------------------------------------------------------------------------------- 1 | 2009-10-06 @ 22:31 2 | 3 | - Ensure JSON-RPC Notifications suppress response (& client side doesn't care) 4 | - Batch JSON-RPC request/responses 5 | - Async JSON-RPC request processing 6 | 7 | - Async pages / controls 8 | 9 | - <%# .... %> fails inside textareas? 10 | - verify that   is not being normalized 11 | - fix jbst:control bindings so data & name literals are emitted as code expressions 12 | e.g. data="this.data.items" is equivalent to data="<%= this.data.items %>" 13 | - replace alert/confirm with window.onerror calls in release mode 14 | - replace regex in rpc proxies with actual name check methods 15 | - rework bindings to fire after insert? 16 | - add JsonFx.Bindings.one which removes once fired (leverage for server jbst:control) 17 | 18 | - explain JSON-RPC callback examples 19 | - explain difference between JsonFx.UI.Binding vs. jQuery.ready 20 | - explain how to switch templates in list JBSTs 21 | - explain using Linq in JSON-RPC 22 | - explain inserting markup data into JBST 23 | 24 | - configurable expires for globalization handler? 25 | 26 | - add anonymous templates inside server jbst:control 27 | - just parse on the fly? 28 | - default inner property for default content? 29 | - figure out a way to custom serialize objects which are closed source (e.g. BCL) 30 | - add use of custom type descriptors to define properties (e.g. convert a Dictionary to object) 31 | - BUG: dictionaries without keys round-trip-able as strings should be rendered as key-value lists 32 | 33 | - create build provider for generating a list of localization values 34 | - client-side localization: add support for <%= Resources.Foo.Bar %> 35 | - emit CSS merge as imports during debug 36 | - add CDN support to JsonFx:ResourceInclude (e.g. Google AJAX APIs) 37 | - add VS2K8 IntelliSense support for JsonFx libs: 38 | - add XML comments 39 | - ease the burden of adding VS Script resource include tags 40 | 41 | - consolidate type loading logic (see System.Workflow.ComponentModel.Compiler.TypeProvider.GetType(string)) 42 | - resolve "~/" vs. HostingEnvironment.AppVirtualPath 43 | - fully support Mod_mono Apache hosting 44 | - Create a Google Code repository 45 | - http://code.google.com/hosting/createProject 46 | - use svnsync to import an existing repository (http://code.google.com/p/support/wiki/FAQ#Subversion) 47 | - build jQuery plugin for JsonML / JSBT 48 | 49 | ___________________________________________________________________________________ 50 | 51 | - JavaScript IntelliSense 52 | - Flesh out the JsonFx IntelliSense story 53 | - add Doc comments to all JsonFx scripts 54 | - http://blogs.msdn.com/webdevtools/archive/2008/11/18/jscript-intellisense-faq.aspx 55 | - http://blogs.msdn.com/webdevtools/archive/2007/03/02/jscript-intellisense-in-orcas.aspx 56 | - http://weblogs.asp.net/bleroy/archive/2007/04/23/the-format-for-javascript-doc-comments.aspx 57 | - http://blogs.msdn.com/webdevtools/archive/2007/11/06/jscript-intellisense-a-reference-for-the-reference-tag.aspx 58 | - http://blogs.msdn.com/webdevtools/archive/tags/IntelliSense/default.aspx 59 | 60 | - customize VS templates 61 | http://msdn.microsoft.com/en-us/library/ms185314(VS.80).aspx 62 | http://msdn.microsoft.com/en-us/library/ms246580(VS.80).aspx 63 | http://msdn.microsoft.com/en-us/magazine/cc188697.aspx 64 | 65 | - enumerate available L10n languages: 66 | http://blogs.msdn.com/michkap/archive/2006/03/25/560838.aspx 67 | 68 | - Plug-Ins via reflection 69 | http://msdn.microsoft.com/en-us/magazine/cc163759.aspx 70 | 71 | - create documentation 72 | see: http://msdn.microsoft.com/en-us/library/ms524716.aspx 73 | see: http://www.jsptut.com/ 74 | see: http://java.sun.com/products/jsp/pdf/card11.pdf 75 | see: http://domscripting.com/presentations/fowa07/slides/03_data_formats.html 76 | 77 | - define mechanism for loading scripts with dependencies 78 | 79 | - Move History & Animation to Options object (onChange? onComplete) 80 | 81 | - Check out competition (http://www.daniel-zeiss.de/AJAXComparison/Results.htm) 82 | 83 | - add support wrapper for responseXML? (http://domscripting.com/presentations/fowa07/slides/03_data_formats.html( 84 | 85 | - Add callbacks to Animate (onBeforeStart, onEachStep, onAfterStop), (http://wiki.script.aculo.us/scriptaculous/show/CoreEffects) 86 | - Change Animation speed to be seconds based? fps? 87 | 88 | - Add IFrame support for downlevel browsers? (http://ajaxpatterns.org/archive/XMLHttpRequest_Call.php) 89 | - Add