diff options
author | Marek Safar <marek.safar@gmail.com> | 2012-12-05 15:11:16 +0400 |
---|---|---|
committer | Marek Safar <marek.safar@gmail.com> | 2012-12-05 15:11:16 +0400 |
commit | f79fec62c57dc3d59807f06ac14c02690bb942f1 (patch) | |
tree | 493b6fe07a9faa27985d9b04d21b96f65e809f28 /mcs/class/System.Json | |
parent | c4b3a047f1c452fede8bf6b7a2d4d3a80399b9af (diff) |
Bring back 2.10 based System.Json and move aspnet stack version to System.Json.Microsoft
Diffstat (limited to 'mcs/class/System.Json')
25 files changed, 1020 insertions, 5098 deletions
diff --git a/mcs/class/System.Json/Assembly/AssemblyInfo.cs b/mcs/class/System.Json/Assembly/AssemblyInfo.cs index a550ea9caa1..b8c49cd952b 100755 --- a/mcs/class/System.Json/Assembly/AssemblyInfo.cs +++ b/mcs/class/System.Json/Assembly/AssemblyInfo.cs @@ -37,6 +37,22 @@ using System.Runtime.InteropServices; // General Information about the System.Json assembly +[assembly: AssemblyTitle ("System.Json.dll")] +[assembly: AssemblyDescription ("System.Json.dll")] [assembly: AssemblyDefaultAlias ("System.Json.dll")] +[assembly: AssemblyCompany (Consts.MonoCompany)] +[assembly: AssemblyProduct (Consts.MonoProduct)] +[assembly: AssemblyCopyright (Consts.MonoCopyright)] +[assembly: AssemblyVersion (Consts.FxVersion)] +[assembly: SatelliteContractVersion (Consts.FxVersion)] [assembly: AssemblyInformationalVersion (Consts.FxFileVersion)] +[assembly: AssemblyFileVersion (Consts.FxFileVersion)] + +[assembly: NeutralResourcesLanguage ("en-US")] +[assembly: AssemblyDelaySign (true)] +[assembly: AssemblyKeyFile ("../winfx.pub")] + +[assembly: ComVisible (false)] + +[assembly: SecurityCritical] diff --git a/mcs/class/System.Json/Makefile b/mcs/class/System.Json/Makefile index ea9811a433b..906b0bf48f1 100644 --- a/mcs/class/System.Json/Makefile +++ b/mcs/class/System.Json/Makefile @@ -2,31 +2,24 @@ thisdir = class/System.Json SUBDIRS = include ../../build/rules.make -System.Json.Properties.Resources.resources: System.Json/Properties/Resources.resx - $(RESGEN) "$<" "$@" - LIBRARY = System.Json.dll -LIB_MCS_FLAGS = /d:ASPNETMVC -keyfile:../winfx.pub -delaysign \ +LIB_MCS_FLAGS = \ /r:System.dll \ /r:System.Xml.dll \ /r:System.Core.dll \ - /r:System.Runtime.Serialization.dll \ - /r:System.ServiceModel.Web.dll \ - /resource:System.Json.Properties.Resources.resources - + /r:System.ServiceModel.Web.dll -EXTRA_DISTFILES = System.Json/Properties/Resources.resx +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -ifeq (4, $(FRAMEWORK_VERSION_MAJOR)) -LIB_MCS_FLAGS += /r:Microsoft.CSharp.dll -d:FEATURE_DYNAMIC -endif +EXTRA_DISTFILES = -ifeq (monodroid, $(PROFILE)) -LIB_MCS_FLAGS += -d:FEATURE_DYNAMIC -endif +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) -TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.Json.dll +NO_INSTALL = yes +NO_SIGN_ASSEMBLY = yes +NO_TEST = yes +endif include ../../build/library.make - -$(the_lib): System.Json.Properties.Resources.resources diff --git a/mcs/class/System.Json/System.Json-net_4_0.csproj b/mcs/class/System.Json/System.Json-net_4_0.csproj index c772ac2c523..2611515e003 100644 --- a/mcs/class/System.Json/System.Json-net_4_0.csproj +++ b/mcs/class/System.Json/System.Json-net_4_0.csproj @@ -16,26 +16,22 @@ <AssemblyName>System.Json</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <!-- Filter out System.Core added by: Microsoft.NETFramework.props -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>false</Optimize>
- <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;ASPNETMVC</DefineConstants>
+ <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_0</AdditionalLibPaths>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>true</Optimize>
- <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;ASPNETMVC</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_0</AdditionalLibPaths>
@@ -44,24 +40,12 @@ <ItemGroup>
<Compile Include="..\..\build\common\Consts.cs" /> <Compile Include="Assembly\AssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\RS.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\CommonAssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\TransparentCommonAssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Properties\AssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Extensions\JsonValueExtensions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\GlobalSuppressions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JXmlToJsonValueConverter.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonArray.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonObject.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonPrimitive.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonType.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValue.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueChange.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueChangeEventArgs.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueDynamicMetaObject.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueLinqExtensions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\NGenWrapper.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Properties\Resources.Designer.cs" /> + <Compile Include="System.Json\JsonArray.cs" /> + <Compile Include="System.Json\JsonObject.cs" /> + <Compile Include="System.Json\JsonPrimitive.cs" /> + <Compile Include="System.Json\JsonType.cs" /> + <Compile Include="System.Json\JsonValue.cs" /> + <Compile Include="..\System.ServiceModel.Web\System.Runtime.Serialization.Json\JavaScriptReader.cs" /> </ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -75,7 +59,7 @@ <PreBuildEvent></PreBuildEvent>
</PropertyGroup>
<ItemGroup>
- <Reference Include="mscorlib.dll"> + <Reference Include="mscorlib.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>mscorlib.dll</HintPath> </Reference> @@ -91,28 +75,15 @@ <SpecificVersion>False</SpecificVersion> <HintPath>System.Core.dll</HintPath> </Reference> - <Reference Include="System.Runtime.Serialization.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>System.Runtime.Serialization.dll</HintPath> - </Reference> <Reference Include="System.ServiceModel.Web.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>System.ServiceModel.Web.dll</HintPath> </Reference> - <Reference Include="Microsoft.CSharp.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>Microsoft.CSharp.dll</HintPath> - </Reference> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
- <ItemGroup> - <EmbeddedResource Include="System.Json.Properties.Resources.resources"> - <LogicalName>System.Json.Properties.Resources.resources</LogicalName> - </EmbeddedResource> - </ItemGroup> -
+
</Project>
diff --git a/mcs/class/System.Json/System.Json-net_4_5.csproj b/mcs/class/System.Json/System.Json-net_4_5.csproj index 5b6ff710cef..3a0996f6c17 100644 --- a/mcs/class/System.Json/System.Json-net_4_5.csproj +++ b/mcs/class/System.Json/System.Json-net_4_5.csproj @@ -16,26 +16,22 @@ <AssemblyName>System.Json</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <!-- Filter out System.Core added by: Microsoft.NETFramework.props -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>false</Optimize>
- <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;ASPNETMVC</DefineConstants>
+ <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_5</AdditionalLibPaths>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>true</Optimize>
- <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;ASPNETMVC</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_5</AdditionalLibPaths>
@@ -44,24 +40,12 @@ <ItemGroup>
<Compile Include="..\..\build\common\Consts.cs" /> <Compile Include="Assembly\AssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\RS.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\CommonAssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\TransparentCommonAssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Properties\AssemblyInfo.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Extensions\JsonValueExtensions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\GlobalSuppressions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JXmlToJsonValueConverter.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonArray.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonObject.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonPrimitive.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonType.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValue.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueChange.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueChangeEventArgs.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueDynamicMetaObject.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\JsonValueLinqExtensions.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\NGenWrapper.cs" /> - <Compile Include="..\..\..\external\aspnetwebstack\src\System.Json\Properties\Resources.Designer.cs" /> + <Compile Include="System.Json\JsonArray.cs" /> + <Compile Include="System.Json\JsonObject.cs" /> + <Compile Include="System.Json\JsonPrimitive.cs" /> + <Compile Include="System.Json\JsonType.cs" /> + <Compile Include="System.Json\JsonValue.cs" /> + <Compile Include="..\System.ServiceModel.Web\System.Runtime.Serialization.Json\JavaScriptReader.cs" /> </ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -75,7 +59,7 @@ <PreBuildEvent></PreBuildEvent>
</PropertyGroup>
<ItemGroup>
- <Reference Include="mscorlib.dll"> + <Reference Include="mscorlib.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>mscorlib.dll</HintPath> </Reference> @@ -91,28 +75,15 @@ <SpecificVersion>False</SpecificVersion> <HintPath>System.Core.dll</HintPath> </Reference> - <Reference Include="System.Runtime.Serialization.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>System.Runtime.Serialization.dll</HintPath> - </Reference> <Reference Include="System.ServiceModel.Web.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>System.ServiceModel.Web.dll</HintPath> </Reference> - <Reference Include="Microsoft.CSharp.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>Microsoft.CSharp.dll</HintPath> - </Reference> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
- <ItemGroup> - <EmbeddedResource Include="System.Json.Properties.Resources.resources"> - <LogicalName>System.Json.Properties.Resources.resources</LogicalName> - </EmbeddedResource> - </ItemGroup> -
+
</Project>
diff --git a/mcs/class/System.Json/System.Json-tests-net_4_0.csproj b/mcs/class/System.Json/System.Json-tests-net_4_0.csproj index b542bdc2960..903d919e976 100644 --- a/mcs/class/System.Json/System.Json-tests-net_4_0.csproj +++ b/mcs/class/System.Json/System.Json-tests-net_4_0.csproj @@ -16,26 +16,22 @@ <AssemblyName>System.Json_test_net_4_0</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <!-- Filter out System.Core added by: Microsoft.NETFramework.props -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>false</Optimize>
- <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;ASPNETMVC</DefineConstants>
+ <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_0</AdditionalLibPaths>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>true</Optimize>
- <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;ASPNETMVC</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_0</AdditionalLibPaths>
@@ -56,7 +52,7 @@ <PreBuildEvent></PreBuildEvent>
</PropertyGroup>
<ItemGroup>
- <Reference Include="mscorlib.dll"> + <Reference Include="mscorlib.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>mscorlib.dll</HintPath> </Reference> @@ -76,29 +72,16 @@ <SpecificVersion>False</SpecificVersion> <HintPath>System.Core.dll</HintPath> </Reference> - <Reference Include="System.Runtime.Serialization.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>System.Runtime.Serialization.dll</HintPath> - </Reference> <Reference Include="System.ServiceModel.Web.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>System.ServiceModel.Web.dll</HintPath> </Reference> - <Reference Include="Microsoft.CSharp.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>Microsoft.CSharp.dll</HintPath> - </Reference> <Reference Include="nunit.framework" /> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
- <ItemGroup> - <EmbeddedResource Include="System.Json.Properties.Resources.resources"> - <LogicalName>System.Json.Properties.Resources.resources</LogicalName> - </EmbeddedResource> - </ItemGroup> -
+
</Project>
diff --git a/mcs/class/System.Json/System.Json-tests-net_4_5.csproj b/mcs/class/System.Json/System.Json-tests-net_4_5.csproj index 052de28c257..b35e9b3a428 100644 --- a/mcs/class/System.Json/System.Json-tests-net_4_5.csproj +++ b/mcs/class/System.Json/System.Json-tests-net_4_5.csproj @@ -16,26 +16,22 @@ <AssemblyName>System.Json_test_net_4_5</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <!-- Filter out System.Core added by: Microsoft.NETFramework.props -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>false</Optimize>
- <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;ASPNETMVC</DefineConstants>
+ <DefineConstants>DEBUG;TRACE;NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_5</AdditionalLibPaths>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<NoWarn>1699</NoWarn>
<Optimize>true</Optimize>
- <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5;ASPNETMVC</DefineConstants>
+ <DefineConstants>NET_1_1;NET_2_0;NET_3_0;NET_3_5;NET_4_0;NET_4_5</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AdditionalLibPaths>./../../class/lib/net_4_5</AdditionalLibPaths>
@@ -56,7 +52,7 @@ <PreBuildEvent></PreBuildEvent>
</PropertyGroup>
<ItemGroup>
- <Reference Include="mscorlib.dll"> + <Reference Include="mscorlib.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>mscorlib.dll</HintPath> </Reference> @@ -76,29 +72,16 @@ <SpecificVersion>False</SpecificVersion> <HintPath>System.Core.dll</HintPath> </Reference> - <Reference Include="System.Runtime.Serialization.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>System.Runtime.Serialization.dll</HintPath> - </Reference> <Reference Include="System.ServiceModel.Web.dll"> <SpecificVersion>False</SpecificVersion> <HintPath>System.ServiceModel.Web.dll</HintPath> </Reference> - <Reference Include="Microsoft.CSharp.dll"> - <SpecificVersion>False</SpecificVersion> - <HintPath>Microsoft.CSharp.dll</HintPath> - </Reference> <Reference Include="nunit.framework" /> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
- <ItemGroup> - <EmbeddedResource Include="System.Json.Properties.Resources.resources"> - <LogicalName>System.Json.Properties.Resources.resources</LogicalName> - </EmbeddedResource> - </ItemGroup> -
+
</Project>
diff --git a/mcs/class/System.Json/System.Json.dll.sources b/mcs/class/System.Json/System.Json.dll.sources index 4d2f589c7ab..47a9ceed63a 100644 --- a/mcs/class/System.Json/System.Json.dll.sources +++ b/mcs/class/System.Json/System.Json.dll.sources @@ -1,22 +1,8 @@ ../../build/common/Consts.cs Assembly/AssemblyInfo.cs - -../../../external/aspnetwebstack/src/RS.cs -../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs -../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs - -System.Json/Properties/AssemblyInfo.cs -System.Json/Extensions/JsonValueExtensions.cs -System.Json/GlobalSuppressions.cs -System.Json/JXmlToJsonValueConverter.cs System.Json/JsonArray.cs System.Json/JsonObject.cs System.Json/JsonPrimitive.cs System.Json/JsonType.cs System.Json/JsonValue.cs -System.Json/JsonValueChange.cs -System.Json/JsonValueChangeEventArgs.cs -System.Json/JsonValueDynamicMetaObject.cs -System.Json/JsonValueLinqExtensions.cs -System.Json/NGenWrapper.cs -System.Json/Properties/Resources.Designer.cs +../System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs
\ No newline at end of file diff --git a/mcs/class/System.Json/System.Json/ChangeLog b/mcs/class/System.Json/System.Json/ChangeLog new file mode 100644 index 00000000000..2c56ec1c650 --- /dev/null +++ b/mcs/class/System.Json/System.Json/ChangeLog @@ -0,0 +1,70 @@ +2010-03-10 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : moved to Sys.SM.Web/Sys.R.S.Json. + +2010-03-10 Atsushi Enomoto <atsushi@ximian.com> + + * JsonValue.cs : use Sys.SM.Web.dll's JavaScriptObjectDeserializer + for silverlight sdk / moonlight compatibility. + * JsonReader.cs : renamed to JavaScriptReader (for disambiguation in + Sys.SM.Web.dll). Now it is native-type based and used by the above + deserializer. + +2010-02-18 Atsushi Enomoto <atsushi@ximian.com> + + * JsonValue.cs : fix string escaping, it was giving wrong output + after \" and \\. + +2010-02-18 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : line endings after a value should not result in + a parse error. + * JsonObject.cs : duplicate object key "SHOULD" not be used, but + they are not rejected. So, make it a bit sloppy. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : oops, added previous change to wrong position. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : It seems it can either return int, long or decimal + depending on the value. Users cannot really predict what type of + the primitive value can be returned and casts to specific types + very likely fail. doh. + +2010-01-27 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : use decimal instead of int to parse decimal part + of numeric value. It can parse bigger value than int now (like + tweet id). + +2009-10-05 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : \uXXXX parser was totally wrong, giving wrong #. + +2009-09-22 Atsushi Enomoto <atsushi@ximian.com> + + * JsonValue.cs, JsonReader.cs, JsonPrimitive.cs : + Handle "null" values, as string, so far (haven't tried what .NET + actually does). + Fix array ToString() that missed commas (while Save() worked fine - + it has different serialization logic). + +2009-01-15 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : consume ',' between items in an array. + +2008-09-15 Atsushi Enomoto <atsushi@ximian.com> + + * JsonObject.cs, JsonValue.cs : SL2b2 updates. + +2008-08-28 Atsushi Enomoto <atsushi@ximian.com> + + * JsonReader.cs : a ReadChar() is missing in number parsing. + +2008-06-10 Atsushi Enomoto <atsushi@ximian.com> + + * JsonArray.cs, JsonObject.cs, JsonPrimitive.cs, JsonReader.cs, + JsonType.cs, JsonValue.cs, MergedEnumerator.cs : initial checkin. + diff --git a/mcs/class/System.Json/System.Json/Extensions/JsonValueExtensions.cs b/mcs/class/System.Json/System.Json/Extensions/JsonValueExtensions.cs deleted file mode 100644 index 2ea0c14bbc1..00000000000 --- a/mcs/class/System.Json/System.Json/Extensions/JsonValueExtensions.cs +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. -#if FEATURE_DYNAMIC -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.Dynamic; -using System.IO; -using System.Json; -using System.Linq.Expressions; - -namespace System.Runtime.Serialization.Json -{ - /// <summary> - /// This class extends the functionality of the <see cref="JsonValue"/> type. - /// </summary> - [EditorBrowsable(EditorBrowsableState.Never)] - public static class JsonValueExtensions - { - /// <summary> - /// Creates a <see cref="System.Json.JsonValue"/> object based on an arbitrary CLR object. - /// </summary> - /// <param name="value">The object to be converted to <see cref="System.Json.JsonValue"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> which represents the given object.</returns> - /// <remarks>The conversion is done through the <see cref="System.Runtime.Serialization.Json.DataContractJsonSerializer"/>; - /// the object is first serialized into JSON using the serializer, then parsed into a <see cref="System.Json.JsonValue"/> - /// object.</remarks> - public static JsonValue CreateFrom(object value) - { - JsonValue jsonValue = null; - - if (value != null) - { - jsonValue = value as JsonValue; - - if (jsonValue == null) - { - jsonValue = JsonValueExtensions.CreatePrimitive(value); - - if (jsonValue == null) - { - jsonValue = JsonValueExtensions.CreateFromDynamic(value); - - if (jsonValue == null) - { - jsonValue = JsonValueExtensions.CreateFromComplex(value); - } - } - } - } - - return jsonValue; - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param> - /// <param name="valueOfT">An instance of T initialized with this instance, or the default - /// value of T, if the conversion cannot be performed.</param> - /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as type T; otherwise, false.</returns> - public static bool TryReadAsType<T>(this JsonValue jsonValue, out T valueOfT) - { - if (jsonValue == null) - { - throw new ArgumentNullException("jsonValue"); - } - - object value; - if (JsonValueExtensions.TryReadAsType(jsonValue, typeof(T), out value)) - { - valueOfT = (T)value; - return true; - } - - valueOfT = default(T); - return false; - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param> - /// <returns>An instance of T initialized with the <see cref="System.Json.JsonValue"/> value - /// specified if the conversion.</returns> - /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be - /// converted into the type T.</exception> - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "The generic parameter is used to specify the output type")] - public static T ReadAsType<T>(this JsonValue jsonValue) - { - if (jsonValue == null) - { - throw new ArgumentNullException("jsonValue"); - } - - return (T)JsonValueExtensions.ReadAsType(jsonValue, typeof(T)); - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T, returning a fallback value - /// if the conversion fails. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param> - /// <param name="fallback">A fallback value to be retuned in case the conversion cannot be performed.</param> - /// <returns>An instance of T initialized with the <see cref="System.Json.JsonValue"/> value - /// specified if the conversion succeeds or the specified fallback value if it fails.</returns> - public static T ReadAsType<T>(this JsonValue jsonValue, T fallback) - { - if (jsonValue == null) - { - throw new ArgumentNullException("jsonValue"); - } - - T outVal; - if (JsonValueExtensions.TryReadAsType<T>(jsonValue, out outVal)) - { - return outVal; - } - - return fallback; - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. - /// </summary> - /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <returns>An object instance initialized with the <see cref="System.Json.JsonValue"/> value - /// specified if the conversion.</returns> - /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be - /// converted into the type T.</exception> - public static object ReadAsType(this JsonValue jsonValue, Type type) - { - if (jsonValue == null) - { - throw new ArgumentNullException("jsonValue"); - } - - if (type == null) - { - throw new ArgumentNullException("type"); - } - - object result; - if (JsonValueExtensions.TryReadAsType(jsonValue, type, out result)) - { - return result; - } - - throw new NotSupportedException(RS.Format(System.Json.Properties.Resources.CannotReadAsType, jsonValue.GetType().FullName, type.FullName)); - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. - /// </summary> - /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <param name="value">An object to be initialized with this instance or null if the conversion cannot be performed.</param> - /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as the specified type; otherwise, false.</returns> - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", - Justification = "This is the non-generic version of the method.")] - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Exception translates to fail.")] - public static bool TryReadAsType(this JsonValue jsonValue, Type type, out object value) - { - if (jsonValue == null) - { - throw new ArgumentNullException("jsonValue"); - } - - if (type == null) - { - throw new ArgumentNullException("type"); - } - - if (type == typeof(JsonValue) || type == typeof(object)) - { - value = jsonValue; - return true; - } - - if (type == typeof(object[]) || type == typeof(Dictionary<string, object>)) - { - if (!JsonValueExtensions.CanConvertToClrCollection(jsonValue, type)) - { - value = null; - return false; - } - } - - if (jsonValue.TryReadAs(type, out value)) - { - return true; - } - - try - { - using (MemoryStream ms = new MemoryStream()) - { - jsonValue.Save(ms); - ms.Position = 0; - DataContractJsonSerializer dcjs = new DataContractJsonSerializer(type); - value = dcjs.ReadObject(ms); - } - - return true; - } - catch (Exception) - { - value = null; - return false; - } - } - - /// <summary> - /// Determines whether the specified <see cref="JsonValue"/> instance can be converted to the specified collection <see cref="Type"/>. - /// </summary> - /// <param name="jsonValue">The instance to be converted.</param> - /// <param name="collectionType">The collection type to convert the instance to.</param> - /// <returns>true if the instance can be converted, false otherwise</returns> - private static bool CanConvertToClrCollection(JsonValue jsonValue, Type collectionType) - { - if (jsonValue != null) - { - return (jsonValue.JsonType == JsonType.Object && collectionType == typeof(Dictionary<string, object>)) || - (jsonValue.JsonType == JsonType.Array && collectionType == typeof(object[])); - } - - return false; - } - - private static JsonValue CreatePrimitive(object value) - { - JsonPrimitive jsonPrimitive; - - if (JsonPrimitive.TryCreate(value, out jsonPrimitive)) - { - return jsonPrimitive; - } - - return null; - } - - private static JsonValue CreateFromComplex(object value) - { - DataContractJsonSerializer dcjs = new DataContractJsonSerializer(value.GetType()); - using (MemoryStream ms = new MemoryStream()) - { - dcjs.WriteObject(ms, value); - ms.Position = 0; - return JsonValue.Load(ms); - } - } - - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "value is not the same")] - private static JsonValue CreateFromDynamic(object value) - { - JsonObject parent = null; - DynamicObject dynObj = value as DynamicObject; - - if (dynObj != null) - { - parent = new JsonObject(); - Stack<CreateFromTypeStackInfo> infoStack = new Stack<CreateFromTypeStackInfo>(); - IEnumerator<string> keys = null; - - do - { - if (keys == null) - { - keys = dynObj.GetDynamicMemberNames().GetEnumerator(); - } - - while (keys.MoveNext()) - { - JsonValue child = null; - string key = keys.Current; - SimpleGetMemberBinder binder = new SimpleGetMemberBinder(key); - - if (dynObj.TryGetMember(binder, out value)) - { - DynamicObject childDynObj = value as DynamicObject; - - if (childDynObj != null) - { - child = new JsonObject(); - parent.Add(key, child); - - infoStack.Push(new CreateFromTypeStackInfo(parent, dynObj, keys)); - - parent = child as JsonObject; - dynObj = childDynObj; - keys = null; - - break; - } - else - { - if (value != null) - { - child = value as JsonValue; - - if (child == null) - { - child = JsonValueExtensions.CreatePrimitive(value); - - if (child == null) - { - child = JsonValueExtensions.CreateFromComplex(value); - } - } - } - - parent.Add(key, child); - } - } - } - - if (infoStack.Count > 0 && keys != null) - { - CreateFromTypeStackInfo info = infoStack.Pop(); - - parent = info.JsonObject; - dynObj = info.DynamicObject; - keys = info.Keys; - } - } - while (infoStack.Count > 0); - } - - return parent; - } - - private class CreateFromTypeStackInfo - { - public CreateFromTypeStackInfo(JsonObject jsonObject, DynamicObject dynamicObject, IEnumerator<string> keyEnumerator) - { - JsonObject = jsonObject; - DynamicObject = dynamicObject; - Keys = keyEnumerator; - } - - /// <summary> - /// Gets of sets - /// </summary> - public JsonObject JsonObject { get; set; } - - /// <summary> - /// Gets of sets - /// </summary> - public DynamicObject DynamicObject { get; set; } - - /// <summary> - /// Gets of sets - /// </summary> - public IEnumerator<string> Keys { get; set; } - } - - private class SimpleGetMemberBinder : GetMemberBinder - { - public SimpleGetMemberBinder(string name) - : base(name, false) - { - } - - public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) - { - if (target != null && errorSuggestion == null) - { - string exceptionMessage = RS.Format(System.Json.Properties.Resources.DynamicPropertyNotDefined, target.LimitType, Name); - Expression throwExpression = Expression.Throw(Expression.Constant(new InvalidOperationException(exceptionMessage)), typeof(object)); - - errorSuggestion = new DynamicMetaObject(throwExpression, target.Restrictions); - } - - return errorSuggestion; - } - } - } -} -#endif diff --git a/mcs/class/System.Json/System.Json/GlobalSuppressions.cs b/mcs/class/System.Json/System.Json/GlobalSuppressions.cs deleted file mode 100644 index 5d3e5578676..00000000000 --- a/mcs/class/System.Json/System.Json/GlobalSuppressions.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "These assemblies are delay-signed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Justification = "Classes are grouped logically for user clarity.", Scope = "namespace", Target = "System.Runtime.Serialization.Json")] diff --git a/mcs/class/System.Json/System.Json/JXmlToJsonValueConverter.cs b/mcs/class/System.Json/System.Json/JXmlToJsonValueConverter.cs deleted file mode 100644 index f4952646b58..00000000000 --- a/mcs/class/System.Json/System.Json/JXmlToJsonValueConverter.cs +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Runtime.Serialization.Json; -using System.Text; -using System.Xml; - -namespace System.Json -{ - internal static class JXmlToJsonValueConverter - { - internal const string RootElementName = "root"; - internal const string ItemElementName = "item"; - internal const string TypeAttributeName = "type"; - internal const string ArrayAttributeValue = "array"; - internal const string BooleanAttributeValue = "boolean"; - internal const string NullAttributeValue = "null"; - internal const string NumberAttributeValue = "number"; - internal const string ObjectAttributeValue = "object"; - internal const string StringAttributeValue = "string"; - private const string TypeHintAttributeName = "__type"; - - private static readonly char[] _floatingPointChars = new char[] { '.', 'e', 'E' }; - - public static JsonValue JXMLToJsonValue(Stream jsonStream) - { - if (jsonStream == null) - { - throw new ArgumentNullException("jsonStream"); - } - - return JXMLToJsonValue(jsonStream, null); - } - - public static JsonValue JXMLToJsonValue(string jsonString) - { - if (jsonString == null) - { - throw new ArgumentNullException("jsonString"); - } - - if (jsonString.Length == 0) - { - throw new ArgumentException(Properties.Resources.JsonStringCannotBeEmpty, "jsonString"); - } - - byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString); - - return JXMLToJsonValue(null, jsonBytes); - } - - public static JsonValue JXMLToJsonValue(XmlDictionaryReader jsonReader) - { - if (jsonReader == null) - { - throw new ArgumentNullException("jsonReader"); - } - - const string RootObjectName = "RootObject"; - Stack<JsonValue> jsonStack = new Stack<JsonValue>(); - string nodeType = null; - bool isEmptyElement = false; - - JsonValue parent = new JsonObject(); - jsonStack.Push(parent); - string currentName = RootObjectName; - - try - { - MoveToRootNode(jsonReader); - - while (jsonStack.Count > 0 && jsonReader.NodeType != XmlNodeType.None) - { - if (parent is JsonObject && currentName == null) - { - currentName = GetMemberName(jsonReader); - } - - nodeType = jsonReader.GetAttribute(TypeAttributeName) ?? StringAttributeValue; - - if (parent is JsonArray) - { - // For arrays, the element name has to be "item" - if (jsonReader.Name != ItemElementName) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - } - - switch (nodeType) - { - case NullAttributeValue: - case BooleanAttributeValue: - case StringAttributeValue: - case NumberAttributeValue: - JsonPrimitive jsonPrimitive = ReadPrimitive(nodeType, jsonReader); - InsertJsonValue(jsonStack, ref parent, ref currentName, jsonPrimitive, true); - break; - case ArrayAttributeValue: - JsonArray jsonArray = CreateJsonArray(jsonReader, ref isEmptyElement); - InsertJsonValue(jsonStack, ref parent, ref currentName, jsonArray, isEmptyElement); - break; - case ObjectAttributeValue: - JsonObject jsonObject = CreateObjectWithTypeHint(jsonReader, ref isEmptyElement); - InsertJsonValue(jsonStack, ref parent, ref currentName, jsonObject, isEmptyElement); - break; - default: - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - - while (jsonReader.NodeType == XmlNodeType.EndElement && jsonStack.Count > 0) - { - jsonReader.Read(); - SkipWhitespace(jsonReader); - jsonStack.Pop(); - if (jsonStack.Count > 0) - { - parent = jsonStack.Peek(); - } - } - } - } - catch (XmlException xmlException) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat, xmlException); - } - - if (jsonStack.Count != 1) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - - return parent[RootObjectName]; - } - - private static JsonValue JXMLToJsonValue(Stream jsonStream, byte[] jsonBytes) - { - try - { - using (XmlDictionaryReader jsonReader = - jsonStream != null - ? JsonReaderWriterFactory.CreateJsonReader(jsonStream, XmlDictionaryReaderQuotas.Max) - : JsonReaderWriterFactory.CreateJsonReader(jsonBytes, XmlDictionaryReaderQuotas.Max)) - { - return JXMLToJsonValue(jsonReader); - } - } - catch (XmlException) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - } - - private static void InsertJsonValue(Stack<JsonValue> jsonStack, ref JsonValue parent, ref string currentName, JsonValue jsonValue, bool isEmptyElement) - { - if (parent is JsonArray) - { - ((JsonArray)parent).Add(jsonValue); - } - else - { - if (currentName != null) - { - ((JsonObject)parent)[currentName] = jsonValue; - currentName = null; - } - } - - if (!isEmptyElement) - { - jsonStack.Push(jsonValue); - parent = jsonValue; - } - } - - private static string GetMemberName(XmlDictionaryReader jsonReader) - { - string name; - if (jsonReader.NamespaceURI == ItemElementName && jsonReader.LocalName == ItemElementName) - { - // JXML special case for names which aren't valid XML names - name = jsonReader.GetAttribute(ItemElementName); - - if (name == null) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - } - else - { - name = jsonReader.Name; - } - - return name; - } - - private static JsonObject CreateObjectWithTypeHint(XmlDictionaryReader jsonReader, ref bool isEmptyElement) - { - JsonObject jsonObject = new JsonObject(); - string typeHintAttribute = jsonReader.GetAttribute(TypeHintAttributeName); - isEmptyElement = jsonReader.IsEmptyElement; - jsonReader.ReadStartElement(); - SkipWhitespace(jsonReader); - - if (typeHintAttribute != null) - { - jsonObject.Add(TypeHintAttributeName, typeHintAttribute); - } - - return jsonObject; - } - - private static JsonArray CreateJsonArray(XmlDictionaryReader jsonReader, ref bool isEmptyElement) - { - JsonArray jsonArray = new JsonArray(); - isEmptyElement = jsonReader.IsEmptyElement; - jsonReader.ReadStartElement(); - SkipWhitespace(jsonReader); - return jsonArray; - } - - private static void MoveToRootNode(XmlDictionaryReader jsonReader) - { - while (!jsonReader.EOF && (jsonReader.NodeType == XmlNodeType.None || jsonReader.NodeType == XmlNodeType.XmlDeclaration)) - { - // read into <root> node - jsonReader.Read(); - SkipWhitespace(jsonReader); - } - - if (jsonReader.NodeType != XmlNodeType.Element || !String.IsNullOrEmpty(jsonReader.NamespaceURI) || jsonReader.Name != RootElementName) - { - throw new FormatException(Properties.Resources.IncorrectJsonFormat); - } - } - - private static JsonPrimitive ReadPrimitive(string type, XmlDictionaryReader jsonReader) - { - JsonValue result = null; - switch (type) - { - case NullAttributeValue: - jsonReader.Skip(); - result = null; - break; - case BooleanAttributeValue: - result = jsonReader.ReadElementContentAsBoolean(); - break; - case StringAttributeValue: - result = jsonReader.ReadElementContentAsString(); - break; - case NumberAttributeValue: - string temp = jsonReader.ReadElementContentAsString(); - result = ConvertStringToJsonNumber(temp); - break; - } - - SkipWhitespace(jsonReader); - return (JsonPrimitive)result; - } - - private static void SkipWhitespace(XmlDictionaryReader reader) - { - while (!reader.EOF && (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.SignificantWhitespace)) - { - reader.Read(); - } - } - - private static JsonValue ConvertStringToJsonNumber(string value) - { - if (value.IndexOfAny(_floatingPointChars) < 0) - { - int intVal; - if (Int32.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out intVal)) - { - return intVal; - } - - long longVal; - if (Int64.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out longVal)) - { - return longVal; - } - } - - decimal decValue; - if (Decimal.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out decValue) && decValue != 0) - { - return decValue; - } - - double dblValue; - if (Double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out dblValue)) - { - return dblValue; - } - - throw new ArgumentException(RS.Format(Properties.Resources.InvalidJsonPrimitive, value.ToString()), "value"); - } - } -} diff --git a/mcs/class/System.Json/System.Json/JsonArray.cs b/mcs/class/System.Json/System.Json/JsonArray.cs index 21d0d03e5ca..c63004422b5 100644 --- a/mcs/class/System.Json/System.Json/JsonArray.cs +++ b/mcs/class/System.Json/System.Json/JsonArray.cs @@ -1,389 +1,139 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. +using System; using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Runtime.Serialization; -using System.Xml; +using System.IO; +using System.Text; namespace System.Json { - /// <summary> - /// A JsonArray is an ordered sequence of zero or more <see cref="System.Json.JsonValue"/> objects. - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Array already conveys the meaning of collection")] - [DataContract] - public sealed class JsonArray : JsonValue, IList<JsonValue> - { - [DataMember] - private List<JsonValue> values = new List<JsonValue>(); - - /// <summary> - /// Creates an instance of the <see cref="System.Json.JsonArray"/> class initialized by - /// an <see cref="System.Collections.Generic.IEnumerable{T}"/> enumeration of - /// objects of type <see cref="System.Json.JsonValue"/>. - /// </summary> - /// <param name="items">The <see cref="System.Collections.Generic.IEnumerable{T}"/> enumeration - /// of objects of type <see cref="System.Json.JsonValue"/> used to initialize the JavaScript Object Notation (JSON) - /// array.</param> - /// <exception cref="System.ArgumentNullException">If items is null.</exception> - /// <exception cref="System.ArgumentException">If any of the items in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public JsonArray(IEnumerable<JsonValue> items) - { - AddRange(items); - } - - /// <summary> - /// Creates an instance of the <see cref="System.Json.JsonArray"/> class, initialized by an array of type <see cref="System.Json.JsonValue"/>. - /// </summary> - /// <param name="items">The array of type <see cref="System.Json.JsonValue"/> used to initialize the - /// JavaScript Object Notation (JSON) array.</param> - /// <exception cref="System.ArgumentException">If any of the items in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public JsonArray(params JsonValue[] items) - { - if (items != null) - { - AddRange(items); - } - } - - /// <summary> - /// Gets the JSON type of this <see cref="System.Json.JsonArray"/>. The return value - /// is always <see cref="F:System.Json.JsonType.Array"/>. - /// </summary> - public override JsonType JsonType - { - get { return JsonType.Array; } - } - - /// <summary> - /// Gets a value indicating whether the <see cref="System.Json.JsonArray"/> is read-only. - /// </summary> - public bool IsReadOnly - { - get { return ((IList)values).IsReadOnly; } - } - - /// <summary> - /// Returns the number of <see cref="System.Json.JsonValue"/> elements in the array. - /// </summary> - public override int Count - { - get { return values.Count; } - } - - /// <summary> - /// Gets or sets the JSON value at a specified index. - /// </summary> - /// <param name="index">The zero-based index of the element to get or set.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> element at the specified index.</returns> - /// <exception cref="System.ArgumentOutOfRangeException">If index is not a valid index for this array.</exception> - /// <exception cref="System.ArgumentException">The property is set and the value is a - /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> - /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public override JsonValue this[int index] - { - get { return values[index]; } - - set - { - if (value != null && value.JsonType == JsonType.Default) - { - throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed); - } - - JsonValue oldValue = values[index]; - RaiseItemChanging(value, JsonValueChange.Replace, index); - values[index] = value; - RaiseItemChanged(oldValue, JsonValueChange.Replace, index); - } - } - - /// <summary> - /// Adds the elements from a collection of type <see cref="System.Json.JsonValue"/> to this instance. - /// </summary> - /// <param name="items">Collection of items to add.</param> - /// <exception cref="System.ArgumentNullException">If items is null.</exception> - /// <exception cref="System.ArgumentException">If any of the items in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void AddRange(IEnumerable<JsonValue> items) - { - if (items == null) - { - throw new ArgumentNullException("items"); - } - - if (ChangingListenersCount > 0) - { - int index = Count; - foreach (JsonValue toBeAdded in items) - { - RaiseItemChanging(toBeAdded, JsonValueChange.Add, index++); - } - } - - foreach (JsonValue item in items) - { - if (item != null && item.JsonType == JsonType.Default) - { - throw new ArgumentNullException("items", Properties.Resources.UseOfDefaultNotAllowed); - } - - values.Add(item); - RaiseItemChanged(item, JsonValueChange.Add, values.Count - 1); - } - } - - /// <summary> - /// Adds the elements from an array of type <see cref="System.Json.JsonValue"/> to this instance. - /// </summary> - /// <param name="items">The array of type JsonValue to be added to this instance.</param> - /// <exception cref="System.ArgumentNullException">If items is null.</exception> - /// <exception cref="System.ArgumentException">If any of the items in the array - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void AddRange(params JsonValue[] items) - { - AddRange(items as IEnumerable<JsonValue>); - } - - /// <summary> - /// Searches for a specified object and returns the zero-based index of its first - /// occurrence within this <see cref="System.Json.JsonArray"/>. - /// </summary> - /// <param name="item">The <see cref="System.Json.JsonValue"/> object to look up.</param> - /// <returns>The zero-based index of the first occurrence of item within the - /// <see cref="System.Json.JsonArray"/>, if found; otherwise, -1.</returns> - public int IndexOf(JsonValue item) - { - return values.IndexOf(item); - } - - /// <summary> - /// Insert a JSON CLR type into the array at a specified index. - /// </summary> - /// <param name="index">The zero-based index at which the item should be inserted.</param> - /// <param name="item">The <see cref="System.Json.JsonValue"/> object to insert.</param> - /// <exception cref="System.ArgumentOutOfRangeException">If index is less than zero or larger than - /// the size of the array.</exception> - /// <exception cref="System.ArgumentException">If the object to insert has a - /// <see cref="System.Json.JsonValue.JsonType"/> property of value - /// <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void Insert(int index, JsonValue item) - { - if (item != null && item.JsonType == JsonType.Default) - { - throw new ArgumentNullException("item", Properties.Resources.UseOfDefaultNotAllowed); - } - - RaiseItemChanging(item, JsonValueChange.Add, index); - values.Insert(index, item); - RaiseItemChanged(item, JsonValueChange.Add, index); - } - - /// <summary> - /// Remove the JSON value at a specified index of <see cref="System.Json.JsonArray"/>. - /// </summary> - /// <param name="index">The zero-based index at which to remove the <see cref="System.Json.JsonValue"/>.</param> - /// <exception cref="System.ArgumentOutOfRangeException">If index is less than zero or index - /// is equal or larger than the size of the array.</exception> - public void RemoveAt(int index) - { - JsonValue item = values[index]; - RaiseItemChanging(item, JsonValueChange.Remove, index); - values.RemoveAt(index); - RaiseItemChanged(item, JsonValueChange.Remove, index); - } - - /// <summary> - /// Adds a <see cref="System.Json.JsonValue"/> object to the end of the array. - /// </summary> - /// <param name="item">The <see cref="System.Json.JsonValue"/> object to add.</param> - /// <exception cref="System.ArgumentException">If the object to add has a - /// <see cref="System.Json.JsonValue.JsonType"/> property of value - /// <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void Add(JsonValue item) - { - if (item != null && item.JsonType == JsonType.Default) - { - throw new ArgumentNullException("item", Properties.Resources.UseOfDefaultNotAllowed); - } - - int index = Count; - RaiseItemChanging(item, JsonValueChange.Add, index); - values.Add(item); - RaiseItemChanged(item, JsonValueChange.Add, index); - } - - /// <summary> - /// Removes all JSON CLR types from the <see cref="System.Json.JsonArray"/>. - /// </summary> - public void Clear() - { - RaiseItemChanging(null, JsonValueChange.Clear, 0); - values.Clear(); - RaiseItemChanged(null, JsonValueChange.Clear, 0); - } - - /// <summary> - /// Checks whether a specified JSON CLR type is in the <see cref="System.Json.JsonArray"/>. - /// </summary> - /// <param name="item">The <see cref="System.Json.JsonValue"/> to check for in the array.</param> - /// <returns>true if item is found in the <see cref="System.Json.JsonArray"/>; otherwise, false.</returns> - public bool Contains(JsonValue item) - { - return values.Contains(item); - } - - /// <summary> - /// Copies the contents of the current JSON CLR array instance into a specified - /// destination array beginning at the specified index. - /// </summary> - /// <param name="array">The destination array to which the elements of the current - /// <see cref="System.Json.JsonArray"/> object are copied.</param> - /// <param name="arrayIndex">The zero-based index in the destination array at which the - /// copying of the elements of the JSON CLR array begins.</param> - public void CopyTo(JsonValue[] array, int arrayIndex) - { - values.CopyTo(array, arrayIndex); - } - - /// <summary> - /// Removes the first occurrence of the specified JSON value from the array. - /// </summary> - /// <param name="item">The <see cref="System.Json.JsonValue"/> to remove from the <see cref="System.Json.JsonArray"/>.</param> - /// <returns>true if item is successfully removed; otherwise, false. This method - /// also returns false if item was not found in the <see cref="System.Json.JsonArray"/>.</returns> - public bool Remove(JsonValue item) - { - int index = -1; - if (ChangingListenersCount > 0 || ChangedListenersCount > 0) - { - index = IndexOf(item); - } - - if (index >= 0) - { - RaiseItemChanging(item, JsonValueChange.Remove, index); - } - - bool result = values.Remove(item); - if (index >= 0) - { - RaiseItemChanged(item, JsonValueChange.Remove, index); - } - - return result; - } - - /// <summary> - /// Returns an enumerator that iterates through the <see cref="System.Json.JsonValue"/> objects in the array. - /// </summary> - /// <returns>Returns an <see cref="System.Collections.IEnumerator"/> object that - /// iterates through the <see cref="System.Json.JsonValue"/> elements in this <see cref="System.Json.JsonArray"/>.</returns> - IEnumerator IEnumerable.GetEnumerator() - { - return values.GetEnumerator(); - } - - /// <summary> - /// Safe indexer for the <see cref="System.Json.JsonValue"/> type. - /// </summary> - /// <param name="index">The zero-based index of the element to get.</param> - /// <returns>If the index is within the array bounds and the value corresponding to the - /// index is not null, then it will return that value. Otherwise it will return a - /// <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - public override JsonValue ValueOrDefault(int index) - { - if (index >= 0 && index < Count && this[index] != null) - { - return this[index]; - } - - return base.ValueOrDefault(index); - } - - /// <summary> - /// Returns an enumerator that iterates through the <see cref="System.Json.JsonValue"/> objects in the array. - /// </summary> - /// <returns>Returns an <see cref="System.Collections.Generic.IEnumerator{T}"/> object that - /// iterates through the <see cref="System.Json.JsonValue"/> elements in this <see cref="System.Json.JsonArray"/>.</returns> - public new IEnumerator<JsonValue> GetEnumerator() - { - return values.GetEnumerator(); - } - - /// <summary> - /// Returns an enumerator which iterates through the values in this object. - /// </summary> - /// <returns>An <see cref="System.Collections.Generic.IEnumerator{T}"/> which iterates through the values in this object.</returns> - /// <remarks>The enumerator returned by this class contains one pair for each element - /// in this array, whose key is the element index (as a string), and the value is the - /// element itself.</remarks> - protected override IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator() - { - for (int i = 0; i < values.Count; i++) - { - yield return new KeyValuePair<string, JsonValue>(i.ToString(CultureInfo.InvariantCulture), values[i]); - } - } - - /// <summary> - /// Callback method called to let an instance write the proper JXML attribute when saving this - /// instance. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - internal override void WriteAttributeString(XmlDictionaryWriter jsonWriter) - { - if (jsonWriter == null) - { - throw new ArgumentNullException("jsonWriter"); - } - - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.ArrayAttributeValue); - } - - /// <summary> - /// Callback method called during Save operations to let the instance write the start element - /// and return the next element in the collection. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - /// <param name="currentIndex">The index within this collection.</param> - /// <returns>The next item in the collection, or null of there are no more items.</returns> - internal override JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int currentIndex) - { - if (jsonWriter == null) - { - throw new ArgumentNullException("jsonWriter"); - } - - jsonWriter.WriteStartElement(JXmlToJsonValueConverter.ItemElementName); - JsonValue nextValue = this[currentIndex]; - return nextValue; - } - - private void RaiseItemChanging(JsonValue child, JsonValueChange change, int index) - { - if (ChangingListenersCount > 0) - { - RaiseChangingEvent(this, new JsonValueChangeEventArgs(child, change, index)); - } - } - - private void RaiseItemChanged(JsonValue child, JsonValueChange change, int index) - { - if (ChangedListenersCount > 0) - { - RaiseChangedEvent(this, new JsonValueChangeEventArgs(child, change, index)); - } - } - } + public class JsonArray : JsonValue, IList<JsonValue> + { + List<JsonValue> list; + + public JsonArray (params JsonValue [] items) + { + list = new List<JsonValue> (); + AddRange (items); + } + + public JsonArray (IEnumerable<JsonValue> items) + { + if (items == null) + throw new ArgumentNullException ("items"); + + list = new List<JsonValue> (items); + } + + public override int Count { + get { return list.Count; } + } + + public bool IsReadOnly { + get { return false; } + } + + public override sealed JsonValue this [int index] { + get { return list [index]; } + set { list [index] = value; } + } + + public override JsonType JsonType { + get { return JsonType.Array; } + } + + public void Add (JsonValue item) + { + if (item == null) + throw new ArgumentNullException ("item"); + + list.Add (item); + } + + public void AddRange (IEnumerable<JsonValue> items) + { + if (items == null) + throw new ArgumentNullException ("items"); + + list.AddRange (items); + } + + public void AddRange (params JsonValue [] items) + { + if (items == null) + return; + + list.AddRange (items); + } + + public void Clear () + { + list.Clear (); + } + + public bool Contains (JsonValue item) + { + return list.Contains (item); + } + + public void CopyTo (JsonValue [] array, int arrayIndex) + { + list.CopyTo (array, arrayIndex); + } + + public int IndexOf (JsonValue item) + { + return list.IndexOf (item); + } + + public void Insert (int index, JsonValue item) + { + list.Insert (index, item); + } + + public bool Remove (JsonValue item) + { + return list.Remove (item); + } + + public void RemoveAt (int index) + { + list.RemoveAt (index); + } + + public override void Save (Stream stream) + { + if (stream == null) + throw new ArgumentNullException ("stream"); + stream.WriteByte ((byte) '['); + for (int i = 0; i < list.Count; i++) { + JsonValue v = list [i]; + if (v != null) + v.Save (stream); + else { + stream.WriteByte ((byte) 'n'); + stream.WriteByte ((byte) 'u'); + stream.WriteByte ((byte) 'l'); + stream.WriteByte ((byte) 'l'); + } + + if (i < Count - 1) { + stream.WriteByte ((byte) ','); + stream.WriteByte ((byte) ' '); + } + } + stream.WriteByte ((byte) ']'); + } + + IEnumerator<JsonValue> IEnumerable<JsonValue>.GetEnumerator () + { + return list.GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return list.GetEnumerator (); + } + } } diff --git a/mcs/class/System.Json/System.Json/JsonObject.cs b/mcs/class/System.Json/System.Json/JsonObject.cs index a8831c64648..33177b1c5f2 100644 --- a/mcs/class/System.Json/System.Json/JsonObject.cs +++ b/mcs/class/System.Json/System.Json/JsonObject.cs @@ -1,474 +1,160 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - +using System; using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.Serialization; -using System.Xml; -using WrappedPair = System.Json.NGenWrapper<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>; +using System.Globalization; +using System.IO; +using System.Text; + +using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>; +using JsonPairEnumerable = System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>; namespace System.Json { - /// <summary> - /// A JsonObject is an unordered collection of zero or more key/value pairs. - /// </summary> - /// <remarks>A JsonObject is an unordered collection of zero or more key/value pairs, - /// where each key is a String and each value is a <see cref="System.Json.JsonValue"/>, which can be a - /// <see cref="System.Json.JsonPrimitive"/>, a <see cref="System.Json.JsonArray"/>, or a JsonObject.</remarks> - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Object in the context of JSON already conveys the meaning of dictionary")] - [DataContract] - public sealed class JsonObject : JsonValue, IDictionary<string, JsonValue> - { - [DataMember] - private Dictionary<string, JsonValue> values = new Dictionary<string, JsonValue>(StringComparer.Ordinal); - - private List<WrappedPair> indexedPairs; - private int instanceSaveCount; - private object saveLock = new object(); - - /// <summary> - /// Creates an instance of the <see cref="System.Json.JsonObject"/> class initialized with an - /// <see cref="System.Collections.Generic.IEnumerable{T}"/> collection of key/value pairs. - /// </summary> - /// <param name="items">The <see cref="System.Collections.Generic.IEnumerable{T}"/> collection of - /// <see cref="System.Collections.Generic.KeyValuePair{K, V}"/> used to initialize the - /// key/value pairs</param> - /// <exception cref="System.ArgumentNullException">If items is null.</exception> - /// <exception cref="System.ArgumentException">If any of the values in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "There's no complexity using this design because nested generic type is atomic type not another collection")] - public JsonObject(IEnumerable<KeyValuePair<string, JsonValue>> items) - { - AddRange(items); - } - - /// <summary> - /// Creates an instance of the <see cref="System.Json.JsonObject"/> class initialized with a collection of key/value pairs. - /// </summary> - /// <param name="items">The <see cref="System.Collections.Generic.KeyValuePair{K, V}"/> objects used to initialize the key/value pairs.</param> - /// <exception cref="System.ArgumentException">If any of the values in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public JsonObject(params KeyValuePair<string, JsonValue>[] items) - { - if (items != null) - { - AddRange(items); - } - } - - /// <summary> - /// Gets the JSON type of this <see cref="System.Json.JsonObject"/>. The return value - /// is always <see cref="F:System.Json.JsonType.Object"/>. - /// </summary> - public override JsonType JsonType - { - get { return JsonType.Object; } - } - - /// <summary> - /// Gets a collection that contains the keys in this <see cref="System.Json.JsonObject"/>. - /// </summary> - public ICollection<string> Keys - { - get { return values.Keys; } - } - - /// <summary> - /// Gets a collection that contains the values in this <see cref="System.Json.JsonObject"/>. - /// </summary> - public ICollection<JsonValue> Values - { - get { return values.Values; } - } - - /// <summary> - /// Returns the number of key/value pairs in this <see cref="System.Json.JsonObject"/>. - /// </summary> - public override int Count - { - get { return values.Count; } - } - - /// <summary> - /// Gets a value indicating whether this JSON CLR object is read-only. - /// </summary> - bool ICollection<KeyValuePair<string, JsonValue>>.IsReadOnly - { - get { return ((ICollection<KeyValuePair<string, JsonValue>>)values).IsReadOnly; } - } - - /// <summary> - /// Gets or sets the value associated with the specified key. - /// </summary> - /// <param name="key">The key of the value to get or set.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> associated to the specified key.</returns> - /// <exception cref="System.ArgumentNullException">If key is null.</exception> - /// <exception cref="System.ArgumentException">The property is set and the value is a - /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> - /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public override JsonValue this[string key] - { - get - { - if (key == null) - { - throw new ArgumentNullException("key"); - } - - return values[key]; - } - - set - { - if (value != null && value.JsonType == JsonType.Default) - { - throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed); - } - - if (key == null) - { - throw new ArgumentNullException("key"); - } - - bool replacement = values.ContainsKey(key); - JsonValue oldValue = null; - if (replacement) - { - oldValue = values[key]; - RaiseItemChanging(value, JsonValueChange.Replace, key); - } - else - { - RaiseItemChanging(value, JsonValueChange.Add, key); - } - - values[key] = value; - if (replacement) - { - RaiseItemChanged(oldValue, JsonValueChange.Replace, key); - } - else - { - RaiseItemChanged(value, JsonValueChange.Add, key); - } - } - } - - /// <summary> - /// Safe string indexer for the <see cref="System.Json.JsonValue"/> type. - /// </summary> - /// <param name="key">The key of the element to get.</param> - /// <returns>If this instance contains the given key and the value corresponding to - /// the key is not null, then it will return that value. Otherwise it will return a - /// <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - public override JsonValue ValueOrDefault(string key) - { - if (key != null && ContainsKey(key) && this[key] != null) - { - return this[key]; - } - - return base.ValueOrDefault(key); - } - - /// <summary> - /// Adds a specified collection of key/value pairs to this instance. - /// </summary> - /// <param name="items">The collection of key/value pairs to add.</param> - /// <exception cref="System.ArgumentNullException">If items is null.</exception> - /// <exception cref="System.ArgumentException">If the value of any of the items in the collection - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "There's no complexity using this design because nested generic type is atomic type not another collection")] - public void AddRange(IEnumerable<KeyValuePair<string, JsonValue>> items) - { - if (items == null) - { - throw new ArgumentNullException("items"); - } - - if (ChangingListenersCount > 0) - { - foreach (KeyValuePair<string, JsonValue> item in items) - { - RaiseItemChanging(item.Value, JsonValueChange.Add, item.Key); - } - } - - foreach (KeyValuePair<string, JsonValue> item in items) - { - if (item.Value != null && item.Value.JsonType == JsonType.Default) - { - throw new ArgumentNullException("items", Properties.Resources.UseOfDefaultNotAllowed); - } - - values.Add(item.Key, item.Value); - RaiseItemChanged(item.Value, JsonValueChange.Add, item.Key); - } - } - - /// <summary> - /// Adds the elements from an array of type <see cref="System.Json.JsonValue"/> to this instance. - /// </summary> - /// <param name="items">The array of key/value paris to be added to this instance.</param> - /// <exception cref="System.ArgumentException">If the value of any of the items in the array - /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void AddRange(params KeyValuePair<string, JsonValue>[] items) - { - AddRange(items as IEnumerable<KeyValuePair<string, JsonValue>>); - } - - /// <summary> - /// - /// </summary> - /// <returns></returns> - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)values).GetEnumerator(); - } - - /// <summary> - /// Adds a key/value pair to this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - /// <param name="key">The key for the element added.</param> - /// <param name="value">The <see cref="System.Json.JsonValue"/> for the element added.</param> - /// <exception cref="System.ArgumentException">If the value is a <see cref="System.Json.JsonValue"/> - /// with <see cref="System.Json.JsonValue.JsonType"/> property of - /// value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void Add(string key, JsonValue value) - { - if (value != null && value.JsonType == JsonType.Default) - { - throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed); - } - - RaiseItemChanging(value, JsonValueChange.Add, key); - values.Add(key, value); - RaiseItemChanged(value, JsonValueChange.Add, key); - } - - /// <summary> - /// Adds a key/value pair to this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - /// <param name="item">The key/value pair to be added.</param> - /// <exception cref="System.ArgumentException">If the value of the pair is a - /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> - /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception> - public void Add(KeyValuePair<string, JsonValue> item) - { - Add(item.Key, item.Value); - } - - /// <summary> - /// Checks whether a key/value pair with a specified key exists in this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - /// <param name="key">The key to check for.</param> - /// <returns>true if this instance contains the key; otherwise, false.</returns> - public override bool ContainsKey(string key) - { - return values.ContainsKey(key); - } - - /// <summary> - /// Removes the key/value pair with a specified key from this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - /// <param name="key">The key of the item to remove.</param> - /// <returns>true if the element is successfully found and removed; otherwise, false. - /// This method returns false if key is not found in this <see cref="System.Json.JsonObject"/> instance.</returns> - public bool Remove(string key) - { - JsonValue original = null; - bool containsKey = false; - if (ChangingListenersCount > 0 || ChangedListenersCount > 0) - { - containsKey = TryGetValue(key, out original); - } - - if (containsKey && ChangingListenersCount > 0) - { - RaiseItemChanging(original, JsonValueChange.Remove, key); - } - - bool result = values.Remove(key); - - if (containsKey && ChangedListenersCount > 0) - { - RaiseItemChanged(original, JsonValueChange.Remove, key); - } - - return result; - } - - /// <summary> - /// Attempts to get the value that corresponds to the specified key. - /// </summary> - /// <param name="key">The key of the value to retrieve.</param> - /// <param name="value">The primitive or structured <see cref="System.Json.JsonValue"/> object that has the key - /// specified. If this object does not contain a key/value pair with the given key, - /// this parameter is set to null.</param> - /// <returns>true if the instance of the <see cref="System.Json.JsonObject"/> contains an element with the - /// specified key; otherwise, false.</returns> - public bool TryGetValue(string key, out JsonValue value) - { - return values.TryGetValue(key, out value); - } - - /// <summary> - /// Removes all key/value pairs from this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - public void Clear() - { - RaiseItemChanging(null, JsonValueChange.Clear, null); - values.Clear(); - RaiseItemChanged(null, JsonValueChange.Clear, null); - } - - bool ICollection<KeyValuePair<string, JsonValue>>.Contains(KeyValuePair<string, JsonValue> item) - { - return ((ICollection<KeyValuePair<string, JsonValue>>)values).Contains(item); - } - - /// <summary> - /// Copies the contents of this <see cref="System.Json.JsonObject"/> instance into a specified - /// key/value destination array beginning at a specified index. - /// </summary> - /// <param name="array">The destination array of type <see cref="System.Collections.Generic.KeyValuePair{K, V}"/> - /// to which the elements of this <see cref="System.Json.JsonObject"/> are copied.</param> - /// <param name="arrayIndex">The zero-based index at which to begin the insertion of the - /// contents from this <see cref="System.Json.JsonObject"/> instance.</param> - public void CopyTo(KeyValuePair<string, JsonValue>[] array, int arrayIndex) - { - ((ICollection<KeyValuePair<string, JsonValue>>)values).CopyTo(array, arrayIndex); - } - - bool ICollection<KeyValuePair<string, JsonValue>>.Remove(KeyValuePair<string, JsonValue> item) - { - if (ChangingListenersCount > 0) - { - if (ContainsKey(item.Key) && EqualityComparer<JsonValue>.Default.Equals(item.Value, values[item.Key])) - { - RaiseItemChanging(item.Value, JsonValueChange.Remove, item.Key); - } - } - - bool result = ((ICollection<KeyValuePair<string, JsonValue>>)values).Remove(item); - if (result) - { - RaiseItemChanged(item.Value, JsonValueChange.Remove, item.Key); - } - - return result; - } - - /// <summary> - /// Returns an enumerator over the key/value pairs contained in this <see cref="System.Json.JsonObject"/> instance. - /// </summary> - /// <returns>An <see cref="System.Collections.Generic.IEnumerator{T}"/> which iterates - /// through the members of this instance.</returns> - protected override IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator() - { - return values.GetEnumerator(); - } - - /// <summary> - /// Callback method called when a Save operation is starting for this instance. - /// </summary> - protected override void OnSaveStarted() - { - lock (saveLock) - { - instanceSaveCount++; - if (indexedPairs == null) - { - indexedPairs = new List<WrappedPair>(); - - foreach (KeyValuePair<string, JsonValue> item in values) - { - indexedPairs.Add(new WrappedPair(item)); - } - } - } - } - - /// <summary> - /// Callback method called when a Save operation is finished for this instance. - /// </summary> - protected override void OnSaveEnded() - { - lock (saveLock) - { - instanceSaveCount--; - if (instanceSaveCount == 0) - { - indexedPairs = null; - } - } - } - - /// <summary> - /// Callback method called to let an instance write the proper JXML attribute when saving this - /// instance. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - internal override void WriteAttributeString(XmlDictionaryWriter jsonWriter) - { - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.ObjectAttributeValue); - } - - /// <summary> - /// Callback method called during Save operations to let the instance write the start element - /// and return the next element in the collection. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - /// <param name="currentIndex">The index within this collection.</param> - /// <returns>The next item in the collection, or null of there are no more items.</returns> - internal override JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int currentIndex) - { - KeyValuePair<string, JsonValue> currentPair = indexedPairs[currentIndex]; - string currentKey = currentPair.Key; - - if (currentKey.Length == 0) - { - // special case in JXML world - jsonWriter.WriteStartElement(JXmlToJsonValueConverter.ItemElementName, JXmlToJsonValueConverter.ItemElementName); - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.ItemElementName, String.Empty); - } - else - { - jsonWriter.WriteStartElement(currentKey); - } - - return currentPair.Value; - } - - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "Context is required by CLR for this to work.")] - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - saveLock = new object(); - } - - private void RaiseItemChanging(JsonValue child, JsonValueChange change, string key) - { - if (ChangingListenersCount > 0) - { - RaiseChangingEvent(this, new JsonValueChangeEventArgs(child, change, key)); - } - } - - private void RaiseItemChanged(JsonValue child, JsonValueChange change, string key) - { - if (ChangedListenersCount > 0) - { - RaiseChangedEvent(this, new JsonValueChangeEventArgs(child, change, key)); - } - } - } + public class JsonObject : JsonValue, IDictionary<string, JsonValue>, ICollection<JsonPair> + { + Dictionary<string, JsonValue> map; + + public JsonObject (params JsonPair [] items) + { + map = new Dictionary<string, JsonValue> (); + + if (items != null) + AddRange (items); + } + + public JsonObject (JsonPairEnumerable items) + { + if (items == null) + throw new ArgumentNullException ("items"); + + map = new Dictionary<string, JsonValue> (); + AddRange (items); + } + + public override int Count { + get { return map.Count; } + } + + public IEnumerator<JsonPair> GetEnumerator () + { + return map.GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return map.GetEnumerator (); + } + + public override sealed JsonValue this [string key] { + get { return map [key]; } + set { map [key] = value; } + } + + public override JsonType JsonType { + get { return JsonType.Object; } + } + + public ICollection<string> Keys { + get { return map.Keys; } + } + + public ICollection<JsonValue> Values { + get { return map.Values; } + } + + public void Add (string key, JsonValue value) + { + if (key == null) + throw new ArgumentNullException ("key"); + + map.Add (key, value); + } + + public void Add (JsonPair pair) + { + Add (pair.Key, pair.Value); + } + + public void AddRange (JsonPairEnumerable items) + { + if (items == null) + throw new ArgumentNullException ("items"); + + foreach (var pair in items) + map.Add (pair.Key, pair.Value); + } + + public void AddRange (params JsonPair [] items) + { + AddRange ((JsonPairEnumerable) items); + } + + public void Clear () + { + map.Clear (); + } + + bool ICollection<JsonPair>.Contains (JsonPair item) + { + return (map as ICollection<JsonPair>).Contains (item); + } + + bool ICollection<JsonPair>.Remove (JsonPair item) + { + return (map as ICollection<JsonPair>).Remove (item); + } + + public override bool ContainsKey (string key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + return map.ContainsKey (key); + } + + public void CopyTo (JsonPair [] array, int arrayIndex) + { + (map as ICollection<JsonPair>).CopyTo (array, arrayIndex); + } + + public bool Remove (string key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + return map.Remove (key); + } + + bool ICollection<JsonPair>.IsReadOnly { + get { return false; } + } + + public override void Save (Stream stream) + { + if (stream == null) + throw new ArgumentNullException ("stream"); + stream.WriteByte ((byte) '{'); + foreach (JsonPair pair in map) { + stream.WriteByte ((byte) '"'); + byte [] bytes = Encoding.UTF8.GetBytes (EscapeString (pair.Key)); + stream.Write (bytes, 0, bytes.Length); + stream.WriteByte ((byte) '"'); + stream.WriteByte ((byte) ','); + stream.WriteByte ((byte) ' '); + if (pair.Value == null) { + stream.WriteByte ((byte) 'n'); + stream.WriteByte ((byte) 'u'); + stream.WriteByte ((byte) 'l'); + stream.WriteByte ((byte) 'l'); + } else + pair.Value.Save (stream); + } + stream.WriteByte ((byte) '}'); + } + + public bool TryGetValue (string key, out JsonValue value) + { + return map.TryGetValue (key, out value); + } + } } diff --git a/mcs/class/System.Json/System.Json/JsonPrimitive.cs b/mcs/class/System.Json/System.Json/JsonPrimitive.cs index 6d5cc7c520f..64518785b87 100644 --- a/mcs/class/System.Json/System.Json/JsonPrimitive.cs +++ b/mcs/class/System.Json/System.Json/JsonPrimitive.cs @@ -1,1151 +1,172 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - +using System; +using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; using System.Globalization; -using System.Runtime.Serialization; +using System.IO; using System.Text; -using System.Xml; namespace System.Json { - /// <summary> - /// Represents a JavaScript Object Notation (JSON) primitive type in the common language runtime (CLR). - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "JsonPrimitive does not represent a collection.")] - [DataContract] - public sealed class JsonPrimitive : JsonValue - { - internal const string DateTimeIsoFormat = "yyyy-MM-ddTHH:mm:ss.fffK"; - private const string UtcString = "UTC"; - private const string GmtString = "GMT"; - private static readonly long UnixEpochTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; - private static readonly char[] FloatingPointChars = new char[] { '.', 'e', 'E' }; - private static readonly Type jsonPrimitiveType = typeof(JsonPrimitive); - private static readonly Type uriType = typeof(Uri); - - private static readonly Dictionary<Type, Func<string, ConvertResult>> stringConverters = new Dictionary<Type, Func<string, ConvertResult>> - { - { typeof(bool), new Func<string, ConvertResult>(StringToBool) }, - { typeof(byte), new Func<string, ConvertResult>(StringToByte) }, - { typeof(char), new Func<string, ConvertResult>(StringToChar) }, - { typeof(sbyte), new Func<string, ConvertResult>(StringToSByte) }, - { typeof(short), new Func<string, ConvertResult>(StringToShort) }, - { typeof(int), new Func<string, ConvertResult>(StringToInt) }, - { typeof(long), new Func<string, ConvertResult>(StringToLong) }, - { typeof(ushort), new Func<string, ConvertResult>(StringToUShort) }, - { typeof(uint), new Func<string, ConvertResult>(StringToUInt) }, - { typeof(ulong), new Func<string, ConvertResult>(StringToULong) }, - { typeof(float), new Func<string, ConvertResult>(StringToFloat) }, - { typeof(double), new Func<string, ConvertResult>(StringToDouble) }, - { typeof(decimal), new Func<string, ConvertResult>(StringToDecimal) }, - { typeof(DateTime), new Func<string, ConvertResult>(StringToDateTime) }, - { typeof(DateTimeOffset), new Func<string, ConvertResult>(StringToDateTimeOffset) }, - { typeof(Guid), new Func<string, ConvertResult>(StringToGuid) }, - { typeof(Uri), new Func<string, ConvertResult>(StringToUri) }, - }; - - [DataMember] - private object value; - - [DataMember] - private JsonType jsonType; - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Boolean"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Boolean"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Boolean"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Boolean"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Boolean"/>.</remarks> - public JsonPrimitive(bool value) - { - jsonType = JsonType.Boolean; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Byte"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Byte"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Byte"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Byte"/>.</remarks> - public JsonPrimitive(byte value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.SByte"/> type. - /// </summary> - /// <param name="value">The <see cref="System.SByte"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.SByte"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.SByte"/>.</remarks> - [CLSCompliant(false)] - public JsonPrimitive(sbyte value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Decimal"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Decimal"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Decimal"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Decimal"/>.</remarks> - public JsonPrimitive(decimal value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int16"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Int16"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Int16"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int16"/>.</remarks> - public JsonPrimitive(short value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt16"/> type. - /// </summary> - /// <param name="value">The <see cref="System.UInt16"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.UInt16"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt16"/>.</remarks> - [CLSCompliant(false)] - public JsonPrimitive(ushort value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int32"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Int32"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Int32"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int32"/>.</remarks> - public JsonPrimitive(int value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt32"/> type. - /// </summary> - /// <param name="value">The <see cref="System.UInt32"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.UInt32"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt32"/>.</remarks> - [CLSCompliant(false)] - public JsonPrimitive(uint value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int64"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Int64"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Int64"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int64"/>.</remarks> - public JsonPrimitive(long value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt64"/> type. - /// </summary> - /// <param name="value">The <see cref="System.UInt64"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.UInt64"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt64"/>.</remarks> - [CLSCompliant(false)] - public JsonPrimitive(ulong value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Single"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Single"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Single"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Single"/>.</remarks> - public JsonPrimitive(float value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Double"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Double"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Double"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Double"/>.</remarks> - public JsonPrimitive(double value) - { - jsonType = JsonType.Number; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.String"/> type. - /// </summary> - /// <param name="value">The <see cref="System.String"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.String"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.String"/>.</remarks> - /// <exception cref="System.ArgumentNullException">value is null.</exception> - [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", - Justification = "This operator does not intend to represent a Uri overload.")] - public JsonPrimitive(string value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - jsonType = JsonType.String; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Char"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Char"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Char"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Char"/>.</remarks> - public JsonPrimitive(char value) - { - jsonType = JsonType.String; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.DateTime"/> type. - /// </summary> - /// <param name="value">The <see cref="System.DateTime"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.DateTime"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.DateTime"/>.</remarks> - public JsonPrimitive(DateTime value) - { - jsonType = JsonType.String; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.DateTimeOffset"/> type. - /// </summary> - /// <param name="value">The <see cref="System.DateTimeOffset"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.DateTimeOffset"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.DateTimeOffset"/>.</remarks> - public JsonPrimitive(DateTimeOffset value) - { - jsonType = JsonType.String; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Uri"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Uri"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Uri"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Uri"/>.</remarks> - /// <exception cref="System.ArgumentNullException">value is null.</exception> - public JsonPrimitive(Uri value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - jsonType = JsonType.String; - this.value = value; - } - - /// <summary> - /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Guid"/> type. - /// </summary> - /// <param name="value">The <see cref="System.Guid"/> object that initializes the new instance.</param> - /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it. - /// When initialized with a <see cref="System.Guid"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be - /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/> - /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Guid"/>.</remarks> - public JsonPrimitive(Guid value) - { - jsonType = JsonType.String; - this.value = value; - } - - private JsonPrimitive(object value, JsonType type) - { - jsonType = type; - this.value = value; - } - - private enum ReadAsFailureKind - { - NoFailure, - InvalidCast, - InvalidDateFormat, - InvalidFormat, - InvalidUriFormat, - Overflow, - } - - /// <summary> - /// Gets the JsonType that is associated with this <see cref="System.Json.JsonPrimitive"/> object. - /// </summary> - public override JsonType JsonType - { - get { return jsonType; } - } + public class JsonPrimitive : JsonValue + { + object value; - /// <summary> - /// Gets the value represented by this instance. - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", - Justification = "Value in this context clearly refers to the underlying CLR value")] - public object Value - { - get { return value; } - } + public JsonPrimitive (bool value) + { + this.value = value; + } - /// <summary> - /// Attempts to create a <see cref="JsonPrimitive"/> instance from the specified <see cref="object"/> value. - /// </summary> - /// <param name="value">The <see cref="object"/> value to create the <see cref="JsonPrimitive"/> instance.</param> - /// <param name="result">The resulting <see cref="JsonPrimitive"/> instance on success, null otherwise.</param> - /// <returns>true if the operation is successful, false otherwise.</returns> - public static bool TryCreate(object value, out JsonPrimitive result) - { - bool allowedType = true; - JsonType jsonType = default(JsonType); + public JsonPrimitive (byte value) + { + this.value = value; + } - if (value != null) - { - Type type = value.GetType(); - switch (Type.GetTypeCode(type)) - { - case TypeCode.Boolean: - jsonType = JsonType.Boolean; - break; - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Decimal: - case TypeCode.Double: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - case TypeCode.Single: - jsonType = JsonType.Number; - break; - case TypeCode.String: - case TypeCode.Char: - case TypeCode.DateTime: - jsonType = JsonType.String; - break; - default: - if (type == typeof(Uri) || type == typeof(Guid) || type == typeof(DateTimeOffset)) - { - jsonType = JsonType.String; - } - else - { - allowedType = false; - } + public JsonPrimitive (char value) + { + this.value = value; + } - break; - } - } - else - { - allowedType = false; - } + public JsonPrimitive (decimal value) + { + this.value = value; + } - if (allowedType) - { - result = new JsonPrimitive(value, jsonType); - return true; - } - else - { - result = null; - return false; - } - } + public JsonPrimitive (double value) + { + this.value = value; + } - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonPrimitive"/> instance into an instance of the specified type. - /// </summary> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <returns>An object instance initialized with the <see cref="System.Json.JsonValue"/> value - /// specified if the conversion.</returns> - /// <exception cref="System.UriFormatException">If T is <see cref="System.Uri"/> and this value does - /// not represent a valid Uri.</exception> - /// <exception cref="OverflowException">If T is a numeric type, and a narrowing conversion would result - /// in a loss of data. For example, if this instance holds an <see cref="System.Int32"/> value of 10000, - /// and T is <see cref="System.Byte"/>, this operation would throw an <see cref="System.OverflowException"/> - /// because 10000 is outside the range of the <see cref="System.Byte"/> data type.</exception> - /// <exception cref="System.FormatException">If the conversion from the string representation of this - /// value into another fails because the string is not in the proper format.</exception> - /// <exception cref="System.InvalidCastException">If this instance cannot be read as type T.</exception> - public override object ReadAs(Type type) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } + public JsonPrimitive (float value) + { + this.value = value; + } - object result; - ReadAsFailureKind failure = TryReadAsInternal(type, out result); - if (failure == ReadAsFailureKind.NoFailure) - { - return result; - } - else - { - string valueStr = value.ToString(); - string typeOfTName = type.Name; - switch (failure) - { - case ReadAsFailureKind.InvalidFormat: - throw new FormatException(RS.Format(Properties.Resources.CannotReadPrimitiveAsType, valueStr, typeOfTName)); - case ReadAsFailureKind.InvalidDateFormat: - throw new FormatException(RS.Format(Properties.Resources.InvalidDateFormat, valueStr, typeOfTName)); - case ReadAsFailureKind.InvalidUriFormat: - throw new UriFormatException(RS.Format(Properties.Resources.InvalidUriFormat, jsonPrimitiveType.Name, valueStr, typeOfTName, uriType.Name)); - case ReadAsFailureKind.Overflow: - throw new OverflowException(RS.Format(Properties.Resources.OverflowReadAs, valueStr, typeOfTName)); - case ReadAsFailureKind.InvalidCast: - default: - throw new InvalidCastException(RS.Format(Properties.Resources.CannotReadPrimitiveAsType, valueStr, typeOfTName)); - } - } - } + public JsonPrimitive (int value) + { + this.value = value; + } - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonPrimitive"/> instance into an instance of the specified type. - /// </summary> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <param name="value">An object instance to be initialized with this instance or null if the conversion cannot be performed.</param> - /// <returns>true if this <see cref="System.Json.JsonPrimitive"/> instance can be read as the specified type; otherwise, false.</returns> - [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value", - Justification = "field is used with 'this' and arg is out param which makes it harder to be misused.")] - public override bool TryReadAs(Type type, out object value) - { - return TryReadAsInternal(type, out value) == ReadAsFailureKind.NoFailure; - } + public JsonPrimitive (long value) + { + this.value = value; + } - /// <summary> - /// Returns the value this object wraps (if any). - /// </summary> - /// <returns>The value wrapped by this instance or null if none.</returns> - internal override object Read() - { - return value; - } + public JsonPrimitive (sbyte value) + { + this.value = value; + } - internal override void Save(XmlDictionaryWriter jsonWriter) - { - if (value == null) - { - throw new ArgumentNullException("jsonWriter"); - } + public JsonPrimitive (short value) + { + this.value = value; + } - switch (jsonType) - { - case JsonType.Boolean: - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.BooleanAttributeValue); - break; - case JsonType.Number: - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NumberAttributeValue); - break; - default: - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.StringAttributeValue); - break; - } + public JsonPrimitive (string value) + { + this.value = value; + } - WriteValue(jsonWriter); - } + public JsonPrimitive (DateTime value) + { + this.value = value; + } - private static ConvertResult StringToBool(string valueString) - { - ConvertResult result = new ConvertResult(); - bool tempBool; - result.ReadAsFailureKind = Boolean.TryParse(valueString, out tempBool) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat; - result.Value = tempBool; - return result; - } + public JsonPrimitive (uint value) + { + this.value = value; + } - private static ConvertResult StringToByte(string valueString) - { - ConvertResult result = new ConvertResult(); - byte tempByte; - result.ReadAsFailureKind = Byte.TryParse(valueString, out tempByte) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<byte>(valueString, out tempByte); - } + public JsonPrimitive (ulong value) + { + this.value = value; + } - result.Value = tempByte; - return result; - } + public JsonPrimitive (ushort value) + { + this.value = value; + } - private static ConvertResult StringToChar(string valueString) - { - ConvertResult result = new ConvertResult(); - char tempChar; - result.ReadAsFailureKind = Char.TryParse(valueString, out tempChar) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat; - result.Value = tempChar; - return result; - } + public JsonPrimitive (DateTimeOffset value) + { + this.value = value; + } - private static ConvertResult StringToDecimal(string valueString) - { - ConvertResult result = new ConvertResult(); - decimal tempDecimal; - result.ReadAsFailureKind = Decimal.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempDecimal) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<decimal>(valueString, out tempDecimal); - } + public JsonPrimitive (Guid value) + { + this.value = value; + } - result.Value = tempDecimal; - return result; - } + public JsonPrimitive (TimeSpan value) + { + this.value = value; + } - private static ConvertResult StringToDateTime(string valueString) - { - ConvertResult result = new ConvertResult(); - DateTime tempDateTime; - result.ReadAsFailureKind = TryParseDateTime(valueString, out tempDateTime) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidDateFormat; - result.Value = tempDateTime; - return result; - } + public JsonPrimitive (Uri value) + { + this.value = value; + } - private static ConvertResult StringToDateTimeOffset(string valueString) - { - ConvertResult result = new ConvertResult(); - DateTimeOffset tempDateTimeOffset; - result.ReadAsFailureKind = TryParseDateTimeOffset(valueString, out tempDateTimeOffset) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidDateFormat; - result.Value = tempDateTimeOffset; - return result; - } + internal object Value { + get { return value; } + } - private static ConvertResult StringToDouble(string valueString) - { - ConvertResult result = new ConvertResult(); - double tempDouble; - result.ReadAsFailureKind = Double.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempDouble) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<double>(valueString, out tempDouble); - } + public override JsonType JsonType { + get { + // FIXME: what should we do for null? Handle it as null so far. + if (value == null) + return JsonType.String; + + switch (Type.GetTypeCode (value.GetType ())) { + case TypeCode.Boolean: + return JsonType.Boolean; + case TypeCode.Char: + case TypeCode.String: + case TypeCode.DateTime: + case TypeCode.Object: // DateTimeOffset || Guid || TimeSpan || Uri + return JsonType.String; + default: + return JsonType.Number; + } + } + } - result.Value = tempDouble; - return result; - } + static readonly byte [] true_bytes = Encoding.UTF8.GetBytes ("true"); + static readonly byte [] false_bytes = Encoding.UTF8.GetBytes ("false"); + + public override void Save (Stream stream) + { + switch (JsonType) { + case JsonType.Boolean: + if ((bool) value) + stream.Write (true_bytes, 0, 4); + else + stream.Write (false_bytes, 0, 5); + break; + case JsonType.String: + stream.WriteByte ((byte) '\"'); + byte [] bytes = Encoding.UTF8.GetBytes (EscapeString (value.ToString ())); + stream.Write (bytes, 0, bytes.Length); + stream.WriteByte ((byte) '\"'); + break; + default: + bytes = Encoding.UTF8.GetBytes (GetFormattedString ()); + stream.Write (bytes, 0, bytes.Length); + break; + } + } - private static bool TryGuidParse (string value, out Guid guid) - { -#if NET_4_0 - return Guid.TryParse (value, out guid); -#else - try { - guid = new Guid (value); - return true; - } catch (Exception) { - guid = Guid.Empty; - return false; + internal string GetFormattedString () + { + switch (JsonType) { + case JsonType.String: + if (value is string || value == null) + return (string) value; + throw new NotImplementedException ("GetFormattedString from value type " + value.GetType ()); + case JsonType.Number: + return ((IFormattable) value).ToString ("G", NumberFormatInfo.InvariantInfo); + default: + throw new InvalidOperationException (); + } } -#endif } - - private static ConvertResult StringToGuid(string valueString) - { - ConvertResult result = new ConvertResult(); - Guid tempGuid; - result.ReadAsFailureKind = TryGuidParse(valueString, out tempGuid) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat; - result.Value = tempGuid; - return result; - } - - private static ConvertResult StringToShort(string valueString) - { - ConvertResult result = new ConvertResult(); - short tempShort; - result.ReadAsFailureKind = Int16.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempShort) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<short>(valueString, out tempShort); - } - - result.Value = tempShort; - return result; - } - - private static ConvertResult StringToInt(string valueString) - { - ConvertResult result = new ConvertResult(); - int tempInt; - result.ReadAsFailureKind = Int32.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempInt) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<int>(valueString, out tempInt); - } - - result.Value = tempInt; - return result; - } - - private static ConvertResult StringToLong(string valueString) - { - ConvertResult result = new ConvertResult(); - long tempLong; - result.ReadAsFailureKind = Int64.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempLong) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<long>(valueString, out tempLong); - } - - result.Value = tempLong; - return result; - } - - private static ConvertResult StringToSByte(string valueString) - { - ConvertResult result = new ConvertResult(); - sbyte tempSByte; - result.ReadAsFailureKind = SByte.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempSByte) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<sbyte>(valueString, out tempSByte); - } - - result.Value = tempSByte; - return result; - } - - private static ConvertResult StringToFloat(string valueString) - { - ConvertResult result = new ConvertResult(); - float tempFloat; - result.ReadAsFailureKind = Single.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempFloat) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<float>(valueString, out tempFloat); - } - - result.Value = tempFloat; - return result; - } - - private static ConvertResult StringToUShort(string valueString) - { - ConvertResult result = new ConvertResult(); - ushort tempUShort; - result.ReadAsFailureKind = UInt16.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempUShort) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<ushort>(valueString, out tempUShort); - } - - result.Value = tempUShort; - return result; - } - - private static ConvertResult StringToUInt(string valueString) - { - ConvertResult result = new ConvertResult(); - uint tempUInt; - result.ReadAsFailureKind = UInt32.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempUInt) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<uint>(valueString, out tempUInt); - } - - result.Value = tempUInt; - return result; - } - - private static ConvertResult StringToULong(string valueString) - { - ConvertResult result = new ConvertResult(); - ulong tempULong; - result.ReadAsFailureKind = UInt64.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempULong) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast; - if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure) - { - result.ReadAsFailureKind = StringToNumberConverter<ulong>(valueString, out tempULong); - } - - result.Value = tempULong; - return result; - } - - private static ConvertResult StringToUri(string valueString) - { - ConvertResult result = new ConvertResult(); - Uri tempUri; - result.ReadAsFailureKind = Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out tempUri) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidUriFormat; - result.Value = tempUri; - return result; - } - - private static ReadAsFailureKind StringToNumberConverter<T>(string valueString, out T valueNumber) - { - string str = valueString.Trim(); - - if (str.IndexOfAny(FloatingPointChars) < 0) - { - long longVal; - if (Int64.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out longVal)) - { - return NumberToNumberConverter<T>(longVal, out valueNumber); - } - } - - decimal decValue; - if (Decimal.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out decValue) && decValue != 0) - { - return NumberToNumberConverter<T>(decValue, out valueNumber); - } - - double dblValue; - if (Double.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out dblValue)) - { - return NumberToNumberConverter<T>(dblValue, out valueNumber); - } - - valueNumber = default(T); - return ReadAsFailureKind.InvalidFormat; - } - - private static ReadAsFailureKind NumberToNumberConverter<T>(object valueObject, out T valueNumber) - { - object value; - ReadAsFailureKind failureKind = NumberToNumberConverter(typeof(T), valueObject, out value); - if (failureKind == ReadAsFailureKind.NoFailure) - { - valueNumber = (T)value; - } - else - { - valueNumber = default(T); - } - - return failureKind; - } - - private static ReadAsFailureKind NumberToNumberConverter(Type type, object valueObject, out object valueNumber) - { - try - { - valueNumber = System.Convert.ChangeType(valueObject, type, CultureInfo.InvariantCulture); - return ReadAsFailureKind.NoFailure; - } - catch (OverflowException) - { - valueNumber = null; - return ReadAsFailureKind.Overflow; - } - } - - private static bool TryParseDateTime(string valueString, out DateTime dateTime) - { - string filteredValue = valueString.EndsWith(UtcString, StringComparison.Ordinal) ? valueString.Replace(UtcString, GmtString) : valueString; - - if (DateTime.TryParse(filteredValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime)) - { - return true; - } - - if (TryParseAspNetDateTimeFormat(valueString, out dateTime)) - { - return true; - } - - return false; - } - - private static bool TryParseDateTimeOffset(string valueString, out DateTimeOffset dateTimeOffset) - { - string filteredValue = valueString.EndsWith(UtcString, StringComparison.Ordinal) ? valueString.Replace(UtcString, GmtString) : valueString; - - if (DateTimeOffset.TryParse(filteredValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset)) - { - return true; - } - - if (TryParseAspNetDateTimeFormat(valueString, out dateTimeOffset)) - { - return true; - } - - return false; - } - - private static bool TryParseAspNetDateTimeFormat(string valueString, out DateTime dateTime) - { - // Reference to the format is available at these sources: - // http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_sidebarb - // http://msdn.microsoft.com/en-us/library/bb412170.aspx - - // The format for the value is given by the following regex: - // \/Date\((?<milliseconds>\-?\d+)(?<offset>[\+\-]?\d{4})\)\/ - // where milliseconds is the number of milliseconds since 1970/01/01:00:00:00.000 UTC (the "unix baseline") - // and offset is an optional which indicates whether the value is local or UTC. - // The actual value of the offset is ignored, since the ticks represent the UTC offset. The value is converted to local time based on that info. - const string DateTimePrefix = "/Date("; - const int DateTimePrefixLength = 6; - const string DateTimeSuffix = ")/"; - const int DateTimeSuffixLength = 2; - - if (valueString.StartsWith(DateTimePrefix, StringComparison.Ordinal) && valueString.EndsWith(DateTimeSuffix, StringComparison.Ordinal)) - { - string ticksValue = valueString.Substring(DateTimePrefixLength, valueString.Length - DateTimePrefixLength - DateTimeSuffixLength); - DateTimeKind dateTimeKind = DateTimeKind.Utc; - - int indexOfTimeZoneOffset = ticksValue.IndexOf('+', 1); - - if (indexOfTimeZoneOffset < 0) - { - indexOfTimeZoneOffset = ticksValue.IndexOf('-', 1); - } - - // If an offset is present, verify it is properly formatted. Actual value is ignored (see spec). - if (indexOfTimeZoneOffset != -1) - { - if (indexOfTimeZoneOffset + 5 == ticksValue.Length - && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 1]) - && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 2]) - && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 3]) - && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 4])) - { - ticksValue = ticksValue.Substring(0, indexOfTimeZoneOffset); - dateTimeKind = DateTimeKind.Local; - } - else - { - dateTime = new DateTime(); - return false; - } - } - - long millisecondsSinceUnixEpoch; - if (Int64.TryParse(ticksValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out millisecondsSinceUnixEpoch)) - { - long ticks = (millisecondsSinceUnixEpoch * 10000) + UnixEpochTicks; - if (ticks < DateTime.MaxValue.Ticks) - { - dateTime = new DateTime(ticks, DateTimeKind.Utc); - if (dateTimeKind == DateTimeKind.Local) - { - dateTime = dateTime.ToLocalTime(); - } - - return true; - } - } - } - - dateTime = new DateTime(); - return false; - } - - private static bool TryParseAspNetDateTimeFormat(string valueString, out DateTimeOffset dateTimeOffset) - { - DateTime dateTime; - if (TryParseAspNetDateTimeFormat(valueString, out dateTime)) - { - dateTimeOffset = new DateTimeOffset(dateTime); - return true; - } - - dateTimeOffset = new DateTimeOffset(); - return false; - } - - private static bool IsLatinDigit(char c) - { - return (c >= '0') && (c <= '9'); - } - - private static string UnescapeJsonString(string val) - { - if (val == null) - { - return null; - } - - StringBuilder sb = null; - int startIndex = 0, count = 0; - for (int i = 0; i < val.Length; i++) - { - if (val[i] == '\\') - { - i++; - if (sb == null) - { - sb = new StringBuilder(); - } - - sb.Append(val, startIndex, count); -#if NET_4_0 - Contract.Assert(i < val.Length, "Found that a '\' was the last character in a string, which is invalid JSON. Verify the calling method uses a valid JSON string as the input parameter of this method."); -#endif - switch (val[i]) - { - case '"': - case '\'': - case '/': - case '\\': - sb.Append(val[i]); - break; - case 'b': - sb.Append('\b'); - break; - case 'f': - sb.Append('\f'); - break; - case 'n': - sb.Append('\n'); - break; - case 'r': - sb.Append('\r'); - break; - case 't': - sb.Append('\t'); - break; - case 'u': -#if NET_4_0 - Contract.Assert((i + 3) < val.Length, String.Format(CultureInfo.CurrentCulture, "Unexpected char {0} at position {1}. The unicode escape sequence should be followed by 4 digits.", val[i], i)); -#endif - sb.Append(ParseChar(val.Substring(i + 1, 4), NumberStyles.HexNumber)); - i += 4; - break; - } - - startIndex = i + 1; - count = 0; - } - else - { - count++; - } - } - - if (sb == null) - { - return val; - } - - if (count > 0) - { - sb.Append(val, startIndex, count); - } - - return sb.ToString(); - } - - private static char ParseChar(string value, NumberStyles style) - { - try - { - int intValue = Int32.Parse(value, style, NumberFormatInfo.InvariantInfo); - return System.Convert.ToChar(intValue); - } - catch (ArgumentException exception) - { - throw new InvalidCastException(exception.Message, exception); - } - catch (FormatException exception) - { - throw new InvalidCastException(exception.Message, exception); - } - catch (OverflowException exception) - { - throw new InvalidCastException(exception.Message, exception); - } - } - - [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value", - Justification = "field is used with 'this' and arg is out param which makes it harder to be misused.")] - private ReadAsFailureKind TryReadAsInternal(Type type, out object value) - { - if (base.TryReadAs(type, out value)) - { - return ReadAsFailureKind.NoFailure; - } - - if (type == this.value.GetType()) - { - value = this.value; - return ReadAsFailureKind.NoFailure; - } - - if (jsonType == JsonType.Number) - { - switch (Type.GetTypeCode(type)) - { - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - return NumberToNumberConverter(type, this.value, out value); - case TypeCode.String: - value = ToString(); - return ReadAsFailureKind.NoFailure; - } - } - - if (jsonType == JsonType.Boolean) - { - if (type == typeof(string)) - { - value = ToString(); - return ReadAsFailureKind.NoFailure; - } - } - - if (jsonType == JsonType.String) - { - string str = UnescapeJsonString(ToString()); -#if NET_4_0 - Contract.Assert(str.Length >= 2 && str.StartsWith("\"", StringComparison.Ordinal) && str.EndsWith("\"", StringComparison.Ordinal), "The unescaped string must begin and end with quotes."); -#endif - str = str.Substring(1, str.Length - 2); - - if (stringConverters.ContainsKey(type)) - { - ConvertResult result = stringConverters[type].Invoke(str); - value = result.Value; - return result.ReadAsFailureKind; - } - - if (type == typeof(string)) - { - value = str; - return ReadAsFailureKind.NoFailure; - } - } - - value = null; - return ReadAsFailureKind.InvalidCast; - } - - private void WriteValue(XmlDictionaryWriter jsonWriter) - { - Type valueType = value.GetType(); - switch (Type.GetTypeCode(valueType)) - { - case TypeCode.Boolean: - jsonWriter.WriteValue((bool)value); - break; - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - case TypeCode.Decimal: - jsonWriter.WriteValue(String.Format(CultureInfo.InvariantCulture, "{0}", value)); - break; - case TypeCode.Single: - case TypeCode.Double: - jsonWriter.WriteValue(String.Format(CultureInfo.InvariantCulture, "{0:R}", value)); - break; - case TypeCode.Char: - jsonWriter.WriteValue(new string((char)value, 1)); - break; - case TypeCode.String: - jsonWriter.WriteValue((string)value); - break; - case TypeCode.DateTime: - jsonWriter.WriteValue(((DateTime)value).ToString(DateTimeIsoFormat, CultureInfo.InvariantCulture)); - break; - default: - if (valueType == typeof(Uri)) - { - Uri uri = (Uri)value; - jsonWriter.WriteValue(uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped)); - } - else if (valueType == typeof(DateTimeOffset)) - { - jsonWriter.WriteValue(((DateTimeOffset)value).ToString(DateTimeIsoFormat, CultureInfo.InvariantCulture)); - } - else - { - jsonWriter.WriteValue(value); - } - - break; - } - } - - private class ConvertResult - { - public ReadAsFailureKind ReadAsFailureKind { get; set; } - - public object Value { get; set; } - } - } } diff --git a/mcs/class/System.Json/System.Json/JsonType.cs b/mcs/class/System.Json/System.Json/JsonType.cs index 785026c32d7..c04f5746c13 100644 --- a/mcs/class/System.Json/System.Json/JsonType.cs +++ b/mcs/class/System.Json/System.Json/JsonType.cs @@ -1,50 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - namespace System.Json { - /// <summary> - /// An enumeration that specifies primitive and structured JavaScript Object - /// Notation (JSON) common language runtime (CLR) types. - /// </summary> - public enum JsonType - { - /// <summary> - /// Specifies the JSON string CLR type. - /// </summary> - String, - - /// <summary> - /// Specifies the JSON number CLR type. - /// </summary> - Number, - - /// <summary> - /// Specifies the JSON object CLR type that consists of an unordered collection - /// of key/value pairs, where the key is of type String and the value is of - /// type <see cref="System.Json.JsonValue"/>, which can, in turn, be either a - /// primitive or a structured JSON type. - /// </summary> - Object, - - /// <summary> - /// Specifies the JSON array CLR type that consists of an ordered collection of - /// <see cref="System.Json.JsonValue"/>types, which can, in turn, be either - /// primitive or structured JSON types. - /// </summary> - Array, - - /// <summary> - /// Specifies the JSON Boolean CLR type. - /// </summary> - Boolean, - - /// <summary> - /// Specifies the type returned by calls to <see cref="System.Json.JsonValue.ValueOrDefault(string)"/> - /// or <see cref="System.Json.JsonValue.ValueOrDefault(int)"/> - /// when the element searches doesn't exist in the JSON collection. This is a special - /// value which does not represent any JSON element, and cannot be added to any - /// JSON collections. - /// </summary> - Default - } + public enum JsonType + { + String, + Number, + Object, + Array, + Boolean, + } } diff --git a/mcs/class/System.Json/System.Json/JsonValue.cs b/mcs/class/System.Json/System.Json/JsonValue.cs index 97dbae5517e..1d16b88e3f4 100644 --- a/mcs/class/System.Json/System.Json/JsonValue.cs +++ b/mcs/class/System.Json/System.Json/JsonValue.cs @@ -1,1249 +1,460 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - +using System; using System.Collections; using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -#if FEATURE_DYNAMIC -using System.Dynamic; -#endif -using System.Globalization; using System.IO; -using System.Linq.Expressions; -using System.Runtime.Serialization; +using System.Linq; using System.Runtime.Serialization.Json; using System.Text; -using System.Xml; - -namespace System.Json -{ - /// <summary> - /// This is the base class for JavaScript Object Notation (JSON) common language runtime (CLR) types. - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "JsonValue is by definition either a collection or a single object.")] - [DataContract] -#if FEATURE_DYNAMIC - public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>>, IDynamicMetaObjectProvider -#else - public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>> -#endif - { - private static JsonValue defaultInstance = new JsonValue(); - private int changingListenersCount; - private int changedListenersCount; - - internal JsonValue() - { - } - - /// <summary> - /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members have changed. - /// </summary> - /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/> - /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/> - /// and <see cref="System.Json.JsonObject"/>.</p> - /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events, - /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while - /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When - /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is - /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the - /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the - /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks> - public event EventHandler<JsonValueChangeEventArgs> Changed - { - add - { - changedListenersCount++; - OnChanged += value; - } - - remove - { - changedListenersCount--; - OnChanged -= value; - } - } - - /// <summary> - /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members are about to be changed. - /// </summary> - /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/> - /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/> - /// and <see cref="System.Json.JsonObject"/>.</p> - /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events, - /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while - /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When - /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is - /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the - /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the - /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks> - public event EventHandler<JsonValueChangeEventArgs> Changing - { - add - { - changingListenersCount++; - OnChanging += value; - } - - remove - { - changingListenersCount--; - OnChanging -= value; - } - } - - private event EventHandler<JsonValueChangeEventArgs> OnChanged; - private event EventHandler<JsonValueChangeEventArgs> OnChanging; - - /// <summary> - /// Gets the JSON CLR type represented by this instance. - /// </summary> - public virtual JsonType JsonType - { - get { return JsonType.Default; } - } - - /// <summary> - /// Gets the number of items in this object. - /// </summary> - public virtual int Count - { - get { return 0; } - } - - /// <summary> - /// Gets the number of listeners to the <see cref="Changing"/> event for this instance. - /// </summary> - protected int ChangingListenersCount - { - get { return changingListenersCount; } - } - - /// <summary> - /// Gets the number of listeners to the <see cref="Changed"/> event for this instance. - /// </summary> - protected int ChangedListenersCount - { - get { return changedListenersCount; } - } - - /// <summary> - /// Gets the default JsonValue instance. - /// This instance enables safe-chaining of JsonValue operations and resolves to 'null' - /// when this instance is used as dynamic, mapping to the JavaScript 'null' value. - /// </summary> - private static JsonValue DefaultInstance - { - get { return defaultInstance; } - } - - /// <summary> - /// This indexer is not supported for this base class and throws an exception. - /// </summary> - /// <param name="key">The key of the element to get or set.</param> - /// <returns><see cref="System.Json.JsonValue"/>.</returns> - /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>. - /// This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/> - /// class, which inherits from this class.</remarks> - public virtual JsonValue this[string key] - { - get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } - - set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); } - } - - /// <summary> - /// This indexer is not supported for this base class and throws an exception. - /// </summary> - /// <param name="index">The zero-based index of the element to get or set.</param> - /// <returns><see cref="System.Json.JsonValue"/>.</returns> - /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>. - /// This method is overloaded in the implementation of the <see cref="System.Json.JsonArray"/> - /// class, which inherits from this class.</remarks> - public virtual JsonValue this[int index] - { - get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } - - set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); } - } - - /// <summary> - /// Deserializes text-based JSON into a JSON CLR type. - /// </summary> - /// <param name="json">The text-based JSON to be parsed into a JSON CLR type.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed - /// text-based JSON as a CLR type.</returns> - /// <exception cref="System.ArgumentException">The length of jsonString is zero.</exception> - /// <exception cref="System.ArgumentNullException">jsonString is null.</exception> - /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, - /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, - /// depending on the text-based JSON supplied to the method.</remarks> - public static JsonValue Parse(string json) - { - return JXmlToJsonValueConverter.JXMLToJsonValue(json); - } - - /// <summary> - /// Deserializes text-based JSON from a text reader into a JSON CLR type. - /// </summary> - /// <param name="textReader">A <see cref="System.IO.TextReader"/> over text-based JSON content.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed - /// text-based JSON as a CLR type.</returns> - /// <exception cref="System.ArgumentNullException">textReader is null.</exception> - /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, - /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, - /// depending on the text-based JSON supplied to the method.</remarks> - public static JsonValue Load(TextReader textReader) - { - if (textReader == null) - { - throw new ArgumentNullException("textReader"); - } - - return JsonValue.Parse(textReader.ReadToEnd()); - } - - /// <summary> - /// Deserializes text-based JSON from a stream into a JSON CLR type. - /// </summary> - /// <param name="stream">A <see cref="System.IO.Stream"/> that contains text-based JSON content.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed - /// text-based JSON as a CLR type.</returns> - /// <exception cref="System.ArgumentNullException">stream is null.</exception> - /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>, - /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>, - /// depending on the text-based JSON supplied to the method.</remarks> - public static JsonValue Load(Stream stream) - { - return JXmlToJsonValueConverter.JXMLToJsonValue(stream); - } - - /// <summary> - /// Performs a cast operation from a <see cref="JsonValue"/> instance into the specified type parameter./> - /// </summary> - /// <typeparam name="T">The type to cast the instance to.</typeparam> - /// <param name="value">The <see cref="System.Json.JsonValue"/> instance.</param> - /// <returns>An object of type T initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - /// <remarks>This method is to support the framework and is not intended to be used externally, use explicit type cast instead.</remarks> - [EditorBrowsable(EditorBrowsableState.Never)] - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "The generic parameter is used to specify the output type")] - public static T CastValue<T>(JsonValue value) - { - Type typeofT = typeof(T); - - if ((value != null && typeofT.IsAssignableFrom(value.GetType())) || typeofT == typeof(object)) - { - return (T)(object)value; - } - - if (value == null || value.JsonType == JsonType.Default) - { - if (typeofT.IsValueType) - { - throw new InvalidCastException(RS.Format(Properties.Resources.InvalidCastNonNullable, typeofT.FullName)); - } - else - { - return default(T); - } - } - - try - { - return value.ReadAs<T>(); - } - catch (Exception ex) - { - if (ex is FormatException || ex is NotSupportedException || ex is InvalidCastException) - { - throw new InvalidCastException(RS.Format(Properties.Resources.CannotCastJsonValue, value.GetType().FullName, typeofT.FullName), ex); - } - - throw; - } - } - - /// <summary> - /// Returns an enumerator which iterates through the values in this object. - /// </summary> - /// <returns>An enumerator which which iterates through the values in this object.</returns> - /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks> - public IEnumerator<KeyValuePair<string, JsonValue>> GetEnumerator() - { - return GetKeyValuePairEnumerator(); - } - - /// <summary> - /// Returns an enumerator which iterates through the values in this object. - /// </summary> - /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns> - /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks> - IEnumerator IEnumerable.GetEnumerator() - { - return GetKeyValuePairEnumerator(); - } - -#if FEATURE_DYNAMIC - /// <summary> - /// Gets this instance as a <code>dynamic</code> object. - /// </summary> - /// <returns>This instance as <code>dynamic</code>.</returns> - public dynamic AsDynamic() - { - return this; - } -#endif - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <param name="valueOfT">An instance of T initialized with this instance, or the default value of T if the conversion cannot be performed.</param> - /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as type T; otherwise, false.</returns> - public bool TryReadAs<T>(out T valueOfT) - { - object value; - if (TryReadAs(typeof(T), out value)) - { - valueOfT = (T)value; - return true; - } - - valueOfT = default(T); - return false; - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <returns>An instance of T initialized with the value from the conversion of this instance.</returns> - /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception> - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", - Justification = "The generic parameter is used to specify the output type")] - public T ReadAs<T>() - { - return (T)ReadAs(typeof(T)); - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T. - /// </summary> - /// <typeparam name="T">The type to which the conversion is being performed.</typeparam> - /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param> - /// <returns>An instance of T initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns> - public T ReadAs<T>(T fallback) - { - return (T)ReadAs(typeof(T), fallback); - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance to an instance of the specified type. - /// </summary> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param> - /// <returns>An instance of the specified type initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns> - public object ReadAs(Type type, object fallback) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - object result; - if (JsonType != JsonType.Default && TryReadAs(type, out result)) - { - return result; - } - else - { - return fallback; - } - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. - /// </summary> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <returns>An instance of the specified type initialized with the value from the conversion of this instance.</returns> - /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception> - public virtual object ReadAs(Type type) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - object result; - if (TryReadAs(type, out result)) - { - return result; - } - - throw new NotSupportedException(RS.Format(Properties.Resources.CannotReadAsType, GetType().FullName, type.FullName)); - } - - /// <summary> - /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type. - /// </summary> - /// <param name="type">The type to which the conversion is being performed.</param> - /// <param name="value">An object to be initialized with this instance or null if the conversion cannot be performed.</param> - /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as the specified type; otherwise, false.</returns> - [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", - Justification = "This is the non-generic version of the method.")] - public virtual bool TryReadAs(Type type, out object value) - { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - if (type.IsAssignableFrom(GetType()) || type == typeof(object)) - { - value = this; - return true; - } - - value = null; - return false; - } - - /// <summary> - /// Writes this <see cref="System.Json.JsonValue"/> instance to a <see cref="System.IO.Stream"/>. - /// </summary> - /// <param name="stream">Stream to which to write text-based JSON.</param> - public void Save(Stream stream) - { - if (JsonType == JsonType.Default) - { - throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); - } - - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - - using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false)) - { - jsonWriter.WriteStartElement(JXmlToJsonValueConverter.RootElementName); - Save(jsonWriter); - jsonWriter.WriteEndElement(); - } - } - - /// <summary> - /// Writes <see cref="System.Json.JsonValue"/> instance to a <see cref="TextWriter"/>. - /// </summary> - /// <param name="textWriter">The <see cref="System.IO.TextWriter"/> used to write text-based JSON.</param> - public void Save(TextWriter textWriter) - { - if (JsonType == JsonType.Default) - { - throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed); - } - - if (textWriter == null) - { - throw new ArgumentNullException("textWriter"); - } - - using (MemoryStream ms = new MemoryStream()) - { - Save(ms); - ms.Position = 0; - textWriter.Write(new StreamReader(ms).ReadToEnd()); - } - } - - /// <summary> - /// Provides a textual representation of this <see cref="System.Json.JsonValue"/> instance. - /// </summary> - /// <returns>A <see cref="System.String"/> containing text-based JSON.</returns> - public override string ToString() - { - if (JsonType == JsonType.Default) - { - return "Default"; - } - - using (MemoryStream ms = new MemoryStream()) - { - Save(ms); - ms.Position = 0; - return new StreamReader(ms).ReadToEnd(); - } - } - - /// <summary> - /// Checks whether a key/value pair with a specified key exists in the JSON CLR object type. - /// </summary> - /// <param name="key">The key to check for.</param> - /// <returns>false in this class; subclasses may override this method to return other values.</returns> - /// <remarks>This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/> - /// class, which inherits from this class.</remarks> - public virtual bool ContainsKey(string key) - { - return false; - } - - /// <summary> - /// Returns the value returned by the safe string indexer for this instance. - /// </summary> - /// <param name="key">The key of the element to get.</param> - /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains - /// the given key and the value corresponding to the key is not null, then it will return that value. - /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - [EditorBrowsable(EditorBrowsableState.Never)] - public virtual JsonValue GetValue(string key) - { - return ValueOrDefault(key); - } - - /// <summary> - /// Returns the value returned by the safe int indexer for this instance. - /// </summary> - /// <param name="index">The zero-based index of the element to get.</param> - /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array - /// bounds, and the value corresponding to the index is not null, then it will return that value. - /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - [EditorBrowsable(EditorBrowsableState.Never)] - public virtual JsonValue GetValue(int index) - { - return ValueOrDefault(index); - } - - /// <summary> - /// Sets the value and returns it. - /// </summary> - /// <param name="key">The key of the element to set.</param> - /// <param name="value">The value to be set.</param> - /// <returns>The value, converted into a JsonValue, set in this collection.</returns> - /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception> - [EditorBrowsable(EditorBrowsableState.Never)] - public virtual JsonValue SetValue(string key, object value) - { - this[key] = ResolveObject(value); - return this[key]; - } - - /// <summary> - /// Sets the value and returns it. - /// </summary> - /// <param name="index">The zero-based index of the element to set.</param> - /// <param name="value">The value to be set.</param> - /// <returns>The value, converted into a JsonValue, set in this collection.</returns> - /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception> - [EditorBrowsable(EditorBrowsableState.Never)] - public virtual JsonValue SetValue(int index, object value) - { - this[index] = ResolveObject(value); - return this[index]; - } - - /// <summary> - /// Safe string indexer for the <see cref="System.Json.JsonValue"/> type. - /// </summary> - /// <param name="key">The key of the element to get.</param> - /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains - /// the given key and the value corresponding to the key is not null, then it will return that value. - /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - public virtual JsonValue ValueOrDefault(string key) - { - return JsonValue.DefaultInstance; - } - - /// <summary> - /// Safe indexer for the <see cref="System.Json.JsonValue"/> type. - /// </summary> - /// <param name="index">The zero-based index of the element to get.</param> - /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array - /// bounds, and the value corresponding to the index is not null, then it will return that value. - /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/> - /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns> - public virtual JsonValue ValueOrDefault(int index) - { - return JsonValue.DefaultInstance; - } - - /// <summary> - /// Safe deep indexer for the <see cref="JsonValue"/> type. - /// </summary> - /// <param name="indexes">The indices to index this type. The indices can be - /// of type <see cref="System.Int32"/> or <see cref="System.String"/>.</param> - /// <returns>A <see cref="JsonValue"/> which is equivalent to calling<see cref="ValueOrDefault(int)"/> or - /// <see cref="ValueOrDefault(string)"/> on the first index, then calling it again on the result - /// for the second index and so on.</returns> - /// <exception cref="System.ArgumentException">If any of the indices is not of type - /// <see cref="System.Int32"/> or <see cref="System.String"/>.</exception> - public JsonValue ValueOrDefault(params object[] indexes) - { - if (indexes == null) - { - return JsonValue.DefaultInstance; - } - - if (indexes.Length == 0) - { - return this; - } - - JsonValue result = this; - for (int i = 0; i < indexes.Length; i++) - { - object index = indexes[i]; - if (index == null) - { - result = JsonValue.DefaultInstance; - continue; - } - - Type indexType = index.GetType(); - - switch (Type.GetTypeCode(indexType)) - { - case TypeCode.Char: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Byte: - case TypeCode.SByte: - index = System.Convert.ChangeType(index, typeof(int), CultureInfo.InvariantCulture); - goto case TypeCode.Int32; - - case TypeCode.Int32: - result = result.ValueOrDefault((int)index); - break; - - case TypeCode.String: - result = result.ValueOrDefault((string)index); - break; - - default: - throw new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, index.GetType()), "indexes"); - } - } - return result; - } +using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>; -#if FEATURE_DYNAMIC - [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", - Justification = "Cannot make this class sealed, it needs to have subclasses. But its subclasses are sealed themselves.")] - DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) - { - if (parameter == null) - { - throw new ArgumentNullException("parameter"); - } - return new JsonValueDynamicMetaObject(parameter, this); - } -#endif - - /// <summary> - /// Resolves the specified object to an appropriate JsonValue instance. - /// </summary> - /// <param name="value">The object to resolve.</param> - /// <returns>A <see cref="JsonValue"/> instance resolved from the specified object.</returns> - internal static JsonValue ResolveObject(object value) - { - JsonPrimitive primitive; - - if (value == null) - { - return null; - } - - JsonValue jsonValue = value as JsonValue; - - if (jsonValue != null) - { - return jsonValue; - } - - if (JsonPrimitive.TryCreate(value, out primitive)) - { - return primitive; - } - - throw new ArgumentException(Properties.Resources.TypeNotSupported, "value"); - } - - /// <summary> - /// Determines whether an explicit cast to JsonValue is provided from the specified type. - /// </summary> - /// <param name="type">The type to check.</param> - /// <returns>true if an explicit cast exists for the specified type, false otherwise.</returns> - internal static bool IsSupportedExplicitCastType(Type type) - { - TypeCode typeCode = Type.GetTypeCode(type); - - switch (typeCode) - { - case TypeCode.Boolean: - case TypeCode.Byte: - case TypeCode.Char: - case TypeCode.DateTime: - case TypeCode.Decimal: - case TypeCode.Double: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.Single: - case TypeCode.String: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - return true; - - default: - return type == typeof(DateTimeOffset) || type == typeof(Guid) || type == typeof(Uri) || - type == typeof(List<object>) || type == typeof(Array) || type == typeof(object[]) || - type == typeof(Dictionary<string, object>); - } - } - - /// <summary> - /// Returns the value this object wraps (if any). - /// </summary> - /// <returns>The value wrapped by this instance or null if none.</returns> - internal virtual object Read() - { - return null; - } - - /// <summary> - /// Serializes this object into the specified <see cref="XmlDictionaryWriter"/> instance. - /// </summary> - /// <param name="jsonWriter">An <see cref="XmlDictionaryWriter"/> instance to serialize this instance into.</param> - internal virtual void Save(XmlDictionaryWriter jsonWriter) - { - if (jsonWriter == null) - { - throw new ArgumentNullException("jsonWriter"); - } - - Stack<JsonValue> objectStack = new Stack<JsonValue>(); - Stack<int> indexStack = new Stack<int>(); - int currentIndex = 0; - JsonValue currentValue = this; - - OnSaveStarted(); - - WriteAttributeString(jsonWriter); - - while (currentIndex < currentValue.Count || objectStack.Count > 0) - { - if (currentValue.Count > currentIndex) - { - JsonValue nextValue = currentValue.WriteStartElementAndGetNext(jsonWriter, currentIndex); - - if (JsonValue.IsJsonCollection(nextValue)) - { - nextValue.OnSaveStarted(); - nextValue.WriteAttributeString(jsonWriter); - - objectStack.Push(currentValue); - indexStack.Push(currentIndex); - currentValue = nextValue; - currentIndex = 0; - } - else - { - if (nextValue == null) - { - jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NullAttributeValue); - } - else - { - nextValue.Save(jsonWriter); - } - - currentIndex++; - jsonWriter.WriteEndElement(); - } - } - else - { - if (objectStack.Count > 0) - { - currentValue.OnSaveEnded(); - jsonWriter.WriteEndElement(); - - currentValue = objectStack.Pop(); - currentIndex = indexStack.Pop() + 1; - } - } - } - - OnSaveEnded(); - } - - /// <summary> - /// Returns an enumerator which iterates through the values in this object. - /// </summary> - /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns> - /// <remarks>This method is the virtual version of the IEnumerator.GetEnumerator method and is provided to allow derived classes to implement the - /// appropriate version of the generic interface (enumerator of values or key/value pairs).</remarks> - [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", - Justification = "This method is a virtual version of the IEnumerable.GetEnumerator method.")] - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "This class is a collection that is properly represented by the nested generic type.")] - protected virtual IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator() - { - yield break; - } - - /// <summary> - /// Callback method called during Save operations to let the instance write the start element - /// and return the next element in the collection. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - /// <param name="index">The index within this collection.</param> - /// <returns>The next item in the collection, or null of there are no more items.</returns> - internal virtual JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int index) - { - return null; - } - - /// <summary> - /// Callback method called to let an instance write the proper JXML attribute when saving this - /// instance. - /// </summary> - /// <param name="jsonWriter">The JXML writer used to write JSON.</param> - internal virtual void WriteAttributeString(XmlDictionaryWriter jsonWriter) - { - } - - /// <summary> - /// Callback method called when a Save operation is starting for this instance. - /// </summary> - protected virtual void OnSaveStarted() - { - } - - /// <summary> - /// Callback method called when a Save operation is finished for this instance. - /// </summary> - protected virtual void OnSaveEnded() - { - } - - /// <summary> - /// Called internally to raise the <see cref="Changing"/> event. - /// </summary> - /// <param name="sender">The object which caused the event to be raised.</param> - /// <param name="eventArgs">The arguments to the event.</param> - [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", - Justification = "This is a helper function used to raise the event.")] - [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", - Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] - protected void RaiseChangingEvent(object sender, JsonValueChangeEventArgs eventArgs) - { - EventHandler<JsonValueChangeEventArgs> changing = OnChanging; - if (changing != null) - { - changing(sender, eventArgs); - } - } - - /// <summary> - /// Called internally to raise the <see cref="Changed"/> event. - /// </summary> - /// <param name="sender">The object which caused the event to be raised.</param> - /// <param name="eventArgs">The arguments to the event.</param> - [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", - Justification = "This is a helper function used to raise the event.")] - [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", - Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")] - protected void RaiseChangedEvent(object sender, JsonValueChangeEventArgs eventArgs) - { - EventHandler<JsonValueChangeEventArgs> changed = OnChanged; - if (changed != null) - { - changed(sender, eventArgs); - } - } - - private static bool IsJsonCollection(JsonValue value) - { - return value != null && (value.JsonType == JsonType.Array || value.JsonType == JsonType.Object); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.String"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.String"/> object.</param> - /// <returns>The <see cref="System.String"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns> - public static explicit operator string(JsonValue value) - { - return CastValue<string>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Double"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Double"/> object.</param> - /// <returns>The <see cref="System.Double"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator double(JsonValue value) - { - return CastValue<double>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Single"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Single"/> object.</param> - /// <returns>The <see cref="System.Single"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator float(JsonValue value) - { - return CastValue<float>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Decimal"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Decimal"/> object.</param> - /// <returns>The <see cref="System.Decimal"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator decimal(JsonValue value) - { - return CastValue<decimal>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int64"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int64"/> object.</param> - /// <returns>The <see cref="System.Int64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator long(JsonValue value) - { - return CastValue<long>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt64"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt64"/> object.</param> - /// <returns>The <see cref="System.UInt64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - [CLSCompliant(false)] - public static explicit operator ulong(JsonValue value) - { - return CastValue<ulong>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int32"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int32"/> object.</param> - /// <returns>The <see cref="System.Int32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator int(JsonValue value) - { - return CastValue<int>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt32"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt32"/> object.</param> - /// <returns>The <see cref="System.UInt32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - [CLSCompliant(false)] - public static explicit operator uint(JsonValue value) - { - return CastValue<uint>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int16"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int16"/> object.</param> - /// <returns>The <see cref="System.Int16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator short(JsonValue value) - { - return CastValue<short>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt16"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt16"/> object.</param> - /// <returns>The <see cref="System.UInt16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - [CLSCompliant(false)] - public static explicit operator ushort(JsonValue value) - { - return CastValue<ushort>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.SByte"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.SByte"/> object.</param> - /// <returns>The <see cref="System.SByte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - [CLSCompliant(false)] - public static explicit operator sbyte(JsonValue value) - { - return CastValue<sbyte>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Byte"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Byte"/> object.</param> - /// <returns>The <see cref="System.Byte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator byte(JsonValue value) - { - return CastValue<byte>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Uri"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Uri"/> object.</param> - /// <returns>The <see cref="System.Uri"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns> - public static explicit operator Uri(JsonValue value) - { - return CastValue<Uri>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Guid"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Guid"/> object.</param> - /// <returns>The <see cref="System.Guid"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator Guid(JsonValue value) - { - return CastValue<Guid>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTime"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTime"/> object.</param> - /// <returns>The <see cref="System.DateTime"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator DateTime(JsonValue value) - { - return CastValue<DateTime>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Char"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Char"/> object.</param> - /// <returns>The <see cref="System.Char"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator char(JsonValue value) - { - return CastValue<char>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Boolean"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Boolean"/> object.</param> - /// <returns>The <see cref="System.Boolean"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator bool(JsonValue value) - { - return CastValue<bool>(value); - } - - /// <summary> - /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTimeOffset"/> object. - /// </summary> - /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTimeOffset"/> object.</param> - /// <returns>The <see cref="System.DateTimeOffset"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns> - public static explicit operator DateTimeOffset(JsonValue value) - { - return CastValue<DateTimeOffset>(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Boolean"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Boolean"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Boolean"/> specified.</returns> - public static implicit operator JsonValue(bool value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Byte"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Byte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Byte"/> specified.</returns> - public static implicit operator JsonValue(byte value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Decimal"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Decimal"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Decimal"/> specified.</returns> - public static implicit operator JsonValue(decimal value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Double"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Double"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Double"/> specified.</returns> - public static implicit operator JsonValue(double value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Int16"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Int16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int16"/> specified.</returns> - public static implicit operator JsonValue(short value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Int32"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Int32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int32"/> specified.</returns> - public static implicit operator JsonValue(int value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Int64"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Int64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int64"/> specified.</returns> - public static implicit operator JsonValue(long value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Single"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Single"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Single"/> specified.</returns> - public static implicit operator JsonValue(float value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.String"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.String"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.String"/> specified, or null if the value is null.</returns> - [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", - Justification = "This operator does not intend to represent a Uri overload.")] - public static implicit operator JsonValue(string value) - { - return value == null ? null : new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Char"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Char"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Char"/> specified.</returns> - public static implicit operator JsonValue(char value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.DateTime"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.DateTime"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTime"/> specified.</returns> - public static implicit operator JsonValue(DateTime value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Guid"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Guid"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Guid"/> specified.</returns> - public static implicit operator JsonValue(Guid value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.Uri"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.Uri"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Uri"/> specified, or null if the value is null.</returns> - public static implicit operator JsonValue(Uri value) - { - return value == null ? null : new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.SByte"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.SByte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.SByte"/> specified.</returns> - [CLSCompliant(false)] - public static implicit operator JsonValue(sbyte value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.UInt16"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.UInt16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt16"/> specified.</returns> - [CLSCompliant(false)] - public static implicit operator JsonValue(ushort value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.UInt32"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.UInt32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt32"/> specified.</returns> - [CLSCompliant(false)] - public static implicit operator JsonValue(uint value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.UInt64"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.UInt64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt64"/> specified.</returns> - [CLSCompliant(false)] - public static implicit operator JsonValue(ulong value) - { - return new JsonPrimitive(value); - } - - /// <summary> - /// Enables implicit casts from type <see cref="System.DateTimeOffset"/> to a <see cref="System.Json.JsonPrimitive"/>. - /// </summary> - /// <param name="value">The <see cref="System.DateTimeOffset"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param> - /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTimeOffset"/> specified.</returns> - public static implicit operator JsonValue(DateTimeOffset value) - { - return new JsonPrimitive(value); - } - } +namespace System.Json +{ + public abstract class JsonValue : IEnumerable + { + public static JsonValue Load (Stream stream) + { + if (stream == null) + throw new ArgumentNullException ("stream"); + return Load (new StreamReader (stream, true)); + } + + public static JsonValue Load (TextReader textReader) + { + if (textReader == null) + throw new ArgumentNullException ("textReader"); + + var ret = new JavaScriptReader (textReader, true).Read (); + + return ToJsonValue (ret); + } + + static IEnumerable<KeyValuePair<string,JsonValue>> ToJsonPairEnumerable (IEnumerable<KeyValuePair<string,object>> kvpc) + { + foreach (var kvp in kvpc) + yield return new KeyValuePair<string,JsonValue> (kvp.Key, ToJsonValue (kvp.Value)); + } + + static IEnumerable<JsonValue> ToJsonValueEnumerable (IEnumerable<object> arr) + { + foreach (var obj in arr) + yield return ToJsonValue (obj); + } + + static JsonValue ToJsonValue (object ret) + { + if (ret == null) + return null; + var kvpc = ret as IEnumerable<KeyValuePair<string,object>>; + if (kvpc != null) + return new JsonObject (ToJsonPairEnumerable (kvpc)); + var arr = ret as IEnumerable<object>; + if (arr != null) + return new JsonArray (ToJsonValueEnumerable (arr)); + + if (ret is bool) + return new JsonPrimitive ((bool) ret); + if (ret is byte) + return new JsonPrimitive ((byte) ret); + if (ret is char) + return new JsonPrimitive ((char) ret); + if (ret is decimal) + return new JsonPrimitive ((decimal) ret); + if (ret is double) + return new JsonPrimitive ((double) ret); + if (ret is float) + return new JsonPrimitive ((float) ret); + if (ret is int) + return new JsonPrimitive ((int) ret); + if (ret is long) + return new JsonPrimitive ((long) ret); + if (ret is sbyte) + return new JsonPrimitive ((sbyte) ret); + if (ret is short) + return new JsonPrimitive ((short) ret); + if (ret is string) + return new JsonPrimitive ((string) ret); + if (ret is uint) + return new JsonPrimitive ((uint) ret); + if (ret is ulong) + return new JsonPrimitive ((ulong) ret); + if (ret is ushort) + return new JsonPrimitive ((ushort) ret); + if (ret is DateTime) + return new JsonPrimitive ((DateTime) ret); + if (ret is DateTimeOffset) + return new JsonPrimitive ((DateTimeOffset) ret); + if (ret is Guid) + return new JsonPrimitive ((Guid) ret); + if (ret is TimeSpan) + return new JsonPrimitive ((TimeSpan) ret); + if (ret is Uri) + return new JsonPrimitive ((Uri) ret); + throw new NotSupportedException (String.Format ("Unexpected parser return type: {0}", ret.GetType ())); + } + + public static JsonValue Parse (string jsonString) + { + if (jsonString == null) + throw new ArgumentNullException ("jsonString"); + return Load (new StringReader (jsonString)); + } + + public virtual int Count { + get { throw new InvalidOperationException (); } + } + + public abstract JsonType JsonType { get; } + + public virtual JsonValue this [int index] { + get { throw new InvalidOperationException (); } + set { throw new InvalidOperationException (); } + } + + public virtual JsonValue this [string key] { + get { throw new InvalidOperationException (); } + set { throw new InvalidOperationException (); } + } + + public virtual bool ContainsKey (string key) + { + throw new InvalidOperationException (); + } + + public virtual void Save (Stream stream) + { + if (stream == null) + throw new ArgumentNullException ("stream"); + Save (new StreamWriter (stream)); + } + + public virtual void Save (TextWriter textWriter) + { + if (textWriter == null) + throw new ArgumentNullException ("textWriter"); + SaveInternal (textWriter); + } + + void SaveInternal (TextWriter w) + { + switch (JsonType) { + case JsonType.Object: + w.Write ('{'); + bool following = false; + foreach (JsonPair pair in ((JsonObject) this)) { + if (following) + w.Write (", "); + w.Write ('\"'); + w.Write (EscapeString (pair.Key)); + w.Write ("\": "); + if (pair.Value == null) + w.Write ("null"); + else + pair.Value.SaveInternal (w); + following = true; + } + w.Write ('}'); + break; + case JsonType.Array: + w.Write ('['); + following = false; + foreach (JsonValue v in ((JsonArray) this)) { + if (following) + w.Write (", "); + if (v != null) + v.SaveInternal (w); + else + w.Write ("null"); + following = true; + } + w.Write (']'); + break; + case JsonType.Boolean: + w.Write ((bool) this ? "true" : "false"); + break; + case JsonType.String: + w.Write ('"'); + w.Write (EscapeString (((JsonPrimitive) this).GetFormattedString ())); + w.Write ('"'); + break; + default: + w.Write (((JsonPrimitive) this).GetFormattedString ()); + break; + } + } + + public override string ToString () + { + StringWriter sw = new StringWriter (); + Save (sw); + return sw.ToString (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + throw new InvalidOperationException (); + } + + internal string EscapeString (string src) + { + if (src == null) + return null; + + for (int i = 0; i < src.Length; i++) + if (src [i] == '"' || src [i] == '\\') { + var sb = new StringBuilder (); + if (i > 0) + sb.Append (src, 0, i); + return DoEscapeString (sb, src, i); + } + return src; + } + + string DoEscapeString (StringBuilder sb, string src, int cur) + { + int start = cur; + for (int i = cur; i < src.Length; i++) + if (src [i] == '"' || src [i] == '\\') { + sb.Append (src, start, i - start); + sb.Append ('\\'); + sb.Append (src [i++]); + start = i; + } + sb.Append (src, start, src.Length - start); + return sb.ToString (); + } + + // CLI -> JsonValue + + public static implicit operator JsonValue (bool value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (byte value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (char value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (decimal value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (double value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (float value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (int value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (long value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (sbyte value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (short value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (string value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (uint value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (ulong value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (ushort value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (DateTime value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (DateTimeOffset value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (Guid value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (TimeSpan value) + { + return new JsonPrimitive (value); + } + + public static implicit operator JsonValue (Uri value) + { + return new JsonPrimitive (value); + } + + // JsonValue -> CLI + + public static implicit operator bool (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToBoolean (((JsonPrimitive) value).Value); + } + + public static implicit operator byte (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToByte (((JsonPrimitive) value).Value); + } + + public static implicit operator char (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToChar (((JsonPrimitive) value).Value); + } + + public static implicit operator decimal (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToDecimal (((JsonPrimitive) value).Value); + } + + public static implicit operator double (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToDouble (((JsonPrimitive) value).Value); + } + + public static implicit operator float (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToSingle (((JsonPrimitive) value).Value); + } + + public static implicit operator int (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToInt32 (((JsonPrimitive) value).Value); + } + + public static implicit operator long (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToInt64 (((JsonPrimitive) value).Value); + } + + public static implicit operator sbyte (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToSByte (((JsonPrimitive) value).Value); + } + + public static implicit operator short (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToInt16 (((JsonPrimitive) value).Value); + } + + public static implicit operator string (JsonValue value) + { + if (value == null) + return null; + return (string) ((JsonPrimitive) value).Value; + } + + public static implicit operator uint (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToUInt16 (((JsonPrimitive) value).Value); + } + + public static implicit operator ulong (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToUInt64(((JsonPrimitive) value).Value); + } + + public static implicit operator ushort (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return Convert.ToUInt16 (((JsonPrimitive) value).Value); + } + + public static implicit operator DateTime (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return (DateTime) ((JsonPrimitive) value).Value; + } + + public static implicit operator DateTimeOffset (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return (DateTimeOffset) ((JsonPrimitive) value).Value; + } + + public static implicit operator TimeSpan (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return (TimeSpan) ((JsonPrimitive) value).Value; + } + + public static implicit operator Guid (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return (Guid) ((JsonPrimitive) value).Value; + } + + public static implicit operator Uri (JsonValue value) + { + if (value == null) + throw new ArgumentNullException ("value"); + return (Uri) ((JsonPrimitive) value).Value; + } + } } diff --git a/mcs/class/System.Json/System.Json/JsonValueChange.cs b/mcs/class/System.Json/System.Json/JsonValueChange.cs deleted file mode 100644 index 2182e622c77..00000000000 --- a/mcs/class/System.Json/System.Json/JsonValueChange.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -namespace System.Json -{ - /// <summary> - /// Specifies the event type when an event is raised for a <see cref="System.Json.JsonValue"/>. - /// </summary> - public enum JsonValueChange - { - /// <summary> - /// An element has been or will be added to the collection. - /// </summary> - Add, - - /// <summary> - /// An element has been or will be removed from the collection. - /// </summary> - Remove, - - /// <summary> - /// An element has been or will be replaced in the collection. Used on indexers. - /// </summary> - Replace, - - /// <summary> - /// All elements of the collection have been or will be removed. - /// </summary> - Clear, - } -} diff --git a/mcs/class/System.Json/System.Json/JsonValueChangeEventArgs.cs b/mcs/class/System.Json/System.Json/JsonValueChangeEventArgs.cs deleted file mode 100644 index cf7097b2047..00000000000 --- a/mcs/class/System.Json/System.Json/JsonValueChangeEventArgs.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -namespace System.Json -{ - /// <summary> - /// Provide data for the <see cref="System.Json.JsonValue.Changing"/> and <see cref="System.Json.JsonValue.Changed"/> events. - /// </summary> - public class JsonValueChangeEventArgs : EventArgs - { - private JsonValue child; - private JsonValueChange change; - private int index; - private string key; - - /// <summary> - /// Initializes a new instance of the <see cref="System.Json.JsonValueChangeEventArgs"/> class for - /// changes in a <see cref="System.Json.JsonArray"/>. - /// </summary> - /// <param name="child">The <see cref="System.Json.JsonValue"/> instance which will be or has been modified.</param> - /// <param name="change">The type of change of the <see cref="System.Json.JsonValue"/> event.</param> - /// <param name="index">The index of the element being changed in a <see cref="System.Json.JsonArray"/>.</param> - public JsonValueChangeEventArgs(JsonValue child, JsonValueChange change, int index) - { - if (index < 0) - { - throw new ArgumentOutOfRangeException("index", RS.Format(Properties.Resources.ArgumentMustBeGreaterThanOrEqualTo, index, 0)); - } - - this.child = child; - this.change = change; - this.index = index; - } - - /// <summary> - /// Initializes a new instance of the <see cref="System.Json.JsonValueChangeEventArgs"/> class for - /// changes in a <see cref="System.Json.JsonObject"/>. - /// </summary> - /// <param name="child">The <see cref="System.Json.JsonValue"/> instance which will be or has been modified.</param> - /// <param name="change">The type of change of the <see cref="System.Json.JsonValue"/> event.</param> - /// <param name="key">The key of the element being changed in a <see cref="System.Json.JsonObject"/>.</param> - public JsonValueChangeEventArgs(JsonValue child, JsonValueChange change, string key) - { - if (change != JsonValueChange.Clear) - { - if (key == null) - { - throw new ArgumentNullException("key"); - } - } - - this.child = child; - this.change = change; - index = -1; - this.key = key; - } - - /// <summary> - /// Gets the child which will be or has been modified. - /// </summary> - /// <remarks><p>This property is <code>null</code> for <see cref="System.Json.JsonValueChange.Clear"/> event types - /// raised by <see cref="System.Json.JsonValue"/> instances.</p> - /// <p>For <see cref="System.Json.JsonValueChange">Replace</see> events, this property contains the new value in - /// the <see cref="System.Json.JsonValue.Changing"/> event, and the old value (the one being replaced) in the - /// <see cref="System.Json.JsonValue.Changed"/> event.</p></remarks> - public JsonValue Child - { - get { return child; } - } - - /// <summary> - /// Gets the type of change. - /// </summary> - public JsonValueChange Change - { - get { return change; } - } - - /// <summary> - /// Gets the index in the <see cref="System.Json.JsonArray"/> where the change happened, or - /// <code>-1</code> if the change happened in a <see cref="System.Json.JsonValue"/> of a different type. - /// </summary> - public int Index - { - get { return index; } - } - - /// <summary> - /// Gets the key in the <see cref="System.Json.JsonObject"/> where the change happened, or - /// <code>null</code> if the change happened in a <see cref="System.Json.JsonValue"/> of a different type. - /// </summary> - /// <remarks>This property can also be <code>null</code> if the event type is - /// <see cref="System.Json.JsonValueChange">Clear</see>.</remarks> - public string Key - { - get { return key; } - } - } -} diff --git a/mcs/class/System.Json/System.Json/JsonValueDynamicMetaObject.cs b/mcs/class/System.Json/System.Json/JsonValueDynamicMetaObject.cs deleted file mode 100644 index f38f98fc4f2..00000000000 --- a/mcs/class/System.Json/System.Json/JsonValueDynamicMetaObject.cs +++ /dev/null @@ -1,384 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. -#if FEATURE_DYNAMIC -using System.Collections.Generic; -using System.Dynamic; -using System.Linq.Expressions; -using System.Reflection; -using System.Runtime.Serialization.Json; - -namespace System.Json -{ - /// <summary> - /// This class provides dynamic behavior support for the JsonValue types. - /// </summary> - internal class JsonValueDynamicMetaObject : DynamicMetaObject - { - private static readonly MethodInfo _getValueByIndexMethodInfo = typeof(JsonValue).GetMethod("GetValue", new Type[] { typeof(int) }); - private static readonly MethodInfo _getValueByKeyMethodInfo = typeof(JsonValue).GetMethod("GetValue", new Type[] { typeof(string) }); - private static readonly MethodInfo _setValueByIndexMethodInfo = typeof(JsonValue).GetMethod("SetValue", new Type[] { typeof(int), typeof(object) }); - private static readonly MethodInfo _setValueByKeyMethodInfo = typeof(JsonValue).GetMethod("SetValue", new Type[] { typeof(string), typeof(object) }); - private static readonly MethodInfo _castValueMethodInfo = typeof(JsonValue).GetMethod("CastValue", new Type[] { typeof(JsonValue) }); - private static readonly MethodInfo _changeTypeMethodInfo = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) }); - - /// <summary> - /// Class constructor. - /// </summary> - /// <param name="parameter">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param> - /// <param name="value">The runtime value represented by the <see cref="DynamicMetaObject"/>.</param> - internal JsonValueDynamicMetaObject(Expression parameter, JsonValue value) - : base(parameter, BindingRestrictions.Empty, value) - { - } - - /// <summary> - /// Gets the default binding restrictions for this type. - /// </summary> - private BindingRestrictions DefaultRestrictions - { - get { return BindingRestrictions.GetTypeRestriction(Expression, LimitType); } - } - - /// <summary> - /// Implements dynamic cast for JsonValue types. - /// </summary> - /// <param name="binder">An instance of the <see cref="ConvertBinder"/> that represents the details of the dynamic operation.</param> - /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns> - public override DynamicMetaObject BindConvert(ConvertBinder binder) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - Expression expression = Expression; - - bool implicitCastSupported = - binder.Type.IsAssignableFrom(LimitType) || - binder.Type == typeof(IEnumerable<KeyValuePair<string, JsonValue>>) || - binder.Type == typeof(IDynamicMetaObjectProvider) || - binder.Type == typeof(object); - - if (!implicitCastSupported) - { - if (JsonValue.IsSupportedExplicitCastType(binder.Type)) - { - Expression instance = Expression.Convert(Expression, LimitType); - expression = Expression.Call(_castValueMethodInfo.MakeGenericMethod(binder.Type), new Expression[] { instance }); - } - else - { - string exceptionMessage = RS.Format(Properties.Resources.CannotCastJsonValue, LimitType.FullName, binder.Type.FullName); - expression = Expression.Throw(Expression.Constant(new InvalidCastException(exceptionMessage)), typeof(object)); - } - } - - expression = Expression.Convert(expression, binder.Type); - - return new DynamicMetaObject(expression, DefaultRestrictions); - } - - /// <summary> - /// Implements setter for dynamic indexer by index (JsonArray) - /// </summary> - /// <param name="binder">An instance of the <see cref="GetIndexBinder"/> that represents the details of the dynamic operation.</param> - /// <param name="indexes">An array of <see cref="DynamicMetaObject"/> instances - indexes for the get index operation.</param> - /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns> - public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - if (indexes == null) - { - throw new ArgumentNullException("indexes"); - } - - Expression indexExpression; - if (!JsonValueDynamicMetaObject.TryGetIndexExpression(indexes, out indexExpression)) - { - return new DynamicMetaObject(indexExpression, DefaultRestrictions); - } - - MethodInfo methodInfo = indexExpression.Type == typeof(string) ? _getValueByKeyMethodInfo : _getValueByIndexMethodInfo; - Expression[] args = new Expression[] { indexExpression }; - - return GetMethodMetaObject(methodInfo, args); - } - - /// <summary> - /// Implements getter for dynamic indexer by index (JsonArray). - /// </summary> - /// <param name="binder">An instance of the <see cref="SetIndexBinder"/> that represents the details of the dynamic operation.</param> - /// <param name="indexes">An array of <see cref="DynamicMetaObject"/> instances - indexes for the set index operation.</param> - /// <param name="value">The <see cref="DynamicMetaObject"/> representing the value for the set index operation.</param> - /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns> - public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - if (indexes == null) - { - throw new ArgumentNullException("indexes"); - } - - if (value == null) - { - throw new ArgumentNullException("value"); - } - - Expression indexExpression; - if (!JsonValueDynamicMetaObject.TryGetIndexExpression(indexes, out indexExpression)) - { - return new DynamicMetaObject(indexExpression, DefaultRestrictions); - } - - MethodInfo methodInfo = indexExpression.Type == typeof(string) ? _setValueByKeyMethodInfo : _setValueByIndexMethodInfo; - Expression[] args = new Expression[] { indexExpression, Expression.Convert(value.Expression, typeof(object)) }; - - return GetMethodMetaObject(methodInfo, args); - } - - /// <summary> - /// Implements getter for dynamic indexer by key (JsonObject). - /// </summary> - /// <param name="binder">An instance of the <see cref="GetMemberBinder"/> that represents the details of the dynamic operation.</param> - /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns> - public override DynamicMetaObject BindGetMember(GetMemberBinder binder) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - PropertyInfo propInfo = LimitType.GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public); - - if (propInfo != null) - { - return base.BindGetMember(binder); - } - - Expression[] args = new Expression[] { Expression.Constant(binder.Name) }; - - return GetMethodMetaObject(_getValueByKeyMethodInfo, args); - } - - /// <summary> - /// Implements setter for dynamic indexer by key (JsonObject). - /// </summary> - /// <param name="binder">An instance of the <see cref="SetMemberBinder"/> that represents the details of the dynamic operation.</param> - /// <param name="value">The <see cref="DynamicMetaObject"/> representing the value for the set member operation.</param> - /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns> - public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - if (value == null) - { - throw new ArgumentNullException("value"); - } - - Expression[] args = new Expression[] { Expression.Constant(binder.Name), Expression.Convert(value.Expression, typeof(object)) }; - - return GetMethodMetaObject(_setValueByKeyMethodInfo, args); - } - - /// <summary> - /// Performs the binding of the dynamic invoke member operation. - /// Implemented to support extension methods defined in <see cref="JsonValueExtensions"/> type. - /// </summary> - /// <param name="binder">An instance of the InvokeMemberBinder that represents the details of the dynamic operation.</param> - /// <param name="args">An array of DynamicMetaObject instances - arguments to the invoke member operation.</param> - /// <returns>The new DynamicMetaObject representing the result of the binding.</returns> - public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) - { - if (binder == null) - { - throw new ArgumentNullException("binder"); - } - - if (args == null) - { - throw new ArgumentNullException("args"); - } - - List<Type> argTypeList = new List<Type>(); - - for (int idx = 0; idx < args.Length; idx++) - { - argTypeList.Add(args[idx].LimitType); - } - - MethodInfo methodInfo = Value.GetType().GetMethod(binder.Name, argTypeList.ToArray()); - - if (methodInfo == null) - { - argTypeList.Insert(0, typeof(JsonValue)); - - Type[] argTypes = argTypeList.ToArray(); - - methodInfo = JsonValueDynamicMetaObject.GetExtensionMethod(typeof(JsonValueExtensions), binder.Name, argTypes); - - if (methodInfo != null) - { - Expression thisInstance = Expression.Convert(Expression, LimitType); - Expression[] argsExpression = new Expression[argTypes.Length]; - - argsExpression[0] = thisInstance; - for (int i = 0; i < args.Length; i++) - { - argsExpression[i + 1] = args[i].Expression; - } - - Expression callExpression = Expression.Call(methodInfo, argsExpression); - - if (methodInfo.ReturnType == typeof(void)) - { - callExpression = Expression.Block(callExpression, Expression.Default(binder.ReturnType)); - } - else - { - callExpression = Expression.Convert(Expression.Call(methodInfo, argsExpression), binder.ReturnType); - } - - return new DynamicMetaObject(callExpression, DefaultRestrictions); - } - } - - return base.BindInvokeMember(binder, args); - } - - /// <summary> - /// Returns the enumeration of all dynamic member names. - /// </summary> - /// <returns>An <see cref="IEnumerable{T}"/> of string reprenseting the dynamic member names.</returns> - public override IEnumerable<string> GetDynamicMemberNames() - { - JsonValue jsonValue = Value as JsonValue; - - if (jsonValue != null) - { - List<string> names = new List<string>(); - - foreach (KeyValuePair<string, JsonValue> pair in jsonValue) - { - names.Add(pair.Key); - } - - return names; - } - - return base.GetDynamicMemberNames(); - } - - /// <summary> - /// Gets a <see cref="MethodInfo"/> instance for the specified method name in the specified type. - /// </summary> - /// <param name="extensionProviderType">The extension provider type.</param> - /// <param name="methodName">The name of the method to get the info for.</param> - /// <param name="argTypes">The types of the method arguments.</param> - /// <returns>A <see cref="MethodInfo"/>instance or null if the method cannot be resolved.</returns> - private static MethodInfo GetExtensionMethod(Type extensionProviderType, string methodName, Type[] argTypes) - { - MethodInfo methodInfo = null; - MethodInfo[] methods = extensionProviderType.GetMethods(); - - foreach (MethodInfo info in methods) - { - if (info.Name == methodName) - { - methodInfo = info; - - if (!info.IsGenericMethodDefinition) - { - bool paramsMatch = true; - ParameterInfo[] args = methodInfo.GetParameters(); - - if (args.Length == argTypes.Length) - { - for (int idx = 0; idx < args.Length; idx++) - { - if (!args[idx].ParameterType.IsAssignableFrom(argTypes[idx])) - { - paramsMatch = false; - break; - } - } - - if (paramsMatch) - { - break; - } - } - } - } - } - - return methodInfo; - } - - /// <summary> - /// Attempts to get an expression for an index parameter. - /// </summary> - /// <param name="indexes">The operation indexes parameter.</param> - /// <param name="expression">A <see cref="Expression"/> to be initialized to the index expression if the operation is successful, otherwise an error expression.</param> - /// <returns>true the operation is successful, false otherwise.</returns> - private static bool TryGetIndexExpression(DynamicMetaObject[] indexes, out Expression expression) - { - if (indexes.Length == 1 && indexes[0] != null && indexes[0].Value != null) - { - DynamicMetaObject index = indexes[0]; - Type indexType = indexes[0].Value.GetType(); - - switch (Type.GetTypeCode(indexType)) - { - case TypeCode.Char: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Byte: - case TypeCode.SByte: - Expression argExp = Expression.Convert(index.Expression, typeof(object)); - Expression typeExp = Expression.Constant(typeof(int)); - expression = Expression.Convert(Expression.Call(_changeTypeMethodInfo, new Expression[] { argExp, typeExp }), typeof(int)); - return true; - - case TypeCode.Int32: - case TypeCode.String: - expression = index.Expression; - return true; - } - - expression = Expression.Throw(Expression.Constant(new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, indexType))), typeof(object)); - return false; - } - - expression = Expression.Throw(Expression.Constant(new ArgumentException(Properties.Resources.NonSingleNonNullIndexNotSupported)), typeof(object)); - return false; - } - - /// <summary> - /// Gets a <see cref="DynamicMetaObject"/> for a method call. - /// </summary> - /// <param name="methodInfo">Info for the method to be performed.</param> - /// <param name="args">expression array representing the method arguments</param> - /// <returns>A meta object for the method call.</returns> - private DynamicMetaObject GetMethodMetaObject(MethodInfo methodInfo, Expression[] args) - { - Expression instance = Expression.Convert(Expression, LimitType); - Expression methodCall = Expression.Call(instance, methodInfo, args); - BindingRestrictions restrictions = DefaultRestrictions; - - DynamicMetaObject metaObj = new DynamicMetaObject(methodCall, restrictions); - - return metaObj; - } - } -} -#endif diff --git a/mcs/class/System.Json/System.Json/JsonValueLinqExtensions.cs b/mcs/class/System.Json/System.Json/JsonValueLinqExtensions.cs deleted file mode 100644 index 5516a037371..00000000000 --- a/mcs/class/System.Json/System.Json/JsonValueLinqExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; - -namespace System.Json -{ - /// <summary> - /// This class extends the funcionality of the <see cref="JsonValue"/> type for better Linq support . - /// </summary> - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Linq is a technical name.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public static class JsonValueLinqExtensions - { - /// <summary> - /// Extension method for creating a <see cref="JsonValue"/> from an <see cref="IEnumerable{T}"/> collection of <see cref="JsonValue"/> types. - /// </summary> - /// <param name="items">The enumerable instance.</param> - /// <returns>A <see cref="JsonArray"/> created from the specified items.</returns> - public static JsonArray ToJsonArray(this IEnumerable<JsonValue> items) - { - return new JsonArray(items); - } - - /// <summary> - /// Extension method for creating a <see cref="JsonValue"/> from an <see cref="IEnumerable{T}"/> collection of <see cref="KeyValuePair{K,V}"/> of <see cref="String"/> and <see cref="JsonValue"/> types. - /// </summary> - /// <param name="items">The enumerable instance.</param> - /// <returns>A <see cref="JsonValue"/> created from the specified items.</returns> - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "JsonValue implements the nested type in param.")] - public static JsonObject ToJsonObject(this IEnumerable<KeyValuePair<string, JsonValue>> items) - { - return new JsonObject(items); - } - } -} diff --git a/mcs/class/System.Json/System.Json/NGenWrapper.cs b/mcs/class/System.Json/System.Json/NGenWrapper.cs deleted file mode 100644 index 4a9e7b5c2a3..00000000000 --- a/mcs/class/System.Json/System.Json/NGenWrapper.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -namespace System.Json -{ - /// <summary> - /// Struct that wraps values which cause JIT compilation at runtime. - /// This Struct is added to solve the FxCop warning CA908 in JsonObject.cs. - /// </summary> - /// <typeparam name="T">Wrapped type.</typeparam> - internal struct NGenWrapper<T> - { - /// <summary> - /// Value of type T which represents the actual data which is currently in hold. - /// </summary> - public T Value; - - /// <summary> - /// Creates an instance of the <see cref="System.Json.NGenWrapper{T}"/> class - /// </summary> - /// <param name="value">The wrapped object of T</param> - public NGenWrapper(T value) - { - Value = value; - } - - /// <summary> - /// Cast operator from <see cref="System.Json.NGenWrapper{T}"/> to <typeparamref name="T"/> - /// </summary> - /// <param name="value">Object in type <see cref="System.Json.NGenWrapper{T}"/></param> - /// <returns>Object in type <typeparamref name="T">The wrapped element type</typeparamref></returns> - /// <typeparamref name="T">The wrapped element type</typeparamref> - public static implicit operator T(NGenWrapper<T> value) - { - return value.Value; - } - - /// <summary> - /// Cast operator from <typeparamref name="T"/> to <see cref="System.Json.NGenWrapper{T}"/> - /// </summary> - /// <param name="value">Object in type <typeparamref name="T"/></param> - /// <returns>Object in type <see cref="System.Json.NGenWrapper{T}"/></returns> - /// <typeparamref name="T">The wrapped element type</typeparamref> - public static implicit operator NGenWrapper<T>(T value) - { - return new NGenWrapper<T>(value); - } - } -} diff --git a/mcs/class/System.Json/System.Json/Properties/AssemblyInfo.cs b/mcs/class/System.Json/System.Json/Properties/AssemblyInfo.cs deleted file mode 100644 index f413e072853..00000000000 --- a/mcs/class/System.Json/System.Json/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. - -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("System.Json")] -[assembly: AssemblyDescription("")] -[assembly: Guid("6fd72360-ebfc-4097-96fa-2ee418c04f7b")] diff --git a/mcs/class/System.Json/System.Json/Properties/Resources.Designer.cs b/mcs/class/System.Json/System.Json/Properties/Resources.Designer.cs deleted file mode 100644 index 5a0e1206de3..00000000000 --- a/mcs/class/System.Json/System.Json/Properties/Resources.Designer.cs +++ /dev/null @@ -1,216 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated by a tool. -// Runtime Version:4.0.30319.239 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// </auto-generated> -//------------------------------------------------------------------------------ - -namespace System.Json.Properties { - using System; - - - /// <summary> - /// A strongly-typed resource class, for looking up localized strings, etc. - /// </summary> - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// <summary> - /// Returns the cached ResourceManager instance used by this class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Json.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// <summary> - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// <summary> - /// Looks up a localized string similar to The argument '{0}' must be greater than or equal to {1}.. - /// </summary> - internal static string ArgumentMustBeGreaterThanOrEqualTo { - get { - return ResourceManager.GetString("ArgumentMustBeGreaterThanOrEqualTo", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Unable to cast object of type '{0}' to type '{1}'.. - /// </summary> - internal static string CannotCastJsonValue { - get { - return ResourceManager.GetString("CannotCastJsonValue", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to CannotReadAsType=Cannot read '{0}' as '{1}' type.. - /// </summary> - internal static string CannotReadAsType { - get { - return ResourceManager.GetString("CannotReadAsType", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Cannot read JsonPrimitive value '{0}' as '{1}'.. - /// </summary> - internal static string CannotReadPrimitiveAsType { - get { - return ResourceManager.GetString("CannotReadPrimitiveAsType", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to '{0}' does not contain a definition for property '{1}'.. - /// </summary> - internal static string DynamicPropertyNotDefined { - get { - return ResourceManager.GetString("DynamicPropertyNotDefined", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to The input source is not correctly formatted.. - /// </summary> - internal static string IncorrectJsonFormat { - get { - return ResourceManager.GetString("IncorrectJsonFormat", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to '{0}' type indexer is not supported on JsonValue of 'JsonType.{1}' type.. - /// </summary> - internal static string IndexerNotSupportedOnJsonType { - get { - return ResourceManager.GetString("IndexerNotSupportedOnJsonType", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Cannot convert null to '{0}' because it is a non-nullable value type.. - /// </summary> - internal static string InvalidCastNonNullable { - get { - return ResourceManager.GetString("InvalidCastNonNullable", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Cannot cast JsonPrimitive value '{0}' as '{1}'. It is not in a valid date format.. - /// </summary> - internal static string InvalidDateFormat { - get { - return ResourceManager.GetString("InvalidDateFormat", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Invalid '{0}' index type; only 'System.String' and non-negative 'System.Int32' types are supported.. - /// </summary> - internal static string InvalidIndexType { - get { - return ResourceManager.GetString("InvalidIndexType", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Invalid JSON primitive: {0}.. - /// </summary> - internal static string InvalidJsonPrimitive { - get { - return ResourceManager.GetString("InvalidJsonPrimitive", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Cannot cast '{0}' value '{1}.{2}' as a type of '{3}'. The provided string is not a valid relative or absolute '{3}'.. - /// </summary> - internal static string InvalidUriFormat { - get { - return ResourceManager.GetString("InvalidUriFormat", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to An empty string cannot be parsed as JSON.. - /// </summary> - internal static string JsonStringCannotBeEmpty { - get { - return ResourceManager.GetString("JsonStringCannotBeEmpty", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Null index or multidimensional indexing is not supported by this indexer; use 'System.Int32' or 'System.String' for array and object indexing respectively.. - /// </summary> - internal static string NonSingleNonNullIndexNotSupported { - get { - return ResourceManager.GetString("NonSingleNonNullIndexNotSupported", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Cannot cast JsonPrimitive value '{0}' as '{1}'. The value is either too large or too small for the specified CLR type.. - /// </summary> - internal static string OverflowReadAs { - get { - return ResourceManager.GetString("OverflowReadAs", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Object type not supported.. - /// </summary> - internal static string TypeNotSupported { - get { - return ResourceManager.GetString("TypeNotSupported", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to Operation not supported on JsonValue instances of 'JsonType.Default' type.. - /// </summary> - internal static string UseOfDefaultNotAllowed { - get { - return ResourceManager.GetString("UseOfDefaultNotAllowed", resourceCulture); - } - } - } -} diff --git a/mcs/class/System.Json/System.Json/Properties/Resources.resx b/mcs/class/System.Json/System.Json/Properties/Resources.resx deleted file mode 100644 index 02fd621dcef..00000000000 --- a/mcs/class/System.Json/System.Json/Properties/Resources.resx +++ /dev/null @@ -1,171 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <data name="ArgumentMustBeGreaterThanOrEqualTo" xml:space="preserve"> - <value>The argument '{0}' must be greater than or equal to {1}.</value> - </data> - <data name="CannotCastJsonValue" xml:space="preserve"> - <value>Unable to cast object of type '{0}' to type '{1}'.</value> - </data> - <data name="CannotReadAsType" xml:space="preserve"> - <value>CannotReadAsType=Cannot read '{0}' as '{1}' type.</value> - </data> - <data name="CannotReadPrimitiveAsType" xml:space="preserve"> - <value>Cannot read JsonPrimitive value '{0}' as '{1}'.</value> - </data> - <data name="DynamicPropertyNotDefined" xml:space="preserve"> - <value>'{0}' does not contain a definition for property '{1}'.</value> - </data> - <data name="IncorrectJsonFormat" xml:space="preserve"> - <value>The input source is not correctly formatted.</value> - </data> - <data name="IndexerNotSupportedOnJsonType" xml:space="preserve"> - <value>'{0}' type indexer is not supported on JsonValue of 'JsonType.{1}' type.</value> - </data> - <data name="InvalidCastNonNullable" xml:space="preserve"> - <value>Cannot convert null to '{0}' because it is a non-nullable value type.</value> - </data> - <data name="InvalidDateFormat" xml:space="preserve"> - <value>Cannot cast JsonPrimitive value '{0}' as '{1}'. It is not in a valid date format.</value> - </data> - <data name="InvalidIndexType" xml:space="preserve"> - <value>Invalid '{0}' index type; only 'System.String' and non-negative 'System.Int32' types are supported.</value> - </data> - <data name="InvalidJsonPrimitive" xml:space="preserve"> - <value>Invalid JSON primitive: {0}.</value> - </data> - <data name="InvalidUriFormat" xml:space="preserve"> - <value>Cannot cast '{0}' value '{1}.{2}' as a type of '{3}'. The provided string is not a valid relative or absolute '{3}'.</value> - </data> - <data name="JsonStringCannotBeEmpty" xml:space="preserve"> - <value>An empty string cannot be parsed as JSON.</value> - </data> - <data name="NonSingleNonNullIndexNotSupported" xml:space="preserve"> - <value>Null index or multidimensional indexing is not supported by this indexer; use 'System.Int32' or 'System.String' for array and object indexing respectively.</value> - </data> - <data name="OverflowReadAs" xml:space="preserve"> - <value>Cannot cast JsonPrimitive value '{0}' as '{1}'. The value is either too large or too small for the specified CLR type.</value> - </data> - <data name="TypeNotSupported" xml:space="preserve"> - <value>Object type not supported.</value> - </data> - <data name="UseOfDefaultNotAllowed" xml:space="preserve"> - <value>Operation not supported on JsonValue instances of 'JsonType.Default' type.</value> - </data> -</root>
\ No newline at end of file diff --git a/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs b/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs index c302a515073..2459c1fc3ad 100644 --- a/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs +++ b/mcs/class/System.Json/Test/System.Json/JsonValueTest.cs @@ -17,6 +17,15 @@ namespace MonoTests.System [TestFixture] public class JsonValueTests { // Tests that a trailing comma is allowed in dictionary definitions + [Test] + public void LoadWithTrailingComma () + { + var j = JsonValue.Load (new StringReader ("{ \"a\": \"b\",}")); + Assert.AreEqual (1, j.Count, "itemcount"); + Assert.AreEqual (JsonType.String, j ["a"].JsonType, "type"); + Assert.AreEqual ("b", (string) j ["a"], "value"); + } + // Test that we correctly serialize JsonArray with null elements. [Test] public void ToStringOnJsonArrayWithNulls () { @@ -24,7 +33,7 @@ namespace MonoTests.System Assert.AreEqual (4, j.Count, "itemcount"); Assert.AreEqual (JsonType.Array, j.JsonType, "type"); var str = j.ToString (); - Assert.AreEqual ("[1,2,3,null]", str); + Assert.AreEqual (str, "[1, 2, 3, null]"); } } } |