/// <summary> /// Get current option values. Options validity is checked here. Returns only options which were present in file or options that were passed through SetOption. /// </summary> /// <param name="structure"></param> /// <returns></returns> internal IEnumerable <OptionValue> GetOptionValues(StructureInfo structure) { if (_mode == ParsingMode.Strict) { markInternalAsUnseen(); } // crawl all sections foreach (var section in structure.Sections) { // acquire default comment if non-default one is not set (and is present in file) // also marks section as seen // in case of missing optional section, itforces its existende bool forced = checkForceSectionCommentAndSeen(section, knownSections); // Forced section, it is optional and not present if (forced) { // crawl all options foreach (var option in section.Options) { // skip optional options if (option.IsOptional) { continue; } // return non-optional option var optionValue = new OptionValue(option.Name, option.DefaultValue); checkValidity(option, optionValue); yield return(optionValue); } } // Standard appropach of data extreaction else { // crawl all options foreach (var option in section.Options) { // acquire default comment if non-default is not set (and is present in file) // also marks option as seen checkOptionCommentAndSeen(option, knownSections); // return value object value = extractValue(option, knownSections); var optionValue = new OptionValue(option.Name, value); checkValidity(option, optionValue); yield return(optionValue); } } } if (_mode == ParsingMode.Strict) { checkInternalAsSeen(); } }
/// <summary> /// Set option info and it's value. /// NOTE: Only options which are set via this call can be ADDED into output (readed options are included automatically). /// </summary> /// <param name="info">Structure describing option format</param> /// <param name="value">Structure wearing option value</param> internal void SetOption(OptionInfo info, OptionValue value) { // Check inner constraints checkValidity(info, value); // obtain qNames QualifiedSectionName qSect = value.Name.Section; QualifiedOptionName qOpt = value.Name; // Check that section exists if (!knownSections.ContainsKey(qSect)) { throw new ParserException( userMsg: "error, unknown section", developerMsg: "tried to set option in unknown section, sections needs to be retrieved from RegisterStructure() or from the actual file"); } // Ensure option exists if (!knownSections[qSect].Options.ContainsKey(qOpt)) { InnerOption newOpt = new InnerOption(qOpt, null); knownSections[qSect].Options.Add(qOpt, newOpt); newOpt.Comment = info.DefaultComment; } // along the way, check the comment checkOptionCommentAndSeen(info, knownSections); // Pass value into option InnerOption curOpt = knownSections[qSect].Options[qOpt]; IValueConverter converter; try { converter = Converters.ConfigConverters.getConverter(info); } catch (Exception ex) { throw new ParserException(userMsg: "Error when deserializing value", developerMsg: "Unsupported value tried to be deserialized", inner: ex); } if (info.IsContainer) { curOpt.strValues.Clear(); foreach (var elem in ConfigRW.ConfigCreation.StructureFactory.GetContainerElements(value.ConvertedValue)) { curOpt.strValues.Add(converter.Serialize(elem)); } } else { curOpt.strValues.Clear(); curOpt.strValues.Add(converter.Serialize(value.ConvertedValue)); } }
/// <summary> /// Checks whether given option value satisfies given option constraints /// for single element (either the only one, or one from many if it is collection) /// </summary> /// <param name="info">Structure describing option format</param> /// <param name="value">Structure wearing option value</param> /// <param name="elem">Single element to be checkd</param> private static void checkValiditySingle(OptionInfo info, OptionValue value, object elem) { if ( (info.LowerBound != null && wrongOrder(info.LowerBound, elem)) || (info.UpperBound != null && wrongOrder(elem, info.UpperBound)) ) { throw new ParserExceptionWithinConfig( userMsg: "Value out of bounds for option '{1}::{2}'", developerMsg: "Given value is out of predefined bounds for option '{1}::{2}'", section: value.Name.Section.ID, option: value.Name.ID); } }
/// <summary> /// Checks whether given option value satisfies given option constraints /// </summary> /// <param name="info">Structure describing option format</param> /// <param name="value">Structure wearing option value</param> internal void checkValidity(OptionInfo info, OptionValue value) { // Container handling if (info.IsContainer) { foreach (var elem in ConfigRW.ConfigCreation.StructureFactory.GetContainerElements(value.ConvertedValue)) { checkValiditySingle(info, value, elem); } } // Scalar handling else { checkValiditySingle(info, value, value.ConvertedValue); } }