Skip to content

Commit 873869e

Browse files
committed
create helper methods and make OpenXmlPartReader a partial class
1 parent 97592df commit 873869e

File tree

6 files changed

+154
-133
lines changed

6 files changed

+154
-133
lines changed

src/DocumentFormat.OpenXml.Framework/OpenXmlPartReader.cs

Lines changed: 16 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@
1010
using System.Diagnostics;
1111
using System.IO;
1212
using System.Linq;
13-
#if TASKS_SUPPORTED
14-
using System.Threading.Tasks;
15-
#endif
1613
using System.Xml;
1714

1815
namespace DocumentFormat.OpenXml
1916
{
2017
/// <summary>
2118
/// Represents the Open XML part reader class.
2219
/// </summary>
23-
public class OpenXmlPartReader : OpenXmlReader
20+
public partial class OpenXmlPartReader : OpenXmlReader
2421
{
2522
private readonly IRootElementFeature _rootElements;
2623
private readonly IOpenXmlNamespaceResolver _resolver;
@@ -397,123 +394,6 @@ public override void Skip()
397394
/// <inheritdoc/>
398395
public override IXmlLineInfo GetLineInfo() => XmlLineInfo.Get(_xmlReader);
399396

400-
#region Async methods
401-
#if TASKS_SUPPORTED
402-
public override Task<bool> ReadAsync()
403-
{
404-
return _xmlReader.ReadAsync();
405-
}
406-
407-
public override Task<string> GetValueAsync()
408-
{
409-
ThrowIfObjectDisposed();
410-
411-
return _xmlReader.GetValueAsync();
412-
}
413-
414-
public async override Task<bool> ReadFirstChildAsync()
415-
{
416-
ThrowIfObjectDisposed();
417-
418-
bool result = await MoveToFirstChildAsync().ConfigureAwait(true);
419-
420-
if (result && !ReadMiscNodes)
421-
{
422-
// skip miscellaneous node
423-
while (result && IsMiscNode)
424-
{
425-
result = MoveToNextSibling();
426-
}
427-
}
428-
429-
return result;
430-
}
431-
432-
private async Task<bool> MoveToFirstChildAsync()
433-
{
434-
switch (_elementState)
435-
{
436-
case ElementState.EOF:
437-
return false;
438-
439-
case ElementState.Start:
440-
if (!(await _xmlReader.ReadAsync().ConfigureAwait(true)))
441-
{
442-
// should can read.
443-
Debug.Assert(false);
444-
return false;
445-
}
446-
447-
GetElementInformation();
448-
if (_elementState == ElementState.End)
449-
{
450-
return false;
451-
}
452-
453-
return true;
454-
455-
case ElementState.LeafStart:
456-
_elementState = ElementState.LeafEnd;
457-
return false;
458-
459-
case ElementState.End:
460-
case ElementState.LeafEnd:
461-
case ElementState.LoadEnd:
462-
case ElementState.MiscNode:
463-
return false;
464-
465-
case ElementState.Null:
466-
ThrowIfNull();
467-
break;
468-
469-
default:
470-
break;
471-
}
472-
473-
return false;
474-
}
475-
476-
private async Task InnerSkipAsync()
477-
{
478-
switch (_elementState)
479-
{
480-
case ElementState.Null:
481-
ThrowIfNull();
482-
break;
483-
484-
case ElementState.EOF:
485-
return;
486-
487-
case ElementState.Start:
488-
case ElementState.End:
489-
case ElementState.MiscNode:
490-
_xmlReader.Skip();
491-
_elementStack.Pop();
492-
GetElementInformation();
493-
return;
494-
495-
case ElementState.LeafStart:
496-
// no move, just process cursor
497-
_elementStack.Pop();
498-
GetElementInformation();
499-
return;
500-
501-
case ElementState.LeafEnd:
502-
case ElementState.LoadEnd:
503-
// cursor is leaf element, pop stack, no move
504-
_elementStack.Pop();
505-
GetElementInformation();
506-
return;
507-
508-
default:
509-
break;
510-
}
511-
512-
return;
513-
}
514-
#endif
515-
#endregion
516-
517397
#region private methods
518398

519399
/// <summary>
@@ -522,11 +402,18 @@ private async Task InnerSkipAsync()
522402
/// <returns>true if the next element was read successfully; false if there are no more elements to read. </returns>
523403
private bool MoveToNextElement()
524404
{
525-
switch (_elementState)
405+
if (_elementState == ElementState.Null)
526406
{
527-
case ElementState.Null:
528-
return ReadRoot();
407+
return ReadRoot();
408+
}
529409

410+
return MoveToNextElementHelper();
411+
}
412+
413+
private bool MoveToNextElementHelper()
414+
{
415+
switch (_elementState)
416+
{
530417
case ElementState.EOF:
531418
return false;
532419

@@ -850,6 +737,11 @@ private bool ReadRoot()
850737
_xmlReader.Skip();
851738
}
852739

740+
return ReadRootHelper();
741+
}
742+
743+
private bool ReadRootHelper()
744+
{
853745
if (_xmlReader.EOF || !_xmlReader.IsStartElement())
854746
{
855747
throw new InvalidDataException(ExceptionMessages.PartIsEmpty);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
7+
using System.IO;
8+
using System.Text;
9+
#if TASKS_SUPPORTED
10+
using System.Threading.Tasks;
11+
#endif
12+
using System.Xml;
13+
14+
namespace DocumentFormat.OpenXml;
15+
16+
/// <summary>
17+
/// Represents the Open XML part reader class.
18+
/// </summary>
19+
public partial class OpenXmlPartReader : OpenXmlReader
20+
{
21+
/// <summary>
22+
/// Gets the type of the current node in the XML document being read.
23+
/// </summary>
24+
/// <remarks>
25+
/// The <see cref="XmlNodeType"/> indicates the type of the current node, such as
26+
/// <c>Element</c>, <c>Attribute</c>, <c>Text</c>, <c>CDATA</c>, <c>Comment</c>, or others.
27+
/// This property provides information about the structure of the XML document
28+
/// and is useful for determining how to process the current node.
29+
/// </remarks>
30+
public override XmlNodeType NodeType
31+
{
32+
get
33+
{
34+
return _xmlReader.NodeType;
35+
}
36+
}
37+
38+
#if TASKS_SUPPORTED
39+
/// <summary>
40+
/// Asynchronously reads the next element in the Open XML document.
41+
/// </summary>
42+
/// <returns>
43+
/// A task that represents the asynchronous read operation. The task result is <c>true</c> if the next element
44+
/// was read successfully; <c>false</c> if there are no more elements to read.
45+
/// </returns>
46+
public async override Task<bool> ReadAsync()
47+
{
48+
ThrowIfObjectDisposed();
49+
50+
bool result = await MoveToNextElementAsync().ConfigureAwait(false);
51+
52+
if (result && !ReadMiscNodes)
53+
{
54+
// skip miscellaneous node
55+
while (result && IsMiscNode)
56+
{
57+
result = await MoveToNextElementAsync().ConfigureAwait(false);
58+
}
59+
}
60+
61+
return result;
62+
}
63+
64+
public async override Task<bool> ReadFirstChildAsync()
65+
{
66+
//ThrowIfObjectDisposed();
67+
68+
//bool result = await MoveToFirstChildAsync().ConfigureAwait(true);
69+
70+
//if (result && !ReadMiscNodes)
71+
//{
72+
// // skip miscellaneous node
73+
// while (result && IsMiscNode)
74+
// {
75+
// result = MoveToNextSibling();
76+
// }
77+
//}
78+
79+
//return result;
80+
return true;
81+
}
82+
83+
private async Task<bool> MoveToNextElementAsync()
84+
{
85+
if (_elementState == ElementState.Null)
86+
{
87+
return await ReadRootAsync().ConfigureAwait(false);
88+
}
89+
90+
return MoveToNextElementHelper();
91+
}
92+
93+
private async Task<bool> ReadRootAsync()
94+
{
95+
Debug.Assert(_elementState == ElementState.Null);
96+
Debug.Assert(_elementStack.Count == 0);
97+
98+
// TODO: should we take care of entity? <!DOCTYPE page [ <!ENTITY company "Microsoft"> ]>
99+
// TODO: is it OK that we skip all prologue ( DOCTYPE, Comment, PT ) ?
100+
await _xmlReader.MoveToContentAsync().ConfigureAwait(false);
101+
102+
while (!_xmlReader.EOF && _xmlReader.NodeType != XmlNodeType.Element)
103+
{
104+
await _xmlReader.SkipAsync().ConfigureAwait(false);
105+
}
106+
107+
return ReadRootHelper();
108+
}
109+
#endif
110+
}

src/DocumentFormat.OpenXml.Framework/OpenXmlReader.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,17 @@ public virtual bool HasAttributes
186186
/// </summary>
187187
public abstract string Prefix { get; }
188188

189+
/// <summary>
190+
/// Gets the type of the current node in the XML document being read.
191+
/// </summary>
192+
/// <remarks>
193+
/// The <see cref="XmlNodeType"/> indicates the type of the current node, such as
194+
/// <c>Element</c>, <c>Attribute</c>, <c>Text</c>, <c>CDATA</c>, <c>Comment</c>, or others.
195+
/// This property provides information about the structure of the XML document
196+
/// and is useful for determining how to process the current node.
197+
/// </remarks>
198+
public virtual XmlNodeType NodeType { get; }
199+
189200
/// <summary>
190201
/// Gets an instance of <see cref="IXmlLineInfo"/> if available for the current reader.
191202
/// </summary>
@@ -250,18 +261,23 @@ public virtual bool HasAttributes
250261
/// </returns>
251262
/// <remarks>
252263
/// This method is only available when the build target supports asynchronous SAX XML processing.
253-
/// It allows non-blocking operations for reading large Open XML documents.
254264
/// </remarks>
255265
public virtual Task<bool> ReadAsync()
256266
{
257267
return Task.FromResult(Read());
258268
}
259269

260-
public virtual Task<string> GetValueAsync()
261-
{
262-
return Task.FromResult(GetText());
263-
}
264-
270+
/// <summary>
271+
/// Asynchronously moves the reader to the first child element of the current node.
272+
/// </summary>
273+
/// <returns>
274+
/// A task that represents the asynchronous operation. The task result is <c>true</c> if the first child element
275+
/// was read successfully; <c>false</c> if there are no child elements to read.
276+
/// </returns>
277+
/// <remarks>
278+
/// This method can only be called when the reader is positioned on an element start. If no child elements exist,
279+
/// the reader will move to the end tag of the current element.
280+
/// </remarks>
265281
public virtual Task<bool> ReadFirstChildAsync()
266282
{
267283
return Task.FromResult(ReadFirstChild());

src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,3 +1009,6 @@ DocumentFormat.OpenXml.OpenXmlPartWriterSettings.Encoding.set -> void
10091009
DocumentFormat.OpenXml.OpenXmlPartWriterSettings.OpenXmlPartWriterSettings() -> void
10101010
DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(DocumentFormat.OpenXml.Packaging.OpenXmlPart! openXmlPart, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void
10111011
DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(System.IO.Stream! partStream, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void
1012+
DocumentFormat.OpenXml.OpenXmlPartReader.NodeType.get -> System.Xml.XmlNodeType
1013+
virtual DocumentFormat.OpenXml.OpenXmlReader.NodeType.get -> System.Xml.XmlNodeType
1014+
override DocumentFormat.OpenXml.OpenXmlPartReader.NodeType.get -> System.Xml.XmlNodeType
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#nullable enable
22
DocumentFormat.OpenXml.OpenXmlPartReaderOptions.Async.get -> bool
33
DocumentFormat.OpenXml.OpenXmlPartReaderOptions.Async.set -> void
4-
override DocumentFormat.OpenXml.OpenXmlPartReader.GetValueAsync() -> System.Threading.Tasks.Task<string!>!
54
override DocumentFormat.OpenXml.OpenXmlPartReader.ReadAsync() -> System.Threading.Tasks.Task<bool>!
6-
virtual DocumentFormat.OpenXml.OpenXmlReader.GetValueAsync() -> System.Threading.Tasks.Task<string!>!
75
virtual DocumentFormat.OpenXml.OpenXmlReader.ReadAsync() -> System.Threading.Tasks.Task<bool>!
86
virtual DocumentFormat.OpenXml.OpenXmlReader.ReadFirstChildAsync() -> System.Threading.Tasks.Task<bool>!

src/DocumentFormat.OpenXml.Framework/XmlConvertingReader.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ protected override void Dispose(bool disposing)
5959
#if TASKS_SUPPORTED
6060
public override Task<bool> ReadAsync() => BaseReader.ReadAsync();
6161

62-
public override Task<string> GetValueAsync() => BaseReader.GetValueAsync();
62+
public override Task SkipAsync() => BaseReader.SkipAsync();
63+
64+
public override Task<XmlNodeType> MoveToContentAsync() => BaseReader.MoveToContentAsync();
6365
#endif
6466

6567
/// <inheritdoc/>

0 commit comments

Comments
 (0)