/
XmlBinaryReaderSession.cs
126 lines (110 loc) · 3.96 KB
/
XmlBinaryReaderSession.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using StringHandle = System.Int64;
using System.Xml;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
namespace System.Xml
{
public class XmlBinaryReaderSession : IXmlDictionary
{
private const int MaxArrayEntries = 2048;
private XmlDictionaryString[]? _strings;
private Dictionary<int, XmlDictionaryString>? _stringDict;
public XmlBinaryReaderSession()
{
}
public XmlDictionaryString Add(int id, string value)
{
if (id < 0)
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(id), SR.XmlInvalidID));
ArgumentNullException.ThrowIfNull(value);
XmlDictionaryString? xmlString;
if (TryLookup(id, out _))
throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.XmlIDDefined));
xmlString = new XmlDictionaryString(this, value, id);
if (id >= MaxArrayEntries)
{
_stringDict ??= new Dictionary<int, XmlDictionaryString>();
_stringDict.Add(id, xmlString);
}
else
{
if (_strings == null)
{
_strings = new XmlDictionaryString[Math.Max(id + 1, 16)];
}
else if (id >= _strings.Length)
{
XmlDictionaryString[] newStrings = new XmlDictionaryString[Math.Min(Math.Max(id + 1, _strings.Length * 2), MaxArrayEntries)];
Array.Copy(_strings, newStrings, _strings.Length);
_strings = newStrings;
}
_strings[id] = xmlString;
}
return xmlString;
}
public bool TryLookup(int key, [NotNullWhen(true)] out XmlDictionaryString? result)
{
if (_strings != null && key >= 0 && key < _strings.Length)
{
result = _strings[key];
return result != null;
}
else if (key >= MaxArrayEntries)
{
if (_stringDict != null)
return _stringDict.TryGetValue(key, out result);
}
result = null;
return false;
}
public bool TryLookup(string value, [NotNullWhen(true)] out XmlDictionaryString? result)
{
ArgumentNullException.ThrowIfNull(value);
if (_strings != null)
{
for (int i = 0; i < _strings.Length; i++)
{
XmlDictionaryString s = _strings[i];
if (s != null && s.Value == value)
{
result = s;
return true;
}
}
}
if (_stringDict != null)
{
foreach (XmlDictionaryString s in _stringDict.Values)
{
if (s.Value == value)
{
result = s;
return true;
}
}
}
result = null;
return false;
}
public bool TryLookup(XmlDictionaryString value, [NotNullWhen(true)] out XmlDictionaryString? result)
{
ArgumentNullException.ThrowIfNull(value);
if (value.Dictionary != this)
{
result = null;
return false;
}
result = value;
return true;
}
public void Clear()
{
if (_strings != null)
Array.Clear(_strings);
_stringDict?.Clear();
}
}
}