Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7238b75bdb | |||
| db2890bf99 | |||
| c8a695034e | |||
| 0332af453a | |||
| f650d8b1ed | |||
| e3b086e4a4 | |||
| 43f19ac206 | |||
| 3fdcad0f8a | |||
| dc737187ee | |||
| ff32ad9d1f | |||
| a4153ded57 | |||
| e4a9cb1995 | |||
| 4cec1c6a20 | |||
| 76a8e350e6 | |||
| d3c6e34350 | |||
| 8382f7f9ea | |||
| 5e6b51506e | |||
| 79183c8b68 | |||
| 18f2fd0b7a | |||
| 9d4c2c170d | |||
| fb58fa8109 | |||
| 00664880fb | |||
| 814800200f | |||
| 2f81aaa73c | |||
| c3f3049174 | |||
| 09bdde310d |
30
.gitignore
vendored
30
.gitignore
vendored
@@ -1,30 +0,0 @@
|
|||||||
#ignorar miniaturas creadas por windows
|
|
||||||
Thumbs.db
|
|
||||||
#Ignorar archivos construidos por Visual Studio
|
|
||||||
*.obj
|
|
||||||
*.exe
|
|
||||||
*.pdb
|
|
||||||
*.user
|
|
||||||
*.aps
|
|
||||||
*.pch
|
|
||||||
*.vspscc
|
|
||||||
*_i.c
|
|
||||||
*_p.c
|
|
||||||
*.ncb
|
|
||||||
*.suo
|
|
||||||
*.tlb
|
|
||||||
*.tlh
|
|
||||||
*.bak
|
|
||||||
*.cache
|
|
||||||
*.ilk
|
|
||||||
*.log
|
|
||||||
[Bb]in
|
|
||||||
[Dd]ebug*/
|
|
||||||
*.lib
|
|
||||||
*.sbr
|
|
||||||
obj/
|
|
||||||
[Rr]elease*/
|
|
||||||
_ReSharper*/
|
|
||||||
*.userprefs
|
|
||||||
*.nupkg
|
|
||||||
/.vs/*
|
|
||||||
21
LICENSE.txt
21
LICENSE.txt
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016-2017 Valeriano Alfonso Rodriguez
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
58
README.md
58
README.md
@@ -1,58 +0,0 @@
|
|||||||
# .Net library for JSON parsing
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### VAR.Json
|
|
||||||
Add the resulting assembly as reference in your projects, and this line on code:
|
|
||||||
|
|
||||||
using VAR.Json;
|
|
||||||
|
|
||||||
Parse any string with JSON content:
|
|
||||||
|
|
||||||
var jsonParser = new JsonParser();
|
|
||||||
object result = jsonParser("{\"Test\": 1}");
|
|
||||||
|
|
||||||
Serialize any object to JSON:
|
|
||||||
|
|
||||||
var jsonWriter = new JsonWriter();
|
|
||||||
string jsonText = jsonWriter(new List<int>{1, 2, 3, 4});
|
|
||||||
|
|
||||||
## Building
|
|
||||||
A Visual Studio 2015 solutions are provided. Simply, click build on the IDE.
|
|
||||||
|
|
||||||
A .nuget package can be build using:
|
|
||||||
VAR.Json\Build.NuGet.cmd
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
1. Fork it!
|
|
||||||
2. Create your feature branch: `git checkout -b my-new-feature`
|
|
||||||
3. Commit your changes: `git commit -am 'Add some feature'`
|
|
||||||
4. Push to the branch: `git push origin my-new-feature`
|
|
||||||
5. Submit a pull request :D
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
* Valeriano Alfonso Rodriguez.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016-2017 Valeriano Alfonso Rodriguez
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace VAR.Json.Tests
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
// http://www.json.org/JSON_checker/
|
|
||||||
|
|
||||||
string currentPath = System.Reflection.Assembly.GetEntryAssembly().Location;
|
|
||||||
currentPath = FindPath(currentPath, "tests");
|
|
||||||
|
|
||||||
// Test all files
|
|
||||||
string[] files;
|
|
||||||
files = Directory.GetFiles(currentPath, "*.json");
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
|
||||||
TestFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.Read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestFile(string fileName)
|
|
||||||
{
|
|
||||||
string testName = Path.GetFileNameWithoutExtension(fileName);
|
|
||||||
string fileContent = File.ReadAllText(fileName, Encoding.UTF8);
|
|
||||||
if (testName.StartsWith("fail"))
|
|
||||||
{
|
|
||||||
TestFailCase(testName, fileContent);
|
|
||||||
}
|
|
||||||
if (testName.StartsWith("pass"))
|
|
||||||
{
|
|
||||||
TestPassCase(testName, fileContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestFailCase(string testName, string fileContent)
|
|
||||||
{
|
|
||||||
JsonParser parser = new JsonParser();
|
|
||||||
object result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = parser.Parse(fileContent);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
OutputFailure(testName, fileContent, ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (parser.Tainted == false)
|
|
||||||
{
|
|
||||||
OutputFailure(testName, fileContent, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Console.Out.WriteLine("OK! {0}", testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestPassCase(string testName, string fileContent)
|
|
||||||
{
|
|
||||||
JsonParser parser = new JsonParser();
|
|
||||||
object result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = parser.Parse(fileContent);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
OutputFailure(testName, fileContent, ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (parser.Tainted)
|
|
||||||
{
|
|
||||||
OutputFailure(testName, fileContent, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Console.Out.WriteLine("OK! {0}", testName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OutputFailure(string testName, string fileContent, object obj)
|
|
||||||
{
|
|
||||||
Console.Out.WriteLine("Failure! {0}", testName);
|
|
||||||
Console.Out.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
Console.Out.WriteLine("Content:\n{0}", fileContent);
|
|
||||||
Console.Out.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
if (obj is Exception)
|
|
||||||
{
|
|
||||||
Exception ex = obj as Exception;
|
|
||||||
Console.Out.WriteLine("Ex.Message: {0}", ex.Message);
|
|
||||||
Console.Out.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
Console.Out.WriteLine("Ex.Stacktrace:\n{0}", ex.StackTrace);
|
|
||||||
Console.Out.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
}
|
|
||||||
if (obj != null && (obj is Exception) == false)
|
|
||||||
{
|
|
||||||
JsonWriter writter = new JsonWriter(new JsonWriterConfiguration(indent: true));
|
|
||||||
Console.Out.WriteLine("Parsed:\n{0}", writter.Write(obj));
|
|
||||||
Console.Out.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FindPath(string currentPath, string directory)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
string testPath = Path.Combine(currentPath, directory);
|
|
||||||
if (Directory.Exists(testPath))
|
|
||||||
{
|
|
||||||
currentPath = testPath;
|
|
||||||
Console.Out.WriteLine(testPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DirectoryInfo dirInfo = Directory.GetParent(currentPath);
|
|
||||||
if (dirInfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception(string.Format("FindPath: Directory {0} not found", directory));
|
|
||||||
}
|
|
||||||
currentPath = dirInfo.ToString();
|
|
||||||
}
|
|
||||||
} while (string.IsNullOrEmpty(currentPath) == false);
|
|
||||||
return currentPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
[assembly: AssemblyTitle("VAR.Json.Tests")]
|
|
||||||
[assembly: AssemblyDescription("Json Tests")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("VAR")]
|
|
||||||
[assembly: AssemblyProduct("VAR.Json.Tests")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © VAR 2016")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
[assembly: Guid("576297b8-423d-4533-b75a-f186ccff0d2a")]
|
|
||||||
[assembly: AssemblyVersion("1.0.*")]
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{576297B8-423D-4533-B75A-F186CCFF0D2A}</ProjectGuid>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>VAR.Json.Tests</RootNamespace>
|
|
||||||
<AssemblyName>VAR.Json.Tests</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="tests\fail01.json" />
|
|
||||||
<None Include="tests\fail10.json" />
|
|
||||||
<None Include="tests\fail11.json" />
|
|
||||||
<None Include="tests\fail12.json" />
|
|
||||||
<None Include="tests\fail13.json" />
|
|
||||||
<None Include="tests\fail14.json" />
|
|
||||||
<None Include="tests\fail15.json" />
|
|
||||||
<None Include="tests\fail16.json" />
|
|
||||||
<None Include="tests\fail17.json" />
|
|
||||||
<None Include="tests\fail18.json" />
|
|
||||||
<None Include="tests\fail19.json" />
|
|
||||||
<None Include="tests\fail02.json" />
|
|
||||||
<None Include="tests\fail20.json" />
|
|
||||||
<None Include="tests\fail21.json" />
|
|
||||||
<None Include="tests\fail22.json" />
|
|
||||||
<None Include="tests\fail23.json" />
|
|
||||||
<None Include="tests\fail24.json" />
|
|
||||||
<None Include="tests\fail25.json" />
|
|
||||||
<None Include="tests\fail26.json" />
|
|
||||||
<None Include="tests\fail27.json" />
|
|
||||||
<None Include="tests\fail28.json" />
|
|
||||||
<None Include="tests\fail29.json" />
|
|
||||||
<None Include="tests\fail03.json" />
|
|
||||||
<None Include="tests\fail30.json" />
|
|
||||||
<None Include="tests\fail31.json" />
|
|
||||||
<None Include="tests\fail32.json" />
|
|
||||||
<None Include="tests\fail33.json" />
|
|
||||||
<None Include="tests\fail04.json" />
|
|
||||||
<None Include="tests\fail05.json" />
|
|
||||||
<None Include="tests\fail06.json" />
|
|
||||||
<None Include="tests\fail07.json" />
|
|
||||||
<None Include="tests\fail08.json" />
|
|
||||||
<None Include="tests\fail09.json" />
|
|
||||||
<None Include="tests\pass01.json" />
|
|
||||||
<None Include="tests\pass02.json" />
|
|
||||||
<None Include="tests\pass03.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\VAR.Json\VAR.Json.csproj">
|
|
||||||
<Project>{28b3f937-145c-4fd4-a75b-a25ea4cc0428}</Project>
|
|
||||||
<Name>VAR.Json</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
"A JSON payload should be an object or array, not a string."
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Unclosed array"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{unquoted_key: "keys must be quoted"}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["extra comma",]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["double extra comma",,]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[ , "<-- missing value"]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Comma after the close"],
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Extra close"]]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Extra comma": true,}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Extra value after close": true} "misplaced quoted value"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Illegal expression": 1 + 2}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Illegal invocation": alert()}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Numbers cannot have leading zeroes": 013}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Numbers cannot be hex": 0x14}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Illegal backslash escape: \x15"]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[\naked]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Illegal backslash escape: \017"]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Missing colon" null}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Double colon":: null}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Comma instead of colon", null}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Colon instead of comma": false]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["Bad value", truth]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
['single quote']
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[" tab character in string "]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["tab\ character\ in\ string\ "]
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
["line
|
|
||||||
break"]
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
["line\
|
|
||||||
break"]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[0e]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[0e+]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[0e+-1]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"Comma instead if closing brace": true,
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
["mismatch"}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
[
|
|
||||||
"JSON Test Pattern pass1",
|
|
||||||
{"object with 1 member":["array with 1 element"]},
|
|
||||||
{},
|
|
||||||
[],
|
|
||||||
-42,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
"integer": 1234567890,
|
|
||||||
"real": -9876.543210,
|
|
||||||
"e": 0.123456789e-12,
|
|
||||||
"E": 1.234567890E+34,
|
|
||||||
"": 23456789012E66,
|
|
||||||
"zero": 0,
|
|
||||||
"one": 1,
|
|
||||||
"space": " ",
|
|
||||||
"quote": "\"",
|
|
||||||
"backslash": "\\",
|
|
||||||
"controls": "\b\f\n\r\t",
|
|
||||||
"slash": "/ & \/",
|
|
||||||
"alpha": "abcdefghijklmnopqrstuvwyz",
|
|
||||||
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
|
||||||
"digit": "0123456789",
|
|
||||||
"0123456789": "digit",
|
|
||||||
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
|
|
||||||
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
|
||||||
"true": true,
|
|
||||||
"false": false,
|
|
||||||
"null": null,
|
|
||||||
"array":[ ],
|
|
||||||
"object":{ },
|
|
||||||
"address": "50 St. James Street",
|
|
||||||
"url": "http://www.JSON.org/",
|
|
||||||
"comment": "// /* <!-- --",
|
|
||||||
"# -- --> */": " ",
|
|
||||||
" s p a c e d " :[1,2 , 3
|
|
||||||
|
|
||||||
,
|
|
||||||
|
|
||||||
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
|
|
||||||
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
|
|
||||||
"quotes": "" \u0022 %22 0x22 034 "",
|
|
||||||
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
|
|
||||||
: "A key can be any string"
|
|
||||||
},
|
|
||||||
0.5 ,98.6
|
|
||||||
,
|
|
||||||
99.44
|
|
||||||
,
|
|
||||||
|
|
||||||
1066,
|
|
||||||
1e1,
|
|
||||||
0.1e1,
|
|
||||||
1e-1,
|
|
||||||
1e00,2e+00,2e-00
|
|
||||||
,"rosebud"]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"JSON Test Pattern pass3": {
|
|
||||||
"The outermost value": "must be an object or array.",
|
|
||||||
"In this test": "It is an object."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
34
VAR.Json.sln
34
VAR.Json.sln
@@ -1,34 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 14
|
|
||||||
VisualStudioVersion = 14.0.25420.1
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.Json", "VAR.Json\VAR.Json.csproj", "{28B3F937-145C-4FD4-A75B-A25EA4CC0428}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.Json.Tests", "VAR.Json.Tests\VAR.Json.Tests.csproj", "{576297B8-423D-4533-B75A-F186CCFF0D2A}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notes", "Notes", "{4C23A421-5348-48F1-8B67-A4D43E616FDE}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
LICENSE.txt = LICENSE.txt
|
|
||||||
README.md = README.md
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{28B3F937-145C-4FD4-A75B-A25EA4CC0428}.Debug|Any CPU.ActiveCfg = Debug .Net 4.6.1|Any CPU
|
|
||||||
{28B3F937-145C-4FD4-A75B-A25EA4CC0428}.Debug|Any CPU.Build.0 = Debug .Net 4.6.1|Any CPU
|
|
||||||
{28B3F937-145C-4FD4-A75B-A25EA4CC0428}.Release|Any CPU.ActiveCfg = Release .Net 4.6.1|Any CPU
|
|
||||||
{28B3F937-145C-4FD4-A75B-A25EA4CC0428}.Release|Any CPU.Build.0 = Release .Net 4.6.1|Any CPU
|
|
||||||
{576297B8-423D-4533-B75A-F186CCFF0D2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{576297B8-423D-4533-B75A-F186CCFF0D2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{576297B8-423D-4533-B75A-F186CCFF0D2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{576297B8-423D-4533-B75A-F186CCFF0D2A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
:: MSBuild and tools path
|
|
||||||
if exist "%ProgramFiles%\MSBuild\14.0\bin" set PATH=%ProgramFiles%\MSBuild\14.0\bin;%PATH%
|
|
||||||
if exist "%ProgramFiles(x86)%\MSBuild\14.0\bin" set PATH=%ProgramFiles(x86)%\MSBuild\14.0\bin;%PATH%
|
|
||||||
|
|
||||||
:: NuGet
|
|
||||||
set nuget="nuget"
|
|
||||||
if exist "%~dp0..\packages\NuGet.CommandLine.3.4.3\tools\NuGet.exe" set nuget="%~dp0\..\packages\NuGet.CommandLine.3.4.3\tools\NuGet.exe"
|
|
||||||
|
|
||||||
:: Release .Net 3.5
|
|
||||||
Title Building Release .Net 3.5
|
|
||||||
msbuild VAR.Json.csproj /t:Build /p:Configuration="Release .Net 3.5" /p:Platform="AnyCPU"
|
|
||||||
|
|
||||||
:: Release .Net 4.6.1
|
|
||||||
Title Building Release .Net 4.6.1
|
|
||||||
msbuild VAR.Json.csproj /t:Build /p:Configuration="Release .Net 4.6.1" /p:Platform="AnyCPU"
|
|
||||||
|
|
||||||
:: Packing Nuget
|
|
||||||
Title Packing Nuget
|
|
||||||
%nuget% pack VAR.Json.csproj -Verbosity detailed -OutputDir "NuGet" -MSBuildVersion "14.0" -Properties Configuration="Release .Net 4.6.1" -Prop Platform=AnyCPU
|
|
||||||
|
|
||||||
title Finished
|
|
||||||
pause
|
|
||||||
@@ -1,642 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace VAR.Json
|
|
||||||
{
|
|
||||||
public class JsonParser
|
|
||||||
{
|
|
||||||
#region Declarations
|
|
||||||
|
|
||||||
private const int MaxRecursiveCount = 20;
|
|
||||||
|
|
||||||
private ParserContext _ctx;
|
|
||||||
private bool _tainted = false;
|
|
||||||
|
|
||||||
private readonly List<Type> _knownTypes = new List<Type>();
|
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
|
|
||||||
public bool Tainted
|
|
||||||
{
|
|
||||||
get { return _tainted; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Type> KnownTypes
|
|
||||||
{
|
|
||||||
get { return _knownTypes; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Properties
|
|
||||||
|
|
||||||
#region Private methods
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, PropertyInfo[]> _dictProperties = new Dictionary<Type, PropertyInfo[]>();
|
|
||||||
|
|
||||||
private PropertyInfo[] Type_GetProperties(Type type)
|
|
||||||
{
|
|
||||||
PropertyInfo[] typeProperties = null;
|
|
||||||
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lock (_dictProperties)
|
|
||||||
{
|
|
||||||
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typeProperties = type.GetProperties(BindingFlags.Public | BindingFlags.OptionalParamBinding | BindingFlags.Instance);
|
|
||||||
_dictProperties.Add(type, typeProperties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typeProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private float CompareToType(Dictionary<string, object> obj, Type type)
|
|
||||||
{
|
|
||||||
PropertyInfo[] typeProperties = Type_GetProperties(type);
|
|
||||||
int count = 0;
|
|
||||||
foreach (PropertyInfo prop in typeProperties)
|
|
||||||
{
|
|
||||||
if (obj.ContainsKey(prop.Name))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ((float)count / (float)typeProperties.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ConvertToType(Dictionary<string, object> obj, Type type)
|
|
||||||
{
|
|
||||||
PropertyInfo[] typeProperties = Type_GetProperties(type);
|
|
||||||
object newObj = ObjectActivator.CreateInstance(type);
|
|
||||||
foreach (PropertyInfo prop in typeProperties)
|
|
||||||
{
|
|
||||||
if (obj.ContainsKey(prop.Name))
|
|
||||||
{
|
|
||||||
Type underliningType = Nullable.GetUnderlyingType(prop.PropertyType);
|
|
||||||
Type effectiveType = underliningType ?? prop.PropertyType;
|
|
||||||
object valueOrig = obj[prop.Name];
|
|
||||||
object valueDest;
|
|
||||||
if (underliningType != null && valueOrig == null)
|
|
||||||
{
|
|
||||||
valueDest = null;
|
|
||||||
}
|
|
||||||
else if (effectiveType == typeof(Guid) && valueOrig is string)
|
|
||||||
{
|
|
||||||
valueDest = new Guid((string)valueOrig);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valueDest = Convert.ChangeType(obj[prop.Name], effectiveType);
|
|
||||||
}
|
|
||||||
prop.SetValue(newObj, valueDest, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private object TryConvertToTypes(Dictionary<string, object> obj)
|
|
||||||
{
|
|
||||||
Type bestMatch = null;
|
|
||||||
float bestMatchFactor = 0.0f;
|
|
||||||
foreach (Type type in _knownTypes)
|
|
||||||
{
|
|
||||||
float matchFactor = CompareToType(obj, type);
|
|
||||||
if (matchFactor > bestMatchFactor)
|
|
||||||
{
|
|
||||||
bestMatch = type;
|
|
||||||
bestMatchFactor = matchFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bestMatch != null)
|
|
||||||
{
|
|
||||||
return ConvertToType(obj, bestMatch);
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int ParseHexShort()
|
|
||||||
{
|
|
||||||
int value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
char c = _ctx.Next();
|
|
||||||
if (char.IsDigit(c))
|
|
||||||
{
|
|
||||||
value = (value << 4) | (c - '0');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c = char.ToLower(c);
|
|
||||||
if (c >= 'a' && c <= 'f')
|
|
||||||
{
|
|
||||||
value = (value << 4) | ((c - 'a') + 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ParseQuotedString()
|
|
||||||
{
|
|
||||||
StringBuilder scratch = new StringBuilder();
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
if (c == '"')
|
|
||||||
{
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
c = _ctx.Next();
|
|
||||||
if (c == '"')
|
|
||||||
{
|
|
||||||
scratch.Append('"');
|
|
||||||
}
|
|
||||||
else if (c == '\\')
|
|
||||||
{
|
|
||||||
scratch.Append('\\');
|
|
||||||
}
|
|
||||||
else if (c == '/')
|
|
||||||
{
|
|
||||||
scratch.Append('/');
|
|
||||||
}
|
|
||||||
else if (c == 'b')
|
|
||||||
{
|
|
||||||
scratch.Append('\b');
|
|
||||||
}
|
|
||||||
else if (c == 'f')
|
|
||||||
{
|
|
||||||
scratch.Append('\f');
|
|
||||||
}
|
|
||||||
else if (c == 'n')
|
|
||||||
{
|
|
||||||
scratch.Append('\n');
|
|
||||||
}
|
|
||||||
else if (c == 'r')
|
|
||||||
{
|
|
||||||
scratch.Append('\r');
|
|
||||||
}
|
|
||||||
else if (c == 't')
|
|
||||||
{
|
|
||||||
scratch.Append('\t');
|
|
||||||
}
|
|
||||||
else if (c == 'u')
|
|
||||||
{
|
|
||||||
scratch.Append((char)ParseHexShort());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted on unknown escaped character
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
else if (c == '"')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted on ilegal characters
|
|
||||||
if (c == '\t' || c == '\n') { _tainted = true; }
|
|
||||||
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
} while (!_ctx.AtEnd());
|
|
||||||
return scratch.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ParseSingleQuotedString()
|
|
||||||
{
|
|
||||||
StringBuilder scratch = new StringBuilder();
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
if (c == '\'')
|
|
||||||
{
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
c = _ctx.Next();
|
|
||||||
if (c == '\'')
|
|
||||||
{
|
|
||||||
scratch.Append('\'');
|
|
||||||
}
|
|
||||||
else if (c == '\\')
|
|
||||||
{
|
|
||||||
scratch.Append('\\');
|
|
||||||
}
|
|
||||||
else if (c == '/')
|
|
||||||
{
|
|
||||||
scratch.Append('/');
|
|
||||||
}
|
|
||||||
else if (c == 'b')
|
|
||||||
{
|
|
||||||
scratch.Append('\b');
|
|
||||||
}
|
|
||||||
else if (c == 'f')
|
|
||||||
{
|
|
||||||
scratch.Append('\f');
|
|
||||||
}
|
|
||||||
else if (c == 'n')
|
|
||||||
{
|
|
||||||
scratch.Append('\n');
|
|
||||||
}
|
|
||||||
else if (c == 'r')
|
|
||||||
{
|
|
||||||
scratch.Append('\r');
|
|
||||||
}
|
|
||||||
else if (c == 't')
|
|
||||||
{
|
|
||||||
scratch.Append('\t');
|
|
||||||
}
|
|
||||||
else if (c == 'u')
|
|
||||||
{
|
|
||||||
scratch.Append((char)ParseHexShort());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted on unknown escaped character
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
else if (c == '\'')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted on ilegal characters
|
|
||||||
if (c == '\t' || c == '\n') { _tainted = true; }
|
|
||||||
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
} while (!_ctx.AtEnd());
|
|
||||||
return scratch.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ParseString(bool mustBeQuoted = false)
|
|
||||||
{
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
if (c == '"')
|
|
||||||
{
|
|
||||||
return ParseQuotedString();
|
|
||||||
}
|
|
||||||
if (c == '\'')
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
return ParseSingleQuotedString();
|
|
||||||
}
|
|
||||||
if (mustBeQuoted) { _tainted = true; }
|
|
||||||
StringBuilder scratch = new StringBuilder();
|
|
||||||
|
|
||||||
while (!_ctx.AtEnd()
|
|
||||||
&& (char.IsLetter(c) || char.IsDigit(c) || c == '_'))
|
|
||||||
{
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return scratch.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ParseNumber()
|
|
||||||
{
|
|
||||||
StringBuilder scratch = new StringBuilder();
|
|
||||||
bool isFloat = false;
|
|
||||||
bool isExp = false;
|
|
||||||
int numberLenght = 0;
|
|
||||||
int expLenght = 0;
|
|
||||||
char c;
|
|
||||||
c = _ctx.SkipWhite();
|
|
||||||
|
|
||||||
// Sign
|
|
||||||
if (c == '-')
|
|
||||||
{
|
|
||||||
scratch.Append('-');
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Integer part
|
|
||||||
bool leadingZeroes = true;
|
|
||||||
int leadingZeroesLenght = 0;
|
|
||||||
while (char.IsDigit(c))
|
|
||||||
{
|
|
||||||
// Count leading zeroes
|
|
||||||
if (leadingZeroes && c == '0') { leadingZeroesLenght++; }
|
|
||||||
else { leadingZeroes = false; }
|
|
||||||
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
numberLenght++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StrictRules: Mark as tainted with leading zeroes
|
|
||||||
if ((leadingZeroesLenght > 0 && leadingZeroesLenght != numberLenght) || leadingZeroesLenght > 1)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decimal part
|
|
||||||
if (c == '.')
|
|
||||||
{
|
|
||||||
isFloat = true;
|
|
||||||
scratch.Append(".");
|
|
||||||
c = _ctx.Next();
|
|
||||||
while (char.IsDigit(c))
|
|
||||||
{
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
numberLenght++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numberLenght == 0)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exponential part
|
|
||||||
if (c == 'e' || c == 'E')
|
|
||||||
{
|
|
||||||
isFloat = true;
|
|
||||||
isExp = true;
|
|
||||||
scratch.Append('E');
|
|
||||||
c = _ctx.Next();
|
|
||||||
if (c == '+' || c == '-')
|
|
||||||
{
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
}
|
|
||||||
while (char.IsDigit(c))
|
|
||||||
{
|
|
||||||
scratch.Append(c);
|
|
||||||
c = _ctx.Next();
|
|
||||||
numberLenght++;
|
|
||||||
expLenght++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isExp && expLenght == 0)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build number from the parsed string
|
|
||||||
string s = scratch.ToString();
|
|
||||||
if (isFloat)
|
|
||||||
{
|
|
||||||
if (numberLenght < 17)
|
|
||||||
{
|
|
||||||
return Convert.ToDouble(s, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Convert.ToDecimal(s, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Convert.ToInt32(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<object> ParseArray(int recursiveCount = 1)
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when MaxRecursiveCount is exceeded
|
|
||||||
if (recursiveCount >= MaxRecursiveCount) { _tainted = true; }
|
|
||||||
|
|
||||||
bool correct = false;
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
List<object> array = new List<object>();
|
|
||||||
if (c == '[')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
}
|
|
||||||
bool? expectValue = null;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = _ctx.SkipWhite();
|
|
||||||
if (c == ']')
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when unexpected end of array
|
|
||||||
if (expectValue == true) { _tainted = true; }
|
|
||||||
correct = true;
|
|
||||||
_ctx.Next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (c == ',')
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when unexpected comma on array
|
|
||||||
if (expectValue == true || array.Count == 0) { _tainted = true; }
|
|
||||||
|
|
||||||
_ctx.Next();
|
|
||||||
expectValue = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when unexpected value on array
|
|
||||||
if (expectValue == false) { _tainted = true; }
|
|
||||||
|
|
||||||
array.Add(ParseValue(recursiveCount + 1));
|
|
||||||
expectValue = false;
|
|
||||||
}
|
|
||||||
} while (!_ctx.AtEnd());
|
|
||||||
if (correct == false)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, object> ParseObject(int recursiveCount = 1)
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when MaxRecursiveCount is exceeded
|
|
||||||
if (recursiveCount >= MaxRecursiveCount) { _tainted = true; }
|
|
||||||
|
|
||||||
bool correct = false;
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
Dictionary<string, object> obj = new Dictionary<string, object>();
|
|
||||||
if (c == '{')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
}
|
|
||||||
string attributeName = null;
|
|
||||||
object attributeValue;
|
|
||||||
bool? expectedKey = null;
|
|
||||||
bool? expectedValue = null;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = _ctx.SkipWhite();
|
|
||||||
if (c == ':')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
if (expectedValue == true)
|
|
||||||
{
|
|
||||||
attributeValue = ParseValue(recursiveCount + 1);
|
|
||||||
obj.Add(attributeName, attributeValue);
|
|
||||||
expectedKey = null;
|
|
||||||
expectedValue = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c == ',')
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
_ctx.SkipWhite();
|
|
||||||
expectedKey = true;
|
|
||||||
expectedValue = false;
|
|
||||||
}
|
|
||||||
else if (c == '}')
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted on unexpected end of object
|
|
||||||
if (expectedValue == true || expectedKey == true)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
correct = true;
|
|
||||||
_ctx.Next();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (expectedKey != false)
|
|
||||||
{
|
|
||||||
attributeName = ParseString(true);
|
|
||||||
_ctx.SkipWhite();
|
|
||||||
expectedKey = false;
|
|
||||||
expectedValue = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Unexpected character
|
|
||||||
_tainted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (!_ctx.AtEnd());
|
|
||||||
if (correct == false)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ParseValue(int recusiveCount = 1)
|
|
||||||
{
|
|
||||||
char c = _ctx.SkipWhite();
|
|
||||||
object token;
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '"':
|
|
||||||
token = ParseQuotedString();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\'':
|
|
||||||
// StrictRules: Mark as tainted when parsing single quoted strings
|
|
||||||
_tainted = true;
|
|
||||||
token = ParseSingleQuotedString();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '{':
|
|
||||||
Dictionary<string, object> obj = ParseObject(recusiveCount);
|
|
||||||
token = TryConvertToTypes(obj);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '[':
|
|
||||||
token = ParseArray(recusiveCount);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (char.IsDigit(c) || c == '-')
|
|
||||||
{
|
|
||||||
token = ParseNumber();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string aux = ParseString();
|
|
||||||
if (aux.CompareTo("true") == 0)
|
|
||||||
{
|
|
||||||
token = true;
|
|
||||||
}
|
|
||||||
else if (aux.CompareTo("false") == 0)
|
|
||||||
{
|
|
||||||
token = false;
|
|
||||||
}
|
|
||||||
else if (aux.CompareTo("null") == 0)
|
|
||||||
{
|
|
||||||
token = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Unexpected string
|
|
||||||
if (aux.Length == 0)
|
|
||||||
{
|
|
||||||
_ctx.Next();
|
|
||||||
}
|
|
||||||
_tainted = true;
|
|
||||||
token = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private methods
|
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
public object Parse(string text)
|
|
||||||
{
|
|
||||||
// Get the first object
|
|
||||||
_ctx = new ParserContext(text);
|
|
||||||
_tainted = false;
|
|
||||||
_ctx.Mark();
|
|
||||||
object obj = ParseValue();
|
|
||||||
_ctx.SkipWhite();
|
|
||||||
if (_ctx.AtEnd())
|
|
||||||
{
|
|
||||||
// StrictRules: Mark as tainted when top level is not object or array
|
|
||||||
if (obj is string || obj is decimal || obj is int || obj is double || obj is float)
|
|
||||||
{
|
|
||||||
_tainted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StrictRules: Mark as tainted when there is more content
|
|
||||||
_tainted = true;
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsonParser _currentInstance = null;
|
|
||||||
|
|
||||||
public static object ParseText(string text)
|
|
||||||
{
|
|
||||||
if(_currentInstance == null)
|
|
||||||
{
|
|
||||||
_currentInstance = new JsonParser();
|
|
||||||
}
|
|
||||||
return _currentInstance.Parse(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,427 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace VAR.Json
|
|
||||||
{
|
|
||||||
public class JsonWriterConfiguration
|
|
||||||
{
|
|
||||||
private bool _indent;
|
|
||||||
public bool Indent { get { return _indent; } }
|
|
||||||
|
|
||||||
private bool _useTabForIndent;
|
|
||||||
public bool UseTabForIndent { get { return _useTabForIndent; } }
|
|
||||||
|
|
||||||
private int _indentChars;
|
|
||||||
public int IndentChars { get { return _indentChars; } }
|
|
||||||
|
|
||||||
private int _indentThresold;
|
|
||||||
public int IndentThresold { get { return _indentThresold; } }
|
|
||||||
|
|
||||||
public JsonWriterConfiguration(
|
|
||||||
bool indent = false,
|
|
||||||
bool useTablForIndent = false,
|
|
||||||
int indentChars = 4,
|
|
||||||
int indentThresold = 3)
|
|
||||||
{
|
|
||||||
_indent = indent;
|
|
||||||
_useTabForIndent = useTablForIndent;
|
|
||||||
_indentChars = indentChars;
|
|
||||||
_indentThresold = indentThresold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(JsonWriterConfiguration other)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
other.Indent == Indent &&
|
|
||||||
other.UseTabForIndent == UseTabForIndent &&
|
|
||||||
other.IndentChars == IndentChars &&
|
|
||||||
other.IndentThresold == IndentThresold &&
|
|
||||||
true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object other)
|
|
||||||
{
|
|
||||||
if(other is JsonWriterConfiguration)
|
|
||||||
{
|
|
||||||
return Equals(other as JsonWriterConfiguration);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return _indent.GetHashCode() ^ _useTabForIndent.GetHashCode() ^ _indentChars.GetHashCode() ^ _indentThresold.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class JsonWriter
|
|
||||||
{
|
|
||||||
#region Declarations
|
|
||||||
|
|
||||||
private JsonWriterConfiguration _config = null;
|
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Creator
|
|
||||||
|
|
||||||
public JsonWriter(JsonWriterConfiguration config = null)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
if (_config == null)
|
|
||||||
{
|
|
||||||
_config = new JsonWriterConfiguration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Creator
|
|
||||||
|
|
||||||
#region Private methods
|
|
||||||
|
|
||||||
private bool IsValue(object obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
(obj is float) ||
|
|
||||||
(obj is double) ||
|
|
||||||
(obj is short) ||
|
|
||||||
(obj is int) ||
|
|
||||||
(obj is long) ||
|
|
||||||
(obj is string) ||
|
|
||||||
(obj is bool) ||
|
|
||||||
false)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteIndent(StringBuilder sbOutput, int level)
|
|
||||||
{
|
|
||||||
if (!_config.Indent)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sbOutput.Append('\n');
|
|
||||||
if (_config.UseTabForIndent)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < level; i++) { sbOutput.Append('\t'); }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int n = level * _config.IndentChars;
|
|
||||||
for (int i = 0; i < n; i++) { sbOutput.Append(' '); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteString(StringBuilder sbOutput, string str)
|
|
||||||
{
|
|
||||||
sbOutput.Append('"');
|
|
||||||
char c;
|
|
||||||
int n = str.Length;
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
c = str[i];
|
|
||||||
if (c == '"') { sbOutput.Append("\\\""); }
|
|
||||||
else if (c == '\\') { sbOutput.Append("\\\\"); }
|
|
||||||
else if (c == '/') { sbOutput.Append("\\/"); }
|
|
||||||
else if (c == '\b') { sbOutput.Append("\\b"); }
|
|
||||||
else if (c == '\f') { sbOutput.Append("\\f"); }
|
|
||||||
else if (c == '\n') { sbOutput.Append("\\n"); }
|
|
||||||
else if (c == '\r') { sbOutput.Append("\\r"); }
|
|
||||||
else if (c == '\t') { sbOutput.Append("\\t"); }
|
|
||||||
else if (c < 32 || c >= 127) { sbOutput.AppendFormat("\\u{0:X04}", (int)c); }
|
|
||||||
else { sbOutput.Append(c); }
|
|
||||||
}
|
|
||||||
sbOutput.Append('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteValue(StringBuilder sbOutput, object obj, List<object> parentLevels, bool useReflection)
|
|
||||||
{
|
|
||||||
if (obj == null || obj is DBNull)
|
|
||||||
{
|
|
||||||
// NULL
|
|
||||||
sbOutput.Append("null");
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
(obj is float) ||
|
|
||||||
(obj is double) ||
|
|
||||||
(obj is short) ||
|
|
||||||
(obj is int) ||
|
|
||||||
(obj is long) ||
|
|
||||||
false)
|
|
||||||
{
|
|
||||||
// Numbers
|
|
||||||
sbOutput.Append(obj.ToString());
|
|
||||||
}
|
|
||||||
else if (obj is string)
|
|
||||||
{
|
|
||||||
// Strings
|
|
||||||
WriteString(sbOutput, (string)obj);
|
|
||||||
}
|
|
||||||
else if (obj is bool)
|
|
||||||
{
|
|
||||||
// Booleans
|
|
||||||
sbOutput.Append(((bool)obj) ? "true" : "false");
|
|
||||||
}
|
|
||||||
else if (obj is DateTime)
|
|
||||||
{
|
|
||||||
// DateTime
|
|
||||||
sbOutput.Append('"');
|
|
||||||
sbOutput.Append(((DateTime)obj).ToString("yyyy-MM-ddTHH:mm:ssZ"));
|
|
||||||
sbOutput.Append('"');
|
|
||||||
}
|
|
||||||
else if (obj is IDictionary)
|
|
||||||
{
|
|
||||||
// Objects
|
|
||||||
WriteObject(sbOutput, obj, parentLevels);
|
|
||||||
}
|
|
||||||
else if (obj is IEnumerable)
|
|
||||||
{
|
|
||||||
// Array/List
|
|
||||||
WriteList(sbOutput, obj, parentLevels);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (useReflection)
|
|
||||||
{
|
|
||||||
// Reflected object
|
|
||||||
WriteReflectedObject(sbOutput, obj, parentLevels);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteString(sbOutput, Convert.ToString(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteList(StringBuilder sbOutput, object obj, List<object> parentLevels)
|
|
||||||
{
|
|
||||||
IEnumerable list = (IEnumerable)obj;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
// Check if it is a leaf object
|
|
||||||
bool isLeaf = true;
|
|
||||||
foreach (object childObj in list)
|
|
||||||
{
|
|
||||||
if (!IsValue(childObj))
|
|
||||||
{
|
|
||||||
isLeaf = false;
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty
|
|
||||||
if (n == 0)
|
|
||||||
{
|
|
||||||
sbOutput.Append("[ ]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write array
|
|
||||||
bool first = true;
|
|
||||||
sbOutput.Append("[ ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
foreach (object childObj in list)
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
sbOutput.Append(", ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
parentLevels.Add(obj);
|
|
||||||
WriteValue(sbOutput, childObj, parentLevels, true);
|
|
||||||
parentLevels.Remove(obj);
|
|
||||||
}
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count);
|
|
||||||
}
|
|
||||||
sbOutput.Append(" ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteObject(StringBuilder sbOutput, object obj, List<object> parentLevels)
|
|
||||||
{
|
|
||||||
IDictionary map = (IDictionary)obj;
|
|
||||||
int n = map.Count;
|
|
||||||
|
|
||||||
// Empty
|
|
||||||
if (map.Count == 0)
|
|
||||||
{
|
|
||||||
sbOutput.Append("{ }");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if it is a leaf object
|
|
||||||
bool isLeaf = true;
|
|
||||||
foreach (object value in map.Values)
|
|
||||||
{
|
|
||||||
if (!IsValue(value))
|
|
||||||
{
|
|
||||||
isLeaf = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write object
|
|
||||||
bool first = true;
|
|
||||||
sbOutput.Append("{ ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
foreach (object key in map.Keys)
|
|
||||||
{
|
|
||||||
object value = map[key];
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
sbOutput.Append(", ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
WriteString(sbOutput, Convert.ToString(key));
|
|
||||||
sbOutput.Append(": ");
|
|
||||||
parentLevels.Add(obj);
|
|
||||||
WriteValue(sbOutput, value, parentLevels, true);
|
|
||||||
parentLevels.Remove(obj);
|
|
||||||
}
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count);
|
|
||||||
}
|
|
||||||
sbOutput.Append(" }");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteReflectedObject(StringBuilder sbOutput, object obj, List<object> parentLevels)
|
|
||||||
{
|
|
||||||
Type type = obj.GetType();
|
|
||||||
PropertyInfo[] rawProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
|
||||||
List<PropertyInfo> properties = new List<PropertyInfo>();
|
|
||||||
foreach (PropertyInfo property in rawProperties)
|
|
||||||
{
|
|
||||||
if (property.CanRead == false) { continue; }
|
|
||||||
|
|
||||||
properties.Add(property);
|
|
||||||
}
|
|
||||||
int n = properties.Count;
|
|
||||||
|
|
||||||
// Empty
|
|
||||||
if (n == 0)
|
|
||||||
{
|
|
||||||
sbOutput.Append("{ }");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if it is a leaf object
|
|
||||||
bool isLeaf = true;
|
|
||||||
foreach (PropertyInfo property in properties)
|
|
||||||
{
|
|
||||||
object value = property.GetValue(obj, null);
|
|
||||||
if (!IsValue(value))
|
|
||||||
{
|
|
||||||
isLeaf = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write object
|
|
||||||
bool first = true;
|
|
||||||
sbOutput.Append("{ ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
foreach (PropertyInfo property in properties)
|
|
||||||
{
|
|
||||||
object value = null;
|
|
||||||
MethodInfo getMethod = property.GetGetMethod();
|
|
||||||
ParameterInfo[] parameters = getMethod.GetParameters();
|
|
||||||
if (parameters.Length == 0)
|
|
||||||
{
|
|
||||||
value = property.GetValue(obj, null);
|
|
||||||
}
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
sbOutput.Append(", ");
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
WriteString(sbOutput, property.Name);
|
|
||||||
sbOutput.Append(": ");
|
|
||||||
parentLevels.Add(obj);
|
|
||||||
if (value != obj && parentLevels.Contains(value) == false)
|
|
||||||
{
|
|
||||||
WriteValue(sbOutput, value, parentLevels, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteValue(sbOutput, null, parentLevels, false);
|
|
||||||
}
|
|
||||||
parentLevels.Remove(obj);
|
|
||||||
}
|
|
||||||
if (!isLeaf || n > _config.IndentThresold)
|
|
||||||
{
|
|
||||||
WriteIndent(sbOutput, parentLevels.Count);
|
|
||||||
}
|
|
||||||
sbOutput.Append(" }");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private methods
|
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
public string Write(object obj)
|
|
||||||
{
|
|
||||||
StringBuilder sbOutput = new StringBuilder();
|
|
||||||
WriteValue(sbOutput, obj, new List<object>(), true);
|
|
||||||
return sbOutput.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<JsonWriterConfiguration, JsonWriter> _dictInstances = new Dictionary<JsonWriterConfiguration, JsonWriter>();
|
|
||||||
|
|
||||||
public static string WriteObject(object obj, JsonWriterConfiguration config = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(_dictInstances.ContainsKey(config) == false)
|
|
||||||
{
|
|
||||||
JsonWriter newJsonWriter = new JsonWriter(config);
|
|
||||||
_dictInstances.Add(config, newJsonWriter);
|
|
||||||
}
|
|
||||||
JsonWriter jsonWriter = _dictInstances[config];
|
|
||||||
return jsonWriter.Write(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string WriteObject(object obj,
|
|
||||||
bool indent = false,
|
|
||||||
bool useTablForIndent = false,
|
|
||||||
int indentChars = 4,
|
|
||||||
int indentThresold = 3)
|
|
||||||
{
|
|
||||||
return WriteObject(obj, new JsonWriterConfiguration(
|
|
||||||
indent: indent,
|
|
||||||
useTablForIndent: useTablForIndent,
|
|
||||||
indentChars: indentChars,
|
|
||||||
indentThresold: indentThresold));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
|
|
||||||
namespace VAR.Json
|
|
||||||
{
|
|
||||||
public class ObjectActivator
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<Type, Func<object>> _creators = new Dictionary<Type, Func<object>>();
|
|
||||||
|
|
||||||
public static Func<object> GetLambdaNew(Type type)
|
|
||||||
{
|
|
||||||
if (_creators.ContainsKey(type))
|
|
||||||
{
|
|
||||||
return _creators[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_creators)
|
|
||||||
{
|
|
||||||
if (_creators.ContainsKey(type))
|
|
||||||
{
|
|
||||||
return _creators[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
NewExpression newExp = Expression.New(type);
|
|
||||||
LambdaExpression lambda = Expression.Lambda(typeof(Func<object>), newExp);
|
|
||||||
Func<object> compiledLambdaNew = (Func<object>)lambda.Compile();
|
|
||||||
|
|
||||||
_creators.Add(type, compiledLambdaNew);
|
|
||||||
return _creators[type];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object CreateInstance(Type type)
|
|
||||||
{
|
|
||||||
Func<object> creator = GetLambdaNew(type);
|
|
||||||
return creator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace VAR.Json
|
|
||||||
{
|
|
||||||
public class ParserContext
|
|
||||||
{
|
|
||||||
#region Declarations
|
|
||||||
|
|
||||||
private string _text;
|
|
||||||
private int _length;
|
|
||||||
private int _i;
|
|
||||||
private int _markStart;
|
|
||||||
|
|
||||||
#endregion Declarations
|
|
||||||
|
|
||||||
#region Creator
|
|
||||||
|
|
||||||
public ParserContext(string text)
|
|
||||||
{
|
|
||||||
_text = text;
|
|
||||||
_length = text.Length;
|
|
||||||
_i = 0;
|
|
||||||
_markStart = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Creator
|
|
||||||
|
|
||||||
#region Public methods
|
|
||||||
|
|
||||||
public char SkipWhite()
|
|
||||||
{
|
|
||||||
while (_i < _length && char.IsWhiteSpace(_text[_i]))
|
|
||||||
{
|
|
||||||
_i++;
|
|
||||||
}
|
|
||||||
if (AtEnd())
|
|
||||||
{
|
|
||||||
return (char)0;
|
|
||||||
}
|
|
||||||
return _text[_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public char Next()
|
|
||||||
{
|
|
||||||
_i++;
|
|
||||||
if (AtEnd())
|
|
||||||
{
|
|
||||||
return (char)0;
|
|
||||||
}
|
|
||||||
return _text[_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AtEnd()
|
|
||||||
{
|
|
||||||
return _i >= _length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Mark()
|
|
||||||
{
|
|
||||||
_markStart = _i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetMarked()
|
|
||||||
{
|
|
||||||
if (_i < _length && _markStart < _length)
|
|
||||||
{
|
|
||||||
return _text.Substring(_markStart, _i - _markStart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_markStart < _length)
|
|
||||||
{
|
|
||||||
return _text.Substring(_markStart, _length - _markStart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
[assembly: AssemblyTitle("VAR.Json")]
|
|
||||||
[assembly: AssemblyDescription(".Net library for JSON parsing")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("VAR")]
|
|
||||||
[assembly: AssemblyProduct("VAR.Json")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © VAR 2016-2017")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
[assembly: Guid("28b3f937-145c-4fd4-a75b-a25ea4cc0428")]
|
|
||||||
[assembly: AssemblyVersion("1.1.0.*")]
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{28B3F937-145C-4FD4-A75B-A25EA4CC0428}</ProjectGuid>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>VAR.Json</RootNamespace>
|
|
||||||
<AssemblyName>VAR.Json</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug .Net 4.6.1|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug\net461</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release .Net 4.6.1|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\Release\net461</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug .Net 3.5|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug\net35</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release .Net 3.5|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\Release\net35</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="JsonParser.cs" />
|
|
||||||
<Compile Include="JsonWriter.cs" />
|
|
||||||
<Compile Include="ObjectActivator.cs" />
|
|
||||||
<Compile Include="ParserContext.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Build.NuGet.cmd" />
|
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="VAR.Json.nuspec" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Nuget\keep.txt" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<package >
|
|
||||||
<metadata>
|
|
||||||
<id>$id$</id>
|
|
||||||
<version>$version$</version>
|
|
||||||
<title>$title$</title>
|
|
||||||
<authors>$author$</authors>
|
|
||||||
<owners>$author$</owners>
|
|
||||||
<licenseUrl>https://github.com/Kableado/VAR.Json/blob/master/LICENSE.txt</licenseUrl>
|
|
||||||
<projectUrl>https://github.com/Kableado/VAR.Json</projectUrl>
|
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
|
||||||
<description>$description$</description>
|
|
||||||
<copyright>Copyright VAR 2016-2017</copyright>
|
|
||||||
<tags>JSON Library</tags>
|
|
||||||
</metadata>
|
|
||||||
<files>
|
|
||||||
<file src="bin\Release\net461\VAR.Json.dll" target="lib\net461\VAR.Json.dll" />
|
|
||||||
<file src="bin\Release\net461\VAR.Json.pdb" target="lib\net461\VAR.Json.pdb" />
|
|
||||||
<file src="bin\Release\net35\VAR.Json.dll" target="lib\net35\VAR.Json.dll" />
|
|
||||||
<file src="bin\Release\net35\VAR.Json.pdb" target="lib\net35\VAR.Json.pdb" />
|
|
||||||
</files>
|
|
||||||
</package>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="NuGet.CommandLine" version="3.4.3" targetFramework="net461" developmentDependency="true" />
|
|
||||||
</packages>
|
|
||||||
6
issues/1.yaml
Normal file
6
issues/1.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
id: 1
|
||||||
|
title: Implementar JSONPath
|
||||||
|
state: open
|
||||||
|
tags: enhancement
|
||||||
|
|
||||||
|
|
||||||
6
issues/2.yaml
Normal file
6
issues/2.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
id: 2
|
||||||
|
title: Optimizar
|
||||||
|
state: open
|
||||||
|
tags: enhancement
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user