├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── empty.md
└── workflows
│ └── test.yml
├── .gitignore
├── LICENSE
├── NOTICE.md
├── README.md
└── src
├── .editorconfig
├── Benchmark
├── Benchmark.csproj
├── Program.cs
└── data
│ ├── large.xml
│ └── small.xml
├── U8XmlParser.sln
├── U8XmlParser
├── LICENSE
└── U8XmlParser.csproj
├── U8XmlParserUnity
├── .gitignore
├── Assets
│ ├── Plugins.meta
│ └── Plugins
│ │ ├── U8XmlParser.meta
│ │ ├── U8XmlParser
│ │ ├── Runtime.meta
│ │ ├── Runtime
│ │ │ ├── AllNodeList.cs
│ │ │ ├── AllNodeList.cs.meta
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── AssemblyInfo.cs.meta
│ │ │ ├── DataLocation.cs
│ │ │ ├── DataLocation.cs.meta
│ │ │ ├── Internal.meta
│ │ │ ├── Internal
│ │ │ │ ├── AllocationSafety.cs
│ │ │ │ ├── AllocationSafety.cs.meta
│ │ │ │ ├── BitOperationHelper.cs
│ │ │ │ ├── BitOperationHelper.cs.meta
│ │ │ │ ├── CustomList.cs
│ │ │ │ ├── CustomList.cs.meta
│ │ │ │ ├── DataOffsetHelper.cs
│ │ │ │ ├── DataOffsetHelper.cs.meta
│ │ │ │ ├── EncodingExtension.cs
│ │ │ │ ├── EncodingExtension.cs.meta
│ │ │ │ ├── IXmlObject.cs
│ │ │ │ ├── IXmlObject.cs.meta
│ │ │ │ ├── NodeStack.cs
│ │ │ │ ├── NodeStack.cs.meta
│ │ │ │ ├── OptionalNodeList.cs
│ │ │ │ ├── OptionalNodeList.cs.meta
│ │ │ │ ├── PredefinedEntityTable.cs
│ │ │ │ ├── PredefinedEntityTable.cs.meta
│ │ │ │ ├── RawStringPairList.cs
│ │ │ │ ├── RawStringPairList.cs.meta
│ │ │ │ ├── RawStringTable.cs
│ │ │ │ ├── RawStringTable.cs.meta
│ │ │ │ ├── SkipLocalsInitCompatible.cs
│ │ │ │ ├── SkipLocalsInitCompatible.cs.meta
│ │ │ │ ├── SpanHelper.cs
│ │ │ │ ├── SpanHelper.cs.meta
│ │ │ │ ├── StreamExtension.cs
│ │ │ │ ├── StreamExtension.cs.meta
│ │ │ │ ├── ThrowHelper.cs
│ │ │ │ ├── ThrowHelper.cs.meta
│ │ │ │ ├── UTF8ExceptionFallbackEncoding.cs
│ │ │ │ ├── UTF8ExceptionFallbackEncoding.cs.meta
│ │ │ │ ├── UnicodeHelper.cs
│ │ │ │ ├── UnicodeHelper.cs.meta
│ │ │ │ ├── UnmanagedBuffer.cs
│ │ │ │ ├── UnmanagedBuffer.cs.meta
│ │ │ │ ├── UnsafeHelper.cs
│ │ │ │ ├── UnsafeHelper.cs.meta
│ │ │ │ ├── XXHash32.cs
│ │ │ │ ├── XXHash32.cs.meta
│ │ │ │ ├── XmlObjectCore.cs
│ │ │ │ ├── XmlObjectCore.cs.meta
│ │ │ │ ├── XmlnsHelper.cs
│ │ │ │ └── XmlnsHelper.cs.meta
│ │ │ ├── Option.cs
│ │ │ ├── Option.cs.meta
│ │ │ ├── RawString.Conversion.cs
│ │ │ ├── RawString.Conversion.cs.meta
│ │ │ ├── RawString.Deprecated.cs
│ │ │ ├── RawString.Deprecated.cs.meta
│ │ │ ├── RawString.cs
│ │ │ ├── RawString.cs.meta
│ │ │ ├── SpanByteExtensions.cs
│ │ │ ├── SpanByteExtensions.cs.meta
│ │ │ ├── SplitRawStrings.cs
│ │ │ ├── SplitRawStrings.cs.meta
│ │ │ ├── Unsafes.meta
│ │ │ ├── Unsafes
│ │ │ │ ├── XmlObjectUnsafe.cs
│ │ │ │ ├── XmlObjectUnsafe.cs.meta
│ │ │ │ ├── XmlParserUnsafe.cs
│ │ │ │ └── XmlParserUnsafe.cs.meta
│ │ │ ├── XmlAttribute.cs
│ │ │ ├── XmlAttribute.cs.meta
│ │ │ ├── XmlAttributeEnumerableExtension.cs
│ │ │ ├── XmlAttributeEnumerableExtension.cs.meta
│ │ │ ├── XmlAttributeList.cs
│ │ │ ├── XmlAttributeList.cs.meta
│ │ │ ├── XmlDeclaration.cs
│ │ │ ├── XmlDeclaration.cs.meta
│ │ │ ├── XmlDocumentType.cs
│ │ │ ├── XmlDocumentType.cs.meta
│ │ │ ├── XmlEntityTable.cs
│ │ │ ├── XmlEntityTable.cs.meta
│ │ │ ├── XmlNode.cs
│ │ │ ├── XmlNode.cs.meta
│ │ │ ├── XmlNodeDescendantList.cs
│ │ │ ├── XmlNodeDescendantList.cs.meta
│ │ │ ├── XmlNodeEnumerableExtension.cs
│ │ │ ├── XmlNodeEnumerableExtension.cs.meta
│ │ │ ├── XmlNodeList.cs
│ │ │ ├── XmlNodeList.cs.meta
│ │ │ ├── XmlObject.cs
│ │ │ ├── XmlObject.cs.meta
│ │ │ ├── XmlParser.cs
│ │ │ └── XmlParser.cs.meta
│ │ ├── Samples~
│ │ │ ├── U8XmlParserSample.meta
│ │ │ └── U8XmlParserSample
│ │ │ │ ├── Scripts.meta
│ │ │ │ ├── Scripts
│ │ │ │ ├── U8XmlSample.cs
│ │ │ │ └── U8XmlSample.cs.meta
│ │ │ │ ├── U8Xml.U8XmlParserSample.asmdef
│ │ │ │ ├── U8Xml.U8XmlParserSample.asmdef.meta
│ │ │ │ ├── U8XmlSampleScene.unity
│ │ │ │ └── U8XmlSampleScene.unity.meta
│ │ ├── System.Buffers.dll
│ │ ├── System.Buffers.dll.meta
│ │ ├── System.Memory.dll
│ │ ├── System.Memory.dll.meta
│ │ ├── System.Runtime.CompilerServices.Unsafe.dll
│ │ ├── System.Runtime.CompilerServices.Unsafe.dll.meta
│ │ ├── U8Xml.U8XmlParser.asmdef
│ │ └── U8Xml.U8XmlParser.asmdef.meta
│ │ ├── package.json
│ │ └── package.json.meta
└── ProjectSettings
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── PackageManagerSettings.asset
│ ├── Physics2DSettings.asset
│ ├── PresetManager.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ ├── UnityConnectSettings.asset
│ ├── VFXManager.asset
│ ├── VersionControlSettings.asset
│ └── XRSettings.asset
└── UnitTest
├── CommentTest.cs
├── Data.cs
├── DataLocationTest.cs
├── DtdParseTest.cs
├── ElementAndTextMixedTest.cs
├── FileParserTest.cs
├── FindAttributeTest.cs
├── FindChildTest.cs
├── NodeInfo.cs
├── NodeStringTest.cs
├── ParseAttributeTest.cs
├── ParserTest.cs
├── RawStringTest.cs
├── TestCases.cs
├── TestFiles
├── test_utf16_be.xml
├── test_utf16_le.xml
├── test_utf8.xml
└── test_utf8_with_bom.xml
├── UnitTest.csproj
├── XmlAttributesTest.cs
└── XmlDeclarationTest.cs
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**:
11 |
12 | **Environment**:
13 |
14 | library version: x.x.x
15 | .NET version: (.NET6, .NET5, etc...)
16 | OS: (Windows10, Ubuntu xx.xx, etc...)
17 |
18 | **Steps to Reproduce**:
19 |
20 | 1.
21 | 2.
22 | 3.
23 |
24 | **Expected behavior**:
25 |
26 |
27 | **Actual Behavior**:
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/empty.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Empty
3 | about: No template
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Build and Test
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 | workflow_dispatch:
9 |
10 | jobs:
11 | build:
12 |
13 | runs-on: ubuntu-latest
14 | strategy:
15 | matrix:
16 | target-framework: [ 'net48', 'netcoreapp3.1', 'net5.0', 'net6.0' ]
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Setup .NET Core SDK
21 | uses: actions/setup-dotnet@v1
22 | with:
23 | dotnet-version: '6.0.100'
24 | - name: Restore dependencies
25 | run: dotnet restore src/U8XmlParser/U8XmlParser.csproj
26 | - name: Build Debug
27 | run: dotnet build --no-restore -c Debug --framework ${{ matrix.target-framework }} /nowarn:cs1591 src/U8XmlParser/U8XmlParser.csproj
28 | - name: Test Debug
29 | run: dotnet test --no-build --verbosity normal -c Debug --framework ${{ matrix.target-framework }} src/UnitTest/UnitTest.csproj
30 | - name: Build Release
31 | run: dotnet build --no-restore -c Release --framework ${{ matrix.target-framework }} /nowarn:cs1591 src/U8XmlParser/U8XmlParser.csproj
32 | - name: Test Release
33 | run: dotnet test --no-build --verbosity normal -c Release --framework ${{ matrix.target-framework }} src/UnitTest/UnitTest.csproj
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 ikorin24
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NOTICE.md:
--------------------------------------------------------------------------------
1 | # NOTICE
2 |
3 | ## BenchmarkDotNet
4 |
5 | The MIT License
6 | Copyright (c) 2013–2020 .NET Foundation and contributors
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 |
12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 |
14 | ## StringLiteralGenerator
15 |
16 | MIT License
17 |
18 | Copyright (c) 2020 Nobuyuki Iwanaga
19 |
20 | Permission is hereby granted, free of charge, to any person obtaining a copy
21 | of this software and associated documentation files (the "Software"), to deal
22 | in the Software without restriction, including without limitation the rights
23 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 | copies of the Software, and to permit persons to whom the Software is
25 | furnished to do so, subject to the following conditions:
26 |
27 | The above copyright notice and this permission notice shall be included in all
28 | copies or substantial portions of the Software.
29 |
30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 | SOFTWARE.
37 |
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
1 | # 上位ディレクトリから .editorconfig 設定を継承する場合は、以下の行を削除します
2 | root = true
3 |
4 | [*]
5 | end_of_line = crlf
6 |
7 | [*.md,*.xml,*.cs,*.xaml,*.glsl,*.vert,*.frag]
8 | # for any text-based file
9 | charset = utf-8
10 | end_of_line = crlf
11 | insert_final_newline = true
12 |
13 | [*.md]
14 | indent_style = space
15 | indent_size = 4
16 | insert_final_newline = true
17 |
18 | [*.xml]
19 | indent_size = 4
20 | indent_style = space
21 | tab_width = 4
22 | insert_final_newline = true
23 |
24 | # CSharp formatting settings:
25 | [*.cs]
26 | # インデントと間隔
27 | indent_size = 4
28 | indent_style = space
29 | tab_width = 4
30 |
31 | # 改行設定
32 | end_of_line = crlf
33 | insert_final_newline = true
34 |
35 | #### .NET コーディング規則 ####
36 |
37 | # using の整理
38 | dotnet_separate_import_directive_groups = false
39 | dotnet_sort_system_directives_first = false
40 |
41 | # this. と Me. の設定
42 | dotnet_style_qualification_for_event = false:silent
43 | dotnet_style_qualification_for_field = false:silent
44 | dotnet_style_qualification_for_method = false:silent
45 | dotnet_style_qualification_for_property = false:silent
46 |
47 | # 言語キーワードと BCL の種類の設定
48 | dotnet_style_predefined_type_for_locals_parameters_members = true:silent
49 | dotnet_style_predefined_type_for_member_access = true:silent
50 |
51 | # かっこの設定
52 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
53 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
54 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
55 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
56 |
57 | # 修飾子設定
58 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
59 |
60 | # 式レベルの設定
61 | csharp_style_deconstructed_variable_declaration = true:suggestion
62 | csharp_style_inlined_variable_declaration = true:suggestion
63 | csharp_style_throw_expression = true:suggestion
64 | dotnet_style_coalesce_expression = true:suggestion
65 | dotnet_style_collection_initializer = true:suggestion
66 | dotnet_style_explicit_tuple_names = true:suggestion
67 | dotnet_style_null_propagation = true:suggestion
68 | dotnet_style_object_initializer = true:suggestion
69 | dotnet_style_prefer_auto_properties = true:silent
70 | dotnet_style_prefer_compound_assignment = true:suggestion
71 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent
72 | dotnet_style_prefer_conditional_expression_over_return = true:silent
73 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
74 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
75 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
76 |
77 | # フィールド設定
78 | dotnet_style_readonly_field = true:suggestion
79 |
80 | # パラメーターの設定
81 | dotnet_code_quality_unused_parameters = all:suggestion
82 |
83 | #### C# コーディング規則 ####
84 |
85 | # var を優先
86 | csharp_style_var_elsewhere = false:silent
87 | csharp_style_var_for_built_in_types = false:silent
88 | csharp_style_var_when_type_is_apparent = false:silent
89 |
90 | # 式のようなメンバー
91 | csharp_style_expression_bodied_accessors = true:silent
92 | csharp_style_expression_bodied_constructors = false:silent
93 | csharp_style_expression_bodied_indexers = true:silent
94 | csharp_style_expression_bodied_lambdas = true:silent
95 | csharp_style_expression_bodied_local_functions = false:silent
96 | csharp_style_expression_bodied_methods = false:silent
97 | csharp_style_expression_bodied_operators = false:silent
98 | csharp_style_expression_bodied_properties = true:silent
99 |
100 | # パターン マッチング設定
101 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
102 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
103 |
104 | # Null チェック設定
105 | csharp_style_conditional_delegate_call = true:suggestion
106 |
107 | # 修飾子設定
108 | csharp_prefer_static_local_function = true:suggestion
109 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
110 |
111 | # コード ブロックの設定
112 | csharp_prefer_braces = true:silent
113 | csharp_prefer_simple_using_statement = true:suggestion
114 |
115 | # 式レベルの設定
116 | csharp_prefer_simple_default_expression = true:suggestion
117 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
118 | csharp_style_prefer_index_operator = true:suggestion
119 | csharp_style_prefer_range_operator = true:suggestion
120 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion
121 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent
122 |
123 | # 'using' ディレクティブの基本設定
124 | csharp_using_directive_placement = outside_namespace:silent
125 |
126 | #### C# 書式ルール ####
127 |
128 | # 改行設定
129 | csharp_new_line_before_catch = true
130 | csharp_new_line_before_else = true
131 | csharp_new_line_before_finally = true
132 | csharp_new_line_before_members_in_anonymous_types = true
133 | csharp_new_line_before_members_in_object_initializers = true
134 | csharp_new_line_before_open_brace = accessors,anonymous_methods,anonymous_types,lambdas,methods,object_collection_array_initializers,properties,types
135 | csharp_new_line_between_query_expression_clauses = true
136 |
137 | # インデント設定
138 | csharp_indent_block_contents = true
139 | csharp_indent_braces = false
140 | csharp_indent_case_contents = true
141 | csharp_indent_case_contents_when_block = false
142 | csharp_indent_labels = one_less_than_current
143 | csharp_indent_switch_labels = true
144 |
145 | # スペース設定
146 | csharp_space_after_cast = false
147 | csharp_space_after_colon_in_inheritance_clause = true
148 | csharp_space_after_comma = true
149 | csharp_space_after_dot = false
150 | csharp_space_after_keywords_in_control_flow_statements = false
151 | csharp_space_after_semicolon_in_for_statement = true
152 | csharp_space_around_binary_operators = before_and_after
153 | csharp_space_around_declaration_statements = false
154 | csharp_space_before_colon_in_inheritance_clause = true
155 | csharp_space_before_comma = false
156 | csharp_space_before_dot = false
157 | csharp_space_before_open_square_brackets = false
158 | csharp_space_before_semicolon_in_for_statement = false
159 | csharp_space_between_empty_square_brackets = false
160 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
161 | csharp_space_between_method_call_name_and_opening_parenthesis = false
162 | csharp_space_between_method_call_parameter_list_parentheses = false
163 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
164 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
165 | csharp_space_between_method_declaration_parameter_list_parentheses = false
166 | csharp_space_between_parentheses = false
167 | csharp_space_between_square_brackets = false
168 |
169 | # 折り返しの設定
170 | csharp_preserve_single_line_blocks = true
171 | csharp_preserve_single_line_statements = true
172 |
--------------------------------------------------------------------------------
/src/Benchmark/Benchmark.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0;net5.0;net48
6 | U8Xml.Benchmark
7 | 8.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Always
21 |
22 |
23 | Always
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/Benchmark/Program.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System.IO;
3 | using BenchmarkDotNet.Running;
4 | using BenchmarkDotNet.Attributes;
5 |
6 | namespace U8Xml.Benchmark
7 | {
8 | class Program
9 | {
10 | public static void Main()
11 | {
12 | // Switch benchmarks
13 |
14 | //BenchmarkRunner.Run();
15 | BenchmarkRunner.Run();
16 | }
17 | }
18 |
19 | [MemoryDiagnoser]
20 | [MarkdownExporterAttribute.GitHub]
21 | [RyuJitX64Job]
22 | [IterationCount(100)]
23 | public class ParserStreamBenchmark
24 | {
25 | private Stream? _stream;
26 |
27 | public ParserStreamBenchmark()
28 | {
29 | // Remove comment-out to switch the file
30 |
31 | //var name = "small.xml";
32 | var name = "large.xml";
33 |
34 | var filePath = Path.Combine("data", name);
35 |
36 | using(var file = File.OpenRead(filePath)) {
37 | var ms = new MemoryStream();
38 | file.CopyTo(ms);
39 | _stream = ms;
40 | }
41 | }
42 |
43 | // *** NOTE ***
44 | // Don't use IterationSetup and IterationCleanup. This benchmark is shorter than 100ms.
45 | // See https://benchmarkdotnet.org/articles/features/setup-and-cleanup.html
46 | //
47 | // > It's not recommended to use this attribute in microbenchmarks because it can spoil the results.
48 | // > However, if you are writing a macrobenchmark (e.g. a benchmark which takes at least 100ms)
49 | // > and you want to prepare some data before each invocation, [IterationSetup] can be useful.
50 |
51 | [Benchmark(Baseline = true, Description = "U8Xml.XmlParser (my lib)")]
52 | public void U8XmlParser()
53 | {
54 | var stream = _stream!;
55 | stream.Position = 0;
56 | using var xml = U8Xml.XmlParser.Parse(stream);
57 | }
58 |
59 | [Benchmark(Description = "System.Xml.Linq.XDocument")]
60 | public void XDocument()
61 | {
62 | var stream = _stream!;
63 | stream.Position = 0;
64 | var xml = System.Xml.Linq.XDocument.Load(stream);
65 | }
66 |
67 | [Benchmark(Description = "System.Xml.XmlDocument")]
68 | public void XmlDocument()
69 | {
70 | var stream = _stream!;
71 | stream.Position = 0;
72 | var xml = new System.Xml.XmlDocument();
73 | xml.Load(stream);
74 | }
75 |
76 | [Benchmark(Description = "System.Xml.XmlReader")]
77 | public void XmlReader()
78 | {
79 | var stream = _stream!;
80 | stream.Position = 0;
81 | using var reader = System.Xml.XmlReader.Create(stream);
82 | while(reader.Read()) {
83 | }
84 | }
85 | }
86 |
87 | [MemoryDiagnoser]
88 | [MarkdownExporterAttribute.GitHub]
89 | [RyuJitX64Job]
90 | [IterationCount(100)]
91 | public class ParserFileBenchmark
92 | {
93 | private string _filePath;
94 |
95 | public ParserFileBenchmark()
96 | {
97 | // Remove comment-out to switch the file
98 |
99 | //var name = "small.xml";
100 | var name = "large.xml";
101 |
102 | _filePath = Path.Combine("data", name);
103 | }
104 |
105 | // *** NOTE ***
106 | // Don't use IterationSetup and IterationCleanup. This benchmark is shorter than 100ms.
107 | // See https://benchmarkdotnet.org/articles/features/setup-and-cleanup.html
108 | //
109 | // > It's not recommended to use this attribute in microbenchmarks because it can spoil the results.
110 | // > However, if you are writing a macrobenchmark (e.g. a benchmark which takes at least 100ms)
111 | // > and you want to prepare some data before each invocation, [IterationSetup] can be useful.
112 |
113 | [Benchmark(Baseline = true, Description = "U8Xml.XmlParser (my lib)")]
114 | public void U8XmlParser_File()
115 | {
116 | using var xml = U8Xml.XmlParser.ParseFile(_filePath);
117 | }
118 |
119 | [Benchmark(Description = "System.Xml.Linq.XDocument")]
120 | public void XDocument_File()
121 | {
122 | var xml = System.Xml.Linq.XDocument.Load(_filePath);
123 | }
124 |
125 | [Benchmark(Description = "System.Xml.XmlDocument")]
126 | public void XmlDocument_File()
127 | {
128 | var xml = new System.Xml.XmlDocument();
129 | xml.Load(_filePath);
130 | }
131 |
132 | [Benchmark(Description = "System.Xml.XmlReader")]
133 | public void XmlReader_File()
134 | {
135 | using var reader = System.Xml.XmlReader.Create(_filePath);
136 | while(reader.Read()) {
137 | }
138 | }
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/src/U8XmlParser.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31112.23
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "U8XmlParser", "U8XmlParser\U8XmlParser.csproj", "{ADD436FC-0CB2-4FDB-AC42-70852E0868BB}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{9906A207-5BFB-45BC-840B-755388A2A368}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark\Benchmark.csproj", "{52C19707-7EF1-44BF-A99A-60A2D145ACAE}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {ADD436FC-0CB2-4FDB-AC42-70852E0868BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {ADD436FC-0CB2-4FDB-AC42-70852E0868BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {ADD436FC-0CB2-4FDB-AC42-70852E0868BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {ADD436FC-0CB2-4FDB-AC42-70852E0868BB}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {9906A207-5BFB-45BC-840B-755388A2A368}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {9906A207-5BFB-45BC-840B-755388A2A368}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {9906A207-5BFB-45BC-840B-755388A2A368}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {9906A207-5BFB-45BC-840B-755388A2A368}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {52C19707-7EF1-44BF-A99A-60A2D145ACAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {52C19707-7EF1-44BF-A99A-60A2D145ACAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {52C19707-7EF1-44BF-A99A-60A2D145ACAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {52C19707-7EF1-44BF-A99A-60A2D145ACAE}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {C7FB9280-6C7E-413B-AC4A-6AB87373C3F9}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/src/U8XmlParser/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 ikorin24
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/U8XmlParser/U8XmlParser.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;net5.0;netcoreapp3.1;net48;netstandard2.0;netstandard2.1
5 | enable
6 | 8.0
7 | U8Xml
8 | true
9 | true
10 | ikorin24
11 | ikorin24
12 | High performance C# xml parser
13 | Copyright © 2022 ikorin24
14 | https://github.com/ikorin24/U8XmlParser.git
15 | true
16 | git
17 | 1.6.1
18 | LICENSE
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | True
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore file should be placed at the root of your Unity project directory
2 | #
3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
4 | #
5 | /[Ll]ibrary/
6 | /[Tt]emp/
7 | /[Oo]bj/
8 | /[Bb]uild/
9 | /[Bb]uilds/
10 | /[Ll]ogs/
11 | /[Uu]ser[Ss]ettings/
12 |
13 | # MemoryCaptures can get excessive in size.
14 | # They also could contain extremely sensitive data
15 | /[Mm]emoryCaptures/
16 |
17 | # Asset meta data should only be ignored when the corresponding asset is also ignored
18 | !/[Aa]ssets/**/*.meta
19 |
20 | # Uncomment this line if you wish to ignore the asset store tools plugin
21 | # /[Aa]ssets/AssetStoreTools*
22 |
23 | # Autogenerated Jetbrains Rider plugin
24 | /[Aa]ssets/Plugins/Editor/JetBrains*
25 |
26 | # Visual Studio cache directory
27 | .vs/
28 |
29 | # Gradle cache directory
30 | .gradle/
31 |
32 | # Autogenerated VS/MD/Consulo solution and project files
33 | ExportedObj/
34 | .consulo/
35 | *.csproj
36 | *.unityproj
37 | *.sln
38 | *.suo
39 | *.tmp
40 | *.user
41 | *.userprefs
42 | *.pidb
43 | *.booproj
44 | *.svd
45 | *.pdb
46 | *.mdb
47 | *.opendb
48 | *.VC.db
49 |
50 | # Unity3D generated meta files
51 | *.pidb.meta
52 | *.pdb.meta
53 | *.mdb.meta
54 |
55 | # Unity3D generated file on crash reports
56 | sysinfo.txt
57 |
58 | # Builds
59 | *.apk
60 | *.aab
61 | *.unitypackage
62 |
63 | # Crashlytics generated file
64 | crashlytics-build.properties
65 |
66 | # Packed Addressables
67 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
68 |
69 | # Temporary auto-generated Android Assets
70 | /[Aa]ssets/[Ss]treamingAssets/aa.meta
71 | /[Aa]ssets/[Ss]treamingAssets/aa/*
72 |
73 | .vsconfig
74 |
75 | !/[Aa]ssets/Plugins/U8XmlParser/*~/
76 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1f69c3da1b7db5347aabb76fa2ff769a
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b8cd984bb5d771941bf6d44f99388290
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bab58fd6c06414a4ead0c2bd187c3a03
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/AllNodeList.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using System.Runtime.CompilerServices;
7 | using U8Xml.Internal;
8 |
9 | namespace U8Xml
10 | {
11 | [DebuggerDisplay("XmlNode[{Count}]")]
12 | [DebuggerTypeProxy(typeof(AllNodeListDebuggerTypeProxy))]
13 | public readonly unsafe struct AllNodeList : IEnumerable
14 | {
15 | private readonly CustomList _nodes;
16 | private readonly int _count;
17 | private readonly XmlNodeType? _targetType;
18 |
19 | public int Count => _count;
20 |
21 | internal AllNodeList(CustomList nodes, int count, XmlNodeType? targetType)
22 | {
23 | _nodes = nodes;
24 | _count = count;
25 | _targetType = targetType;
26 | }
27 |
28 | public XmlNode First()
29 | {
30 | if(FirstOrDefault().TryGetValue(out var node) == false) {
31 | ThrowHelper.ThrowInvalidOperation("Sequence contains no elements.");
32 | }
33 | return node;
34 | }
35 |
36 | public Option FirstOrDefault()
37 | {
38 | using var e = GetEnumerator();
39 | if(e.MoveNext() == false) {
40 | return Option.Null;
41 | }
42 | return e.Current;
43 | }
44 |
45 | public XmlNode First(Func predicate)
46 | {
47 | if(FirstOrDefault(predicate).TryGetValue(out var node) == false) {
48 | ThrowHelper.ThrowInvalidOperation("Sequence contains no matching elements.");
49 | }
50 | return node;
51 | }
52 |
53 | public Option FirstOrDefault(Func predicate)
54 | {
55 | if(predicate is null) { ThrowHelper.ThrowNullArg(nameof(predicate)); }
56 | foreach(var node in this) {
57 | if(predicate!(node)) {
58 | return node;
59 | }
60 | }
61 | return Option.Null;
62 | }
63 |
64 | public Enumerator GetEnumerator() => new Enumerator(_nodes.GetEnumerator(), _targetType);
65 |
66 | IEnumerator IEnumerable.GetEnumerator() => new EnumeratorClass(_nodes.GetEnumerator(), _targetType);
67 |
68 | IEnumerator IEnumerable.GetEnumerator() => new EnumeratorClass(_nodes.GetEnumerator(), _targetType);
69 |
70 |
71 | public struct Enumerator : IEnumerator
72 | {
73 | private CustomList.Enumerator _e;
74 | private readonly XmlNodeType _targetType;
75 | private readonly bool _hasTargetType;
76 |
77 | internal Enumerator(CustomList.Enumerator e, XmlNodeType? targetType)
78 | {
79 | _e = e;
80 | (_hasTargetType, _targetType) = targetType.HasValue switch
81 | {
82 | true => (true, targetType.Value),
83 | false => (false, default),
84 | };
85 | }
86 |
87 | public XmlNode Current => new XmlNode(_e.Current);
88 |
89 | object IEnumerator.Current => Current;
90 |
91 | public void Dispose() => _e.Dispose();
92 |
93 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
94 | public bool MoveNext()
95 | {
96 | MoveNext:
97 | if(_e.MoveNext() == false) {
98 | return false;
99 | }
100 | if(_hasTargetType == false || _e.Current->NodeType == _targetType) {
101 | return true;
102 | }
103 | goto MoveNext;
104 | }
105 |
106 | public void Reset() => _e.Reset();
107 | }
108 |
109 | internal sealed class EnumeratorClass : IEnumerator
110 | {
111 | private Enumerator _e;
112 |
113 | internal EnumeratorClass(CustomList.Enumerator e, XmlNodeType? targetType)
114 | {
115 | _e = new Enumerator(e, targetType);
116 | }
117 |
118 | public XmlNode Current => _e.Current;
119 |
120 | object IEnumerator.Current => Current;
121 |
122 | public void Dispose() => _e.Dispose();
123 |
124 | public bool MoveNext() => _e.MoveNext();
125 |
126 | public void Reset() => _e.Reset();
127 | }
128 |
129 | internal sealed class AllNodeListDebuggerTypeProxy
130 | {
131 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
132 | private readonly AllNodeList _list;
133 |
134 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
135 | public XmlNode[] Item => System.Linq.Enumerable.ToArray(_list);
136 |
137 | public AllNodeListDebuggerTypeProxy(AllNodeList list)
138 | {
139 | _list = list;
140 | }
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/AllNodeList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6d0ea6380985e6e49b1fbf817a317aa9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_2018_1_OR_NEWER
2 | #define IS_UNITY
3 | #endif
4 |
5 | #if !IS_UNITY
6 | using System.Runtime.CompilerServices;
7 |
8 | [assembly: InternalsVisibleTo("UnitTest")]
9 | #endif
10 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/AssemblyInfo.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ef8ba4dd9e0bd9846b4e75e05c8d62ab
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/DataLocation.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8e7e4a164e54cc6419ba5ffe2c2be876
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ad02885932ce5304387056a3f8fcc8ca
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/AllocationSafety.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Diagnostics;
4 |
5 | namespace U8Xml.Internal
6 | {
7 | internal static class AllocationSafety
8 | {
9 | [ThreadStatic]
10 | private static int _size;
11 |
12 | [Conditional("DEBUG")]
13 | public static void Add(int size)
14 | {
15 | _size += size;
16 | }
17 |
18 | [Conditional("DEBUG")]
19 | public static void Remove(int size)
20 | {
21 | _size -= size;
22 | }
23 |
24 | [Conditional("DEBUG")]
25 | public static void Ensure()
26 | {
27 | var size = _size;
28 | _size = 0;
29 | if(size != 0) {
30 | throw new Exception($"Memory leak happened or something wrong. ({_size} bytes)");
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/AllocationSafety.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4d4c78a6690297348b5624cd8b04f06f
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/BitOperationHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | #if NETCOREAPP3_1_OR_GREATER
3 | #define SUPPORT_BIT_OPERATIONS
4 | #endif
5 |
6 | using System;
7 | using System.Diagnostics;
8 | using System.Runtime.CompilerServices;
9 |
10 | #if SUPPORT_BIT_OPERATIONS
11 | using System.Numerics;
12 | #else
13 | using System.Runtime.InteropServices;
14 | #endif
15 |
16 | namespace U8Xml.Internal
17 | {
18 | internal static class BitOperationHelper
19 | {
20 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
21 | public static uint RotateLeft(uint value, int offset)
22 | {
23 | return (value << offset) | (value >> (32 - offset));
24 | }
25 |
26 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
27 | public static int Log2(uint value)
28 | {
29 | #if SUPPORT_BIT_OPERATIONS
30 | return BitOperations.Log2(value);
31 | #else
32 | // https://source.dot.net/#System.Private.CoreLib/BitOperations.cs,178
33 |
34 | // The 0->0 contract is fulfilled by setting the LSB to 1.
35 | // Log(1) is 0, and setting the LSB for values > 1 does not change the log2 result.
36 | value |= 1;
37 | return Log2SoftwareFallback(value);
38 | #endif
39 | }
40 |
41 | #if !SUPPORT_BIT_OPERATIONS
42 | private static ReadOnlySpan Log2DeBruijn => new byte[32]
43 | {
44 | 00, 09, 01, 10, 13, 21, 02, 29,
45 | 11, 14, 16, 18, 22, 25, 03, 30,
46 | 08, 12, 20, 28, 15, 17, 24, 07,
47 | 19, 27, 23, 06, 26, 05, 04, 31
48 | };
49 |
50 | private static int Log2SoftwareFallback(uint value)
51 | {
52 | // https://source.dot.net/#System.Private.CoreLib/BitOperations.cs,253
53 |
54 | // No AggressiveInlining due to large method size
55 | // Has conventional contract 0->0 (Log(0) is undefined)
56 |
57 | // Fill trailing zeros with ones, eg 00010010 becomes 00011111
58 | value |= value >> 01;
59 | value |= value >> 02;
60 | value |= value >> 04;
61 | value |= value >> 08;
62 | value |= value >> 16;
63 |
64 | // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
65 | return Unsafe.AddByteOffset(
66 | // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u
67 | ref MemoryMarshal.GetReference(Log2DeBruijn),
68 | // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here
69 | (IntPtr)(int)((value * 0x07C4ACDDu) >> 27));
70 | }
71 | #endif
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/BitOperationHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1de7f9bfd588d2846a09993dccdca0ba
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/CustomList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fe5b87eef17f35b48a66d251383c411c
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/DataOffsetHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System.Diagnostics;
3 |
4 | namespace U8Xml.Internal
5 | {
6 | internal static unsafe class DataOffsetHelper
7 | {
8 | public static int? GetOffset(byte* dataHead, int dataLen, byte* target)
9 | {
10 | if(dataLen < 0) { ThrowHelper.ThrowArgOutOfRange(nameof(dataLen)); }
11 | if(CheckContainsMemory(dataHead, dataLen, target, 0) == false) {
12 | return null;
13 | }
14 | long offset = target - dataHead;
15 | return checked((int)(uint)offset);
16 | }
17 |
18 | public static DataLocation? GetLocation(byte* dataHead, int dataLen, byte* targetHead, int targetLen)
19 | {
20 | if(dataLen < 0) { ThrowHelper.ThrowArgOutOfRange(nameof(dataLen)); }
21 | if(targetLen < 0) { ThrowHelper.ThrowArgOutOfRange(nameof(targetLen)); }
22 | if(CheckContainsMemory(dataHead, dataLen, targetHead, targetLen) == false) {
23 | return null;
24 | }
25 |
26 | var start = GetLinePositionPrivate(dataHead, dataLen, targetHead);
27 | var endOffset = GetLinePositionPrivate(targetHead, targetLen, targetHead + targetLen);
28 | var end = new DataLinePosition(
29 | line: start.Line + endOffset.Line,
30 | position: (endOffset.Line == 0) ? (start.Position + endOffset.Position) : endOffset.Position
31 | );
32 |
33 | int byteOffset = checked((int)(uint)(targetHead - dataHead));
34 | var range = new DataRange(byteOffset, targetLen);
35 | return new DataLocation(start, end, range);
36 | }
37 |
38 | public static DataLinePosition? GetLinePosition(byte* dataHead, int dataLen, byte* target)
39 | {
40 | if(dataLen < 0) { ThrowHelper.ThrowArgOutOfRange(nameof(dataLen)); }
41 | if(CheckContainsMemory(dataHead, dataLen, target, 0) == false) {
42 | return null;
43 | }
44 | return GetLinePositionPrivate(dataHead, dataLen, target);
45 | }
46 |
47 | private static DataLinePosition GetLinePositionPrivate(byte* dataHead, int dataLen, byte* target)
48 | {
49 | Debug.Assert(dataLen >= 0);
50 | Debug.Assert(dataHead <= target);
51 |
52 | int lineNum = 0;
53 | byte* lastLineHead = dataHead;
54 | for(byte* p = dataHead; p < target; p++) {
55 | if(*p == '\n') {
56 | lineNum++;
57 | lastLineHead = p + 1;
58 | }
59 | }
60 | int byteCountInLastLine = checked((int)(uint)(target - lastLineHead));
61 | var utf8 = UTF8ExceptionFallbackEncoding.Instance;
62 | var pos = utf8.GetCharCount(lastLineHead, byteCountInLastLine);
63 | return new DataLinePosition(lineNum, pos);
64 | }
65 |
66 | private static bool CheckContainsMemory(byte* dataHead, int dataLen, byte* targetHead, int targetLen)
67 | {
68 | Debug.Assert(targetLen >= 0);
69 | Debug.Assert(dataLen >= 0);
70 | return (dataHead <= targetHead) && (targetHead + targetLen) <= (dataHead + dataLen);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/DataOffsetHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fbd5c9e8d0193f84fb4415abd83d4e2a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/EncodingExtension.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | #if UNITY_2018_1_OR_NEWER
4 | #define IS_UNITY
5 | #endif
6 |
7 | #if !(NETSTANDARD2_0 || NET48 || IS_UNITY)
8 | #define ENCODING_SPAN_API
9 | #endif
10 |
11 |
12 | #if !ENCODING_SPAN_API
13 | using System;
14 | using System.Text;
15 |
16 | namespace U8Xml.Internal
17 | {
18 | internal static class EncodingExtension
19 | {
20 | public static unsafe int GetByteCount(this Encoding encoding, ReadOnlySpan span)
21 | {
22 | fixed(char* ptr = span) {
23 | return encoding.GetByteCount(ptr, span.Length);
24 | }
25 | }
26 | }
27 | }
28 | #endif // ENCODING_SPAN_API
29 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/EncodingExtension.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6b00765bedd1f4f4bbfac6cf73eeb159
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/IXmlObject.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 |
4 | namespace U8Xml.Internal
5 | {
6 | internal interface IXmlObject : IDisposable
7 | {
8 | bool IsDisposed { get; }
9 | XmlNode Root { get; }
10 | Option Declaration { get; }
11 | Option DocumentType { get; }
12 | XmlEntityTable EntityTable { get; }
13 | RawString AsRawString();
14 | RawString AsRawString(int start);
15 | RawString AsRawString(int start, int length);
16 | RawString AsRawString(DataRange range);
17 |
18 | AllNodeList GetAllNodes();
19 | AllNodeList GetAllNodes(XmlNodeType? targetType);
20 |
21 | DataLocation GetLocation(XmlNode node);
22 | DataLocation GetLocation(XmlAttribute attr);
23 | DataLocation GetLocation(RawString str);
24 | DataLocation GetLocation(DataRange range);
25 |
26 | DataRange GetRange(XmlNode node);
27 | DataRange GetRange(XmlAttribute attr);
28 | DataRange GetRange(RawString str);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/IXmlObject.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9359032f80e955a489641cea191bf17b
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/NodeStack.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Diagnostics;
6 |
7 | namespace U8Xml.Internal
8 | {
9 | [DebuggerDisplay("NodeStack[{Count}]")]
10 | [DebuggerTypeProxy(typeof(NodeStackDebuggerTypeProxy))]
11 | internal unsafe struct NodeStack : IDisposable
12 | {
13 | private XmlNode_** _ptr;
14 | private int _capacity;
15 | private int _count;
16 |
17 | public int Capacity => _capacity;
18 |
19 | public int Count => _count;
20 |
21 | public NodeStack(int capacity)
22 | {
23 | Debug.Assert(capacity >= 0);
24 | _ptr = (XmlNode_**)Marshal.AllocHGlobal(capacity * sizeof(XmlNode_*));
25 | AllocationSafety.Add(capacity * sizeof(XmlNode_*));
26 | _capacity = capacity;
27 | _count = 0;
28 | }
29 |
30 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
31 | public void Push(XmlNode_* value)
32 | {
33 | if(_capacity == _count) {
34 | GrowUp();
35 | }
36 | Debug.Assert(_capacity > _count);
37 | _ptr[_count] = value;
38 | _count++;
39 | }
40 |
41 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
42 | public XmlNode_* Pop()
43 | {
44 | if(_count == 0) { ThrowHelper.ThrowInvalidOperation("Stack has no items."); }
45 | _count--;
46 | return _ptr[_count];
47 | }
48 |
49 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
50 | public XmlNode_* Peek()
51 | {
52 | if(_count == 0) { ThrowHelper.ThrowInvalidOperation("Stack has no items."); }
53 | return _ptr[_count - 1];
54 | }
55 |
56 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 | public bool TryPeek(out XmlNode_* item)
58 | {
59 | if(_count == 0) {
60 | item = null;
61 | return false;
62 | }
63 | item = _ptr[_count - 1];
64 | return true;
65 | }
66 |
67 | public void Dispose()
68 | {
69 | Marshal.FreeHGlobal((IntPtr)_ptr);
70 | AllocationSafety.Remove(_capacity * sizeof(XmlNode_*));
71 | _capacity = 0;
72 | _count = 0;
73 | }
74 |
75 | [MethodImpl(MethodImplOptions.NoInlining)] // uncommon path, no inlining
76 | private void GrowUp()
77 | {
78 | var newCapacity = Math.Max(4, _capacity * 2);
79 | var ptr = (XmlNode_**)Marshal.AllocHGlobal(newCapacity * sizeof(XmlNode_*));
80 | AllocationSafety.Add(newCapacity * sizeof(XmlNode_*));
81 | try {
82 | SpanHelper.CreateSpan(_ptr, _count).CopyTo(SpanHelper.CreateSpan(ptr, newCapacity));
83 | Marshal.FreeHGlobal((IntPtr)_ptr);
84 | AllocationSafety.Remove(_capacity * sizeof(XmlNode_*));
85 | _ptr = ptr;
86 | _capacity = newCapacity;
87 | }
88 | catch {
89 | Marshal.FreeHGlobal((IntPtr)ptr);
90 | AllocationSafety.Remove(newCapacity * sizeof(XmlNode_*));
91 | throw;
92 | }
93 | }
94 |
95 |
96 | private class NodeStackDebuggerTypeProxy
97 | {
98 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
99 | private NodeStack _entity;
100 |
101 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
102 | public unsafe XmlNode_*[] Items
103 | {
104 | get
105 | {
106 | var array = new XmlNode_*[_entity.Count];
107 | for(int i = 0; i < array.Length; i++) {
108 | array[i] = _entity._ptr[i];
109 | }
110 | return array;
111 | }
112 | }
113 |
114 | public NodeStackDebuggerTypeProxy(NodeStack entity)
115 | {
116 | _entity = entity;
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/NodeStack.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e098653ee80931d44b89d575b7de216e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/OptionalNodeList.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace U8Xml.Internal
7 | {
8 | internal unsafe readonly struct OptionalNodeList : IDisposable, IReference
9 | {
10 | private readonly IntPtr _list; // OptionalNodeList_*
11 |
12 | public bool IsNull => _list == IntPtr.Zero;
13 |
14 | public XmlDeclaration_* Declaration => &((OptionalNodeList_*)_list)->Declaration;
15 |
16 | public XmlDocumentType_* DocumentType => &((OptionalNodeList_*)_list)->DocumentType;
17 |
18 | private OptionalNodeList(IntPtr list)
19 | {
20 | _list = list;
21 | }
22 |
23 | public static OptionalNodeList Create()
24 | {
25 | var ptr = (OptionalNodeList_*)Marshal.AllocHGlobal(sizeof(OptionalNodeList_));
26 | AllocationSafety.Add(sizeof(OptionalNodeList_));
27 | *ptr = default;
28 | return new OptionalNodeList((IntPtr)ptr);
29 | }
30 |
31 | public void Dispose()
32 | {
33 | Marshal.FreeHGlobal(_list);
34 | AllocationSafety.Remove(sizeof(OptionalNodeList_));
35 | Unsafe.AsRef(_list) = IntPtr.Zero;
36 | }
37 |
38 |
39 | private struct OptionalNodeList_
40 | {
41 | public XmlDeclaration_ Declaration;
42 | public XmlDocumentType_ DocumentType;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/OptionalNodeList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3138f6fd8a4bfb645b90e1c5c324131d
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/PredefinedEntityTable.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 |
4 | namespace U8Xml.Internal
5 | {
6 | internal static class PredefinedEntityTable
7 | {
8 | private static ReadOnlySpan EntityAMP => new byte[1] { (byte)'&' };
9 | private static ReadOnlySpan EntityLT => new byte[1] { (byte)'<' };
10 | private static ReadOnlySpan EntityGT => new byte[1] { (byte)'>' };
11 | private static ReadOnlySpan EntityQUOT => new byte[1] { (byte)'"' };
12 | private static ReadOnlySpan EntityAPOS => new byte[1] { (byte)'\'' };
13 |
14 | public static unsafe bool TryGetPredefinedValue(in RawString alias, out ReadOnlySpan value)
15 | {
16 | if(alias.Length == 2) {
17 | if(alias.At(0) == 'l' && alias.At(1) == 't') {
18 | // <
19 | value = EntityLT;
20 | return true;
21 | }
22 | if(alias.At(0) == 'g' && alias.At(1) == 't') {
23 | // >
24 | value = EntityGT;
25 | return true;
26 | }
27 | }
28 | else if(alias.Length == 3) {
29 | if(alias.At(0) == 'a' && alias.At(1) == 'm' && alias.At(2) == 'p') {
30 | // &
31 | value = EntityAMP;
32 | return true;
33 | }
34 | }
35 | else if(alias.Length == 4) {
36 | if(alias.At(0) == 'q' && alias.At(1) == 'u' && alias.At(2) == 'o' && alias.At(3) == 't') {
37 | // "
38 | value = EntityQUOT;
39 | return true;
40 | }
41 | if(alias.At(0) == 'a' && alias.At(1) == 'p' && alias.At(2) == 'o' && alias.At(3) == 's') {
42 | // '
43 | value = EntityAPOS;
44 | return true;
45 | }
46 | }
47 |
48 | value = default;
49 | return false;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/PredefinedEntityTable.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2daed0ca7b46eae4bb27e830a30ac938
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/RawStringPairList.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Diagnostics;
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace U8Xml.Internal
8 | {
9 | // [NOTE]
10 | // - This list re-allocate and copy memory when capacity increases, the address of memories can be changed.
11 |
12 | [DebuggerDisplay("{DebugDisplay,nq}")]
13 | [DebuggerTypeProxy(typeof(RawStringPairListTypeProxy))]
14 | internal unsafe ref struct RawStringPairList
15 | {
16 | private Pair* _ptr;
17 | private int _capacity;
18 | private int _count;
19 |
20 | public int Count => _count;
21 |
22 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
23 | private string DebugDisplay => $"{nameof(RawStringPairList)} (Count={_count})";
24 |
25 | public ref readonly Pair this[int index]
26 | {
27 | get
28 | {
29 | // Check index boundary only when DEBUG because this is internal.
30 | Debug.Assert((uint)index < (uint)_count);
31 | return ref _ptr[index];
32 | }
33 | }
34 |
35 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
36 | public void Add(in RawString key, in RawString value)
37 | {
38 | if(_capacity <= _count) {
39 | Growup(); // no inlining, uncommon path
40 | }
41 | Debug.Assert(_capacity > _count);
42 | ref var p = ref _ptr[_count++];
43 | p.Key = key;
44 | p.Value = value;
45 | }
46 |
47 | [MethodImpl(MethodImplOptions.NoInlining)] // no inlining, uncommon path
48 | private void Growup()
49 | {
50 | if(_capacity == 0) {
51 | const int InitialCapacity = 32;
52 | var size = InitialCapacity * sizeof(Pair);
53 |
54 | // It does not need to be cleared to zero.
55 | _ptr = (Pair*)Marshal.AllocHGlobal(size);
56 | AllocationSafety.Add(size);
57 | _capacity = InitialCapacity;
58 | _count = 0;
59 | }
60 | else {
61 | Debug.Assert(_capacity > 0);
62 | var newCapacity = _capacity * 2;
63 | var newSize = newCapacity * sizeof(Pair);
64 | var newPtr = (Pair*)Marshal.AllocHGlobal(newSize);
65 | AllocationSafety.Add(newSize);
66 |
67 | var sizeToCopy = _count * sizeof(Pair);
68 | Buffer.MemoryCopy(_ptr, newPtr, sizeToCopy, sizeToCopy);
69 | Marshal.FreeHGlobal((IntPtr)_ptr);
70 | AllocationSafety.Remove(_capacity * sizeof(Pair));
71 | _capacity = newCapacity;
72 | _ptr = newPtr;
73 | }
74 | }
75 |
76 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
77 | public void Dispose()
78 | {
79 | Marshal.FreeHGlobal((IntPtr)_ptr);
80 | AllocationSafety.Remove(_capacity * sizeof(Pair));
81 | _capacity = 0;
82 | _count = 0;
83 | }
84 |
85 | [DebuggerDisplay("Key={Key}, Value={Value}")]
86 | public struct Pair
87 | {
88 | public RawString Key;
89 | public RawString Value;
90 | }
91 |
92 | private class RawStringPairListTypeProxy
93 | {
94 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
95 | private Pair[] _items;
96 |
97 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
98 | public Pair[] Items => _items;
99 |
100 | public RawStringPairListTypeProxy(RawStringPairList entity)
101 | {
102 | var items = new Pair[entity.Count];
103 | for(int i = 0; i < items.Length; i++) {
104 | items[i] = entity[i];
105 | }
106 | _items = items;
107 | }
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/RawStringPairList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 83270f91d3ba80f41aaa1be25e3b970a
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/RawStringTable.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4f14f38b8e643fe4eb5249e57106e1da
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/SkipLocalsInitCompatible.cs:
--------------------------------------------------------------------------------
1 | #if !NET5_0_OR_GREATER
2 | #nullable enable
3 | namespace System.Runtime.CompilerServices
4 | {
5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Module | AttributeTargets.Property | AttributeTargets.Struct, Inherited = false)]
6 | internal sealed class SkipLocalsInitAttribute : Attribute
7 | {
8 | }
9 | }
10 | #endif
11 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/SkipLocalsInitCompatible.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 632756180bb87844a974e3d4fa0637a0
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/SpanHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | #if UNITY_2018_1_OR_NEWER
4 | #define IS_UNITY
5 | #endif
6 |
7 | #if NETSTANDARD2_0 || NET48 || IS_UNITY
8 | #define NO_SPAN_API
9 | #endif
10 |
11 | #if NETCOREAPP3_1_OR_GREATER
12 | #define FAST_SPAN
13 | #endif
14 |
15 | using System;
16 | using System.Text;
17 | using System.Runtime.CompilerServices;
18 |
19 | #if FAST_SPAN
20 | using System.Runtime.InteropServices;
21 | #endif
22 |
23 | namespace U8Xml.Internal
24 | {
25 | internal static class SpanHelper
26 | {
27 | public static string Utf8ToString(this ReadOnlySpan source)
28 | {
29 | #if NO_SPAN_API
30 | unsafe { fixed(byte* ptr = source) { return UTF8ExceptionFallbackEncoding.Instance.GetString(ptr, source.Length); } }
31 | #else
32 | return UTF8ExceptionFallbackEncoding.Instance.GetString(source);
33 | #endif
34 | }
35 |
36 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
37 | public static unsafe ReadOnlySpan CreateReadOnlySpan(void* ptr, int length) where T : unmanaged
38 | {
39 | #if FAST_SPAN
40 | return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(ptr), length);
41 | #else
42 | return new ReadOnlySpan(ptr, length);
43 | #endif
44 | }
45 |
46 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
47 | public static unsafe Span CreateSpan(void* ptr, int length) where T : unmanaged
48 | {
49 | #if FAST_SPAN
50 | return MemoryMarshal.CreateSpan(ref Unsafe.AsRef(ptr), length);
51 | #else
52 | return new Span(ptr, length);
53 | #endif
54 | }
55 |
56 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 | public static ref readonly byte At(this ReadOnlySpan span, int index)
58 | {
59 | #if FAST_SPAN
60 | #if DEBUG
61 | if((uint)index >= (uint)span.Length) { throw new IndexOutOfRangeException(); }
62 | #endif
63 | return ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
64 | #else
65 | return ref span[index];
66 | #endif
67 | }
68 |
69 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 | public static ref byte At(this Span span, int index)
71 | {
72 | #if FAST_SPAN
73 | #if DEBUG
74 | if((uint)index >= (uint)span.Length) { throw new IndexOutOfRangeException(); }
75 | #endif
76 | return ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
77 | #else
78 | return ref span[index];
79 | #endif
80 | }
81 |
82 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
83 | internal static ReadOnlySpan SliceUnsafe(this ReadOnlySpan span, int start, int length)
84 | {
85 | #if DEBUG
86 | if((uint)start > (uint)span.Length) { ThrowHelper.ThrowArgOutOfRange(nameof(start)); }
87 | if((uint)length > (uint)(span.Length - start)) { ThrowHelper.ThrowArgOutOfRange(nameof(length)); }
88 | #endif
89 |
90 | #if FAST_SPAN
91 | return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), start), length);
92 | #else
93 | return span.Slice(start, length);
94 | #endif
95 | }
96 |
97 | /// Trim invisible charactors. (whitespace, '\t', '\r', and '\n')
98 | /// trimmed string
99 | internal static ReadOnlySpan Trim(this ReadOnlySpan span)
100 | {
101 | return span.TrimStart().TrimEnd();
102 | }
103 |
104 | /// Trim invisible charactors of start. (whitespace, '\t', '\r', and '\n')
105 | /// trimmed string
106 | internal static ReadOnlySpan TrimStart(this ReadOnlySpan span)
107 | {
108 | for(int i = 0; i < span.Length; i++) {
109 | ref readonly var p = ref span.At(i);
110 | if(p != ' ' && p != '\t' && p != '\r' && p != '\n') {
111 | return span.SliceUnsafe(i, span.Length - i);
112 | }
113 | }
114 | return ReadOnlySpan.Empty;
115 | }
116 |
117 | /// Trim invisible charactors of end. (whitespace, '\t', '\r' and '\n')
118 | /// trimmed string
119 | internal static ReadOnlySpan TrimEnd(this ReadOnlySpan span)
120 | {
121 | for(int i = span.Length - 1; i >= 0; i--) {
122 | ref readonly var p = ref span.At(i);
123 | if(p != ' ' && p != '\t' && p != '\r' && p != '\n') {
124 | return span.SliceUnsafe(0, i + 1);
125 | }
126 | }
127 | return span;
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/SpanHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: cc249a921bf655342ac09244195c7569
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/StreamExtension.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | #if UNITY_2018_1_OR_NEWER
4 | #define IS_UNITY
5 | #endif
6 |
7 | #if !(NETSTANDARD2_0 || NET48 || IS_UNITY)
8 | #define STREAM_SPAN_API
9 | #endif
10 |
11 | #if !STREAM_SPAN_API
12 | using System.Buffers;
13 | #endif
14 |
15 | using System;
16 | using System.IO;
17 |
18 | namespace U8Xml.Internal
19 | {
20 | internal static class StreamExtension
21 | {
22 | public static unsafe (UnmanagedBuffer buffer, int length) ReadAllToUnmanaged(this Stream stream, int fileSizeHint)
23 | {
24 | int capacity = Math.Min(int.MaxValue, Math.Max(0, fileSizeHint)); // 0 <= capacity <= int.MaxValue
25 |
26 | #if STREAM_SPAN_API
27 | var buf = new UnmanagedBuffer(capacity);
28 | var length = 0;
29 | try {
30 | while(true) {
31 | const int LengthToRead = 4096;
32 | if(buf.Length < length + LengthToRead) {
33 | var tmp = new UnmanagedBuffer(checked(length + LengthToRead));
34 | buf.AsSpan(0, length).CopyTo(tmp.AsSpan());
35 | buf.Dispose();
36 | buf = tmp;
37 | }
38 | var readlen = stream.Read(buf.AsSpan(length));
39 | length += readlen;
40 | if(stream.CanSeek && stream.Position == stream.Length) { break; }
41 | if(readlen == 0) { break; }
42 | }
43 | return (buf, length);
44 | }
45 | catch {
46 | buf.Dispose();
47 | throw;
48 | }
49 | #else
50 | const int LengthToRead = 4096;
51 | int bufSize = Math.Min(fileSizeHint, LengthToRead);
52 | var rentArray = ArrayPool.Shared.Rent(bufSize);
53 |
54 | var buf = new UnmanagedBuffer(fileSizeHint);
55 | var totalLen = 0;
56 | try {
57 | while(true) {
58 | var readlen = stream!.Read(rentArray, 0, bufSize);
59 | if(readlen == 0) { break; }
60 |
61 | if(buf.Length < totalLen + readlen) {
62 | ExtendBuffer(ref buf, totalLen);
63 | }
64 | rentArray.AsSpan(0, readlen).CopyTo(buf.AsSpan(totalLen));
65 | totalLen += readlen;
66 |
67 | if(stream.CanSeek && stream.Position == stream.Length) { break; }
68 | }
69 | return (buf, totalLen);
70 | }
71 | catch {
72 | buf.Dispose();
73 | throw;
74 | }
75 | finally {
76 | ArrayPool.Shared.Return(rentArray);
77 | }
78 |
79 | static void ExtendBuffer(ref UnmanagedBuffer buf, int currentUsedLen)
80 | {
81 | var newBufSize = buf.Length <= 0 ? 1024 : buf.Length * 2;
82 | var newBuf = new UnmanagedBuffer(newBufSize);
83 | try {
84 | buf.AsSpan(0, currentUsedLen).CopyTo(newBuf.AsSpan());
85 | }
86 | catch {
87 | newBuf.Dispose();
88 | throw;
89 | }
90 | buf.Dispose();
91 | buf = newBuf;
92 | }
93 | #endif
94 | }
95 | }
96 |
97 | internal static class FileHelper
98 | {
99 | public static unsafe (UnmanagedBuffer buffer, int length) ReadFileToUnmanaged(string filePath)
100 | {
101 | #if NET6_0_OR_GREATER
102 | UnmanagedBuffer buffer = default;
103 | try {
104 | int length;
105 | using var handle = File.OpenHandle(filePath);
106 | var fileLength = RandomAccess.GetLength(handle);
107 | if(fileLength > int.MaxValue) {
108 | ThrowHelper.ThrowNotSupported("The file is too large to parse. The parser only supports the file whose size is less than 2GB.");
109 | }
110 | buffer = new UnmanagedBuffer((int)fileLength);
111 | length = RandomAccess.Read(handle, buffer.AsSpan(), 0);
112 | return (buffer, length);
113 | }
114 | catch {
115 | buffer.Dispose();
116 | throw;
117 | }
118 | #else
119 | using(var stream = File.OpenRead(filePath)) {
120 | var fileLength = stream.Length;
121 | if(fileLength > int.MaxValue) {
122 | ThrowHelper.ThrowNotSupported("The file is too large to parse. The parser only supports the file whose size is less than 2GB.");
123 | }
124 | return stream.ReadAllToUnmanaged((int)fileLength);
125 | }
126 | #endif
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/StreamExtension.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 236dc4363e83c9c4aa0d3bc05a5cc687
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/ThrowHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | #if UNITY_2018_1_OR_NEWER
4 | #define IS_UNITY
5 | #endif
6 |
7 | #if !(NETSTANDARD2_0 || NET48) && !IS_UNITY
8 | #define CODE_ANALYTICS
9 | #endif
10 |
11 | using System;
12 | #if CODE_ANALYTICS
13 | using System.Diagnostics.CodeAnalysis;
14 | #endif
15 |
16 |
17 | namespace U8Xml.Internal
18 | {
19 | internal static class ThrowHelper
20 | {
21 | #if CODE_ANALYTICS
22 | [DoesNotReturn]
23 | #endif
24 | public static void ThrowNotSupported(string message)
25 | {
26 | throw new NotSupportedException(message);
27 | }
28 |
29 | #if CODE_ANALYTICS
30 | [DoesNotReturn]
31 | #endif
32 | public static void ThrowNullArg(string message)
33 | {
34 | throw new ArgumentNullException(message);
35 | }
36 |
37 |
38 | #if CODE_ANALYTICS
39 | [DoesNotReturn]
40 | #endif
41 | public static void ThrowFormatException(string? message = null)
42 | {
43 | throw new FormatException(message);
44 | }
45 |
46 | #if CODE_ANALYTICS
47 | [DoesNotReturn]
48 | #endif
49 | public static void ThrowArgOutOfRange(string? message = null)
50 | {
51 | throw new ArgumentOutOfRangeException(message);
52 | }
53 |
54 | #if CODE_ANALYTICS
55 | [DoesNotReturn]
56 | #endif
57 | public static void ThrowArg(string? message = null)
58 | {
59 | throw new ArgumentException(message);
60 | }
61 |
62 | #if CODE_ANALYTICS
63 | [DoesNotReturn]
64 | #endif
65 | public static void ThrowInvalidOperation(string? message = null)
66 | {
67 | throw new InvalidOperationException(message);
68 | }
69 |
70 | #if CODE_ANALYTICS
71 | [DoesNotReturn]
72 | #endif
73 | public static void ThrowDisposed(string objectName)
74 | {
75 | throw new ObjectDisposedException(objectName);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/ThrowHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c67bfff535b8b4b44bda84029b3bfefd
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UTF8ExceptionFallbackEncoding.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System.Text;
3 |
4 | namespace U8Xml.Internal
5 | {
6 | internal sealed class UTF8ExceptionFallbackEncoding : UTF8Encoding
7 | {
8 | public static UTF8ExceptionFallbackEncoding Instance { get; } = new UTF8ExceptionFallbackEncoding();
9 | private UTF8ExceptionFallbackEncoding() : base(false, true) { }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UTF8ExceptionFallbackEncoding.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0a46b099fe6a83a49905a532b2fa91a0
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnicodeHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Runtime.CompilerServices;
4 |
5 | namespace U8Xml.Internal
6 | {
7 | internal static class UnicodeHelper
8 | {
9 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
10 | public static bool TryEncodeCodePointToUtf8(uint codePoint, Span destination, out int bytesWritten)
11 | {
12 | #if NETCOREAPP3_1_OR_GREATER
13 | return new System.Text.Rune(codePoint).TryEncodeToUtf8(destination, out bytesWritten);
14 | #else
15 | return TryEncodeToUtf8ForLegacyRuntime(codePoint, destination, out bytesWritten);
16 | #endif
17 | }
18 |
19 | #if !NETCOREAPP3_1_OR_GREATER
20 |
21 | // The following implementation is copied from System.Text.Rune
22 | //
23 | // original source code
24 | // https://github.com/dotnet/runtime/blob/be19e1cc6aad0f28e3bf1d7c7201c455a96b3a9d/src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs#L1061
25 |
26 | private static bool TryEncodeToUtf8ForLegacyRuntime(uint codePoint, Span destination, out int bytesWritten)
27 | {
28 | // The bit patterns below come from the Unicode Standard, Table 3-6.
29 |
30 | if(!destination.IsEmpty) {
31 | if(codePoint <= 0x7Fu) {
32 | destination[0] = (byte)codePoint;
33 | bytesWritten = 1;
34 | return true;
35 | }
36 |
37 | if(1 < (uint)destination.Length) {
38 | if((int)codePoint <= 0x7FFu) {
39 | // Scalar 00000yyy yyxxxxxx -> bytes [ 110yyyyy 10xxxxxx ]
40 | destination[0] = (byte)((codePoint + (0b110u << 11)) >> 6);
41 | destination[1] = (byte)((codePoint & 0x3Fu) + 0x80u);
42 | bytesWritten = 2;
43 | return true;
44 | }
45 |
46 | if(2 < (uint)destination.Length) {
47 | if((int)codePoint <= 0xFFFFu) {
48 | // Scalar zzzzyyyy yyxxxxxx -> bytes [ 1110zzzz 10yyyyyy 10xxxxxx ]
49 | destination[0] = (byte)((codePoint + (0b1110 << 16)) >> 12);
50 | destination[1] = (byte)(((codePoint & (0x3Fu << 6)) >> 6) + 0x80u);
51 | destination[2] = (byte)((codePoint & 0x3Fu) + 0x80u);
52 | bytesWritten = 3;
53 | return true;
54 | }
55 |
56 | if(3 < (uint)destination.Length) {
57 | // Scalar 000uuuuu zzzzyyyy yyxxxxxx -> bytes [ 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ]
58 | destination[0] = (byte)((codePoint + (0b11110 << 21)) >> 18);
59 | destination[1] = (byte)(((codePoint & (0x3Fu << 12)) >> 12) + 0x80u);
60 | destination[2] = (byte)(((codePoint & (0x3Fu << 6)) >> 6) + 0x80u);
61 | destination[3] = (byte)((codePoint & 0x3Fu) + 0x80u);
62 | bytesWritten = 4;
63 | return true;
64 | }
65 | }
66 | }
67 | }
68 |
69 | // Destination buffer not large enough
70 |
71 | bytesWritten = default;
72 | return false;
73 | }
74 | #endif
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnicodeHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b360cb6179f93e04eafd9516a1728e3e
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnmanagedBuffer.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Runtime.InteropServices;
4 | using System.Runtime.CompilerServices;
5 | using System.Diagnostics;
6 |
7 | namespace U8Xml.Internal
8 | {
9 | /// Unmanaged memory buffer of type
10 | [DebuggerTypeProxy(typeof(UnmanagedBufferDebuggerTypeProxy))]
11 | [DebuggerDisplay("byte[{Length}]")]
12 | internal unsafe readonly struct UnmanagedBuffer : IDisposable
13 | {
14 | private readonly IntPtr _ptr; // byte*
15 | private readonly int _length;
16 |
17 | public bool IsEmpty => _length == 0;
18 |
19 | public int Length => _length;
20 |
21 | public IntPtr Ptr => _ptr;
22 |
23 | public UnmanagedBuffer(int length)
24 | {
25 | if(length == 0) {
26 | this = default;
27 | return;
28 | }
29 | _ptr = Marshal.AllocHGlobal(length);
30 | AllocationSafety.Add(length);
31 | _length = length;
32 | }
33 |
34 | public UnmanagedBuffer(ReadOnlySpan source)
35 | {
36 | if(source.IsEmpty) {
37 | this = default;
38 | return;
39 | }
40 | _ptr = Marshal.AllocHGlobal(source.Length);
41 | AllocationSafety.Add(source.Length);
42 | _length = source.Length;
43 | source.CopyTo(SpanHelper.CreateSpan(_ptr.ToPointer(), _length));
44 | }
45 |
46 | public void TransferMemoryOwnership(out IntPtr ptr, out int length)
47 | {
48 | ptr = _ptr;
49 | length = _length;
50 | Unsafe.AsRef(_ptr) = default;
51 | Unsafe.AsRef(_length) = 0;
52 | }
53 |
54 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
55 | public void Dispose()
56 | {
57 | Marshal.FreeHGlobal(_ptr);
58 | AllocationSafety.Remove(_length);
59 | Unsafe.AsRef(_ptr) = default;
60 | Unsafe.AsRef(_length) = 0;
61 | }
62 |
63 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 | public Span AsSpan() => SpanHelper.CreateSpan(_ptr.ToPointer(), _length);
65 |
66 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
67 | public Span AsSpan(int start) => AsSpan().Slice(start); // check boundary
68 |
69 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 | public Span AsSpan(int start, int length) => AsSpan().Slice(start, length); // check boundary
71 |
72 |
73 |
74 | private sealed class UnmanagedBufferDebuggerTypeProxy
75 | {
76 | [DebuggerBrowsable(DebuggerBrowsableState.Never)]
77 | private readonly UnmanagedBuffer _entity;
78 |
79 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
80 | public byte[] Items => _entity.AsSpan().ToArray();
81 |
82 | public UnmanagedBufferDebuggerTypeProxy(UnmanagedBuffer entity)
83 | {
84 | _entity = entity;
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnmanagedBuffer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ba1a379101847cd479ed96410c6a4d4f
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnsafeHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace U8Xml.Internal
5 | {
6 | internal static class UnsafeHelper
7 | {
8 | public static void SkipInit(out T value)
9 | {
10 | #if !NETCOREAPP3_1
11 | Unsafe.SkipInit(out value);
12 | #else
13 | value = default!;
14 | #endif
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/UnsafeHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: da75a68723d5bf149aad886b29b16516
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/XXHash32.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 |
3 | #if NETCOREAPP3_1_OR_GREATER
4 | #define FAST_SPAN
5 | #endif
6 |
7 | using System;
8 | using System.Diagnostics;
9 | using System.Runtime.CompilerServices;
10 |
11 | #if FAST_SPAN
12 | using System.Runtime.InteropServices;
13 | #endif
14 |
15 | namespace U8Xml.Internal
16 | {
17 | internal static unsafe class XXHash32
18 | {
19 | private static readonly uint _seed = (uint)DateTime.UtcNow.Ticks;
20 |
21 | private const uint Prime1 = 2654435761U;
22 | private const uint Prime2 = 2246822519U;
23 | private const uint Prime3 = 3266489917U;
24 | private const uint Prime4 = 668265263U;
25 | private const uint Prime5 = 374761393U;
26 |
27 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
28 | public static int ComputeHash(in T data) where T : unmanaged
29 | {
30 | #if FAST_SPAN
31 | var span = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref Unsafe.AsRef(in data)), sizeof(T));
32 | fixed(byte* p = span) {
33 | return ComputeHash(p, span.Length);
34 | }
35 | #else
36 | var localCopy = data;
37 | return ComputeHash((byte*)&localCopy, sizeof(T));
38 | #endif
39 | }
40 |
41 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
42 | public static int ComputeHash(byte* data, int byteLength)
43 | {
44 | Debug.Assert(byteLength >= 0);
45 |
46 | if(byteLength == 0) { return 0; }
47 | if(byteLength < 16) {
48 | var acc = _seed + Prime5 + (uint)byteLength;
49 | return (int)ComputeHashShort(data, byteLength, acc);
50 | }
51 | else {
52 | return (int)ComputeHashFull(data, byteLength);
53 | }
54 | }
55 |
56 | private static uint ComputeHashShort(byte* data, int byteLength, uint acc)
57 | {
58 | Debug.Assert(byteLength < 16 && byteLength >= 0);
59 |
60 | var laneCount = Math.DivRem(byteLength, 4, out int mod4);
61 | if(laneCount == 1) {
62 | acc = AccumRemainingLane(acc, *(uint*)data);
63 | }
64 | else if(laneCount == 2) {
65 | acc = AccumRemainingLane(acc, *(uint*)data);
66 | acc = AccumRemainingLane(acc, *(uint*)(data + 4));
67 | }
68 | else if(laneCount == 3) {
69 | acc = AccumRemainingLane(acc, *(uint*)data);
70 | acc = AccumRemainingLane(acc, *(uint*)(data + 4));
71 | acc = AccumRemainingLane(acc, *(uint*)(data + 8));
72 | }
73 |
74 | byte* bytes = data + 4 * laneCount;
75 | if(mod4 == 1) {
76 | acc = AccumByte(acc, bytes[0]);
77 | }
78 | else if(mod4 == 2) {
79 | acc = AccumByte(acc, bytes[0]);
80 | acc = AccumByte(acc, bytes[1]);
81 | }
82 | else if(mod4 == 3) {
83 | acc = AccumByte(acc, bytes[0]);
84 | acc = AccumByte(acc, bytes[1]);
85 | acc = AccumByte(acc, bytes[2]);
86 | }
87 | return MixFinal(acc);
88 | }
89 |
90 | private static uint ComputeHashFull(byte* data, int byteLength)
91 | {
92 | var blockCount = Math.DivRem(byteLength, 16, out int mod16);
93 | Initialize(out uint acc1, out uint acc2, out uint acc3, out uint acc4);
94 | for(int i = 0; i < blockCount; i++) {
95 | uint lane1 = *(uint*)(data + 16 * i);
96 | uint lane2 = *(uint*)(data + 16 * i + 4);
97 | uint lane3 = *(uint*)(data + 16 * i + 8);
98 | uint lane4 = *(uint*)(data + 16 * i + 12);
99 | acc1 = AccumBlockLane(acc1, lane1);
100 | acc2 = AccumBlockLane(acc2, lane2);
101 | acc3 = AccumBlockLane(acc3, lane3);
102 | acc4 = AccumBlockLane(acc4, lane4);
103 | }
104 | uint acc = MixState(acc1, acc2, acc3, acc4) + (uint)byteLength;
105 | return ComputeHashShort(data + byteLength - mod16, mod16, acc);
106 | }
107 |
108 |
109 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
110 | private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4)
111 | {
112 | v1 = _seed + Prime1 + Prime2;
113 | v2 = _seed + Prime2;
114 | v3 = _seed;
115 | v4 = _seed - Prime1;
116 | }
117 |
118 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
119 | private static uint AccumBlockLane(uint hash, uint lane)
120 | {
121 | return BitOperationHelper.RotateLeft(hash + lane * Prime2, 13) * Prime1;
122 | }
123 |
124 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
125 | private static uint AccumRemainingLane(uint hash, uint lane)
126 | {
127 | return BitOperationHelper.RotateLeft(hash + lane * Prime3, 17) * Prime4;
128 | }
129 |
130 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
131 | private static uint AccumByte(uint hash, byte b)
132 | {
133 | return BitOperationHelper.RotateLeft(hash + (uint)b * Prime5, 11) * Prime1;
134 | }
135 |
136 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
137 | private static uint MixState(uint v1, uint v2, uint v3, uint v4)
138 | {
139 | return BitOperationHelper.RotateLeft(v1, 1) + BitOperationHelper.RotateLeft(v2, 7) + BitOperationHelper.RotateLeft(v3, 12) + BitOperationHelper.RotateLeft(v4, 18);
140 | }
141 |
142 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
143 | private static uint MixFinal(uint hash)
144 | {
145 | hash ^= hash >> 15;
146 | hash *= Prime2;
147 | hash ^= hash >> 13;
148 | hash *= Prime3;
149 | hash ^= hash >> 16;
150 | return hash;
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/XXHash32.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2bdf07b0c0f1eb646a5b03f0453e47e9
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/XmlObjectCore.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 14fc39f22e968884fa7c28428e2432ac
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/XmlnsHelper.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Diagnostics;
4 |
5 | namespace U8Xml.Internal
6 | {
7 | internal static class XmlnsHelper
8 | {
9 | private const uint Bytes_xmln = (byte)'x' + ((byte)'m' << 8) + ((byte)'l' << 16) + ((byte)'n' << 24);
10 | private const uint Bytes_s_colon = (byte)'s' + ((byte)':' << 8);
11 |
12 | public unsafe static bool TryResolveNamespaceAlias(ReadOnlySpan nsName, XmlNode node, out RawString alias)
13 | {
14 | // xmlns:[alias]="[nsName]"
15 | // nsName -> alias
16 |
17 | var currentNode = node;
18 | while(true) {
19 | if(currentNode.HasXmlNamespaceAttr) {
20 | foreach(var attr in currentNode.Attributes) {
21 | var attrName = attr.Name;
22 | if((attrName.Length >= 5) && (*(uint*)attrName.GetPtr() == Bytes_xmln)
23 | && (attrName.At(4) == (byte)'s')) {
24 | if(attrName.Length == 5 && attr.Value == nsName) {
25 | // xmlns="[nsName]"
26 | return Validate(RawString.Empty, nsName, node, out alias);
27 | }
28 | else if(attrName.Length >= 7 && attrName[5] == (byte)':' && attr.Value == nsName) {
29 | // xmlns:[alias]="[nsName]"
30 | return Validate(attrName.Slice(6), nsName, node, out alias);
31 | }
32 | }
33 | }
34 | }
35 | if(currentNode.TryGetParent(out currentNode) == false) {
36 | alias = RawString.Empty;
37 | return false;
38 | }
39 | }
40 |
41 | static bool Validate(RawString aliasToValidate, ReadOnlySpan nsName, XmlNode targetNode, out RawString alias)
42 | {
43 | if(TryFindXmlnsRecursively(targetNode, aliasToValidate.AsSpan(), out var nsn)) {
44 | if(nsn == nsName) {
45 | alias = aliasToValidate;
46 | return true;
47 | }
48 | else {
49 | alias = RawString.Empty;
50 | return false;
51 | }
52 | }
53 | else {
54 | Debug.Fail("Why are you getting here?");
55 | alias = RawString.Empty;
56 | return false;
57 | }
58 | }
59 | }
60 |
61 | public unsafe static bool TryGetAttributeFullName(XmlAttribute attr, out RawString nsName, out RawString name)
62 | {
63 | RawString nsAlias;
64 | var attrName = attr.Name;
65 | if(attr.Node.TryGetValue(out var node) == false) {
66 | nsName = RawString.Empty;
67 | name = attr.Name;
68 | return false;
69 | }
70 | for(int i = 0; i < attrName.Length; i++) {
71 | if(attrName.At(i) == (byte)':') {
72 | nsAlias = attrName.SliceUnsafe(0, i);
73 | name = attrName.SliceUnsafe(i + 1, attrName.Length - i - 1);
74 | return TryFindXmlnsRecursively(node, nsAlias.AsSpan(), out nsName);
75 | }
76 | }
77 | name = attrName;
78 | return TryFindXmlnsRecursively(node, ReadOnlySpan.Empty, out nsName);
79 | }
80 |
81 | public unsafe static bool TryGetNodeFullName(XmlNode node, out RawString nsName, out RawString name)
82 | {
83 | RawString nsAlias;
84 | var nodeName = node.Name;
85 | for(int i = 0; i < nodeName.Length; i++) {
86 | if(nodeName.At(i) == (byte)':') {
87 | nsAlias = nodeName.SliceUnsafe(0, i);
88 | name = nodeName.SliceUnsafe(i + 1, nodeName.Length - i - 1);
89 | return TryFindXmlnsRecursively(node, nsAlias.AsSpan(), out nsName);
90 | }
91 | }
92 | name = nodeName;
93 | return TryFindXmlnsRecursively(node, ReadOnlySpan.Empty, out nsName);
94 | }
95 |
96 | private static bool TryFindXmlnsRecursively(XmlNode target, ReadOnlySpan alias, out RawString nsName)
97 | {
98 | // xmlns:[alias]="[nsName]"
99 | // alias -> nsName (recursive)
100 |
101 | var current = target;
102 |
103 | while(true) {
104 | if(TryFindXmlns(current, alias, out var nsn)) {
105 | nsName = nsn;
106 | return true;
107 | }
108 |
109 | if(current.TryGetParent(out current) == false) {
110 | nsName = RawString.Empty;
111 | return false;
112 | }
113 | }
114 | }
115 |
116 | private unsafe static bool TryFindXmlns(XmlNode target, ReadOnlySpan alias, out RawString nsName)
117 | {
118 | // xmlns:[alias]="[nsName]"
119 | // alias -> nsName (not recursive)
120 |
121 | if(alias.IsEmpty) {
122 | foreach(var attr in target.Attributes) {
123 | var attrName = attr.Name;
124 | if((attrName.Length == 5) && (*(uint*)attrName.GetPtr() == Bytes_xmln)
125 | && (attrName.At(4) == (byte)'s')) {
126 | nsName = attr.Value;
127 | return true;
128 | }
129 | }
130 | }
131 | else {
132 | foreach(var attr in target.Attributes) {
133 | var attrName = attr.Name;
134 | if((attrName.Length >= 7) && (*(uint*)attrName.GetPtr() == Bytes_xmln)
135 | && (*(ushort*)(attrName.GetPtr() + 4) == Bytes_s_colon)
136 | && attrName.Slice(6) == alias) {
137 | nsName = attr.Value;
138 | return true;
139 | }
140 | }
141 | }
142 | nsName = RawString.Empty;
143 | return false;
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Internal/XmlnsHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 409f9c954a13fe047b9f97719cc171a7
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/src/U8XmlParserUnity/Assets/Plugins/U8XmlParser/Runtime/Option.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Runtime.CompilerServices;
6 | using U8Xml.Internal;
7 |
8 | namespace U8Xml
9 | {
10 | /// A type that represents a value that may exist.
11 | /// type of the value
12 | [DebuggerDisplay("{ToString(),nq}")]
13 | public readonly struct Option : IEquatable