SectionRecord
class SectionRecord
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Configuration
{
[DebuggerDisplay("SectionRecord {ConfigKey}")]
internal class SectionRecord
{
private const int FlagLocked = 1;
private const int FlagLockChildren = 2;
private const int FlagRequirePermission = 8;
private const int FlagLocationInputLockApplied = 16;
private const int FlagIndirectLocationInputLockApplied = 32;
private const int FlagChildrenLockWithoutFileInput = 64;
private const int FlagAddUpdate = 65536;
private static readonly object s_unevaluated = new object();
private SafeBitVector32 _flags;
internal string ConfigKey { get; }
internal bool Locked => _flags[1];
internal bool LockChildren => _flags[2];
internal bool LockChildrenWithoutFileInput {
get {
bool result = LockChildren;
if (HasFileInput)
result = _flags[64];
return result;
}
}
internal bool RequirePermission {
get {
return _flags[8];
}
set {
_flags[8] = value;
}
}
internal bool AddUpdate {
get {
return _flags[65536];
}
set {
_flags[65536] = value;
}
}
internal bool HasLocationInputs {
get {
if (LocationInputs != null)
return LocationInputs.Count > 0;
return false;
}
}
internal List<SectionInput> LocationInputs { get; set; }
internal SectionInput LastLocationInput {
get {
if (!HasLocationInputs)
return null;
return LocationInputs[LocationInputs.Count - 1];
}
}
internal bool HasFileInput => FileInput != null;
internal SectionInput FileInput { get; set; }
internal bool HasIndirectLocationInputs {
get {
if (IndirectLocationInputs != null)
return IndirectLocationInputs.Count > 0;
return false;
}
}
internal List<SectionInput> IndirectLocationInputs { get; set; }
internal SectionInput LastIndirectLocationInput {
get {
if (!HasIndirectLocationInputs)
return null;
return IndirectLocationInputs[IndirectLocationInputs.Count - 1];
}
}
internal bool HasInput {
get {
if (!HasLocationInputs && !HasFileInput)
return HasIndirectLocationInputs;
return true;
}
}
internal bool HasResult => Result != s_unevaluated;
internal bool HasResultRuntimeObject => ResultRuntimeObject != s_unevaluated;
internal object Result { get; set; }
internal object ResultRuntimeObject { get; set; }
internal bool HasErrors {
get {
if (HasLocationInputs) {
foreach (SectionInput locationInput in LocationInputs) {
if (locationInput.HasErrors)
return true;
}
}
if (HasIndirectLocationInputs) {
foreach (SectionInput indirectLocationInput in IndirectLocationInputs) {
if (indirectLocationInput.HasErrors)
return true;
}
}
if (HasFileInput)
return FileInput.HasErrors;
return false;
}
}
internal SectionRecord(string configKey)
{
ConfigKey = configKey;
Result = s_unevaluated;
ResultRuntimeObject = s_unevaluated;
}
internal void AddLocationInput(SectionInput sectionInput)
{
AddLocationInputImpl(sectionInput, false);
}
internal void ChangeLockSettings(OverrideMode forSelf, OverrideMode forChildren)
{
if (forSelf != 0) {
_flags[1] = (forSelf == OverrideMode.Deny);
_flags[2] = (forSelf == OverrideMode.Deny);
}
if (forChildren != 0)
_flags[2] = (forSelf == OverrideMode.Deny || forChildren == OverrideMode.Deny);
}
internal void AddFileInput(SectionInput sectionInput)
{
FileInput = sectionInput;
if (!sectionInput.HasErrors) {
OverrideModeSetting overrideModeSetting = sectionInput.SectionXmlInfo.OverrideModeSetting;
if (overrideModeSetting.OverrideMode != 0) {
_flags[64] = LockChildren;
overrideModeSetting = sectionInput.SectionXmlInfo.OverrideModeSetting;
ChangeLockSettings(OverrideMode.Inherit, overrideModeSetting.OverrideMode);
}
}
}
internal void RemoveFileInput()
{
if (FileInput != null) {
FileInput = null;
_flags[2] = Locked;
}
}
internal void AddIndirectLocationInput(SectionInput sectionInput)
{
AddLocationInputImpl(sectionInput, true);
}
private void AddLocationInputImpl(SectionInput sectionInput, bool isIndirectLocation)
{
List<SectionInput> list = isIndirectLocation ? IndirectLocationInputs : LocationInputs;
int bit = isIndirectLocation ? 32 : 16;
if (list == null) {
list = new List<SectionInput>(1);
if (isIndirectLocation)
IndirectLocationInputs = list;
else
LocationInputs = list;
}
list.Insert(0, sectionInput);
if (!sectionInput.HasErrors && !_flags[bit]) {
OverrideMode overrideMode = sectionInput.SectionXmlInfo.OverrideModeSetting.OverrideMode;
if (overrideMode != 0) {
ChangeLockSettings(overrideMode, overrideMode);
_flags[bit] = true;
}
}
}
internal void ClearRawXml()
{
if (HasLocationInputs) {
foreach (SectionInput locationInput in LocationInputs) {
locationInput.SectionXmlInfo.RawXml = null;
}
}
if (HasIndirectLocationInputs) {
foreach (SectionInput indirectLocationInput in IndirectLocationInputs) {
indirectLocationInput.SectionXmlInfo.RawXml = null;
}
}
if (HasFileInput)
FileInput.SectionXmlInfo.RawXml = null;
}
internal void ClearResult()
{
FileInput?.ClearResult();
if (LocationInputs != null) {
foreach (SectionInput locationInput in LocationInputs) {
locationInput.ClearResult();
}
}
Result = s_unevaluated;
ResultRuntimeObject = s_unevaluated;
}
private List<ConfigurationException> GetAllErrors()
{
List<ConfigurationException> errors = null;
if (HasLocationInputs) {
foreach (SectionInput locationInput in LocationInputs) {
ErrorsHelper.AddErrors(ref errors, locationInput.Errors);
}
}
if (HasIndirectLocationInputs) {
foreach (SectionInput indirectLocationInput in IndirectLocationInputs) {
ErrorsHelper.AddErrors(ref errors, indirectLocationInput.Errors);
}
}
if (HasFileInput)
ErrorsHelper.AddErrors(ref errors, FileInput.Errors);
return errors;
}
internal void ThrowOnErrors()
{
if (HasErrors)
throw new ConfigurationErrorsException(GetAllErrors());
}
}
}