# HG changeset patch
# User cin
# Date 1505945667 -10800
# Node ID 133ba4444accbdff9ad910c2052121a2f8e31968
# Parent 3eaa9372c75403ba69b0a023f114fc53176ff8ee# Parent 3e26338eb97732f552aaf60ac01bc23116429d02
Слияние
diff -r 3eaa9372c754 -r 133ba4444acc Implab.mono.sln
--- a/Implab.mono.sln Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
- ProjectSection(SolutionItems) = preProject
- Implab.vsmdi = Implab.vsmdi
- Local.testsettings = Local.testsettings
- TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BCA337C3-BFDC-4825-BBDB-E6D467E4E452}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test.mono", "Implab.Test\Implab.Test.mono.csproj", "{2BD05F84-E067-4B87-9477-FDC2676A21C6}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Format.Test", "Implab.Test\Implab.Format.Test\Implab.Format.Test.csproj", "{4D364996-7ECD-4193-8F90-F223FFEA49DA}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoPlay", "MonoPlay\MonoPlay.csproj", "{15DD7123-D504-4627-8B4F-D00C7F04D033}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- Debug 4.5|Any CPU = Debug 4.5|Any CPU
- Release 4.5|Any CPU = Release 4.5|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Release 4.5|Any CPU.Build.0 = Release|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {15DD7123-D504-4627-8B4F-D00C7F04D033}.Release|Any CPU.Build.0 = Release|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.Build.0 = Release|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.Build.0 = Release|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.Build.0 = Release|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
- {4D364996-7ECD-4193-8F90-F223FFEA49DA} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
- EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
- Policies = $0
- $0.CSharpFormattingPolicy = $1
- $1.IndentSwitchBody = True
- $1.NamespaceBraceStyle = EndOfLine
- $1.ClassBraceStyle = EndOfLine
- $1.InterfaceBraceStyle = EndOfLine
- $1.StructBraceStyle = EndOfLine
- $1.EnumBraceStyle = EndOfLine
- $1.MethodBraceStyle = EndOfLine
- $1.ConstructorBraceStyle = EndOfLine
- $1.DestructorBraceStyle = EndOfLine
- $1.BeforeMethodDeclarationParentheses = False
- $1.BeforeMethodCallParentheses = False
- $1.BeforeConstructorDeclarationParentheses = False
- $1.NewLineBeforeConstructorInitializerColon = NewLine
- $1.NewLineAfterConstructorInitializerColon = SameLine
- $1.BeforeIndexerDeclarationBracket = False
- $1.BeforeDelegateDeclarationParentheses = False
- $1.NewParentheses = False
- $1.SpacesBeforeBrackets = False
- $1.inheritsSet = Mono
- $1.inheritsScope = text/x-csharp
- $1.scope = text/x-csharp
- $0.TextStylePolicy = $2
- $2.FileWidth = 120
- $2.EolMarker = Unix
- $2.inheritsSet = VisualStudio
- $2.inheritsScope = text/plain
- $2.scope = text/x-csharp
- $0.DotNetNamingPolicy = $3
- $3.DirectoryNamespaceAssociation = PrefixedHierarchical
- $3.ResourceNamePolicy = MSBuild
- $0.TextStylePolicy = $4
- $4.FileWidth = 120
- $4.TabsToSpaces = False
- $4.inheritsSet = VisualStudio
- $4.inheritsScope = text/plain
- $4.scope = application/xml
- $0.XmlFormattingPolicy = $5
- $5.inheritsSet = Mono
- $5.inheritsScope = application/xml
- $5.scope = application/xml
- $0.TextStylePolicy = $6
- $6.FileWidth = 120
- $6.TabsToSpaces = False
- $6.inheritsSet = VisualStudio
- $6.inheritsScope = text/plain
- $6.scope = text/plain
- $0.NameConventionPolicy = $7
- $7.Rules = $8
- $8.NamingRule = $9
- $9.Name = Namespaces
- $9.AffectedEntity = Namespace
- $9.VisibilityMask = VisibilityMask
- $9.NamingStyle = PascalCase
- $9.IncludeInstanceMembers = True
- $9.IncludeStaticEntities = True
- $8.NamingRule = $10
- $10.Name = Types
- $10.AffectedEntity = Class, Struct, Enum, Delegate
- $10.VisibilityMask = VisibilityMask
- $10.NamingStyle = PascalCase
- $10.IncludeInstanceMembers = True
- $10.IncludeStaticEntities = True
- $8.NamingRule = $11
- $11.Name = Interfaces
- $11.RequiredPrefixes = $12
- $12.String = I
- $11.AffectedEntity = Interface
- $11.VisibilityMask = VisibilityMask
- $11.NamingStyle = PascalCase
- $11.IncludeInstanceMembers = True
- $11.IncludeStaticEntities = True
- $8.NamingRule = $13
- $13.Name = Attributes
- $13.RequiredSuffixes = $14
- $14.String = Attribute
- $13.AffectedEntity = CustomAttributes
- $13.VisibilityMask = VisibilityMask
- $13.NamingStyle = PascalCase
- $13.IncludeInstanceMembers = True
- $13.IncludeStaticEntities = True
- $8.NamingRule = $15
- $15.Name = Event Arguments
- $15.RequiredSuffixes = $16
- $16.String = EventArgs
- $15.AffectedEntity = CustomEventArgs
- $15.VisibilityMask = VisibilityMask
- $15.NamingStyle = PascalCase
- $15.IncludeInstanceMembers = True
- $15.IncludeStaticEntities = True
- $8.NamingRule = $17
- $17.Name = Exceptions
- $17.RequiredSuffixes = $18
- $18.String = Exception
- $17.AffectedEntity = CustomExceptions
- $17.VisibilityMask = VisibilityMask
- $17.NamingStyle = PascalCase
- $17.IncludeInstanceMembers = True
- $17.IncludeStaticEntities = True
- $8.NamingRule = $19
- $19.Name = Methods
- $19.AffectedEntity = Methods
- $19.VisibilityMask = VisibilityMask
- $19.NamingStyle = PascalCase
- $19.IncludeInstanceMembers = True
- $19.IncludeStaticEntities = True
- $8.NamingRule = $20
- $20.Name = Static Readonly Fields
- $20.AffectedEntity = ReadonlyField
- $20.VisibilityMask = Internal, Protected, Public
- $20.NamingStyle = PascalCase
- $20.IncludeInstanceMembers = False
- $20.IncludeStaticEntities = True
- $8.NamingRule = $21
- $21.Name = Fields (Non Private)
- $21.AffectedEntity = Field
- $21.VisibilityMask = Internal, Public
- $21.NamingStyle = CamelCase
- $21.IncludeInstanceMembers = True
- $21.IncludeStaticEntities = True
- $8.NamingRule = $22
- $22.Name = ReadOnly Fields (Non Private)
- $22.AffectedEntity = ReadonlyField
- $22.VisibilityMask = Internal, Public
- $22.NamingStyle = CamelCase
- $22.IncludeInstanceMembers = True
- $22.IncludeStaticEntities = False
- $8.NamingRule = $23
- $23.Name = Fields (Private)
- $23.RequiredPrefixes = $24
- $24.String = m_
- $23.AffectedEntity = Field, ReadonlyField
- $23.VisibilityMask = Private, Protected
- $23.NamingStyle = CamelCase
- $23.IncludeInstanceMembers = True
- $23.IncludeStaticEntities = False
- $8.NamingRule = $25
- $25.Name = Static Fields (Private)
- $25.RequiredPrefixes = $26
- $26.String = _
- $25.AffectedEntity = Field
- $25.VisibilityMask = Private
- $25.NamingStyle = CamelCase
- $25.IncludeInstanceMembers = False
- $25.IncludeStaticEntities = True
- $8.NamingRule = $27
- $27.Name = ReadOnly Fields (Private)
- $27.RequiredPrefixes = $28
- $28.String = m_
- $27.AffectedEntity = ReadonlyField
- $27.VisibilityMask = Private, Protected
- $27.NamingStyle = CamelCase
- $27.IncludeInstanceMembers = True
- $27.IncludeStaticEntities = False
- $8.NamingRule = $29
- $29.Name = Constant Fields
- $29.AffectedEntity = ConstantField
- $29.VisibilityMask = VisibilityMask
- $29.NamingStyle = AllUpper
- $29.IncludeInstanceMembers = True
- $29.IncludeStaticEntities = True
- $8.NamingRule = $30
- $30.Name = Properties
- $30.AffectedEntity = Property
- $30.VisibilityMask = VisibilityMask
- $30.NamingStyle = PascalCase
- $30.IncludeInstanceMembers = True
- $30.IncludeStaticEntities = True
- $8.NamingRule = $31
- $31.Name = Events
- $31.AffectedEntity = Event
- $31.VisibilityMask = VisibilityMask
- $31.NamingStyle = PascalCase
- $31.IncludeInstanceMembers = True
- $31.IncludeStaticEntities = True
- $8.NamingRule = $32
- $32.Name = Enum Members
- $32.AffectedEntity = EnumMember
- $32.VisibilityMask = VisibilityMask
- $32.NamingStyle = PascalCase
- $32.IncludeInstanceMembers = True
- $32.IncludeStaticEntities = True
- $8.NamingRule = $33
- $33.Name = Parameters
- $33.AffectedEntity = Parameter, LocalVariable
- $33.VisibilityMask = VisibilityMask
- $33.NamingStyle = CamelCase
- $33.IncludeInstanceMembers = True
- $33.IncludeStaticEntities = True
- $8.NamingRule = $34
- $34.Name = Type Parameters
- $34.RequiredPrefixes = $35
- $35.String = T
- $34.AffectedEntity = TypeParameter
- $34.VisibilityMask = VisibilityMask
- $34.NamingStyle = PascalCase
- $34.IncludeInstanceMembers = True
- $34.IncludeStaticEntities = True
- version = 0.2
- StartupItem = MonoPlay\MonoPlay.csproj
- EndGlobalSection
- GlobalSection(TestCaseManagementSettings) = postSolution
- CategoryFile = Implab.vsmdi
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff -r 3eaa9372c754 -r 133ba4444acc Implab.sln
--- a/Implab.sln Thu Sep 21 01:06:32 2017 +0300
+++ b/Implab.sln Thu Sep 21 01:14:27 2017 +0300
@@ -75,188 +75,6 @@
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
- StartupItem = Implab\Implab.csproj
- Policies = $0
- $0.CSharpFormattingPolicy = $1
- $1.IndentSwitchBody = True
- $1.NamespaceBraceStyle = EndOfLine
- $1.ClassBraceStyle = EndOfLine
- $1.InterfaceBraceStyle = EndOfLine
- $1.StructBraceStyle = EndOfLine
- $1.EnumBraceStyle = EndOfLine
- $1.MethodBraceStyle = EndOfLine
- $1.ConstructorBraceStyle = EndOfLine
- $1.DestructorBraceStyle = EndOfLine
- $1.BeforeMethodDeclarationParentheses = False
- $1.BeforeMethodCallParentheses = False
- $1.BeforeConstructorDeclarationParentheses = False
- $1.NewLineBeforeConstructorInitializerColon = NewLine
- $1.NewLineAfterConstructorInitializerColon = SameLine
- $1.BeforeIndexerDeclarationBracket = False
- $1.BeforeDelegateDeclarationParentheses = False
- $1.NewParentheses = False
- $1.SpacesBeforeBrackets = False
- $1.inheritsSet = Mono
- $1.inheritsScope = text/x-csharp
- $1.scope = text/x-csharp
- $0.TextStylePolicy = $6
- $2.FileWidth = 120
- $2.EolMarker = Unix
- $2.inheritsSet = VisualStudio
- $2.inheritsScope = text/plain
- $2.scope = text/x-csharp
- $0.DotNetNamingPolicy = $3
- $3.DirectoryNamespaceAssociation = PrefixedHierarchical
- $3.ResourceNamePolicy = MSBuild
- $4.FileWidth = 120
- $4.TabsToSpaces = False
- $4.inheritsSet = VisualStudio
- $4.inheritsScope = text/plain
- $4.scope = application/xml
- $0.XmlFormattingPolicy = $5
- $5.inheritsSet = Mono
- $5.inheritsScope = application/xml
- $5.scope = application/xml
- $6.FileWidth = 120
- $6.TabsToSpaces = False
- $6.inheritsSet = VisualStudio
- $6.inheritsScope = text/plain
- $6.scope = text/plain
- $0.NameConventionPolicy = $7
- $7.Rules = $8
- $8.NamingRule = $34
- $9.Name = Namespaces
- $9.AffectedEntity = Namespace
- $9.VisibilityMask = VisibilityMask
- $9.NamingStyle = PascalCase
- $9.IncludeInstanceMembers = True
- $9.IncludeStaticEntities = True
- $10.Name = Types
- $10.AffectedEntity = Class, Struct, Enum, Delegate
- $10.VisibilityMask = VisibilityMask
- $10.NamingStyle = PascalCase
- $10.IncludeInstanceMembers = True
- $10.IncludeStaticEntities = True
- $11.Name = Interfaces
- $11.RequiredPrefixes = $12
- $12.String = I
- $11.AffectedEntity = Interface
- $11.VisibilityMask = VisibilityMask
- $11.NamingStyle = PascalCase
- $11.IncludeInstanceMembers = True
- $11.IncludeStaticEntities = True
- $13.Name = Attributes
- $13.RequiredSuffixes = $14
- $14.String = Attribute
- $13.AffectedEntity = CustomAttributes
- $13.VisibilityMask = VisibilityMask
- $13.NamingStyle = PascalCase
- $13.IncludeInstanceMembers = True
- $13.IncludeStaticEntities = True
- $15.Name = Event Arguments
- $15.RequiredSuffixes = $16
- $16.String = EventArgs
- $15.AffectedEntity = CustomEventArgs
- $15.VisibilityMask = VisibilityMask
- $15.NamingStyle = PascalCase
- $15.IncludeInstanceMembers = True
- $15.IncludeStaticEntities = True
- $17.Name = Exceptions
- $17.RequiredSuffixes = $18
- $18.String = Exception
- $17.AffectedEntity = CustomExceptions
- $17.VisibilityMask = VisibilityMask
- $17.NamingStyle = PascalCase
- $17.IncludeInstanceMembers = True
- $17.IncludeStaticEntities = True
- $19.Name = Methods
- $19.AffectedEntity = Methods
- $19.VisibilityMask = VisibilityMask
- $19.NamingStyle = PascalCase
- $19.IncludeInstanceMembers = True
- $19.IncludeStaticEntities = True
- $20.Name = Static Readonly Fields
- $20.AffectedEntity = ReadonlyField
- $20.VisibilityMask = Internal, Protected, Public
- $20.NamingStyle = CamelCase
- $20.IncludeInstanceMembers = False
- $20.IncludeStaticEntities = True
- $21.Name = Fields (Non Private)
- $21.AffectedEntity = Field
- $21.VisibilityMask = Internal, Public
- $21.NamingStyle = CamelCase
- $21.IncludeInstanceMembers = True
- $21.IncludeStaticEntities = True
- $22.Name = ReadOnly Fields (Non Private)
- $22.AffectedEntity = ReadonlyField
- $22.VisibilityMask = Internal, Public
- $22.NamingStyle = CamelCase
- $22.IncludeInstanceMembers = True
- $22.IncludeStaticEntities = False
- $23.Name = Fields (Private)
- $23.RequiredPrefixes = $24
- $24.String = m_
- $23.AffectedEntity = Field, ReadonlyField
- $23.VisibilityMask = Private, Protected
- $23.NamingStyle = CamelCase
- $23.IncludeInstanceMembers = True
- $23.IncludeStaticEntities = False
- $25.Name = Static Fields (Private)
- $25.RequiredPrefixes = $26
- $26.String = _
- $25.AffectedEntity = Field
- $25.VisibilityMask = Private
- $25.NamingStyle = CamelCase
- $25.IncludeInstanceMembers = False
- $25.IncludeStaticEntities = True
- $27.Name = ReadOnly Fields (Private)
- $27.RequiredPrefixes = $28
- $28.String = m_
- $27.AffectedEntity = ReadonlyField
- $27.VisibilityMask = Private, Protected
- $27.NamingStyle = CamelCase
- $27.IncludeInstanceMembers = True
- $27.IncludeStaticEntities = False
- $29.Name = Constant Fields
- $29.AffectedEntity = ConstantField
- $29.VisibilityMask = VisibilityMask
- $29.NamingStyle = AllUpper
- $29.IncludeInstanceMembers = True
- $29.IncludeStaticEntities = True
- $30.Name = Properties
- $30.AffectedEntity = Property
- $30.VisibilityMask = VisibilityMask
- $30.NamingStyle = PascalCase
- $30.IncludeInstanceMembers = True
- $30.IncludeStaticEntities = True
- $31.Name = Events
- $31.AffectedEntity = Event
- $31.VisibilityMask = VisibilityMask
- $31.NamingStyle = PascalCase
- $31.IncludeInstanceMembers = True
- $31.IncludeStaticEntities = True
- $32.Name = Enum Members
- $32.AffectedEntity = EnumMember
- $32.VisibilityMask = VisibilityMask
- $32.NamingStyle = PascalCase
- $32.IncludeInstanceMembers = True
- $32.IncludeStaticEntities = True
- $33.Name = Parameters
- $33.AffectedEntity = Parameter, LocalVariable
- $33.VisibilityMask = VisibilityMask
- $33.NamingStyle = CamelCase
- $33.IncludeInstanceMembers = True
- $33.IncludeStaticEntities = True
- $34.Name = Type Parameters
- $34.RequiredPrefixes = $35
- $35.String = T
- $34.AffectedEntity = TypeParameter
- $34.VisibilityMask = VisibilityMask
- $34.NamingStyle = PascalCase
- $34.IncludeInstanceMembers = True
- $34.IncludeStaticEntities = True
- EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Implab.vsmdi
EndGlobalSection
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonElementContext.cs
--- a/Implab/Formats/JSON/JsonElementContext.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-namespace Implab.Formats.Json {
- ///
- /// internal
- ///
- enum JsonElementContext {
- None,
- Object,
- Array,
- Closed
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonElementType.cs
--- a/Implab/Formats/JSON/JsonElementType.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-namespace Implab.Formats.Json {
- ///
- /// Тип элемента на котором находится парсер
- ///
- public enum JsonElementType {
- None,
- ///
- /// Начало объекта
- ///
- BeginObject,
- ///
- /// Конец объекта
- ///
- EndObject,
- ///
- /// Начало массива
- ///
- BeginArray,
- ///
- /// Конец массива
- ///
- EndArray,
- ///
- /// Простое значение
- ///
- Value
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonGrammar.cs
--- a/Implab/Formats/JSON/JsonGrammar.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-using System.Linq;
-using Implab.Automaton.RegularExpressions;
-using System;
-using Implab.Automaton;
-using Implab.Components;
-
-namespace Implab.Formats.Json {
- public class JsonGrammar : Grammar {
- public enum TokenType {
- None,
- BeginObject,
- EndObject,
- BeginArray,
- EndArray,
- String,
- Number,
- Literal,
- NameSeparator,
- ValueSeparator,
- Whitespace,
-
- StringBound,
- EscapedChar,
- UnescapedChar,
- EscapedUnicode
- }
-
- static LazyAndWeak _instance = new LazyAndWeak(() => new JsonGrammar());
-
- public static JsonGrammar Instance {
- get { return _instance.Value; }
- }
-
- readonly InputScanner m_jsonExpression;
- readonly InputScanner m_stringExpression;
- readonly CharAlphabet m_defaultAlphabet = new CharAlphabet();
-
- public CharAlphabet DefaultAlphabet { get { return m_defaultAlphabet; } }
-
- public JsonGrammar() {
- DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
- var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
- var digit9 = SymbolRangeToken('1', '9');
- var zero = SymbolToken('0');
- var digit = zero.Or(digit9);
- var dot = SymbolToken('.');
- var minus = SymbolToken('-');
- var sign = SymbolSetToken('-', '+');
- var expSign = SymbolSetToken('e', 'E');
- var letters = SymbolRangeToken('a', 'z');
- var integer = zero.Or(digit9.Cat(digit.EClosure()));
- var frac = dot.Cat(digit.Closure());
- var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
- var quote = SymbolToken('"');
- var backSlash = SymbolToken('\\');
- var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
- var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
- var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
- var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
- var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
- var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
- var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
- var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
- var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
-
- var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
- var literal = letters.Closure();
- var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
-
- var jsonExpression =
- number.Tag(TokenType.Number)
- .Or(literal.Tag(TokenType.Literal))
- .Or(quote.Tag(TokenType.StringBound))
- .Or(beginObject.Tag(TokenType.BeginObject))
- .Or(endObject.Tag(TokenType.EndObject))
- .Or(beginArray.Tag(TokenType.BeginArray))
- .Or(endArray.Tag(TokenType.EndArray))
- .Or(nameSep.Tag(TokenType.NameSeparator))
- .Or(valueSep.Tag(TokenType.ValueSeparator))
- .Or(SymbolSetToken('\n', '\r', '\t', ' ').Closure().Tag(TokenType.Whitespace));
-
-
- var jsonStringExpression =
- quote.Tag(TokenType.StringBound)
- .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
- .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
- .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
-
-
- m_jsonExpression = BuildScanner(jsonExpression);
- m_stringExpression = BuildScanner(jsonStringExpression);
- }
-
- public static InputScanner CreateJsonExpressionScanner() {
- return Instance.m_jsonExpression.Clone();
- }
-
- public static InputScanner CreateStringExpressionScanner() {
- return Instance.m_stringExpression.Clone();
- }
-
- protected override IAlphabetBuilder AlphabetBuilder {
- get {
- return m_defaultAlphabet;
- }
- }
-
- Token SymbolRangeToken(char start, char stop) {
- return SymbolToken(Enumerable.Range(start, stop - start + 1).Select(x => (char)x));
- }
-
- public InputScanner BuildScanner(Token regexp) {
- var dfa = new RegularDFA(AlphabetBuilder);
-
- var visitor = new RegularExpressionVisitor(dfa);
- regexp.Accept(visitor);
- visitor.BuildDFA();
-
- if (dfa.IsFinalState(dfa.InitialState))
- throw new ApplicationException("The specified language contains empty token");
-
- var ab = new CharAlphabet();
- var optimal = dfa.Optimize(ab);
-
- return new InputScanner(
- optimal.CreateTransitionTable(),
- optimal.CreateFinalStateTable(),
- NormalizeTags(optimal.CreateTagTable()),
- optimal.InitialState,
- ab.CreateCharMap()
- );
- }
-
- static TokenType[] NormalizeTags(TokenType[][] tags) {
- var result = new TokenType[tags.Length];
- for(var i = 0; i< tags.Length; i++) {
- if (tags[i] == null || tags[i].Length == 0)
- result[i] = default(TokenType);
- else if (tags[i].Length == 1)
- result[i] = tags[i][0];
- else
- throw new Exception($"Ambigous state tags {string.Join(", ", tags[i])}");
- }
- return result;
- }
-
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonReader.cs
--- a/Implab/Formats/JSON/JsonReader.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,318 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using Implab.Automaton;
-using Implab.Automaton.RegularExpressions;
-using System.Linq;
-using Implab.Components;
-using System.Collections.Generic;
-using System.Text;
-using System.Globalization;
-
-namespace Implab.Formats.Json {
- ///
- /// Pull парсер JSON данных.
- ///
- ///
- /// Следует отметить отдельную интерпретацию свойства ,
- /// оно означает текущий уровень вложенности объектов, однако закрывающий
- /// элемент объекта и массива имеет уровень меньше, чем сам объект.
- ///
- /// { // Level = 1
- /// "name" : "Peter", // Level = 1
- /// "address" : { // Level = 2
- /// city : "Stern" // Level = 2
- /// } // Level = 1
- /// } // Level = 0
- ///
- ///
- public class JsonReader : Disposable {
-
- enum MemberContext {
- MemberName,
- MemberValue
- }
-
- #region Parser rules
- struct ParserContext {
- readonly int[,] m_dfa;
- int m_state;
-
- readonly JsonElementContext m_elementContext;
-
- public ParserContext(int[,] dfa, int state, JsonElementContext context) {
- m_dfa = dfa;
- m_state = state;
- m_elementContext = context;
- }
-
- public bool Move(JsonTokenType token) {
- var next = m_dfa[m_state, (int)token];
- if (next == AutomatonConst.UNREACHABLE_STATE)
- return false;
- m_state = next;
- return true;
- }
-
- public JsonElementContext ElementContext {
- get { return m_elementContext; }
- }
- }
-
- static readonly ParserContext _jsonContext;
- static readonly ParserContext _objectContext;
- static readonly ParserContext _arrayContext;
-
- static JsonReader() {
-
- var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
- var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression);
-
- var objectExpression = memberExpression
- .Cat(
- MakeToken(JsonTokenType.ValueSeparator)
- .Cat(memberExpression)
- .EClosure()
- )
- .Optional()
- .Cat(MakeToken(JsonTokenType.EndObject))
- .End();
-
- var arrayExpression = valueExpression
- .Cat(
- MakeToken(JsonTokenType.ValueSeparator)
- .Cat(valueExpression)
- .EClosure()
- )
- .Optional()
- .Cat(MakeToken(JsonTokenType.EndArray))
- .End();
-
- var jsonExpression = valueExpression.End();
-
- _jsonContext = CreateParserContext(jsonExpression, JsonElementContext.None);
- _objectContext = CreateParserContext(objectExpression, JsonElementContext.Object);
- _arrayContext = CreateParserContext(arrayExpression, JsonElementContext.Array);
- }
-
- static Token MakeToken(params JsonTokenType[] input) {
- return Token.New( input.Select(t => (int)t).ToArray() );
- }
-
- static ParserContext CreateParserContext(Token expr, JsonElementContext context) {
-
- var dfa = new DFATable();
- var builder = new RegularExpressionVisitor(dfa);
- expr.Accept(builder);
- builder.BuildDFA();
-
- return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context);
- }
-
- #endregion
-
- readonly JsonScanner m_scanner;
- // json starts from the value context and may content even a single literal
- MemberContext m_memberContext = MemberContext.MemberValue;
-
- JsonElementType m_elementType;
- object m_elementValue;
- string m_memberName = String.Empty;
-
- Stack m_stack = new Stack();
- ParserContext m_context = _jsonContext;
-
- ///
- /// Создает новый парсер на основе строки, содержащей JSON
- ///
- ///
- JsonReader(JsonScanner scanner) {
- m_scanner = scanner;
- }
-
- public int Level {
- get { return m_stack.Count; }
- }
-
- ///
- /// Тип текущего элемента на котором стоит парсер.
- ///
- public JsonElementType ElementType {
- get { return m_elementType; }
- }
-
- ///
- /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
- /// пустая строка.
- ///
- public string ElementName {
- get { return m_memberName; }
- }
-
- ///
- /// Значение элемента. Только для элементов типа , для остальных null
- ///
- public object ElementValue {
- get { return m_elementValue; }
- }
-
- ///
- /// Читает слеюудущий объект из потока
- ///
- /// true - операция чтения прошла успешно, false - конец данных
- public bool Read() {
- string tokenValue;
- JsonTokenType tokenType;
-
- m_memberName = String.Empty;
-
- while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
- if(!m_context.Move(tokenType))
- UnexpectedToken(tokenValue, tokenType);
-
- switch (tokenType) {
- case JsonTokenType.BeginObject:
- m_stack.Push(m_context);
- m_context = _objectContext;
-
- m_elementValue = null;
- m_memberContext = MemberContext.MemberName;
- m_elementType = JsonElementType.BeginObject;
- return true;
- case JsonTokenType.EndObject:
- if (m_stack.Count == 0)
- UnexpectedToken(tokenValue, tokenType);
- m_context = m_stack.Pop();
-
- m_elementValue = null;
- m_elementType = JsonElementType.EndObject;
- return true;
- case JsonTokenType.BeginArray:
- m_stack.Push(m_context);
- m_context = _arrayContext;
-
- m_elementValue = null;
- m_memberContext = MemberContext.MemberValue;
- m_elementType = JsonElementType.BeginArray;
- return true;
- case JsonTokenType.EndArray:
- if (m_stack.Count == 0)
- UnexpectedToken(tokenValue, tokenType);
- m_context = m_stack.Pop();
-
- m_elementValue = null;
- m_elementType = JsonElementType.EndArray;
- return true;
- case JsonTokenType.String:
- if (m_memberContext == MemberContext.MemberName) {
- m_memberName = tokenValue;
- break;
- }
- m_elementType = JsonElementType.Value;
- m_elementValue = tokenValue;
- return true;
- case JsonTokenType.Number:
- m_elementType = JsonElementType.Value;
- m_elementValue = double.Parse(tokenValue, CultureInfo.InvariantCulture);
- return true;
- case JsonTokenType.Literal:
- m_elementType = JsonElementType.Value;
- m_elementValue = ParseLiteral(tokenValue);
- return true;
- case JsonTokenType.NameSeparator:
- m_memberContext = MemberContext.MemberValue;
- break;
- case JsonTokenType.ValueSeparator:
- m_memberContext = m_context.ElementContext == JsonElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
- break;
- default:
- UnexpectedToken(tokenValue, tokenType);
- break;
- }
- }
- if (m_context.ElementContext != JsonElementContext.None)
- throw new ParserException("Unexpedted end of data");
-
- Eof = true;
-
- return false;
- }
-
- object ParseLiteral(string literal) {
- switch (literal) {
- case "null":
- return null;
- case "false":
- return false;
- case "true":
- return true;
- default:
- UnexpectedToken(literal, JsonTokenType.Literal);
- return null; // avoid compliler error
- }
- }
-
- void UnexpectedToken(object value, JsonTokenType tokenType) {
- throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
- }
-
-
- ///
- /// Признак конца потока
- ///
- public bool Eof {
- get;
- private set;
- }
-
- protected override void Dispose(bool disposing) {
- if (disposing)
- m_scanner.Dispose();
- }
-
- ///
- /// Переходит в конец текущего объекта.
- ///
- public void SeekElementEnd() {
- var level = Level - 1;
-
- Debug.Assert(level >= 0);
-
- while (Level != level)
- Read();
- }
-
- public static JsonReader Create(string file, Encoding encoding) {
- return new JsonReader(JsonTextScanner.Create(file, encoding));
- }
-
- public static JsonReader Create(string file) {
- return new JsonReader(JsonTextScanner.Create(file));
- }
-
- public static JsonReader Create(Stream stream, Encoding encoding) {
- return new JsonReader(JsonTextScanner.Create(stream, encoding));
- }
-
- public static JsonReader Create(Stream stream) {
- return new JsonReader(JsonTextScanner.Create(stream));
- }
-
- public static JsonReader Create(TextReader reader) {
- return new JsonReader(JsonTextScanner.Create(reader));
- }
-
- public static JsonReader ParseString(string data) {
- return new JsonReader(JsonStringScanner.Create(data));
- }
-
- public static JsonReader ParseString(string data, int offset, int length) {
- return new JsonReader(JsonStringScanner.Create(data, offset, length));
- }
-
- public static JsonReader ParseString(char[] data, int offset, int lenght) {
- return new JsonReader(JsonStringScanner.Create(data, offset, lenght));
- }
- }
-
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonScanner.cs
--- a/Implab/Formats/JSON/JsonScanner.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-using System;
-using System.Globalization;
-using Implab.Automaton;
-using System.Text;
-using Implab.Components;
-using System.IO;
-
-namespace Implab.Formats.Json {
- ///
- /// Сканнер (лексер), разбивающий поток символов на токены JSON.
- ///
- public abstract class JsonScanner : Disposable {
- readonly InputScanner m_jsonContext = JsonGrammar.CreateJsonExpressionScanner();
- readonly InputScanner m_stringContext = JsonGrammar.CreateStringExpressionScanner();
-
- readonly char[] m_unescapeBuf = new char[4];
- readonly char[] m_buffer;
- int m_length;
- int m_pos;
- readonly StringBuilder m_tokenBuilder = new StringBuilder();
-
- protected JsonScanner(char[] buffer, int pos, int length) {
- m_buffer = buffer;
- m_pos = pos;
- m_length = length;
- }
-
- bool ReadChunk(InputScanner scanner, out JsonGrammar.TokenType tokenType) {
- scanner.ResetState();
-
- while(scanner.Scan(m_buffer, m_pos, m_length)) {
- // scanner requests new data
-
- if (m_pos != m_length) // capture results for the future
- m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos);
-
- // read next data
- m_length = Read(m_buffer, 0, m_buffer.Length);
-
- if (m_length == 0) {
- // no data is read
- if (scanner.Position == m_pos) {
- // scanned hasn't moved, that's the end
- m_pos = 0;
- tokenType = JsonGrammar.TokenType.None;
- return false;
- }
-
- if (scanner.IsFinal) {
- m_pos = 0;
- tokenType = scanner.Tag;
- return true;
- } else {
- throw new ParserException("Unexpected EOF");
- }
- }
-
- m_pos = 0;
- }
- var scannerPos = scanner.Position;
-
- // scanner stops as scannerPos
- if (!scanner.IsFinal)
- throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'");
-
- tokenType = scanner.Tag;
- if (scannerPos != m_pos && tokenType == JsonGrammar.TokenType.Number || tokenType == JsonGrammar.TokenType.Literal)
- m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos);
-
- m_pos = scannerPos;
- return true;
- }
-
- bool ReadStringChunk(InputScanner scanner, out JsonGrammar.TokenType tokenType) {
- scanner.ResetState();
-
- while (scanner.Scan(m_buffer, m_pos, m_length)) {
- // scanner requests new data
-
- if (m_pos != m_length) // capture results for the future
- m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos);
-
- // read next data
- m_length = Read(m_buffer, 0, m_buffer.Length);
-
- if (m_length == 0) {
- // no data is read
- if (scanner.Position == m_pos) {
- // scanned hasn't moved, that's the end
- m_pos = 0;
- tokenType = JsonGrammar.TokenType.None;
- return false;
- }
-
- if (scanner.IsFinal) {
- m_pos = 0;
- tokenType = scanner.Tag;
- return true;
- } else {
- throw new ParserException("Unexpected EOF");
- }
- }
-
- m_pos = 0;
- }
- var scannerPos = scanner.Position;
-
- // scanner stops as scannerPos
- if (!scanner.IsFinal)
- throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'");
-
- if (scannerPos != m_pos) {
- m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos);
- m_pos = scannerPos;
- }
- tokenType = scanner.Tag;
- return true;
- }
-
- protected abstract int Read(char[] buffer, int offset, int size);
-
-
- ///
- /// Читает следующий лексический элемент из входных данных.
- ///
- /// Возвращает значение прочитанного токена.
- /// Возвращает тип прочитанного токена.
- /// true - чтение произведено успешно. false - достигнут конец входных данных
- /// В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
- /// в строках обрабатываются экранированные символы, числа становтся типа double.
- public bool ReadToken(out string tokenValue, out JsonTokenType tokenType) {
- JsonGrammar.TokenType tag;
- m_tokenBuilder.Clear();
- while (ReadChunk(m_jsonContext, out tag)) {
- switch (tag) {
- case JsonGrammar.TokenType.StringBound:
- tokenValue = ReadString();
- tokenType = JsonTokenType.String;
- break;
- case JsonGrammar.TokenType.Number:
- tokenValue = m_tokenBuilder.ToString();
- tokenType = JsonTokenType.Number;
- break;
- case JsonGrammar.TokenType.Literal:
- tokenType = JsonTokenType.Literal;
- tokenValue = m_tokenBuilder.ToString();
- break;
- case JsonGrammar.TokenType.Whitespace:
- m_tokenBuilder.Clear();
- continue;
- default:
- tokenType = (JsonTokenType)tag;
- tokenValue = null;
- break;
- }
- return true;
- }
- tokenValue = null;
- tokenType = JsonTokenType.None;
- return false;
- }
-
- string ReadString() {
- JsonGrammar.TokenType tag;
- m_tokenBuilder.Clear();
-
- while (ReadStringChunk(m_stringContext, out tag)) {
- switch (tag) {
- case JsonGrammar.TokenType.StringBound:
- m_tokenBuilder.Length--;
- return m_tokenBuilder.ToString();
- case JsonGrammar.TokenType.UnescapedChar:
- break;
- case JsonGrammar.TokenType.EscapedUnicode: // \xXXXX - unicode escape sequence
- m_tokenBuilder.CopyTo(m_tokenBuilder.Length - 4, m_unescapeBuf, 0, 4);
- m_tokenBuilder.Length -= 6;
- m_tokenBuilder.Append(StringTranslator.TranslateHexUnicode(m_unescapeBuf, 0));
- break;
- case JsonGrammar.TokenType.EscapedChar: // \t - escape sequence
- var ch = m_tokenBuilder[m_tokenBuilder.Length-1];
- m_tokenBuilder.Length -= 2;
- m_tokenBuilder.Append(StringTranslator.TranslateEscapedChar(ch));
- break;
- }
- }
-
- throw new ParserException("Unexpected end of data");
- }
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonStringScanner.cs
--- a/Implab/Formats/JSON/JsonStringScanner.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.Formats.Json {
- public class JsonStringScanner : JsonScanner {
- const int _defaultBuffer = 64;
-
- readonly string m_data;
- int m_offset;
-
- JsonStringScanner(string data, char[] buffer, int pos, int length, int offset) : base(buffer, pos, length) {
- m_data = data;
- m_offset = offset;
- }
-
- protected override int Read(char[] buffer, int offset, int size) {
- if (m_data == null)
- return 0;
- if (m_offset >= m_data.Length)
- return 0;
-
- var count = Math.Min(size, m_data.Length - m_offset);
-
- m_data.CopyTo(m_offset, buffer, offset, count);
- m_offset += count;
-
- return count;
- }
-
- public static JsonStringScanner Create(string data) {
- Safe.ArgumentNotNull(data, nameof(data));
-
- if (data.Length <= _defaultBuffer)
- return new JsonStringScanner(null, data.ToCharArray(), 0, data.Length, data.Length);
-
- var buffer = new char[_defaultBuffer];
- data.CopyTo(0, buffer, 0, _defaultBuffer);
- return new JsonStringScanner(data, buffer, 0, _defaultBuffer, _defaultBuffer);
- }
-
- public static JsonStringScanner Create(string data, int offset, int length) {
- Safe.ArgumentNotNull(data, nameof(data));
- Safe.ArgumentGreaterThan(offset, 0, nameof(offset));
- Safe.ArgumentGreaterThan(length, 0, nameof(length));
-
- if (offset + length > data.Length)
- throw new ArgumentOutOfRangeException("Specified offset and length are out of the string bounds");
-
- if (length <= _defaultBuffer) {
- var buffer = new char[length];
- data.CopyTo(offset, buffer, 0, length);
-
- return new JsonStringScanner(null, buffer, 0, length, length);
- } else {
- var buffer = new char[_defaultBuffer];
- data.CopyTo(offset, buffer, 0, _defaultBuffer);
- return new JsonStringScanner(data, buffer, 0, _defaultBuffer, offset + _defaultBuffer);
- }
- }
-
- public static JsonStringScanner Create(char[] data, int offset, int length) {
- Safe.ArgumentNotNull(data, nameof(data));
- Safe.ArgumentGreaterThan(offset, 0, nameof(offset));
- Safe.ArgumentGreaterThan(length, 0, nameof(length));
-
- if (offset + length > data.Length)
- throw new ArgumentOutOfRangeException("Specified offset and length are out of the array bounds");
-
- return new JsonStringScanner(null, data, offset, offset + length, offset + length);
-
- }
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonTextScanner.cs
--- a/Implab/Formats/JSON/JsonTextScanner.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.Formats.Json {
- public class JsonTextScanner : JsonScanner {
- const int _bufferSize = 16*4096;
- readonly TextReader m_reader;
-
- JsonTextScanner(TextReader reader, char[] buffer) : base(buffer, 0, 0) {
- m_reader = reader;
- }
-
- protected override int Read(char[] buffer, int offset, int size) {
- return m_reader.Read(buffer, offset, size);
- }
-
- public static JsonTextScanner Create(string file, Encoding encoding) {
- return new JsonTextScanner(new StreamReader(file, encoding), new char[_bufferSize]);
- }
-
- public static JsonTextScanner Create(string file) {
- return new JsonTextScanner(new StreamReader(file), new char[_bufferSize]);
- }
-
- public static JsonTextScanner Create(Stream stream, Encoding encoding) {
- return new JsonTextScanner(new StreamReader(stream, encoding), new char[_bufferSize]);
- }
-
- public static JsonTextScanner Create(Stream stream) {
- return new JsonTextScanner(new StreamReader(stream), new char[_bufferSize]);
- }
-
- public static JsonTextScanner Create(TextReader reader) {
- Safe.ArgumentNotNull(reader, nameof(reader));
- return new JsonTextScanner(reader, new char[_bufferSize]);
- }
-
- protected override void Dispose(bool disposing) {
- if (disposing)
- Safe.Dispose(m_reader);
-
- base.Dispose(disposing);
- }
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonTokenType.cs
--- a/Implab/Formats/JSON/JsonTokenType.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-namespace Implab.Formats.Json {
- ///
- /// Тип токенов, возвращаемых .
- ///
- public enum JsonTokenType : int {
- None = 0,
- ///
- /// Начало объекта
- ///
- BeginObject,
- ///
- /// Конец объекта
- ///
- EndObject,
- ///
- /// Начало массива
- ///
- BeginArray,
- ///
- /// Конец массива
- ///
- EndArray,
- ///
- /// Строка
- ///
- String,
- ///
- /// Число
- ///
- Number,
- ///
- /// Литерал
- ///
- Literal,
- ///
- /// Разделитель имени :
- ///
- NameSeparator,
- ///
- /// Разделитель имени ,
- ///
- ValueSeparator
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/JsonWriter.cs
--- a/Implab/Formats/JSON/JsonWriter.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,319 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace Implab.Formats.Json {
- public class JsonWriter {
- struct Context {
- public bool needComma;
- public JsonElementContext element;
- }
- Stack m_contextStack = new Stack();
- Context m_context;
-
- const int BUFFER_SIZE = 64;
-
- TextWriter m_writer;
- readonly bool m_indent = true;
- readonly int m_indentSize = 4;
- readonly char[] m_buffer = new char[BUFFER_SIZE];
- int m_bufferPos;
-
- static readonly char [] _hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- static readonly char [] _escapeBKS,
- _escapeFWD,
- _escapeCR,
- _escapeNL,
- _escapeTAB,
- _escapeBSLASH,
- _escapeQ;
-
- static JsonWriter() {
- _escapeBKS = "\\b".ToCharArray();
- _escapeFWD = "\\f".ToCharArray();
- _escapeCR = "\\r".ToCharArray();
- _escapeNL = "\\n".ToCharArray();
- _escapeTAB = "\\t".ToCharArray();
- _escapeBSLASH = "\\\\".ToCharArray();
- _escapeQ = "\\\"".ToCharArray();
- }
-
- public JsonWriter(TextWriter writer) {
- Safe.ArgumentNotNull(writer, "writer");
- m_writer = writer;
- }
-
- public JsonWriter(TextWriter writer, bool indent) {
- Safe.ArgumentNotNull(writer, "writer");
-
- m_writer = writer;
- m_indent = indent;
- }
-
- void WriteIndent() {
- if (m_indent) {
- var indent = new char[m_contextStack.Count * m_indentSize + 1];
- indent[0] = '\n';
- for (int i = 1; i < indent.Length; i++)
- indent[i] = ' ';
- m_writer.Write(new String(indent));
- } else {
- m_writer.Write(' ');
- }
- }
-
- void WriteMemberName(string name) {
- Safe.ArgumentNotEmpty(name, "name");
- if (m_context.element != JsonElementContext.Object)
- OperationNotApplicable("WriteMember");
- if (m_context.needComma)
- m_writer.Write(",");
-
- WriteIndent();
- m_context.needComma = true;
- Write(name);
- m_writer.Write(" : ");
- }
-
- public void WriteValue(string name, string value) {
- WriteMemberName(name);
- Write(value);
- }
-
- public void WriteValue(string name, bool value) {
- WriteMemberName(name);
- Write(value);
- }
-
- public void WriteValue(string name, double value) {
- WriteMemberName(name);
- Write(value);
- }
-
- public void WriteValue(string value) {
- if (m_context.element == JsonElementContext.Array) {
-
- if (m_context.needComma)
- m_writer.Write(",");
- WriteIndent();
- m_context.needComma = true;
-
- Write(value);
- } else if (m_context.element == JsonElementContext.None) {
- Write(value);
- m_context.element = JsonElementContext.Closed;
- } else {
- OperationNotApplicable("WriteValue");
- }
- }
-
- public void WriteValue(bool value) {
- if (m_context.element == JsonElementContext.Array) {
-
- if (m_context.needComma)
- m_writer.Write(",");
- WriteIndent();
- m_context.needComma = true;
-
- Write(value);
- } else if (m_context.element == JsonElementContext.None) {
- Write(value);
- m_context.element = JsonElementContext.Closed;
- } else {
- OperationNotApplicable("WriteValue");
- }
- }
-
- public void WriteValue(double value) {
- if (m_context.element == JsonElementContext.Array) {
-
- if (m_context.needComma)
- m_writer.Write(",");
- WriteIndent();
- m_context.needComma = true;
-
- Write(value);
- } else if (m_context.element == JsonElementContext.None) {
- Write(value);
- m_context.element = JsonElementContext.Closed;
- } else {
- OperationNotApplicable("WriteValue");
- }
- }
-
- public void BeginObject() {
- if (m_context.element != JsonElementContext.None && m_context.element != JsonElementContext.Array)
- OperationNotApplicable("BeginObject");
- if (m_context.needComma)
- m_writer.Write(",");
-
- WriteIndent();
-
- m_context.needComma = true;
-
- m_contextStack.Push(m_context);
-
- m_context = new Context { element = JsonElementContext.Object, needComma = false };
- m_writer.Write("{");
- }
-
- public void BeginObject(string name) {
- WriteMemberName(name);
-
- m_contextStack.Push(m_context);
-
- m_context = new Context { element = JsonElementContext.Object, needComma = false };
- m_writer.Write("{");
- }
-
- public void EndObject() {
- if (m_context.element != JsonElementContext.Object)
- OperationNotApplicable("EndObject");
-
- m_context = m_contextStack.Pop();
- if (m_contextStack.Count == 0)
- m_context.element = JsonElementContext.Closed;
- WriteIndent();
- m_writer.Write("}");
- }
-
- public void BeginArray() {
- if (m_context.element != JsonElementContext.None && m_context.element != JsonElementContext.Array)
- throw new InvalidOperationException();
- if (m_context.needComma) {
- m_writer.Write(",");
-
- }
- m_context.needComma = true;
-
- WriteIndent();
- m_contextStack.Push(m_context);
- m_context = new Context { element = JsonElementContext.Array, needComma = false };
- m_writer.Write("[");
- }
-
- public void BeginArray(string name) {
- WriteMemberName(name);
-
- m_contextStack.Push(m_context);
-
- m_context = new Context { element = JsonElementContext.Array, needComma = false };
- m_writer.Write("[");
- }
-
- public void EndArray() {
- if (m_context.element != JsonElementContext.Array)
- OperationNotApplicable("EndArray");
-
- m_context = m_contextStack.Pop();
- if (m_contextStack.Count == 0)
- m_context.element = JsonElementContext.Closed;
- WriteIndent();
- m_writer.Write("]");
- }
-
- void Write(bool value) {
- m_writer.Write(value ? "true" : "false");
- }
-
- void FlushBuffer() {
- if (m_bufferPos > 0) {
- m_writer.Write(m_buffer, 0, m_bufferPos);
- m_bufferPos = 0;
- }
- }
-
- void Write(string value) {
- if (value == null) {
- m_writer.Write("null");
- return;
- }
-
- Debug.Assert(m_bufferPos == 0);
-
- var chars = value.ToCharArray();
- m_buffer[m_bufferPos++] = '"';
-
- // Analysis disable once ForCanBeConvertedToForeach
- for (int i = 0; i < chars.Length; i++) {
- var ch = chars[i];
-
- char[] escapeSeq;
-
- switch (ch) {
- case '\b':
- escapeSeq = _escapeBKS;
- break;
- case '\f':
- escapeSeq = _escapeFWD;
- break;
- case '\r':
- escapeSeq = _escapeCR;
- break;
- case '\n':
- escapeSeq = _escapeNL;
- break;
- case '\t':
- escapeSeq = _escapeTAB;
- break;
- case '\\':
- escapeSeq = _escapeBSLASH;
- break;
- case '"':
- escapeSeq = _escapeQ;
- break;
- default:
- if (ch < 0x20) {
- if (m_bufferPos + 6 > BUFFER_SIZE)
- FlushBuffer();
-
- m_buffer[m_bufferPos++] = '\\';
- m_buffer[m_bufferPos++] = 'u';
- m_buffer[m_bufferPos++] = '0';
- m_buffer[m_bufferPos++] = '0';
- m_buffer[m_bufferPos++] = _hex[ch >> 4 & 0xf];
- m_buffer[m_bufferPos++] = _hex[ch & 0xf];
-
- } else {
- if (m_bufferPos >= BUFFER_SIZE)
- FlushBuffer();
- m_buffer[m_bufferPos++] = ch;
- }
- continue;
- }
-
- if (m_bufferPos + escapeSeq.Length > BUFFER_SIZE)
- FlushBuffer();
-
- Array.Copy(escapeSeq, 0, m_buffer, m_bufferPos, escapeSeq.Length);
- m_bufferPos += escapeSeq.Length;
-
- }
-
- if (m_bufferPos >= BUFFER_SIZE)
- FlushBuffer();
-
- m_buffer[m_bufferPos++] = '"';
-
- FlushBuffer();
- }
-
- void Write(double value) {
- if (double.IsNaN(value))
- Write("NaN");
- else if (double.IsNegativeInfinity(value))
- Write("-Infinity");
- else if (double.IsPositiveInfinity(value))
- Write("Infinity");
- else
- m_writer.Write(value.ToString(CultureInfo.InvariantCulture));
- }
-
- void OperationNotApplicable(string opName) {
- throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
- }
-
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/JSON/StringTranslator.cs
--- a/Implab/Formats/JSON/StringTranslator.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-using Implab;
-using Implab.Formats;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.Formats.Json {
- ///
- /// Класс для преобразования экранированной строки JSON
- ///
- static class StringTranslator {
- static readonly char[] _escMap;
- static readonly int[] _hexMap;
-
- static StringTranslator() {
- var chars = new char[] { 'b', 'f', 't', 'r', 'n', '\\', '/', '"' };
- var vals = new char[] { '\b', '\f', '\t', '\r', '\n', '\\', '/', '"' };
-
- _escMap = new char[chars.Max() + 1];
-
- for (int i = 0; i < chars.Length; i++)
- _escMap[chars[i]] = vals[i];
-
- var hexs = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F' };
- var ints = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15 };
-
- _hexMap = new int[hexs.Max() + 1];
-
- for (int i = 0; i < hexs.Length; i++)
- _hexMap[hexs[i]] = ints[i];
-
- }
-
- internal static char TranslateEscapedChar(char symbol) {
- return _escMap[symbol];
- }
-
- internal static char TranslateHexUnicode(char[] symbols, int offset) {
- Debug.Assert(symbols != null);
- Debug.Assert(symbols.Length - offset >= 4);
-
- int value = (_hexMap[symbols[offset]] << 12)
- | (_hexMap[symbols[offset + 1]] << 8)
- | (_hexMap[symbols[offset + 2]] << 4)
- | (_hexMap[symbols[offset + 3]]);
- return (char)value;
- }
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonElementContext.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonElementContext.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,11 @@
+namespace Implab.Formats.Json {
+ ///
+ /// internal
+ ///
+ enum JsonElementContext {
+ None,
+ Object,
+ Array,
+ Closed
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonElementType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonElementType.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,28 @@
+namespace Implab.Formats.Json {
+ ///
+ /// Тип элемента на котором находится парсер
+ ///
+ public enum JsonElementType {
+ None,
+ ///
+ /// Начало объекта
+ ///
+ BeginObject,
+ ///
+ /// Конец объекта
+ ///
+ EndObject,
+ ///
+ /// Начало массива
+ ///
+ BeginArray,
+ ///
+ /// Конец массива
+ ///
+ EndArray,
+ ///
+ /// Простое значение
+ ///
+ Value
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonGrammar.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonGrammar.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,148 @@
+using System.Linq;
+using Implab.Automaton.RegularExpressions;
+using System;
+using Implab.Automaton;
+using Implab.Components;
+
+namespace Implab.Formats.Json {
+ public class JsonGrammar : Grammar {
+ public enum TokenType {
+ None,
+ BeginObject,
+ EndObject,
+ BeginArray,
+ EndArray,
+ String,
+ Number,
+ Literal,
+ NameSeparator,
+ ValueSeparator,
+ Whitespace,
+
+ StringBound,
+ EscapedChar,
+ UnescapedChar,
+ EscapedUnicode
+ }
+
+ static LazyAndWeak _instance = new LazyAndWeak(() => new JsonGrammar());
+
+ public static JsonGrammar Instance {
+ get { return _instance.Value; }
+ }
+
+ readonly InputScanner m_jsonExpression;
+ readonly InputScanner m_stringExpression;
+ readonly CharAlphabet m_defaultAlphabet = new CharAlphabet();
+
+ public CharAlphabet DefaultAlphabet { get { return m_defaultAlphabet; } }
+
+ public JsonGrammar() {
+ DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
+ var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
+ var digit9 = SymbolRangeToken('1', '9');
+ var zero = SymbolToken('0');
+ var digit = zero.Or(digit9);
+ var dot = SymbolToken('.');
+ var minus = SymbolToken('-');
+ var sign = SymbolSetToken('-', '+');
+ var expSign = SymbolSetToken('e', 'E');
+ var letters = SymbolRangeToken('a', 'z');
+ var integer = zero.Or(digit9.Cat(digit.EClosure()));
+ var frac = dot.Cat(digit.Closure());
+ var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
+ var quote = SymbolToken('"');
+ var backSlash = SymbolToken('\\');
+ var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
+ var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
+ var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
+ var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
+ var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
+ var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
+ var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
+ var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
+ var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
+
+ var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
+ var literal = letters.Closure();
+ var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
+
+ var jsonExpression =
+ number.Tag(TokenType.Number)
+ .Or(literal.Tag(TokenType.Literal))
+ .Or(quote.Tag(TokenType.StringBound))
+ .Or(beginObject.Tag(TokenType.BeginObject))
+ .Or(endObject.Tag(TokenType.EndObject))
+ .Or(beginArray.Tag(TokenType.BeginArray))
+ .Or(endArray.Tag(TokenType.EndArray))
+ .Or(nameSep.Tag(TokenType.NameSeparator))
+ .Or(valueSep.Tag(TokenType.ValueSeparator))
+ .Or(SymbolSetToken('\n', '\r', '\t', ' ').Closure().Tag(TokenType.Whitespace));
+
+
+ var jsonStringExpression =
+ quote.Tag(TokenType.StringBound)
+ .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
+ .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
+ .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
+
+
+ m_jsonExpression = BuildScanner(jsonExpression);
+ m_stringExpression = BuildScanner(jsonStringExpression);
+ }
+
+ public static InputScanner CreateJsonExpressionScanner() {
+ return Instance.m_jsonExpression.Clone();
+ }
+
+ public static InputScanner CreateStringExpressionScanner() {
+ return Instance.m_stringExpression.Clone();
+ }
+
+ protected override IAlphabetBuilder AlphabetBuilder {
+ get {
+ return m_defaultAlphabet;
+ }
+ }
+
+ Token SymbolRangeToken(char start, char stop) {
+ return SymbolToken(Enumerable.Range(start, stop - start + 1).Select(x => (char)x));
+ }
+
+ public InputScanner BuildScanner(Token regexp) {
+ var dfa = new RegularDFA(AlphabetBuilder);
+
+ var visitor = new RegularExpressionVisitor(dfa);
+ regexp.Accept(visitor);
+ visitor.BuildDFA();
+
+ if (dfa.IsFinalState(dfa.InitialState))
+ throw new ApplicationException("The specified language contains empty token");
+
+ var ab = new CharAlphabet();
+ var optimal = dfa.Optimize(ab);
+
+ return new InputScanner(
+ optimal.CreateTransitionTable(),
+ optimal.CreateFinalStateTable(),
+ NormalizeTags(optimal.CreateTagTable()),
+ optimal.InitialState,
+ ab.CreateCharMap()
+ );
+ }
+
+ static TokenType[] NormalizeTags(TokenType[][] tags) {
+ var result = new TokenType[tags.Length];
+ for(var i = 0; i< tags.Length; i++) {
+ if (tags[i] == null || tags[i].Length == 0)
+ result[i] = default(TokenType);
+ else if (tags[i].Length == 1)
+ result[i] = tags[i][0];
+ else
+ throw new Exception($"Ambigous state tags {string.Join(", ", tags[i])}");
+ }
+ return result;
+ }
+
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonReader.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonReader.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,318 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Implab.Automaton;
+using Implab.Automaton.RegularExpressions;
+using System.Linq;
+using Implab.Components;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+
+namespace Implab.Formats.Json {
+ ///
+ /// Pull парсер JSON данных.
+ ///
+ ///
+ /// Следует отметить отдельную интерпретацию свойства ,
+ /// оно означает текущий уровень вложенности объектов, однако закрывающий
+ /// элемент объекта и массива имеет уровень меньше, чем сам объект.
+ ///
+ /// { // Level = 1
+ /// "name" : "Peter", // Level = 1
+ /// "address" : { // Level = 2
+ /// city : "Stern" // Level = 2
+ /// } // Level = 1
+ /// } // Level = 0
+ ///
+ ///
+ public class JsonReader : Disposable {
+
+ enum MemberContext {
+ MemberName,
+ MemberValue
+ }
+
+ #region Parser rules
+ struct ParserContext {
+ readonly int[,] m_dfa;
+ int m_state;
+
+ readonly JsonElementContext m_elementContext;
+
+ public ParserContext(int[,] dfa, int state, JsonElementContext context) {
+ m_dfa = dfa;
+ m_state = state;
+ m_elementContext = context;
+ }
+
+ public bool Move(JsonTokenType token) {
+ var next = m_dfa[m_state, (int)token];
+ if (next == AutomatonConst.UNREACHABLE_STATE)
+ return false;
+ m_state = next;
+ return true;
+ }
+
+ public JsonElementContext ElementContext {
+ get { return m_elementContext; }
+ }
+ }
+
+ static readonly ParserContext _jsonContext;
+ static readonly ParserContext _objectContext;
+ static readonly ParserContext _arrayContext;
+
+ static JsonReader() {
+
+ var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
+ var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression);
+
+ var objectExpression = memberExpression
+ .Cat(
+ MakeToken(JsonTokenType.ValueSeparator)
+ .Cat(memberExpression)
+ .EClosure()
+ )
+ .Optional()
+ .Cat(MakeToken(JsonTokenType.EndObject))
+ .End();
+
+ var arrayExpression = valueExpression
+ .Cat(
+ MakeToken(JsonTokenType.ValueSeparator)
+ .Cat(valueExpression)
+ .EClosure()
+ )
+ .Optional()
+ .Cat(MakeToken(JsonTokenType.EndArray))
+ .End();
+
+ var jsonExpression = valueExpression.End();
+
+ _jsonContext = CreateParserContext(jsonExpression, JsonElementContext.None);
+ _objectContext = CreateParserContext(objectExpression, JsonElementContext.Object);
+ _arrayContext = CreateParserContext(arrayExpression, JsonElementContext.Array);
+ }
+
+ static Token MakeToken(params JsonTokenType[] input) {
+ return Token.New( input.Select(t => (int)t).ToArray() );
+ }
+
+ static ParserContext CreateParserContext(Token expr, JsonElementContext context) {
+
+ var dfa = new DFATable();
+ var builder = new RegularExpressionVisitor(dfa);
+ expr.Accept(builder);
+ builder.BuildDFA();
+
+ return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context);
+ }
+
+ #endregion
+
+ readonly JsonScanner m_scanner;
+ // json starts from the value context and may content even a single literal
+ MemberContext m_memberContext = MemberContext.MemberValue;
+
+ JsonElementType m_elementType;
+ object m_elementValue;
+ string m_memberName = String.Empty;
+
+ Stack m_stack = new Stack();
+ ParserContext m_context = _jsonContext;
+
+ ///
+ /// Создает новый парсер на основе строки, содержащей JSON
+ ///
+ ///
+ JsonReader(JsonScanner scanner) {
+ m_scanner = scanner;
+ }
+
+ public int Level {
+ get { return m_stack.Count; }
+ }
+
+ ///
+ /// Тип текущего элемента на котором стоит парсер.
+ ///
+ public JsonElementType ElementType {
+ get { return m_elementType; }
+ }
+
+ ///
+ /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
+ /// пустая строка.
+ ///
+ public string ElementName {
+ get { return m_memberName; }
+ }
+
+ ///
+ /// Значение элемента. Только для элементов типа , для остальных null
+ ///
+ public object ElementValue {
+ get { return m_elementValue; }
+ }
+
+ ///
+ /// Читает слеюудущий объект из потока
+ ///
+ /// true - операция чтения прошла успешно, false - конец данных
+ public bool Read() {
+ string tokenValue;
+ JsonTokenType tokenType;
+
+ m_memberName = String.Empty;
+
+ while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
+ if(!m_context.Move(tokenType))
+ UnexpectedToken(tokenValue, tokenType);
+
+ switch (tokenType) {
+ case JsonTokenType.BeginObject:
+ m_stack.Push(m_context);
+ m_context = _objectContext;
+
+ m_elementValue = null;
+ m_memberContext = MemberContext.MemberName;
+ m_elementType = JsonElementType.BeginObject;
+ return true;
+ case JsonTokenType.EndObject:
+ if (m_stack.Count == 0)
+ UnexpectedToken(tokenValue, tokenType);
+ m_context = m_stack.Pop();
+
+ m_elementValue = null;
+ m_elementType = JsonElementType.EndObject;
+ return true;
+ case JsonTokenType.BeginArray:
+ m_stack.Push(m_context);
+ m_context = _arrayContext;
+
+ m_elementValue = null;
+ m_memberContext = MemberContext.MemberValue;
+ m_elementType = JsonElementType.BeginArray;
+ return true;
+ case JsonTokenType.EndArray:
+ if (m_stack.Count == 0)
+ UnexpectedToken(tokenValue, tokenType);
+ m_context = m_stack.Pop();
+
+ m_elementValue = null;
+ m_elementType = JsonElementType.EndArray;
+ return true;
+ case JsonTokenType.String:
+ if (m_memberContext == MemberContext.MemberName) {
+ m_memberName = tokenValue;
+ break;
+ }
+ m_elementType = JsonElementType.Value;
+ m_elementValue = tokenValue;
+ return true;
+ case JsonTokenType.Number:
+ m_elementType = JsonElementType.Value;
+ m_elementValue = double.Parse(tokenValue, CultureInfo.InvariantCulture);
+ return true;
+ case JsonTokenType.Literal:
+ m_elementType = JsonElementType.Value;
+ m_elementValue = ParseLiteral(tokenValue);
+ return true;
+ case JsonTokenType.NameSeparator:
+ m_memberContext = MemberContext.MemberValue;
+ break;
+ case JsonTokenType.ValueSeparator:
+ m_memberContext = m_context.ElementContext == JsonElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
+ break;
+ default:
+ UnexpectedToken(tokenValue, tokenType);
+ break;
+ }
+ }
+ if (m_context.ElementContext != JsonElementContext.None)
+ throw new ParserException("Unexpedted end of data");
+
+ Eof = true;
+
+ return false;
+ }
+
+ object ParseLiteral(string literal) {
+ switch (literal) {
+ case "null":
+ return null;
+ case "false":
+ return false;
+ case "true":
+ return true;
+ default:
+ UnexpectedToken(literal, JsonTokenType.Literal);
+ return null; // avoid compliler error
+ }
+ }
+
+ void UnexpectedToken(object value, JsonTokenType tokenType) {
+ throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
+ }
+
+
+ ///
+ /// Признак конца потока
+ ///
+ public bool Eof {
+ get;
+ private set;
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing)
+ m_scanner.Dispose();
+ }
+
+ ///
+ /// Переходит в конец текущего объекта.
+ ///
+ public void SeekElementEnd() {
+ var level = Level - 1;
+
+ Debug.Assert(level >= 0);
+
+ while (Level != level)
+ Read();
+ }
+
+ public static JsonReader Create(string file, Encoding encoding) {
+ return new JsonReader(JsonTextScanner.Create(file, encoding));
+ }
+
+ public static JsonReader Create(string file) {
+ return new JsonReader(JsonTextScanner.Create(file));
+ }
+
+ public static JsonReader Create(Stream stream, Encoding encoding) {
+ return new JsonReader(JsonTextScanner.Create(stream, encoding));
+ }
+
+ public static JsonReader Create(Stream stream) {
+ return new JsonReader(JsonTextScanner.Create(stream));
+ }
+
+ public static JsonReader Create(TextReader reader) {
+ return new JsonReader(JsonTextScanner.Create(reader));
+ }
+
+ public static JsonReader ParseString(string data) {
+ return new JsonReader(JsonStringScanner.Create(data));
+ }
+
+ public static JsonReader ParseString(string data, int offset, int length) {
+ return new JsonReader(JsonStringScanner.Create(data, offset, length));
+ }
+
+ public static JsonReader ParseString(char[] data, int offset, int lenght) {
+ return new JsonReader(JsonStringScanner.Create(data, offset, lenght));
+ }
+ }
+
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonScanner.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonScanner.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,190 @@
+using System;
+using System.Globalization;
+using Implab.Automaton;
+using System.Text;
+using Implab.Components;
+using System.IO;
+
+namespace Implab.Formats.Json {
+ ///
+ /// Сканнер (лексер), разбивающий поток символов на токены JSON.
+ ///
+ public abstract class JsonScanner : Disposable {
+ readonly InputScanner m_jsonContext = JsonGrammar.CreateJsonExpressionScanner();
+ readonly InputScanner m_stringContext = JsonGrammar.CreateStringExpressionScanner();
+
+ readonly char[] m_unescapeBuf = new char[4];
+ readonly char[] m_buffer;
+ int m_length;
+ int m_pos;
+ readonly StringBuilder m_tokenBuilder = new StringBuilder();
+
+ protected JsonScanner(char[] buffer, int pos, int length) {
+ m_buffer = buffer;
+ m_pos = pos;
+ m_length = length;
+ }
+
+ bool ReadChunk(InputScanner scanner, out JsonGrammar.TokenType tokenType) {
+ scanner.ResetState();
+
+ while(scanner.Scan(m_buffer, m_pos, m_length)) {
+ // scanner requests new data
+
+ if (m_pos != m_length) // capture results for the future
+ m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos);
+
+ // read next data
+ m_length = Read(m_buffer, 0, m_buffer.Length);
+
+ if (m_length == 0) {
+ // no data is read
+ if (scanner.Position == m_pos) {
+ // scanned hasn't moved, that's the end
+ m_pos = 0;
+ tokenType = JsonGrammar.TokenType.None;
+ return false;
+ }
+
+ if (scanner.IsFinal) {
+ m_pos = 0;
+ tokenType = scanner.Tag;
+ return true;
+ } else {
+ throw new ParserException("Unexpected EOF");
+ }
+ }
+
+ m_pos = 0;
+ }
+ var scannerPos = scanner.Position;
+
+ // scanner stops as scannerPos
+ if (!scanner.IsFinal)
+ throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'");
+
+ tokenType = scanner.Tag;
+ if (scannerPos != m_pos && tokenType == JsonGrammar.TokenType.Number || tokenType == JsonGrammar.TokenType.Literal)
+ m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos);
+
+ m_pos = scannerPos;
+ return true;
+ }
+
+ bool ReadStringChunk(InputScanner scanner, out JsonGrammar.TokenType tokenType) {
+ scanner.ResetState();
+
+ while (scanner.Scan(m_buffer, m_pos, m_length)) {
+ // scanner requests new data
+
+ if (m_pos != m_length) // capture results for the future
+ m_tokenBuilder.Append(m_buffer, m_pos, m_length - m_pos);
+
+ // read next data
+ m_length = Read(m_buffer, 0, m_buffer.Length);
+
+ if (m_length == 0) {
+ // no data is read
+ if (scanner.Position == m_pos) {
+ // scanned hasn't moved, that's the end
+ m_pos = 0;
+ tokenType = JsonGrammar.TokenType.None;
+ return false;
+ }
+
+ if (scanner.IsFinal) {
+ m_pos = 0;
+ tokenType = scanner.Tag;
+ return true;
+ } else {
+ throw new ParserException("Unexpected EOF");
+ }
+ }
+
+ m_pos = 0;
+ }
+ var scannerPos = scanner.Position;
+
+ // scanner stops as scannerPos
+ if (!scanner.IsFinal)
+ throw new ParserException($"Unexpected character '{m_buffer[scannerPos + 1]}'");
+
+ if (scannerPos != m_pos) {
+ m_tokenBuilder.Append(m_buffer, m_pos, scannerPos - m_pos);
+ m_pos = scannerPos;
+ }
+ tokenType = scanner.Tag;
+ return true;
+ }
+
+ protected abstract int Read(char[] buffer, int offset, int size);
+
+
+ ///
+ /// Читает следующий лексический элемент из входных данных.
+ ///
+ /// Возвращает значение прочитанного токена.
+ /// Возвращает тип прочитанного токена.
+ /// true - чтение произведено успешно. false - достигнут конец входных данных
+ /// В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
+ /// в строках обрабатываются экранированные символы, числа становтся типа double.
+ public bool ReadToken(out string tokenValue, out JsonTokenType tokenType) {
+ JsonGrammar.TokenType tag;
+ m_tokenBuilder.Clear();
+ while (ReadChunk(m_jsonContext, out tag)) {
+ switch (tag) {
+ case JsonGrammar.TokenType.StringBound:
+ tokenValue = ReadString();
+ tokenType = JsonTokenType.String;
+ break;
+ case JsonGrammar.TokenType.Number:
+ tokenValue = m_tokenBuilder.ToString();
+ tokenType = JsonTokenType.Number;
+ break;
+ case JsonGrammar.TokenType.Literal:
+ tokenType = JsonTokenType.Literal;
+ tokenValue = m_tokenBuilder.ToString();
+ break;
+ case JsonGrammar.TokenType.Whitespace:
+ m_tokenBuilder.Clear();
+ continue;
+ default:
+ tokenType = (JsonTokenType)tag;
+ tokenValue = null;
+ break;
+ }
+ return true;
+ }
+ tokenValue = null;
+ tokenType = JsonTokenType.None;
+ return false;
+ }
+
+ string ReadString() {
+ JsonGrammar.TokenType tag;
+ m_tokenBuilder.Clear();
+
+ while (ReadStringChunk(m_stringContext, out tag)) {
+ switch (tag) {
+ case JsonGrammar.TokenType.StringBound:
+ m_tokenBuilder.Length--;
+ return m_tokenBuilder.ToString();
+ case JsonGrammar.TokenType.UnescapedChar:
+ break;
+ case JsonGrammar.TokenType.EscapedUnicode: // \xXXXX - unicode escape sequence
+ m_tokenBuilder.CopyTo(m_tokenBuilder.Length - 4, m_unescapeBuf, 0, 4);
+ m_tokenBuilder.Length -= 6;
+ m_tokenBuilder.Append(StringTranslator.TranslateHexUnicode(m_unescapeBuf, 0));
+ break;
+ case JsonGrammar.TokenType.EscapedChar: // \t - escape sequence
+ var ch = m_tokenBuilder[m_tokenBuilder.Length-1];
+ m_tokenBuilder.Length -= 2;
+ m_tokenBuilder.Append(StringTranslator.TranslateEscapedChar(ch));
+ break;
+ }
+ }
+
+ throw new ParserException("Unexpected end of data");
+ }
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonStringScanner.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonStringScanner.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Implab.Formats.Json {
+ public class JsonStringScanner : JsonScanner {
+ const int _defaultBuffer = 64;
+
+ readonly string m_data;
+ int m_offset;
+
+ JsonStringScanner(string data, char[] buffer, int pos, int length, int offset) : base(buffer, pos, length) {
+ m_data = data;
+ m_offset = offset;
+ }
+
+ protected override int Read(char[] buffer, int offset, int size) {
+ if (m_data == null)
+ return 0;
+ if (m_offset >= m_data.Length)
+ return 0;
+
+ var count = Math.Min(size, m_data.Length - m_offset);
+
+ m_data.CopyTo(m_offset, buffer, offset, count);
+ m_offset += count;
+
+ return count;
+ }
+
+ public static JsonStringScanner Create(string data) {
+ Safe.ArgumentNotNull(data, nameof(data));
+
+ if (data.Length <= _defaultBuffer)
+ return new JsonStringScanner(null, data.ToCharArray(), 0, data.Length, data.Length);
+
+ var buffer = new char[_defaultBuffer];
+ data.CopyTo(0, buffer, 0, _defaultBuffer);
+ return new JsonStringScanner(data, buffer, 0, _defaultBuffer, _defaultBuffer);
+ }
+
+ public static JsonStringScanner Create(string data, int offset, int length) {
+ Safe.ArgumentNotNull(data, nameof(data));
+ Safe.ArgumentGreaterThan(offset, 0, nameof(offset));
+ Safe.ArgumentGreaterThan(length, 0, nameof(length));
+
+ if (offset + length > data.Length)
+ throw new ArgumentOutOfRangeException("Specified offset and length are out of the string bounds");
+
+ if (length <= _defaultBuffer) {
+ var buffer = new char[length];
+ data.CopyTo(offset, buffer, 0, length);
+
+ return new JsonStringScanner(null, buffer, 0, length, length);
+ } else {
+ var buffer = new char[_defaultBuffer];
+ data.CopyTo(offset, buffer, 0, _defaultBuffer);
+ return new JsonStringScanner(data, buffer, 0, _defaultBuffer, offset + _defaultBuffer);
+ }
+ }
+
+ public static JsonStringScanner Create(char[] data, int offset, int length) {
+ Safe.ArgumentNotNull(data, nameof(data));
+ Safe.ArgumentGreaterThan(offset, 0, nameof(offset));
+ Safe.ArgumentGreaterThan(length, 0, nameof(length));
+
+ if (offset + length > data.Length)
+ throw new ArgumentOutOfRangeException("Specified offset and length are out of the array bounds");
+
+ return new JsonStringScanner(null, data, offset, offset + length, offset + length);
+
+ }
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonTextScanner.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonTextScanner.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Implab.Formats.Json {
+ public class JsonTextScanner : JsonScanner {
+ const int _bufferSize = 16*4096;
+ readonly TextReader m_reader;
+
+ JsonTextScanner(TextReader reader, char[] buffer) : base(buffer, 0, 0) {
+ m_reader = reader;
+ }
+
+ protected override int Read(char[] buffer, int offset, int size) {
+ return m_reader.Read(buffer, offset, size);
+ }
+
+ public static JsonTextScanner Create(string file, Encoding encoding) {
+ return new JsonTextScanner(new StreamReader(file, encoding), new char[_bufferSize]);
+ }
+
+ public static JsonTextScanner Create(string file) {
+ return new JsonTextScanner(new StreamReader(file), new char[_bufferSize]);
+ }
+
+ public static JsonTextScanner Create(Stream stream, Encoding encoding) {
+ return new JsonTextScanner(new StreamReader(stream, encoding), new char[_bufferSize]);
+ }
+
+ public static JsonTextScanner Create(Stream stream) {
+ return new JsonTextScanner(new StreamReader(stream), new char[_bufferSize]);
+ }
+
+ public static JsonTextScanner Create(TextReader reader) {
+ Safe.ArgumentNotNull(reader, nameof(reader));
+ return new JsonTextScanner(reader, new char[_bufferSize]);
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing)
+ Safe.Dispose(m_reader);
+
+ base.Dispose(disposing);
+ }
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonTokenType.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonTokenType.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,44 @@
+namespace Implab.Formats.Json {
+ ///
+ /// Тип токенов, возвращаемых .
+ ///
+ public enum JsonTokenType : int {
+ None = 0,
+ ///
+ /// Начало объекта
+ ///
+ BeginObject,
+ ///
+ /// Конец объекта
+ ///
+ EndObject,
+ ///
+ /// Начало массива
+ ///
+ BeginArray,
+ ///
+ /// Конец массива
+ ///
+ EndArray,
+ ///
+ /// Строка
+ ///
+ String,
+ ///
+ /// Число
+ ///
+ Number,
+ ///
+ /// Литерал
+ ///
+ Literal,
+ ///
+ /// Разделитель имени :
+ ///
+ NameSeparator,
+ ///
+ /// Разделитель имени ,
+ ///
+ ValueSeparator
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/JsonWriter.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/JsonWriter.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,319 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Globalization;
+using System.Diagnostics;
+
+namespace Implab.Formats.Json {
+ public class JsonWriter {
+ struct Context {
+ public bool needComma;
+ public JsonElementContext element;
+ }
+ Stack m_contextStack = new Stack();
+ Context m_context;
+
+ const int BUFFER_SIZE = 64;
+
+ TextWriter m_writer;
+ readonly bool m_indent = true;
+ readonly int m_indentSize = 4;
+ readonly char[] m_buffer = new char[BUFFER_SIZE];
+ int m_bufferPos;
+
+ static readonly char [] _hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ static readonly char [] _escapeBKS,
+ _escapeFWD,
+ _escapeCR,
+ _escapeNL,
+ _escapeTAB,
+ _escapeBSLASH,
+ _escapeQ;
+
+ static JsonWriter() {
+ _escapeBKS = "\\b".ToCharArray();
+ _escapeFWD = "\\f".ToCharArray();
+ _escapeCR = "\\r".ToCharArray();
+ _escapeNL = "\\n".ToCharArray();
+ _escapeTAB = "\\t".ToCharArray();
+ _escapeBSLASH = "\\\\".ToCharArray();
+ _escapeQ = "\\\"".ToCharArray();
+ }
+
+ public JsonWriter(TextWriter writer) {
+ Safe.ArgumentNotNull(writer, "writer");
+ m_writer = writer;
+ }
+
+ public JsonWriter(TextWriter writer, bool indent) {
+ Safe.ArgumentNotNull(writer, "writer");
+
+ m_writer = writer;
+ m_indent = indent;
+ }
+
+ void WriteIndent() {
+ if (m_indent) {
+ var indent = new char[m_contextStack.Count * m_indentSize + 1];
+ indent[0] = '\n';
+ for (int i = 1; i < indent.Length; i++)
+ indent[i] = ' ';
+ m_writer.Write(new String(indent));
+ } else {
+ m_writer.Write(' ');
+ }
+ }
+
+ void WriteMemberName(string name) {
+ Safe.ArgumentNotEmpty(name, "name");
+ if (m_context.element != JsonElementContext.Object)
+ OperationNotApplicable("WriteMember");
+ if (m_context.needComma)
+ m_writer.Write(",");
+
+ WriteIndent();
+ m_context.needComma = true;
+ Write(name);
+ m_writer.Write(" : ");
+ }
+
+ public void WriteValue(string name, string value) {
+ WriteMemberName(name);
+ Write(value);
+ }
+
+ public void WriteValue(string name, bool value) {
+ WriteMemberName(name);
+ Write(value);
+ }
+
+ public void WriteValue(string name, double value) {
+ WriteMemberName(name);
+ Write(value);
+ }
+
+ public void WriteValue(string value) {
+ if (m_context.element == JsonElementContext.Array) {
+
+ if (m_context.needComma)
+ m_writer.Write(",");
+ WriteIndent();
+ m_context.needComma = true;
+
+ Write(value);
+ } else if (m_context.element == JsonElementContext.None) {
+ Write(value);
+ m_context.element = JsonElementContext.Closed;
+ } else {
+ OperationNotApplicable("WriteValue");
+ }
+ }
+
+ public void WriteValue(bool value) {
+ if (m_context.element == JsonElementContext.Array) {
+
+ if (m_context.needComma)
+ m_writer.Write(",");
+ WriteIndent();
+ m_context.needComma = true;
+
+ Write(value);
+ } else if (m_context.element == JsonElementContext.None) {
+ Write(value);
+ m_context.element = JsonElementContext.Closed;
+ } else {
+ OperationNotApplicable("WriteValue");
+ }
+ }
+
+ public void WriteValue(double value) {
+ if (m_context.element == JsonElementContext.Array) {
+
+ if (m_context.needComma)
+ m_writer.Write(",");
+ WriteIndent();
+ m_context.needComma = true;
+
+ Write(value);
+ } else if (m_context.element == JsonElementContext.None) {
+ Write(value);
+ m_context.element = JsonElementContext.Closed;
+ } else {
+ OperationNotApplicable("WriteValue");
+ }
+ }
+
+ public void BeginObject() {
+ if (m_context.element != JsonElementContext.None && m_context.element != JsonElementContext.Array)
+ OperationNotApplicable("BeginObject");
+ if (m_context.needComma)
+ m_writer.Write(",");
+
+ WriteIndent();
+
+ m_context.needComma = true;
+
+ m_contextStack.Push(m_context);
+
+ m_context = new Context { element = JsonElementContext.Object, needComma = false };
+ m_writer.Write("{");
+ }
+
+ public void BeginObject(string name) {
+ WriteMemberName(name);
+
+ m_contextStack.Push(m_context);
+
+ m_context = new Context { element = JsonElementContext.Object, needComma = false };
+ m_writer.Write("{");
+ }
+
+ public void EndObject() {
+ if (m_context.element != JsonElementContext.Object)
+ OperationNotApplicable("EndObject");
+
+ m_context = m_contextStack.Pop();
+ if (m_contextStack.Count == 0)
+ m_context.element = JsonElementContext.Closed;
+ WriteIndent();
+ m_writer.Write("}");
+ }
+
+ public void BeginArray() {
+ if (m_context.element != JsonElementContext.None && m_context.element != JsonElementContext.Array)
+ throw new InvalidOperationException();
+ if (m_context.needComma) {
+ m_writer.Write(",");
+
+ }
+ m_context.needComma = true;
+
+ WriteIndent();
+ m_contextStack.Push(m_context);
+ m_context = new Context { element = JsonElementContext.Array, needComma = false };
+ m_writer.Write("[");
+ }
+
+ public void BeginArray(string name) {
+ WriteMemberName(name);
+
+ m_contextStack.Push(m_context);
+
+ m_context = new Context { element = JsonElementContext.Array, needComma = false };
+ m_writer.Write("[");
+ }
+
+ public void EndArray() {
+ if (m_context.element != JsonElementContext.Array)
+ OperationNotApplicable("EndArray");
+
+ m_context = m_contextStack.Pop();
+ if (m_contextStack.Count == 0)
+ m_context.element = JsonElementContext.Closed;
+ WriteIndent();
+ m_writer.Write("]");
+ }
+
+ void Write(bool value) {
+ m_writer.Write(value ? "true" : "false");
+ }
+
+ void FlushBuffer() {
+ if (m_bufferPos > 0) {
+ m_writer.Write(m_buffer, 0, m_bufferPos);
+ m_bufferPos = 0;
+ }
+ }
+
+ void Write(string value) {
+ if (value == null) {
+ m_writer.Write("null");
+ return;
+ }
+
+ Debug.Assert(m_bufferPos == 0);
+
+ var chars = value.ToCharArray();
+ m_buffer[m_bufferPos++] = '"';
+
+ // Analysis disable once ForCanBeConvertedToForeach
+ for (int i = 0; i < chars.Length; i++) {
+ var ch = chars[i];
+
+ char[] escapeSeq;
+
+ switch (ch) {
+ case '\b':
+ escapeSeq = _escapeBKS;
+ break;
+ case '\f':
+ escapeSeq = _escapeFWD;
+ break;
+ case '\r':
+ escapeSeq = _escapeCR;
+ break;
+ case '\n':
+ escapeSeq = _escapeNL;
+ break;
+ case '\t':
+ escapeSeq = _escapeTAB;
+ break;
+ case '\\':
+ escapeSeq = _escapeBSLASH;
+ break;
+ case '"':
+ escapeSeq = _escapeQ;
+ break;
+ default:
+ if (ch < 0x20) {
+ if (m_bufferPos + 6 > BUFFER_SIZE)
+ FlushBuffer();
+
+ m_buffer[m_bufferPos++] = '\\';
+ m_buffer[m_bufferPos++] = 'u';
+ m_buffer[m_bufferPos++] = '0';
+ m_buffer[m_bufferPos++] = '0';
+ m_buffer[m_bufferPos++] = _hex[ch >> 4 & 0xf];
+ m_buffer[m_bufferPos++] = _hex[ch & 0xf];
+
+ } else {
+ if (m_bufferPos >= BUFFER_SIZE)
+ FlushBuffer();
+ m_buffer[m_bufferPos++] = ch;
+ }
+ continue;
+ }
+
+ if (m_bufferPos + escapeSeq.Length > BUFFER_SIZE)
+ FlushBuffer();
+
+ Array.Copy(escapeSeq, 0, m_buffer, m_bufferPos, escapeSeq.Length);
+ m_bufferPos += escapeSeq.Length;
+
+ }
+
+ if (m_bufferPos >= BUFFER_SIZE)
+ FlushBuffer();
+
+ m_buffer[m_bufferPos++] = '"';
+
+ FlushBuffer();
+ }
+
+ void Write(double value) {
+ if (double.IsNaN(value))
+ Write("NaN");
+ else if (double.IsNegativeInfinity(value))
+ Write("-Infinity");
+ else if (double.IsPositiveInfinity(value))
+ Write("Infinity");
+ else
+ m_writer.Write(value.ToString(CultureInfo.InvariantCulture));
+ }
+
+ void OperationNotApplicable(string opName) {
+ throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
+ }
+
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Formats/Json/StringTranslator.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/Json/StringTranslator.cs Thu Sep 21 01:14:27 2017 +0300
@@ -0,0 +1,52 @@
+using Implab;
+using Implab.Formats;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Implab.Formats.Json {
+ ///
+ /// Класс для преобразования экранированной строки JSON
+ ///
+ static class StringTranslator {
+ static readonly char[] _escMap;
+ static readonly int[] _hexMap;
+
+ static StringTranslator() {
+ var chars = new char[] { 'b', 'f', 't', 'r', 'n', '\\', '/', '"' };
+ var vals = new char[] { '\b', '\f', '\t', '\r', '\n', '\\', '/', '"' };
+
+ _escMap = new char[chars.Max() + 1];
+
+ for (int i = 0; i < chars.Length; i++)
+ _escMap[chars[i]] = vals[i];
+
+ var hexs = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F' };
+ var ints = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15 };
+
+ _hexMap = new int[hexs.Max() + 1];
+
+ for (int i = 0; i < hexs.Length; i++)
+ _hexMap[hexs[i]] = ints[i];
+
+ }
+
+ internal static char TranslateEscapedChar(char symbol) {
+ return _escMap[symbol];
+ }
+
+ internal static char TranslateHexUnicode(char[] symbols, int offset) {
+ Debug.Assert(symbols != null);
+ Debug.Assert(symbols.Length - offset >= 4);
+
+ int value = (_hexMap[symbols[offset]] << 12)
+ | (_hexMap[symbols[offset + 1]] << 8)
+ | (_hexMap[symbols[offset + 2]] << 4)
+ | (_hexMap[symbols[offset + 3]]);
+ return (char)value;
+ }
+ }
+}
diff -r 3eaa9372c754 -r 133ba4444acc Implab/Implab.csproj
--- a/Implab/Implab.csproj Thu Sep 21 01:06:32 2017 +0300
+++ b/Implab/Implab.csproj Thu Sep 21 01:14:27 2017 +0300
@@ -14,7 +14,7 @@
full
false
bin\Debug
- TRACE;DEBUG;
+ TRACE;DEBUG;NET_4_5
prompt
4
false
@@ -24,44 +24,7 @@
full
true
bin\Release
- prompt
- 4
- false
-
-
- true
- full
- false
- bin\Debug
- TRACE;DEBUG;NET_4_5
- prompt
- 4
- true
- false
-
-
- true
- bin\Release
- prompt
- 4
- false
NET_4_5
-
-
- true
- full
- false
- bin\Debug
- TRACE;DEBUG;NET_4_5;MONO
- prompt
- 4
- true
- false
-
-
- true
- bin\Release
- NET_4_5;MONO;
prompt
4
false
@@ -206,77 +169,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- I
-
-
-
-
- Attribute
-
-
-
-
- EventArgs
-
-
-
-
- Exception
-
-
-
-
-
-
-
-
- m_
-
-
-
-
- _
-
-
-
-
- m_
-
-
-
-
-
-
-
-
-
- T
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff -r 3eaa9372c754 -r 133ba4444acc MonoPlay/MonoPlay.csproj
--- a/MonoPlay/MonoPlay.csproj Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {15DD7123-D504-4627-8B4F-D00C7F04D033}
- Exe
- MonoPlay
- MonoPlay
- v4.5
- 0.2
-
-
- true
- full
- false
- bin\Debug
- DEBUG;TRACE;
- prompt
- 4
- false
-
-
- full
- true
- bin\Release
- prompt
- 4
- false
-
-
-
-
- ..\packages\System.Text.Json.2.0.0.11\lib\net40\System.Text.Json.dll
-
-
-
-
-
-
-
-
-
- {F550F1F8-8746-4AD0-9614-855F4C4B7F05}
- Implab
-
-
-
-
-
-
\ No newline at end of file
diff -r 3eaa9372c754 -r 133ba4444acc MonoPlay/Program.cs
--- a/MonoPlay/Program.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-using Implab;
-using Implab.Parallels;
-using Implab.Diagnostics;
-using System.Threading;
-
-namespace MonoPlay {
- class MainClass {
-
-
- public static void Main(string[] args) {
- var pool = new WorkerPool(10);
-
- var listerner = new ConsoleTraceListener();
- listerner.Subscribe();
-
- TraceLog.StartLogicalOperation("Main");
-
-
- var d = pool.Invoke(() => {
- TraceLog.StartLogicalOperation("Worker");
- Thread.Sleep(100);
- TraceLog.TraceInformation("worker done");
- TraceLog.EndLogicalOperation();
- });
-
- var op = TraceContext.Instance.CurrentOperation;
- ThreadPool.QueueUserWorkItem((o) => {
- TraceContext.Instance.EnterLogicalOperation(op, false);
- TraceLog.StartLogicalOperation("Thread");
- Thread.Sleep(100);
- TraceLog.TraceInformation("thread done");
- TraceLog.EndLogicalOperation();
- });
-
- TraceLog.TraceInformation("main done");
- TraceLog.EndLogicalOperation();
-
- d.Join();
-
-
-
- }
-
- }
-}
diff -r 3eaa9372c754 -r 133ba4444acc MonoPlay/Properties/AssemblyInfo.cs
--- a/MonoPlay/Properties/AssemblyInfo.cs Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("MonoPlay")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("sergey")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff -r 3eaa9372c754 -r 133ba4444acc MonoPlay/packages.config
--- a/MonoPlay/packages.config Thu Sep 21 01:06:32 2017 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file