| File: System\Configuration\UpdateConfigHost.cs | Web Access |
| Project: src\runtime\src\libraries\System.Configuration.ConfigurationManager\src\System.Configuration.ConfigurationManager.csproj (System.Configuration.ConfigurationManager) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Specialized; using System.Configuration.Internal; using System.Diagnostics; using System.IO; namespace System.Configuration { // Configuration host that intercepts calls to filename functions // to support SaveAs to an alternate file stream. internal sealed class UpdateConfigHost : DelegatingConfigHost { private HybridDictionary _streams; // oldStreamname -> StreamUpdate internal UpdateConfigHost(IInternalConfigHost host) { // Delegate to the host provided. Host = host; } // Add a stream to the list of streams to intercept. // // Parameters: // alwaysIntercept - If true, then don't check whether the old stream and the new stream are the same. // SaveAs() will set this to true if oldStreamname is actually referring to a stream // on a remote machine. internal void AddStreamname(string oldStreamname, string newStreamname, bool alwaysIntercept) { // After reviewing all the code paths, oldStreamname shouldn't be Null or Empty. // It actually doesn't make much sense if we're asked to intercept an null or empty stream. Debug.Assert(!string.IsNullOrEmpty(oldStreamname)); if (string.IsNullOrEmpty(oldStreamname)) return; if (!alwaysIntercept && StringUtil.EqualsIgnoreCase(oldStreamname, newStreamname)) return; _streams ??= new HybridDictionary(true); _streams[oldStreamname] = new StreamUpdate(newStreamname); } // Get the new stream name for a stream if a new name exists, otherwise // return the original stream name. internal string GetNewStreamname(string oldStreamname) { StreamUpdate streamUpdate = GetStreamUpdate(oldStreamname, false); return streamUpdate != null ? streamUpdate.NewStreamname : oldStreamname; } // Get the StreamUpdate for a stream. // If alwaysIntercept is true, then the StreamUpdate is // always returned if it exists. // If alwaysIntercept is false, then only return the StreamUpdate // if the new stream has been successfully written to. private StreamUpdate GetStreamUpdate(string oldStreamname, bool alwaysIntercept) { if (_streams == null) return null; StreamUpdate streamUpdate = (StreamUpdate)_streams[oldStreamname]; if ((streamUpdate != null) && !alwaysIntercept && !streamUpdate.WriteCompleted) streamUpdate = null; return streamUpdate; } public override object GetStreamVersion(string streamName) { StreamUpdate streamUpdate = GetStreamUpdate(streamName, false); return streamUpdate != null ? InternalConfigHost.StaticGetStreamVersion(streamUpdate.NewStreamname) : Host.GetStreamVersion(streamName); } public override Stream OpenStreamForRead(string streamName) { StreamUpdate streamUpdate = GetStreamUpdate(streamName, false); return streamUpdate != null ? InternalConfigHost.StaticOpenStreamForRead(streamUpdate.NewStreamname) : Host.OpenStreamForRead(streamName); } public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) { // Always attempt to write to the new stream name if it exists. StreamUpdate streamUpdate = GetStreamUpdate(streamName, true); if (streamUpdate != null) { return InternalConfigHost.StaticOpenStreamForWrite( streamUpdate.NewStreamname, templateStreamName, ref writeContext); } return Host.OpenStreamForWrite(streamName, templateStreamName, ref writeContext); } public override void WriteCompleted(string streamName, bool success, object writeContext) { StreamUpdate streamUpdate = GetStreamUpdate(streamName, true); if (streamUpdate != null) { InternalConfigHost.StaticWriteCompleted(streamUpdate.NewStreamname, success, writeContext); // Mark the write as having successfully completed, so that subsequent calls // to Read() will use the new stream name. if (success) streamUpdate.WriteCompleted = true; } else { Host.WriteCompleted(streamName, success, writeContext); } } public override bool IsConfigRecordRequired(string configPath) { return true; } public override void DeleteStream(string streamName) { StreamUpdate streamUpdate = GetStreamUpdate(streamName, false); if (streamUpdate != null) InternalConfigHost.StaticDeleteStream(streamUpdate.NewStreamname); else Host.DeleteStream(streamName); } public override bool IsFile(string streamName) { StreamUpdate streamUpdate = GetStreamUpdate(streamName, false); return streamUpdate != null ? InternalConfigHost.StaticIsFile(streamUpdate.NewStreamname) : Host.IsFile(streamName); } } }