private void SaveConfigSource(DefinitionUpdate update) {
string configSourceStreamName;
if (update.SectionRecord.HasResult) {
ConfigurationSection configSection = (ConfigurationSection) update.SectionRecord.Result;
configSourceStreamName = configSection.SectionInformation.ConfigSourceStreamName;
}
else {
Debug.Assert(update.SectionRecord.HasFileInput, "update.SectionRecord.HasFileInput");
SectionInput fileInput = update.SectionRecord.FileInput;
configSourceStreamName = fileInput.SectionXmlInfo.ConfigSourceStreamName;
}
// Copy the input stream before opening the output stream.
byte[] readBuffer = null;
using (Stream streamRead = Host.OpenStreamForRead(configSourceStreamName)) {
if (streamRead != null) {
readBuffer = new byte[streamRead.Length];
int count = streamRead.Read(readBuffer, 0, (int) streamRead.Length);
if (count != streamRead.Length) {
throw new ConfigurationErrorsException();
}
}
}
// Write the changes to the output stream.
bool hasFile = (readBuffer != null);
object writeContext = null;
bool streamOpened = false;
try {
try {
string templateStreamName;
if (Host.IsRemote) {
// templateStreamName is used by OpenStreamForWrite for copying file attributes during saving.
// (for details, see WriteFileContext.Complete.)
//
// If we're using a remote host, then ConfigStreamInfo.StreamName is actually pointing to a
// full filepath on a remote machine. In this case, it's impossible to copy the attributes
// over, and thus we won't do it.
templateStreamName = null;
}
else {
templateStreamName = ConfigStreamInfo.StreamName;
}
using (Stream streamWrite = Host.OpenStreamForWrite(configSourceStreamName, templateStreamName, ref writeContext)) {
streamOpened = true;
if (update.UpdatedXml == null) {
Debug.Assert(hasFile, "hasFile");
if (hasFile) {
streamWrite.Write(readBuffer, 0, readBuffer.Length);
}
}
else {
using (StreamWriter streamWriter = new StreamWriter(streamWrite)) {
XmlUtilWriter utilWriter = new XmlUtilWriter(streamWriter, true);
if (hasFile) {
CopyConfigSource(utilWriter, update.UpdatedXml, configSourceStreamName, readBuffer);
}
else {
CreateNewConfigSource(utilWriter, update.UpdatedXml, DEFAULT_INDENT);
}
}
}
}
}
catch {
if (streamOpened) {
Host.WriteCompleted(configSourceStreamName, false, writeContext);
}
throw;
}
}
//
// Guarantee that exceptions contain at least the name of the stream by wrapping them
// in a ConfigurationException.
//
catch (Exception e) {
throw ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, configSourceStreamName, 0);
}
catch {
throw ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, configSourceStreamName, 0);
}
Host.WriteCompleted(configSourceStreamName, true, writeContext);
}