Auto status change to "Under Review"
@@ -0,0 +1,6 | |||||
|
1 | <?xml version="1.0" encoding="utf-8" ?> | |||
|
2 | <configuration> | |||
|
3 | <startup> | |||
|
4 | <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> | |||
|
5 | </startup> | |||
|
6 | </configuration> No newline at end of file |
@@ -0,0 +1,68 | |||||
|
1 | <?xml version="1.0" encoding="utf-8"?> | |||
|
2 | <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
|
3 | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |||
|
4 | <PropertyGroup> | |||
|
5 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
|
6 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
|
7 | <ProjectGuid>{100DFEB0-75BE-436F-ADDF-1F46EF433F46}</ProjectGuid> | |||
|
8 | <OutputType>Exe</OutputType> | |||
|
9 | <AppDesignerFolder>Properties</AppDesignerFolder> | |||
|
10 | <RootNamespace>Implab.Playground</RootNamespace> | |||
|
11 | <AssemblyName>Implab.Playground</AssemblyName> | |||
|
12 | <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> | |||
|
13 | <FileAlignment>512</FileAlignment> | |||
|
14 | <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |||
|
15 | </PropertyGroup> | |||
|
16 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
|
17 | <PlatformTarget>AnyCPU</PlatformTarget> | |||
|
18 | <DebugSymbols>true</DebugSymbols> | |||
|
19 | <DebugType>full</DebugType> | |||
|
20 | <Optimize>false</Optimize> | |||
|
21 | <OutputPath>bin\Debug\</OutputPath> | |||
|
22 | <DefineConstants>DEBUG;TRACE</DefineConstants> | |||
|
23 | <ErrorReport>prompt</ErrorReport> | |||
|
24 | <WarningLevel>4</WarningLevel> | |||
|
25 | </PropertyGroup> | |||
|
26 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
|
27 | <PlatformTarget>AnyCPU</PlatformTarget> | |||
|
28 | <DebugType>pdbonly</DebugType> | |||
|
29 | <Optimize>true</Optimize> | |||
|
30 | <OutputPath>bin\Release\</OutputPath> | |||
|
31 | <DefineConstants>TRACE</DefineConstants> | |||
|
32 | <ErrorReport>prompt</ErrorReport> | |||
|
33 | <WarningLevel>4</WarningLevel> | |||
|
34 | <Prefer32Bit>true</Prefer32Bit> | |||
|
35 | <DebugSymbols>true</DebugSymbols> | |||
|
36 | </PropertyGroup> | |||
|
37 | <ItemGroup> | |||
|
38 | <Reference Include="System" /> | |||
|
39 | <Reference Include="System.Core" /> | |||
|
40 | <Reference Include="System.Xml.Linq" /> | |||
|
41 | <Reference Include="System.Data.DataSetExtensions" /> | |||
|
42 | <Reference Include="Microsoft.CSharp" /> | |||
|
43 | <Reference Include="System.Data" /> | |||
|
44 | <Reference Include="System.Net.Http" /> | |||
|
45 | <Reference Include="System.Xml" /> | |||
|
46 | </ItemGroup> | |||
|
47 | <ItemGroup> | |||
|
48 | <Compile Include="Program.cs" /> | |||
|
49 | <Compile Include="Properties\AssemblyInfo.cs" /> | |||
|
50 | </ItemGroup> | |||
|
51 | <ItemGroup> | |||
|
52 | <None Include="App.config" /> | |||
|
53 | </ItemGroup> | |||
|
54 | <ItemGroup> | |||
|
55 | <ProjectReference Include="..\Implab\Implab.csproj"> | |||
|
56 | <Project>{f550f1f8-8746-4ad0-9614-855f4c4b7f05}</Project> | |||
|
57 | <Name>Implab</Name> | |||
|
58 | </ProjectReference> | |||
|
59 | </ItemGroup> | |||
|
60 | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
|
61 | <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
|
62 | Other similar extension points exist, see Microsoft.Common.targets. | |||
|
63 | <Target Name="BeforeBuild"> | |||
|
64 | </Target> | |||
|
65 | <Target Name="AfterBuild"> | |||
|
66 | </Target> | |||
|
67 | --> | |||
|
68 | </Project> No newline at end of file |
@@ -0,0 +1,42 | |||||
|
1 | using Implab.Formats.Json; | |||
|
2 | using Implab.Xml; | |||
|
3 | using System; | |||
|
4 | using System.Collections.Generic; | |||
|
5 | using System.IO; | |||
|
6 | using System.Linq; | |||
|
7 | using System.Text; | |||
|
8 | using System.Threading.Tasks; | |||
|
9 | using System.Xml; | |||
|
10 | using System.Xml.Serialization; | |||
|
11 | ||||
|
12 | namespace Implab.Playground { | |||
|
13 | public class Program { | |||
|
14 | ||||
|
15 | [XmlRoot(Namespace = "XmlSimpleData")] | |||
|
16 | public class XmlSimpleModel { | |||
|
17 | [XmlElement] | |||
|
18 | public string Name { get; set; } | |||
|
19 | ||||
|
20 | [XmlElement] | |||
|
21 | public int Order { get; set; } | |||
|
22 | ||||
|
23 | [XmlElement] | |||
|
24 | public string[] Items { get; set; } | |||
|
25 | ||||
|
26 | } | |||
|
27 | ||||
|
28 | static void Main(string[] args) { | |||
|
29 | var model = new XmlSimpleModel { | |||
|
30 | Name = "Tablet", | |||
|
31 | Order = 10, | |||
|
32 | Items = new string[] { "z1", "z2", "z3" } | |||
|
33 | }; | |||
|
34 | ||||
|
35 | var doc = SerializationHelpers.SerializeAsXmlDocument(model); | |||
|
36 | ||||
|
37 | var m2 = SerializationHelpers.DeserializeFromXmlNode<XmlSimpleModel>(doc.DocumentElement); | |||
|
38 | ||||
|
39 | Console.WriteLine("done"); | |||
|
40 | } | |||
|
41 | } | |||
|
42 | } |
@@ -0,0 +1,36 | |||||
|
1 | using System.Reflection; | |||
|
2 | using System.Runtime.CompilerServices; | |||
|
3 | using System.Runtime.InteropServices; | |||
|
4 | ||||
|
5 | // General Information about an assembly is controlled through the following | |||
|
6 | // set of attributes. Change these attribute values to modify the information | |||
|
7 | // associated with an assembly. | |||
|
8 | [assembly: AssemblyTitle("Implab.Playground")] | |||
|
9 | [assembly: AssemblyDescription("")] | |||
|
10 | [assembly: AssemblyConfiguration("")] | |||
|
11 | [assembly: AssemblyCompany("")] | |||
|
12 | [assembly: AssemblyProduct("Implab.Playground")] | |||
|
13 | [assembly: AssemblyCopyright("Copyright © 2017")] | |||
|
14 | [assembly: AssemblyTrademark("")] | |||
|
15 | [assembly: AssemblyCulture("")] | |||
|
16 | ||||
|
17 | // Setting ComVisible to false makes the types in this assembly not visible | |||
|
18 | // to COM components. If you need to access a type in this assembly from | |||
|
19 | // COM, set the ComVisible attribute to true on that type. | |||
|
20 | [assembly: ComVisible(false)] | |||
|
21 | ||||
|
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM | |||
|
23 | [assembly: Guid("100dfeb0-75be-436f-addf-1f46ef433f46")] | |||
|
24 | ||||
|
25 | // Version information for an assembly consists of the following four values: | |||
|
26 | // | |||
|
27 | // Major Version | |||
|
28 | // Minor Version | |||
|
29 | // Build Number | |||
|
30 | // Revision | |||
|
31 | // | |||
|
32 | // You can specify all the values or you can default the Build and Revision Numbers | |||
|
33 | // by using the '*' as shown below: | |||
|
34 | // [assembly: AssemblyVersion("1.0.*")] | |||
|
35 | [assembly: AssemblyVersion("1.0.0.0")] | |||
|
36 | [assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,75 | |||||
|
1 | <?xml version="1.0" encoding="UTF-8"?> | |||
|
2 | <VSPerformanceSession Version="1.00"> | |||
|
3 | <Options> | |||
|
4 | <Solution>Implab.sln</Solution> | |||
|
5 | <CollectionMethod>Sampling</CollectionMethod> | |||
|
6 | <AllocationMethod>None</AllocationMethod> | |||
|
7 | <AddReport>true</AddReport> | |||
|
8 | <ResourceBasedAnalysisSelected>true</ResourceBasedAnalysisSelected> | |||
|
9 | <UniqueReport>Timestamp</UniqueReport> | |||
|
10 | <SamplingMethod>Cycles</SamplingMethod> | |||
|
11 | <CycleCount>50000</CycleCount> | |||
|
12 | <PageFaultCount>10</PageFaultCount> | |||
|
13 | <SysCallCount>10</SysCallCount> | |||
|
14 | <SamplingCounter Name="" ReloadValue="00000000000f4240" DisplayName="" /> | |||
|
15 | <RelocateBinaries>false</RelocateBinaries> | |||
|
16 | <HardwareCounters EnableHWCounters="false" /> | |||
|
17 | <EtwSettings /> | |||
|
18 | <PdhSettings> | |||
|
19 | <PdhCountersEnabled>false</PdhCountersEnabled> | |||
|
20 | <PdhCountersRate>500</PdhCountersRate> | |||
|
21 | <PdhCounters> | |||
|
22 | <PdhCounter>\Память\Обмен страниц/с</PdhCounter> | |||
|
23 | <PdhCounter>\Процессор(_Total)\% загруженности процессора</PdhCounter> | |||
|
24 | <PdhCounter>\Физический диск(_Total)\Средняя длина очереди диска</PdhCounter> | |||
|
25 | </PdhCounters> | |||
|
26 | </PdhSettings> | |||
|
27 | </Options> | |||
|
28 | <ExcludeSmallFuncs>true</ExcludeSmallFuncs> | |||
|
29 | <InteractionProfilingEnabled>false</InteractionProfilingEnabled> | |||
|
30 | <JScriptProfilingEnabled>false</JScriptProfilingEnabled> | |||
|
31 | <PreinstrumentEvent> | |||
|
32 | <InstrEventExclude>false</InstrEventExclude> | |||
|
33 | </PreinstrumentEvent> | |||
|
34 | <PostinstrumentEvent> | |||
|
35 | <InstrEventExclude>false</InstrEventExclude> | |||
|
36 | </PostinstrumentEvent> | |||
|
37 | <Binaries> | |||
|
38 | <ProjBinary> | |||
|
39 | <Path>Implab.Playground\obj\Debug\Implab.Playground.exe</Path> | |||
|
40 | <ArgumentTimestamp>01/01/0001 00:00:00</ArgumentTimestamp> | |||
|
41 | <Instrument>true</Instrument> | |||
|
42 | <Sample>true</Sample> | |||
|
43 | <ExternalWebsite>false</ExternalWebsite> | |||
|
44 | <InteractionProfilingEnabled>false</InteractionProfilingEnabled> | |||
|
45 | <IsLocalJavascript>false</IsLocalJavascript> | |||
|
46 | <IsWindowsStoreApp>false</IsWindowsStoreApp> | |||
|
47 | <IsWWA>false</IsWWA> | |||
|
48 | <LaunchProject>true</LaunchProject> | |||
|
49 | <OverrideProjectSettings>false</OverrideProjectSettings> | |||
|
50 | <LaunchMethod>Executable</LaunchMethod> | |||
|
51 | <ExecutablePath>Implab.Playground\bin\Release\Implab.Playground.exe</ExecutablePath> | |||
|
52 | <StartupDirectory>Implab.Playground\bin\Release\</StartupDirectory> | |||
|
53 | <Arguments> | |||
|
54 | </Arguments> | |||
|
55 | <NetAppHost>IIS</NetAppHost> | |||
|
56 | <NetBrowser>InternetExplorer</NetBrowser> | |||
|
57 | <ExcludeSmallFuncs>true</ExcludeSmallFuncs> | |||
|
58 | <JScriptProfilingEnabled>false</JScriptProfilingEnabled> | |||
|
59 | <PreinstrumentEvent> | |||
|
60 | <InstrEventExclude>false</InstrEventExclude> | |||
|
61 | </PreinstrumentEvent> | |||
|
62 | <PostinstrumentEvent> | |||
|
63 | <InstrEventExclude>false</InstrEventExclude> | |||
|
64 | </PostinstrumentEvent> | |||
|
65 | <ProjRef>{100DFEB0-75BE-436F-ADDF-1F46EF433F46}|Implab.Playground\Implab.Playground.csproj</ProjRef> | |||
|
66 | <ProjPath>Implab.Playground\Implab.Playground.csproj</ProjPath> | |||
|
67 | <ProjName>Implab.Playground</ProjName> | |||
|
68 | </ProjBinary> | |||
|
69 | </Binaries> | |||
|
70 | <Launches> | |||
|
71 | <ProjBinary> | |||
|
72 | <Path>:PB:{100DFEB0-75BE-436F-ADDF-1F46EF433F46}|Implab.Playground\Implab.Playground.csproj</Path> | |||
|
73 | </ProjBinary> | |||
|
74 | </Launches> | |||
|
75 | </VSPerformanceSession> No newline at end of file |
@@ -0,0 +1,45 | |||||
|
1 | using System; | |||
|
2 | using System.Collections.Generic; | |||
|
3 | using System.Linq; | |||
|
4 | using System.Text; | |||
|
5 | using System.Threading.Tasks; | |||
|
6 | using System.Xml; | |||
|
7 | using System.Xml.Linq; | |||
|
8 | ||||
|
9 | namespace Implab.Xml { | |||
|
10 | public static class SerializationHelpers { | |||
|
11 | public static string SerializeAsString<T>(T obj) { | |||
|
12 | return SerializersPool<T>.Instance.SerializeAsString(obj); | |||
|
13 | } | |||
|
14 | ||||
|
15 | public static void Serialize<T>(XmlWriter writer, T obj) { | |||
|
16 | SerializersPool<T>.Instance.Serialize(writer, obj); | |||
|
17 | } | |||
|
18 | ||||
|
19 | public static XmlDocument SerializeAsXmlDocument<T>(T obj) { | |||
|
20 | var doc = new XmlDocument(); | |||
|
21 | using (var writer = doc.CreateNavigator().AppendChild()) { | |||
|
22 | SerializersPool<T>.Instance.Serialize(writer, obj); | |||
|
23 | } | |||
|
24 | return doc; | |||
|
25 | } | |||
|
26 | ||||
|
27 | public static XDocument SerializeAsXDocument<T>(T obj) { | |||
|
28 | var doc = new XDocument(); | |||
|
29 | using (var writer = doc.CreateWriter()) { | |||
|
30 | SerializersPool<T>.Instance.Serialize(writer, obj); | |||
|
31 | } | |||
|
32 | return doc; | |||
|
33 | } | |||
|
34 | ||||
|
35 | public static T DeserializeFromString<T>(string data) { | |||
|
36 | return SerializersPool<T>.Instance.DeserializeFromString(data); | |||
|
37 | } | |||
|
38 | ||||
|
39 | public static T DeserializeFromXmlNode<T>(XmlNode node) { | |||
|
40 | Safe.ArgumentNotNull(node, nameof(node)); | |||
|
41 | using (var reader = node.CreateNavigator().ReadSubtree()) | |||
|
42 | return SerializersPool<T>.Instance.Deserialize(reader); | |||
|
43 | } | |||
|
44 | } | |||
|
45 | } |
@@ -0,0 +1,76 | |||||
|
1 | using Implab.Components; | |||
|
2 | using System; | |||
|
3 | using System.Collections.Generic; | |||
|
4 | using System.IO; | |||
|
5 | using System.Linq; | |||
|
6 | using System.Text; | |||
|
7 | using System.Threading.Tasks; | |||
|
8 | using System.Xml; | |||
|
9 | using System.Xml.Serialization; | |||
|
10 | ||||
|
11 | namespace Implab.Xml { | |||
|
12 | public class SerializersPool<T> : ObjectPool<XmlSerializer> { | |||
|
13 | ||||
|
14 | static readonly SerializersPool<T> _instance = new SerializersPool<T>(); | |||
|
15 | ||||
|
16 | public static SerializersPool<T> Instance { | |||
|
17 | get { return _instance; } | |||
|
18 | } | |||
|
19 | ||||
|
20 | #region implemented abstract members of ObjectPool | |||
|
21 | protected override XmlSerializer CreateInstance() { | |||
|
22 | return new XmlSerializer(typeof(T)); | |||
|
23 | } | |||
|
24 | #endregion | |||
|
25 | ||||
|
26 | public T DeserializeFromString(string data) { | |||
|
27 | using (var reader = new StringReader(data)) { | |||
|
28 | return Deserialize(reader); | |||
|
29 | } | |||
|
30 | } | |||
|
31 | ||||
|
32 | public T Deserialize(TextReader reader) { | |||
|
33 | var sr = Allocate(); | |||
|
34 | try { | |||
|
35 | return (T)sr.Deserialize(reader); | |||
|
36 | } finally { | |||
|
37 | Release(sr); | |||
|
38 | } | |||
|
39 | } | |||
|
40 | ||||
|
41 | public T Deserialize(XmlReader reader) { | |||
|
42 | var sr = Allocate(); | |||
|
43 | try { | |||
|
44 | return (T)sr.Deserialize(reader); | |||
|
45 | } finally { | |||
|
46 | Release(sr); | |||
|
47 | } | |||
|
48 | } | |||
|
49 | ||||
|
50 | public string SerializeAsString(T data) { | |||
|
51 | using (var writer = new StringWriter()) { | |||
|
52 | Serialize(writer, data); | |||
|
53 | return writer.ToString(); | |||
|
54 | } | |||
|
55 | } | |||
|
56 | ||||
|
57 | public void Serialize(TextWriter writer, T data) { | |||
|
58 | var sr = Allocate(); | |||
|
59 | try { | |||
|
60 | sr.Serialize(writer, data); | |||
|
61 | } finally { | |||
|
62 | Release(sr); | |||
|
63 | } | |||
|
64 | } | |||
|
65 | ||||
|
66 | public void Serialize(XmlWriter writer, T data) { | |||
|
67 | var sr = Allocate(); | |||
|
68 | try { | |||
|
69 | sr.Serialize(writer, data); | |||
|
70 | } finally { | |||
|
71 | Release(sr); | |||
|
72 | } | |||
|
73 | } | |||
|
74 | ||||
|
75 | } | |||
|
76 | } |
@@ -21,3 +21,5 Implab.Test/Implab.Format.Test/obj/ | |||||
21 | Implab.Format.Test/bin/ |
|
21 | Implab.Format.Test/bin/ | |
22 | Implab.Format.Test/obj/ |
|
22 | Implab.Format.Test/obj/ | |
23 | packages/ |
|
23 | packages/ | |
|
24 | Implab.Playground/obj/ | |||
|
25 | Implab.Playground/bin/ |
@@ -5,6 +5,7 using Implab.Xml; | |||||
5 | using System.Xml; |
|
5 | using System.Xml; | |
6 | using Implab.Formats; |
|
6 | using Implab.Formats; | |
7 | using Implab.Formats.Json; |
|
7 | using Implab.Formats.Json; | |
|
8 | using System.IO; | |||
8 |
|
9 | |||
9 | namespace Implab.Format.Test { |
|
10 | namespace Implab.Format.Test { | |
10 | [TestFixture] |
|
11 | [TestFixture] | |
@@ -15,19 +16,19 namespace Implab.Format.Test { | |||||
15 | using (var scanner = JsonStringScanner.Create(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) { |
|
16 | using (var scanner = JsonStringScanner.Create(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) { | |
16 |
|
17 | |||
17 | Tuple<JsonTokenType, object>[] expexted = { |
|
18 | Tuple<JsonTokenType, object>[] expexted = { | |
18 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, |
|
19 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "9123"), | |
19 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
20 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
20 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, |
|
21 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "-123"), | |
21 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
22 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
22 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, |
|
23 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "0"), | |
23 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
24 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
24 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, |
|
25 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "0.1"), | |
25 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
26 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
26 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, |
|
27 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "-0.2"), | |
27 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
28 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
28 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, -0.1e3 |
|
29 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "-0.1e3"), | |
29 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
30 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
30 |
new Tuple<JsonTokenType,object>(JsonTokenType.Number, 1.3E-3 |
|
31 | new Tuple<JsonTokenType,object>(JsonTokenType.Number, "1.3E-3"), | |
31 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
32 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
32 | new Tuple<JsonTokenType,object>(JsonTokenType.String, "some \t\n text"), |
|
33 | new Tuple<JsonTokenType,object>(JsonTokenType.String, "some \t\n text"), | |
33 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), |
|
34 | new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, null), | |
@@ -39,7 +40,7 namespace Implab.Format.Test { | |||||
39 | new Tuple<JsonTokenType,object>(JsonTokenType.NameSeparator, null) |
|
40 | new Tuple<JsonTokenType,object>(JsonTokenType.NameSeparator, null) | |
40 | }; |
|
41 | }; | |
41 |
|
42 | |||
42 |
|
|
43 | string value; | |
43 | JsonTokenType tokenType; |
|
44 | JsonTokenType tokenType; | |
44 | for (var i = 0; i < expexted.Length; i++) { |
|
45 | for (var i = 0; i < expexted.Length; i++) { | |
45 |
|
46 | |||
@@ -73,7 +74,7 namespace Implab.Format.Test { | |||||
73 | foreach (var json in bad) { |
|
74 | foreach (var json in bad) { | |
74 | using (var scanner = JsonStringScanner.Create(json)) { |
|
75 | using (var scanner = JsonStringScanner.Create(json)) { | |
75 | try { |
|
76 | try { | |
76 |
|
|
77 | string value; | |
77 | JsonTokenType token; |
|
78 | JsonTokenType token; | |
78 | scanner.ReadToken(out value, out token); |
|
79 | scanner.ReadToken(out value, out token); | |
79 | if (!Object.Equals(value, json)) { |
|
80 | if (!Object.Equals(value, json)) { | |
@@ -109,11 +110,11 namespace Implab.Format.Test { | |||||
109 | //DumpJsonParse("{}"); |
|
110 | //DumpJsonParse("{}"); | |
110 | //DumpJsonParse("[]"); |
|
111 | //DumpJsonParse("[]"); | |
111 | DumpJsonParse("{\"one\":1, \"two\":2}"); |
|
112 | DumpJsonParse("{\"one\":1, \"two\":2}"); | |
112 | DumpJsonParse("[1,2,3]"); |
|
113 | DumpJsonParse("[1,\"\",2,3]"); | |
113 | DumpJsonParse("[{\"info\": [7,8,9]}]"); |
|
114 | DumpJsonParse("[{\"info\": [7,8,9]}]"); | |
114 | DumpJsonFlatParse("[1,2,[3,4],{\"info\": [5,6]},{\"num\": [7,8,null]}, null,[null]]"); |
|
115 | DumpJsonFlatParse("[1,2,\"\",[3,4],{\"info\": [5,6]},{\"num\": [7,8,null]}, null,[null]]"); | |
115 | } |
|
116 | } | |
116 |
|
117 | |||
117 | void AssertRead(XmlReader reader, XmlNodeType expected) { |
|
118 | void AssertRead(XmlReader reader, XmlNodeType expected) { | |
118 | Assert.IsTrue(reader.Read()); |
|
119 | Assert.IsTrue(reader.Read()); | |
119 | Console.WriteLine($"{new string(' ', reader.Depth*2)}{reader}"); |
|
120 | Console.WriteLine($"{new string(' ', reader.Depth*2)}{reader}"); | |
@@ -123,7 +124,7 namespace Implab.Format.Test { | |||||
123 | void DumpJsonParse(string json) { |
|
124 | void DumpJsonParse(string json) { | |
124 | Console.WriteLine($"JSON: {json}"); |
|
125 | Console.WriteLine($"JSON: {json}"); | |
125 | Console.WriteLine("XML"); |
|
126 | Console.WriteLine("XML"); | |
126 |
using (var xmlReader = new JsonXmlReader( |
|
127 | using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "json" })) { | |
127 | while (xmlReader.Read()) |
|
128 | while (xmlReader.Read()) | |
128 | Console.WriteLine($"{new string(' ', xmlReader.Depth * 2)}{xmlReader}"); |
|
129 | Console.WriteLine($"{new string(' ', xmlReader.Depth * 2)}{xmlReader}"); | |
129 | } |
|
130 | } | |
@@ -137,7 +138,7 namespace Implab.Format.Test { | |||||
137 | CloseOutput = false, |
|
138 | CloseOutput = false, | |
138 | ConformanceLevel = ConformanceLevel.Document |
|
139 | ConformanceLevel = ConformanceLevel.Document | |
139 | })) |
|
140 | })) | |
140 |
using (var xmlReader = new JsonXmlReader( |
|
141 | using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "", FlattenArrays = true })) { | |
141 | xmlWriter.WriteNode(xmlReader, false); |
|
142 | xmlWriter.WriteNode(xmlReader, false); | |
142 | } |
|
143 | } | |
143 | } |
|
144 | } |
@@ -16,11 +16,14 Project("{FAE04EC0-301F-11D3-BF4B-00C04F | |||||
16 | EndProject |
|
16 | EndProject | |
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}" |
|
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}" | |
18 | EndProject |
|
18 | EndProject | |
19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}" |
|
|||
20 | EndProject |
|
|||
21 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Format.Test", "Implab.Format.Test\Implab.Format.Test.csproj", "{4D364996-7ECD-4193-8F90-F223FFEA49DA}" |
|
19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Format.Test", "Implab.Format.Test\Implab.Format.Test.csproj", "{4D364996-7ECD-4193-8F90-F223FFEA49DA}" | |
22 | EndProject |
|
20 | EndProject | |
|
21 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Playground", "Implab.Playground\Implab.Playground.csproj", "{100DFEB0-75BE-436F-ADDF-1F46EF433F46}" | |||
|
22 | EndProject | |||
23 | Global |
|
23 | Global | |
|
24 | GlobalSection(Performance) = preSolution | |||
|
25 | HasPerformanceSessions = true | |||
|
26 | EndGlobalSection | |||
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|
27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution | |
25 | Debug 4.5|Any CPU = Debug 4.5|Any CPU |
|
28 | Debug 4.5|Any CPU = Debug 4.5|Any CPU | |
26 | Debug|Any CPU = Debug|Any CPU |
|
29 | Debug|Any CPU = Debug|Any CPU | |
@@ -52,14 +55,6 Global | |||||
52 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU |
|
55 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU | |
53 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
56 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
54 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU |
|
57 | {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU | |
55 | {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU |
|
|||
56 | {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU |
|
|||
57 | {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
|||
58 | {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
|||
59 | {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU |
|
|||
60 | {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU |
|
|||
61 | {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
|||
62 | {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU |
|
|||
63 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU |
|
58 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU | |
64 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU |
|
59 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU | |
65 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
60 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
@@ -68,6 +63,14 Global | |||||
68 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.Build.0 = Release|Any CPU |
|
63 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.Build.0 = Release|Any CPU | |
69 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
64 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
70 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.Build.0 = Release|Any CPU |
|
65 | {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.Build.0 = Release|Any CPU | |
|
66 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU | |||
|
67 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU | |||
|
68 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
|
69 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
|
70 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU | |||
|
71 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Release 4.5|Any CPU.Build.0 = Release|Any CPU | |||
|
72 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
|
73 | {100DFEB0-75BE-436F-ADDF-1F46EF433F46}.Release|Any CPU.Build.0 = Release|Any CPU | |||
71 | EndGlobalSection |
|
74 | EndGlobalSection | |
72 | GlobalSection(SolutionProperties) = preSolution |
|
75 | GlobalSection(SolutionProperties) = preSolution | |
73 | HideSolutionNode = FALSE |
|
76 | HideSolutionNode = FALSE |
@@ -119,7 +119,7 namespace Implab.Automaton { | |||||
119 | table[i, j] = AutomatonConst.UNREACHABLE_STATE; |
|
119 | table[i, j] = AutomatonConst.UNREACHABLE_STATE; | |
120 |
|
120 | |||
121 | foreach (var t in this) |
|
121 | foreach (var t in this) | |
122 | table[t.s1,t.edge] = t.s2; |
|
122 | table[t.s1,t.edge] = (byte)t.s2; | |
123 |
|
123 | |||
124 | return table; |
|
124 | return table; | |
125 | } |
|
125 | } |
@@ -2,6 +2,7 | |||||
2 | using System; |
|
2 | using System; | |
3 | using System.Collections.Generic; |
|
3 | using System.Collections.Generic; | |
4 | using System.Linq; |
|
4 | using System.Linq; | |
|
5 | using System.Runtime.CompilerServices; | |||
5 | using System.Text; |
|
6 | using System.Text; | |
6 | using System.Threading.Tasks; |
|
7 | using System.Threading.Tasks; | |
7 |
|
8 | |||
@@ -30,24 +31,28 namespace Implab.Formats { | |||||
30 | } |
|
31 | } | |
31 |
|
32 | |||
32 | public TTag Tag { |
|
33 | public TTag Tag { | |
|
34 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
33 | get { |
|
35 | get { | |
34 | return m_tags[m_state]; |
|
36 | return m_tags[m_state]; | |
35 | } |
|
37 | } | |
36 | } |
|
38 | } | |
37 |
|
39 | |||
38 | public int Position { |
|
40 | public int Position { | |
|
41 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
39 | get { |
|
42 | get { | |
40 | return m_position; |
|
43 | return m_position; | |
41 | } |
|
44 | } | |
42 | } |
|
45 | } | |
43 |
|
46 | |||
44 | public bool IsFinal { |
|
47 | public bool IsFinal { | |
|
48 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
45 | get { |
|
49 | get { | |
46 | return m_final[m_state]; |
|
50 | return m_final[m_state]; | |
47 | } |
|
51 | } | |
48 | } |
|
52 | } | |
49 |
|
53 | |||
50 | public void Reset() { |
|
54 | [MethodImpl(MethodImplOptions.AggressiveInlining)] | |
|
55 | public void ResetState() { | |||
51 | m_state = m_initialState; |
|
56 | m_state = m_initialState; | |
52 | } |
|
57 | } | |
53 |
|
58 | |||
@@ -58,13 +63,8 namespace Implab.Formats { | |||||
58 | return clone; |
|
63 | return clone; | |
59 | } |
|
64 | } | |
60 |
|
65 | |||
61 | public bool Scan(char[] data, int offset, int length) { |
|
66 | //[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
62 | if (length <= 0) { |
|
67 | public bool Scan(char[] data, int offset, int max) { | |
63 | m_position = offset; |
|
|||
64 | return false; // EOF |
|
|||
65 | } |
|
|||
66 |
|
||||
67 | var max = offset + length; |
|
|||
68 | var next = m_state; |
|
68 | var next = m_state; | |
69 |
|
69 | |||
70 | while(offset < max) { |
|
70 | while(offset < max) { |
@@ -6,6 +6,8 using Implab.Automaton.RegularExpression | |||||
6 | using System.Linq; |
|
6 | using System.Linq; | |
7 | using Implab.Components; |
|
7 | using Implab.Components; | |
8 | using System.Collections.Generic; |
|
8 | using System.Collections.Generic; | |
|
9 | using System.Text; | |||
|
10 | using System.Globalization; | |||
9 |
|
11 | |||
10 | namespace Implab.Formats.Json { |
|
12 | namespace Implab.Formats.Json { | |
11 | /// <summary> |
|
13 | /// <summary> | |
@@ -24,7 +26,7 namespace Implab.Formats.Json { | |||||
24 | /// } // Level = 0 |
|
26 | /// } // Level = 0 | |
25 | /// </code> |
|
27 | /// </code> | |
26 | /// </remarks> |
|
28 | /// </remarks> | |
27 |
public class Json |
|
29 | public class JsonReader : Disposable { | |
28 |
|
30 | |||
29 | enum MemberContext { |
|
31 | enum MemberContext { | |
30 | MemberName, |
|
32 | MemberName, | |
@@ -61,7 +63,7 namespace Implab.Formats.Json { | |||||
61 | static readonly ParserContext _objectContext; |
|
63 | static readonly ParserContext _objectContext; | |
62 | static readonly ParserContext _arrayContext; |
|
64 | static readonly ParserContext _arrayContext; | |
63 |
|
65 | |||
64 |
static Json |
|
66 | static JsonReader() { | |
65 |
|
67 | |||
66 | var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); |
|
68 | var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); | |
67 | var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression); |
|
69 | var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression); | |
@@ -124,20 +126,10 namespace Implab.Formats.Json { | |||||
124 | /// Создает новый парсер на основе строки, содержащей JSON |
|
126 | /// Создает новый парсер на основе строки, содержащей JSON | |
125 | /// </summary> |
|
127 | /// </summary> | |
126 | /// <param name="text"></param> |
|
128 | /// <param name="text"></param> | |
127 | public JsonParser(string text) { |
|
129 | JsonReader(JsonScanner scanner) { | |
128 | Safe.ArgumentNotEmpty(text, "text"); |
|
130 | m_scanner = scanner; | |
129 | m_scanner = JsonStringScanner.Create(text); |
|
|||
130 | } |
|
131 | } | |
131 |
|
132 | |||
132 | /// <summary> |
|
|||
133 | /// Создает новый экземпляр парсера, на основе текстового потока. |
|
|||
134 | /// </summary> |
|
|||
135 | /// <param name="reader">Текстовый поток.</param> |
|
|||
136 | public JsonParser(TextReader reader) { |
|
|||
137 | Safe.ArgumentNotNull(reader, "reader"); |
|
|||
138 | m_scanner = JsonTextScanner.Create(reader); |
|
|||
139 | } |
|
|||
140 |
|
||||
141 | public int Level { |
|
133 | public int Level { | |
142 | get { return m_stack.Count; } |
|
134 | get { return m_stack.Count; } | |
143 | } |
|
135 | } | |
@@ -169,7 +161,7 namespace Implab.Formats.Json { | |||||
169 | /// </summary> |
|
161 | /// </summary> | |
170 | /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns> |
|
162 | /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns> | |
171 | public bool Read() { |
|
163 | public bool Read() { | |
172 |
|
|
164 | string tokenValue; | |
173 | JsonTokenType tokenType; |
|
165 | JsonTokenType tokenType; | |
174 |
|
166 | |||
175 | m_memberName = String.Empty; |
|
167 | m_memberName = String.Empty; | |
@@ -213,7 +205,7 namespace Implab.Formats.Json { | |||||
213 | return true; |
|
205 | return true; | |
214 | case JsonTokenType.String: |
|
206 | case JsonTokenType.String: | |
215 | if (m_memberContext == MemberContext.MemberName) { |
|
207 | if (m_memberContext == MemberContext.MemberName) { | |
216 |
m_memberName = |
|
208 | m_memberName = tokenValue; | |
217 | break; |
|
209 | break; | |
218 | } |
|
210 | } | |
219 | m_elementType = JsonElementType.Value; |
|
211 | m_elementType = JsonElementType.Value; | |
@@ -221,11 +213,11 namespace Implab.Formats.Json { | |||||
221 | return true; |
|
213 | return true; | |
222 | case JsonTokenType.Number: |
|
214 | case JsonTokenType.Number: | |
223 | m_elementType = JsonElementType.Value; |
|
215 | m_elementType = JsonElementType.Value; | |
224 | m_elementValue = tokenValue; |
|
216 | m_elementValue = double.Parse(tokenValue, CultureInfo.InvariantCulture); | |
225 | return true; |
|
217 | return true; | |
226 | case JsonTokenType.Literal: |
|
218 | case JsonTokenType.Literal: | |
227 | m_elementType = JsonElementType.Value; |
|
219 | m_elementType = JsonElementType.Value; | |
228 |
m_elementValue = ParseLiteral( |
|
220 | m_elementValue = ParseLiteral(tokenValue); | |
229 | return true; |
|
221 | return true; | |
230 | case JsonTokenType.NameSeparator: |
|
222 | case JsonTokenType.NameSeparator: | |
231 | m_memberContext = MemberContext.MemberValue; |
|
223 | m_memberContext = MemberContext.MemberValue; | |
@@ -241,7 +233,7 namespace Implab.Formats.Json { | |||||
241 | if (m_context.ElementContext != JsonElementContext.None) |
|
233 | if (m_context.ElementContext != JsonElementContext.None) | |
242 | throw new ParserException("Unexpedted end of data"); |
|
234 | throw new ParserException("Unexpedted end of data"); | |
243 |
|
235 | |||
244 |
E |
|
236 | Eof = true; | |
245 |
|
237 | |||
246 | return false; |
|
238 | return false; | |
247 | } |
|
239 | } | |
@@ -268,7 +260,7 namespace Implab.Formats.Json { | |||||
268 | /// <summary> |
|
260 | /// <summary> | |
269 | /// Признак конца потока |
|
261 | /// Признак конца потока | |
270 | /// </summary> |
|
262 | /// </summary> | |
271 |
public bool E |
|
263 | public bool Eof { | |
272 | get; |
|
264 | get; | |
273 | private set; |
|
265 | private set; | |
274 | } |
|
266 | } | |
@@ -289,6 +281,38 namespace Implab.Formats.Json { | |||||
289 | while (Level != level) |
|
281 | while (Level != level) | |
290 | Read(); |
|
282 | Read(); | |
291 | } |
|
283 | } | |
|
284 | ||||
|
285 | public static JsonReader Create(string file, Encoding encoding) { | |||
|
286 | return new JsonReader(JsonTextScanner.Create(file, encoding)); | |||
|
287 | } | |||
|
288 | ||||
|
289 | public static JsonReader Create(string file) { | |||
|
290 | return new JsonReader(JsonTextScanner.Create(file)); | |||
|
291 | } | |||
|
292 | ||||
|
293 | public static JsonReader Create(Stream stream, Encoding encoding) { | |||
|
294 | return new JsonReader(JsonTextScanner.Create(stream, encoding)); | |||
|
295 | } | |||
|
296 | ||||
|
297 | public static JsonReader Create(Stream stream) { | |||
|
298 | return new JsonReader(JsonTextScanner.Create(stream)); | |||
|
299 | } | |||
|
300 | ||||
|
301 | public static JsonReader Create(TextReader reader) { | |||
|
302 | return new JsonReader(JsonTextScanner.Create(reader)); | |||
|
303 | } | |||
|
304 | ||||
|
305 | public static JsonReader ParseString(string data) { | |||
|
306 | return new JsonReader(JsonStringScanner.Create(data)); | |||
|
307 | } | |||
|
308 | ||||
|
309 | public static JsonReader ParseString(string data, int offset, int length) { | |||
|
310 | return new JsonReader(JsonStringScanner.Create(data, offset, length)); | |||
|
311 | } | |||
|
312 | ||||
|
313 | public static JsonReader ParseString(char[] data, int offset, int lenght) { | |||
|
314 | return new JsonReader(JsonStringScanner.Create(data, offset, lenght)); | |||
|
315 | } | |||
292 | } |
|
316 | } | |
293 |
|
317 | |||
294 | } |
|
318 | } |
@@ -25,38 +25,94 namespace Implab.Formats.Json { | |||||
25 | m_length = length; |
|
25 | m_length = length; | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
28 | bool Read(InputScanner<JsonGrammar.TokenType> scanner, out JsonGrammar.TokenType tokenType) { |
|
28 | bool ReadChunk(InputScanner<JsonGrammar.TokenType> scanner, out JsonGrammar.TokenType tokenType) { | |
29 | scanner.Reset(); |
|
29 | scanner.ResetState(); | |
|
30 | ||||
|
31 | while(scanner.Scan(m_buffer, m_pos, m_length)) { | |||
|
32 | // scanner requests new data | |||
30 |
|
33 | |||
31 |
if (m_pos |
|
34 | if (m_pos != m_length) // capture results for the future | |
32 | m_pos = 0; |
|
35 | m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos); | |
|
36 | ||||
|
37 | // read next data | |||
33 | m_length = Read(m_buffer, 0, m_buffer.Length); |
|
38 | m_length = Read(m_buffer, 0, m_buffer.Length); | |
|
39 | ||||
34 | if (m_length == 0) { |
|
40 | if (m_length == 0) { | |
35 | tokenType = JsonGrammar.TokenType.None; |
|
41 | // no data is read | |
36 | return false; // EOF |
|
42 | if (scanner.Position == m_pos) { | |
|
43 | // scanned hasn't moved, that's the end | |||
|
44 | m_pos = 0; | |||
|
45 | tokenType = JsonGrammar.TokenType.None; | |||
|
46 | return false; | |||
|
47 | } | |||
|
48 | ||||
|
49 | if (scanner.IsFinal) { | |||
|
50 | m_pos = 0; | |||
|
51 | tokenType = scanner.Tag; | |||
|
52 | return true; | |||
|
53 | } else { | |||
|
54 | throw new ParserException("Unexpected EOF"); | |||
|
55 | } | |||
37 | } |
|
56 | } | |
38 | } |
|
57 | ||
39 |
|
||||
40 | while(scanner.Scan(m_buffer, m_pos, m_length - m_pos)) { |
|
|||
41 | m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos); |
|
|||
42 | m_pos = 0; |
|
58 | m_pos = 0; | |
43 | m_length = Read(m_buffer, 0, m_buffer.Length); |
|
|||
44 | } |
|
59 | } | |
45 | var scannerPos = scanner.Position; |
|
60 | var scannerPos = scanner.Position; | |
|
61 | ||||
|
62 | // scanner stops as scannerPos | |||
|
63 | if (!scanner.IsFinal) | |||
|
64 | throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'"); | |||
|
65 | ||||
|
66 | tokenType = scanner.Tag; | |||
|
67 | if (scannerPos != m_pos && tokenType == JsonGrammar.TokenType.Number || tokenType == JsonGrammar.TokenType.Literal) | |||
|
68 | m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos); | |||
|
69 | ||||
|
70 | m_pos = scannerPos; | |||
|
71 | return true; | |||
|
72 | } | |||
|
73 | ||||
|
74 | bool ReadStringChunk(InputScanner<JsonGrammar.TokenType> scanner, out JsonGrammar.TokenType tokenType) { | |||
|
75 | scanner.ResetState(); | |||
|
76 | ||||
|
77 | while (scanner.Scan(m_buffer, m_pos, m_length)) { | |||
|
78 | // scanner requests new data | |||
|
79 | ||||
|
80 | if (m_pos != m_length) // capture results for the future | |||
|
81 | m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos); | |||
|
82 | ||||
|
83 | // read next data | |||
|
84 | m_length = Read(m_buffer, 0, m_buffer.Length); | |||
|
85 | ||||
|
86 | if (m_length == 0) { | |||
|
87 | // no data is read | |||
|
88 | if (scanner.Position == m_pos) { | |||
|
89 | // scanned hasn't moved, that's the end | |||
|
90 | m_pos = 0; | |||
|
91 | tokenType = JsonGrammar.TokenType.None; | |||
|
92 | return false; | |||
|
93 | } | |||
|
94 | ||||
|
95 | if (scanner.IsFinal) { | |||
|
96 | m_pos = 0; | |||
|
97 | tokenType = scanner.Tag; | |||
|
98 | return true; | |||
|
99 | } else { | |||
|
100 | throw new ParserException("Unexpected EOF"); | |||
|
101 | } | |||
|
102 | } | |||
|
103 | ||||
|
104 | m_pos = 0; | |||
|
105 | } | |||
|
106 | var scannerPos = scanner.Position; | |||
|
107 | ||||
|
108 | // scanner stops as scannerPos | |||
|
109 | if (!scanner.IsFinal) | |||
|
110 | throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'"); | |||
|
111 | ||||
46 | if (scannerPos != m_pos) { |
|
112 | if (scannerPos != m_pos) { | |
47 | m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos); |
|
113 | m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos); | |
48 | m_pos = scannerPos; |
|
114 | m_pos = scannerPos; | |
49 | } |
|
115 | } | |
50 |
|
||||
51 | if (!scanner.IsFinal) { |
|
|||
52 | if (m_length == 0) { |
|
|||
53 | // unexpected EOF |
|
|||
54 | throw new ParserException("Unexpected EOF"); |
|
|||
55 | } else { |
|
|||
56 | // unecpected character |
|
|||
57 | throw new ParserException($"Unexpected character '{m_buffer[m_pos + 1]}'"); |
|
|||
58 | } |
|
|||
59 | } |
|
|||
60 | tokenType = scanner.Tag; |
|
116 | tokenType = scanner.Tag; | |
61 | return true; |
|
117 | return true; | |
62 | } |
|
118 | } | |
@@ -72,17 +128,17 namespace Implab.Formats.Json { | |||||
72 | /// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns> |
|
128 | /// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns> | |
73 | /// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е. |
|
129 | /// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е. | |
74 | /// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks> |
|
130 | /// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks> | |
75 |
public bool ReadToken(out |
|
131 | public bool ReadToken(out string tokenValue, out JsonTokenType tokenType) { | |
76 | JsonGrammar.TokenType tag; |
|
132 | JsonGrammar.TokenType tag; | |
77 | m_tokenBuilder.Clear(); |
|
133 | m_tokenBuilder.Clear(); | |
78 | while (Read(m_jsonContext, out tag)) { |
|
134 | while (ReadChunk(m_jsonContext, out tag)) { | |
79 | switch (tag) { |
|
135 | switch (tag) { | |
80 | case JsonGrammar.TokenType.StringBound: |
|
136 | case JsonGrammar.TokenType.StringBound: | |
81 | tokenValue = ReadString(); |
|
137 | tokenValue = ReadString(); | |
82 | tokenType = JsonTokenType.String; |
|
138 | tokenType = JsonTokenType.String; | |
83 | break; |
|
139 | break; | |
84 | case JsonGrammar.TokenType.Number: |
|
140 | case JsonGrammar.TokenType.Number: | |
85 |
tokenValue = |
|
141 | tokenValue = m_tokenBuilder.ToString(); | |
86 | tokenType = JsonTokenType.Number; |
|
142 | tokenType = JsonTokenType.Number; | |
87 | break; |
|
143 | break; | |
88 | case JsonGrammar.TokenType.Literal: |
|
144 | case JsonGrammar.TokenType.Literal: | |
@@ -108,7 +164,7 namespace Implab.Formats.Json { | |||||
108 | JsonGrammar.TokenType tag; |
|
164 | JsonGrammar.TokenType tag; | |
109 | m_tokenBuilder.Clear(); |
|
165 | m_tokenBuilder.Clear(); | |
110 |
|
166 | |||
111 | while (Read(m_stringContext, out tag)) { |
|
167 | while (ReadStringChunk(m_stringContext, out tag)) { | |
112 | switch (tag) { |
|
168 | switch (tag) { | |
113 | case JsonGrammar.TokenType.StringBound: |
|
169 | case JsonGrammar.TokenType.StringBound: | |
114 | m_tokenBuilder.Length--; |
|
170 | m_tokenBuilder.Length--; |
@@ -7,7 +7,7 using System.Threading.Tasks; | |||||
7 |
|
7 | |||
8 | namespace Implab.Formats.Json { |
|
8 | namespace Implab.Formats.Json { | |
9 | public class JsonTextScanner : JsonScanner { |
|
9 | public class JsonTextScanner : JsonScanner { | |
10 | const int _bufferSize = 4096; |
|
10 | const int _bufferSize = 16*4096; | |
11 | readonly TextReader m_reader; |
|
11 | readonly TextReader m_reader; | |
12 |
|
12 | |||
13 | JsonTextScanner(TextReader reader, char[] buffer) : base(buffer, 0, 0) { |
|
13 | JsonTextScanner(TextReader reader, char[] buffer) : base(buffer, 0, 0) { |
@@ -70,6 +70,7 | |||||
70 | <Reference Include="System" /> |
|
70 | <Reference Include="System" /> | |
71 | <Reference Include="System.Xml" /> |
|
71 | <Reference Include="System.Xml" /> | |
72 | <Reference Include="mscorlib" /> |
|
72 | <Reference Include="mscorlib" /> | |
|
73 | <Reference Include="System.Xml.Linq" /> | |||
73 | </ItemGroup> |
|
74 | </ItemGroup> | |
74 | <ItemGroup> |
|
75 | <ItemGroup> | |
75 | <Compile Include="Components\StateChangeEventArgs.cs" /> |
|
76 | <Compile Include="Components\StateChangeEventArgs.cs" /> | |
@@ -171,7 +172,7 | |||||
171 | <Compile Include="Formats\Json\JsonElementContext.cs" /> |
|
172 | <Compile Include="Formats\Json\JsonElementContext.cs" /> | |
172 | <Compile Include="Formats\Json\JsonElementType.cs" /> |
|
173 | <Compile Include="Formats\Json\JsonElementType.cs" /> | |
173 | <Compile Include="Formats\Json\JsonGrammar.cs" /> |
|
174 | <Compile Include="Formats\Json\JsonGrammar.cs" /> | |
174 |
<Compile Include="Formats\Json\Json |
|
175 | <Compile Include="Formats\Json\JsonReader.cs" /> | |
175 | <Compile Include="Formats\Json\JsonScanner.cs" /> |
|
176 | <Compile Include="Formats\Json\JsonScanner.cs" /> | |
176 | <Compile Include="Formats\Json\JsonTokenType.cs" /> |
|
177 | <Compile Include="Formats\Json\JsonTokenType.cs" /> | |
177 | <Compile Include="Formats\Json\JsonWriter.cs" /> |
|
178 | <Compile Include="Formats\Json\JsonWriter.cs" /> | |
@@ -199,6 +200,8 | |||||
199 | <Compile Include="Xml\JsonXmlReader.cs" /> |
|
200 | <Compile Include="Xml\JsonXmlReader.cs" /> | |
200 | <Compile Include="Xml\JsonXmlReaderOptions.cs" /> |
|
201 | <Compile Include="Xml\JsonXmlReaderOptions.cs" /> | |
201 | <Compile Include="Xml\JsonXmlReaderPosition.cs" /> |
|
202 | <Compile Include="Xml\JsonXmlReaderPosition.cs" /> | |
|
203 | <Compile Include="Xml\SerializationHelpers.cs" /> | |||
|
204 | <Compile Include="Xml\SerializersPool.cs" /> | |||
202 | <Compile Include="Xml\XmlSimpleAttribute.cs" /> |
|
205 | <Compile Include="Xml\XmlSimpleAttribute.cs" /> | |
203 | <Compile Include="Xml\XmlNameContext.cs" /> |
|
206 | <Compile Include="Xml\XmlNameContext.cs" /> | |
204 | </ItemGroup> |
|
207 | </ItemGroup> |
@@ -12,7 +12,7 namespace Implab.Xml { | |||||
12 | public bool skip; |
|
12 | public bool skip; | |
13 | } |
|
13 | } | |
14 |
|
14 | |||
15 |
Json |
|
15 | JsonReader m_parser; | |
16 | JsonXmlReaderOptions m_options; |
|
16 | JsonXmlReaderOptions m_options; | |
17 | JsonXmlReaderPosition m_position = JsonXmlReaderPosition.Initial; |
|
17 | JsonXmlReaderPosition m_position = JsonXmlReaderPosition.Initial; | |
18 | XmlNameTable m_nameTable; |
|
18 | XmlNameTable m_nameTable; | |
@@ -57,7 +57,7 namespace Implab.Xml { | |||||
57 | readonly string m_xsiNamespace; |
|
57 | readonly string m_xsiNamespace; | |
58 |
|
58 | |||
59 |
|
59 | |||
60 |
public JsonXmlReader(Json |
|
60 | public JsonXmlReader(JsonReader parser, JsonXmlReaderOptions options) { | |
61 | Safe.ArgumentNotNull(parser, nameof(parser)); |
|
61 | Safe.ArgumentNotNull(parser, nameof(parser)); | |
62 | m_parser = parser; |
|
62 | m_parser = parser; | |
63 |
|
63 | |||
@@ -77,7 +77,7 namespace Implab.Xml { | |||||
77 |
|
77 | |||
78 | // TODO validate m_jsonRootName, m_jsonArrayItemName |
|
78 | // TODO validate m_jsonRootName, m_jsonArrayItemName | |
79 |
|
79 | |||
80 | m_context = new XmlNameContext(null); |
|
80 | m_context = new XmlNameContext(null, 0); | |
81 | } |
|
81 | } | |
82 |
|
82 | |||
83 | public override int AttributeCount { |
|
83 | public override int AttributeCount { | |
@@ -314,22 +314,6 namespace Implab.Xml { | |||||
314 | case XmlNodeType.Element: |
|
314 | case XmlNodeType.Element: | |
315 | // if the elemnt is empty the next element will be it's sibling |
|
315 | // if the elemnt is empty the next element will be it's sibling | |
316 | return m_isEmpty; |
|
316 | return m_isEmpty; | |
317 |
|
||||
318 | case XmlNodeType.Document: |
|
|||
319 | case XmlNodeType.DocumentFragment: |
|
|||
320 | case XmlNodeType.Entity: |
|
|||
321 | case XmlNodeType.Text: |
|
|||
322 | case XmlNodeType.CDATA: |
|
|||
323 | case XmlNodeType.EntityReference: |
|
|||
324 | case XmlNodeType.ProcessingInstruction: |
|
|||
325 | case XmlNodeType.Comment: |
|
|||
326 | case XmlNodeType.DocumentType: |
|
|||
327 | case XmlNodeType.Notation: |
|
|||
328 | case XmlNodeType.Whitespace: |
|
|||
329 | case XmlNodeType.SignificantWhitespace: |
|
|||
330 | case XmlNodeType.EndElement: |
|
|||
331 | case XmlNodeType.EndEntity: |
|
|||
332 | case XmlNodeType.XmlDeclaration: |
|
|||
333 | default: |
|
317 | default: | |
334 | return true; |
|
318 | return true; | |
335 | } |
|
319 | } | |
@@ -351,25 +335,29 namespace Implab.Xml { | |||||
351 | if (!IsSibling()) // the node is nested |
|
335 | if (!IsSibling()) // the node is nested | |
352 | m_xmlDepth++; |
|
336 | m_xmlDepth++; | |
353 |
|
337 | |||
354 |
|
|
338 | var context = m_context; | |
355 | List<XmlSimpleAttribute> definedAttrs = null; |
|
339 | List<XmlSimpleAttribute> definedAttrs = null; | |
356 |
|
340 | |||
357 | // define new namespaces |
|
341 | // define new namespaces | |
358 | if (attrs != null) { |
|
342 | if (attrs != null) { | |
359 | foreach (var attr in attrs) { |
|
343 | foreach (var attr in attrs) { | |
360 | if (attr.QName.Name == "xmlns") { |
|
344 | if (attr.QName.Name == "xmlns") { | |
361 | m_context.DefinePrefix(ConvertValueToString(attr.Value), string.Empty); |
|
345 | if (context == m_context) | |
|
346 | context = new XmlNameContext(m_context, m_xmlDepth); | |||
|
347 | context.DefinePrefix(ConvertValueToString(attr.Value), string.Empty); | |||
362 | } else if (attr.Prefix == m_xmlnsPrefix) { |
|
348 | } else if (attr.Prefix == m_xmlnsPrefix) { | |
363 | m_context.DefinePrefix(ConvertValueToString(attr.Value), attr.QName.Name); |
|
349 | if (context == m_context) | |
|
350 | context = new XmlNameContext(m_context, m_xmlDepth); | |||
|
351 | context.DefinePrefix(ConvertValueToString(attr.Value), attr.QName.Name); | |||
364 | } else { |
|
352 | } else { | |
365 | string attrPrefix; |
|
353 | string attrPrefix; | |
366 | if (string.IsNullOrEmpty(attr.QName.Namespace)) |
|
354 | if (string.IsNullOrEmpty(attr.QName.Namespace)) | |
367 | continue; |
|
355 | continue; | |
368 |
|
356 | |||
369 | // auto-define prefixes |
|
357 | // auto-define prefixes | |
370 |
if (! |
|
358 | if (!context.LookupNamespacePrefix(attr.QName.Namespace, out attrPrefix) || string.IsNullOrEmpty(attrPrefix)) { | |
371 | // new namespace prefix added |
|
359 | // new namespace prefix added | |
372 |
attrPrefix = |
|
360 | attrPrefix = context.CreateNamespacePrefix(attr.QName.Namespace); | |
373 | attr.Prefix = attrPrefix; |
|
361 | attr.Prefix = attrPrefix; | |
374 |
|
362 | |||
375 | if (definedAttrs == null) |
|
363 | if (definedAttrs == null) | |
@@ -383,8 +371,10 namespace Implab.Xml { | |||||
383 |
|
371 | |||
384 | string p; |
|
372 | string p; | |
385 | // auto-define prefixes |
|
373 | // auto-define prefixes | |
386 |
if (! |
|
374 | if (!context.LookupNamespacePrefix(ns, out p)) { | |
387 | p = m_context.CreateNamespacePrefix(ns); |
|
375 | if (context == m_context) | |
|
376 | context = new XmlNameContext(m_context, m_xmlDepth); | |||
|
377 | p = context.CreateNamespacePrefix(ns); | |||
388 | if (definedAttrs == null) |
|
378 | if (definedAttrs == null) | |
389 | definedAttrs = new List<XmlSimpleAttribute>(); |
|
379 | definedAttrs = new List<XmlSimpleAttribute>(); | |
390 |
|
380 | |||
@@ -397,6 +387,9 namespace Implab.Xml { | |||||
397 | attrs = definedAttrs.ToArray(); |
|
387 | attrs = definedAttrs.ToArray(); | |
398 | } |
|
388 | } | |
399 |
|
389 | |||
|
390 | if (!empty) | |||
|
391 | m_context = context; | |||
|
392 | ||||
400 | m_nodeType = XmlNodeType.Element; |
|
393 | m_nodeType = XmlNodeType.Element; | |
401 | m_qName = new XmlQualifiedName(name, ns); |
|
394 | m_qName = new XmlQualifiedName(name, ns); | |
402 | m_prefix = p; |
|
395 | m_prefix = p; | |
@@ -406,14 +399,18 namespace Implab.Xml { | |||||
406 | } |
|
399 | } | |
407 |
|
400 | |||
408 | void EndElementNode(string name, string ns) { |
|
401 | void EndElementNode(string name, string ns) { | |
409 | if (IsSibling()) // closing the element which has children |
|
402 | if (IsSibling()) { | |
|
403 | // closing the element which has children | |||
410 | m_xmlDepth--; |
|
404 | m_xmlDepth--; | |
|
405 | } | |||
411 |
|
406 | |||
412 | string p; |
|
407 | string p; | |
413 | if (!m_context.LookupNamespacePrefix(ns, out p)) |
|
408 | if (!m_context.LookupNamespacePrefix(ns, out p)) | |
414 | throw new Exception($"Failed to lookup namespace '{ns}'"); |
|
409 | throw new Exception($"Failed to lookup namespace '{ns}'"); | |
415 |
|
410 | |||
416 | m_context = m_context.ParentContext; |
|
411 | if (m_context.Depth == m_xmlDepth) | |
|
412 | m_context = m_context.ParentContext; | |||
|
413 | ||||
417 | m_nodeType = XmlNodeType.EndElement; |
|
414 | m_nodeType = XmlNodeType.EndElement; | |
418 | m_prefix = p; |
|
415 | m_prefix = p; | |
419 | m_qName = new XmlQualifiedName(name, ns); |
|
416 | m_qName = new XmlQualifiedName(name, ns); | |
@@ -456,7 +453,10 namespace Implab.Xml { | |||||
456 | break; |
|
453 | break; | |
457 | case JsonXmlReaderPosition.ValueElement: |
|
454 | case JsonXmlReaderPosition.ValueElement: | |
458 | if (!m_isEmpty) { |
|
455 | if (!m_isEmpty) { | |
459 |
|
|
456 | if (m_parser.ElementValue != null && !m_parser.ElementValue.Equals(string.Empty)) | |
|
457 | ValueNode(m_parser.ElementValue); | |||
|
458 | else | |||
|
459 | goto case JsonXmlReaderPosition.ValueContent; | |||
460 | m_position = JsonXmlReaderPosition.ValueContent; |
|
460 | m_position = JsonXmlReaderPosition.ValueContent; | |
461 | return true; |
|
461 | return true; | |
462 | } else { |
|
462 | } else { | |
@@ -521,7 +521,7 namespace Implab.Xml { | |||||
521 | true |
|
521 | true | |
522 | ); |
|
522 | ); | |
523 | else |
|
523 | else | |
524 |
ElementNode(m_jsonValueName, m_jsonNamespace, elementAttrs, m_parser.ElementValue |
|
524 | ElementNode(m_jsonValueName, m_jsonNamespace, elementAttrs, m_parser.ElementValue.Equals(string.Empty)); | |
525 | break; |
|
525 | break; | |
526 | default: |
|
526 | default: | |
527 | throw new Exception($"Unexpected JSON element {m_parser.ElementType}: {m_parser.ElementName}"); |
|
527 | throw new Exception($"Unexpected JSON element {m_parser.ElementType}: {m_parser.ElementName}"); |
@@ -5,7 +5,7 using System.Text; | |||||
5 | using System.Threading.Tasks; |
|
5 | using System.Threading.Tasks; | |
6 |
|
6 | |||
7 | namespace Implab.Xml { |
|
7 | namespace Implab.Xml { | |
8 |
|
|
8 | enum JsonXmlReaderPosition { | |
9 | Initial, |
|
9 | Initial, | |
10 | Declaration, |
|
10 | Declaration, | |
11 | BeginArray, |
|
11 | BeginArray, |
@@ -6,7 +6,7 using System.Threading.Tasks; | |||||
6 | using System.Xml; |
|
6 | using System.Xml; | |
7 |
|
7 | |||
8 | namespace Implab.Xml { |
|
8 | namespace Implab.Xml { | |
9 |
|
|
9 | class XmlNameContext { | |
10 | public const string XmlnsNamespace = "http://www.w3.org/2000/xmlns/"; |
|
10 | public const string XmlnsNamespace = "http://www.w3.org/2000/xmlns/"; | |
11 | public const string XmlnsPrefix = "xmlns"; |
|
11 | public const string XmlnsPrefix = "xmlns"; | |
12 | public const string XmlNamespace = "http://www.w3.org/XML/1998/namespace"; |
|
12 | public const string XmlNamespace = "http://www.w3.org/XML/1998/namespace"; | |
@@ -19,11 +19,17 namespace Implab.Xml { | |||||
19 | Dictionary<string, string> m_ns2prefix; |
|
19 | Dictionary<string, string> m_ns2prefix; | |
20 | Dictionary<string, string> m_prefix2ns; |
|
20 | Dictionary<string, string> m_prefix2ns; | |
21 | int m_nextPrefix = 1; |
|
21 | int m_nextPrefix = 1; | |
|
22 | string m_lastNs; | |||
|
23 | string m_lastPrefix; | |||
22 |
|
24 | |||
23 | public XmlNameContext ParentContext { get; private set; } |
|
25 | public XmlNameContext ParentContext { get; private set; } | |
24 |
|
26 | |||
25 | public XmlNameContext(XmlNameContext parent) { |
|
27 | public int Depth { get; private set; } | |
|
28 | ||||
|
29 | public XmlNameContext(XmlNameContext parent, int depth) { | |||
26 | ParentContext = parent; |
|
30 | ParentContext = parent; | |
|
31 | Depth = depth; | |||
|
32 | ||||
27 | if (parent == null) { |
|
33 | if (parent == null) { | |
28 | DefinePrefixNoCheck(XmlnsNamespace, XmlnsPrefix); |
|
34 | DefinePrefixNoCheck(XmlnsNamespace, XmlnsPrefix); | |
29 | DefinePrefixNoCheck(XmlNamespace, XmlPrefix); |
|
35 | DefinePrefixNoCheck(XmlNamespace, XmlPrefix); | |
@@ -35,12 +41,17 namespace Implab.Xml { | |||||
35 | public bool LookupNamespacePrefix(string ns, out string prefix) { |
|
41 | public bool LookupNamespacePrefix(string ns, out string prefix) { | |
36 | if (ns == null) |
|
42 | if (ns == null) | |
37 | ns = string.Empty; |
|
43 | ns = string.Empty; | |
|
44 | if (ns == m_lastNs) { | |||
|
45 | prefix = m_lastPrefix; | |||
|
46 | return true; | |||
|
47 | } | |||
|
48 | ||||
38 |
|
49 | |||
39 | prefix = null; |
|
50 | prefix = null; | |
40 | for (var ctx = this; ctx != null; ctx = ctx.ParentContext) { |
|
51 | for (var ctx = this; ctx != null; ctx = ctx.ParentContext) { | |
41 |
if (ctx.m_ns2prefix |
|
52 | if (ctx.m_ns2prefix != null && ctx.m_ns2prefix.TryGetValue(ns, out prefix)) { | |
42 | if (ctx != this) // cache for the future use |
|
53 | m_lastNs = ns; | |
43 |
|
|
54 | m_lastPrefix = prefix; | |
44 | return true; |
|
55 | return true; | |
45 | } |
|
56 | } | |
46 | } |
|
57 | } | |
@@ -88,11 +99,8 namespace Implab.Xml { | |||||
88 | prefix = string.Empty; |
|
99 | prefix = string.Empty; | |
89 | string ns = null; |
|
100 | string ns = null; | |
90 | for(var ctx = this; ctx != null; ctx = ctx.ParentContext) { |
|
101 | for(var ctx = this; ctx != null; ctx = ctx.ParentContext) { | |
91 |
if (ctx.m_prefix2ns |
|
102 | if (ctx.m_prefix2ns != null && ctx.m_prefix2ns.TryGetValue(prefix, out ns) == true) | |
92 | if (ctx != this) // cache for the future use |
|
|||
93 | DefinePrefixNoCheck(ns, prefix); |
|
|||
94 | return ns; |
|
103 | return ns; | |
95 | } |
|
|||
96 | } |
|
104 | } | |
97 | return null; |
|
105 | return null; | |
98 | } |
|
106 | } |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now