|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/*++
Module Name:
Abstract:
This file contains the definition and implementation
for PartEditor and XmlPartEditor classes. These classes
are used as wrappers around the Metro package API part
classes.
--*/
using System.IO;
using System.IO.Packaging;
using System.Xml;
namespace System.Windows.Xps.Packaging
{
/// <summary>
/// Provides access to the stream of a Metro part
/// </summary>
internal class PartEditor : IDisposable
{
#region Constructors
/// <summary>
/// Attach an editor to a part
/// </summary>
/// <param name="metroPart"></param>
internal
PartEditor(
PackagePart metroPart
)
{
ArgumentNullException.ThrowIfNull(metroPart);
_metroPart = metroPart;
}
#endregion Constructors
#region Protected properties
protected PackagePart MetroPart
{
get
{
return _metroPart;
}
}
#endregion Protected properties
#region Internal properties
/// <summary>
/// Return a data stream for the part
/// </summary>
/// <value></value>
internal Stream DataStream
{
get
{
if (null == _partDataStream)
{
if (_metroPart.Package.FileOpenAccess == FileAccess.Write)
{
_partDataStream = _metroPart.GetStream(FileMode.Create);
}
else
{
_partDataStream = _metroPart.GetStream(FileMode.OpenOrCreate);
}
}
return _partDataStream;
}
}
#endregion Internal properties
#region Internal methods
/// <summary>
/// Close the part data stream
/// </summary>
internal
virtual
void
Close(
)
{
if (null != _partDataStream)
{
if (_partDataStream.CanWrite)
{
_partDataStream.Close();
}
GC.SuppressFinalize(this);
_partDataStream = null;
}
}
/// <summary>
/// Forcibly flush the part data stream
/// </summary>
internal
virtual
void
Flush(
)
{
if (null != _partDataStream)
{
_partDataStream.Flush();
}
}
#endregion Internal methods
#region Private data
private PackagePart _metroPart;
private Stream _partDataStream;
#endregion Private data
#region IDisposable implementation
void
IDisposable.Dispose(
)
{
Close();
}
#endregion IDisposable implementation
}
/// <summary>
/// Part editor with XML content
/// </summary>
internal class XmlPartEditor : PartEditor
{
#region Constructors
/// <summary>
/// Attach an editor to an existing part
/// </summary>
/// <param name="metroPart"></param>
internal
XmlPartEditor(
PackagePart metroPart
)
: base(metroPart)
{
_doesWriteStartEndTags = true;
_isStartElementWritten = false;
}
#endregion Constructors
#region Internal properties
internal bool DoesWriteStartEndTags
{
get
{
return _doesWriteStartEndTags;
}
set
{
_doesWriteStartEndTags = value;
}
}
internal bool IsStartElementWritten
{
get
{
return _isStartElementWritten;
}
}
internal XmlTextWriter XmlWriter
{
get
{
if (null == _xmlWriter)
{
OpenDocumentForWrite();
}
return _xmlWriter;
}
}
internal XmlTextReader XmlReader
{
get
{
if (null == _xmlReader)
{
OpenDocumentForRead();
}
return _xmlReader;
}
}
#endregion Internal properties
#region Internal methods
/// <summary>
/// Setup for writing
/// </summary>
internal
void
OpenDocumentForRead(
)
{
if (_xmlReader != null)
{
throw new XpsPackagingException(SR.ReachPackaging_OpenDocOrElementAlreadyCalled);
}
Stream stream = MetroPart.GetStream(FileMode.Open);
_xmlReader = new XmlTextReader(stream);
}
/// <summary>
/// Setup for writing
/// </summary>
internal
void
OpenDocumentForWrite(
)
{
if (_xmlWriter != null)
{
throw new XpsPackagingException(SR.ReachPackaging_OpenDocOrElementAlreadyCalled);
}
Stream stream = MetroPart.GetStream(FileMode.Create);
_xmlWriter = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
}
internal
void
PrepareXmlWriter(
string startTag,
string namespaceUri
)
{
if (null == _xmlWriter)
{
//
// Stream not open yet, create it and write open tag
//
OpenDocumentForWrite();
if (_doesWriteStartEndTags)
{
_xmlWriter.WriteStartDocument();
}
_xmlWriter.WriteStartElement(startTag, namespaceUri);
_isStartElementWritten = true;
}
}
/// <summary>
/// Flush any XML written so far for sequence (does not end Sequence tag)
/// </summary>
internal
override
void
Flush(
)
{
if (null != _xmlWriter)
{
_xmlWriter.Flush();
}
}
/// <summary>
/// Close XML written for sequence (adds end Sequence tag)
/// </summary>
internal
override
void
Close(
)
{
if (null != _xmlWriter)
{
_xmlWriter.Close();
_xmlWriter = null;
}
if (null != _xmlReader)
{
_xmlReader.Close();
_xmlReader = null;
}
base.Close();
}
#endregion Internal methods
#region Private data
private bool _doesWriteStartEndTags;
private XmlTextWriter _xmlWriter;
private XmlTextReader _xmlReader;
private bool _isStartElementWritten;
#endregion Private data
}
}
|