private IConfigurationItem DeserializeItem(DelimiterSeparatedValues.DsvRow row) { if (row == null) { throw new ArgumentNullException(nameof(row)); } if (row.ItemArray.Length != 4) { throw new ArgumentNullException(nameof(row), $"Parameter {nameof(row)} is invalid."); } var groupName = row.ItemArray[0].ToString(); var itemName = row.ItemArray[1].ToString(); var valueTypeName = row.ItemArray[2].ToString(); var content = row.ItemArray[3].ToString(); // check for special case: empty group if (!(string.IsNullOrWhiteSpace(groupName)) && (string.IsNullOrWhiteSpace(itemName)) && (string.IsNullOrWhiteSpace(valueTypeName)) && (string.IsNullOrWhiteSpace(content))) { return(null); } else if (string.IsNullOrWhiteSpace(valueTypeName)) { // **** AUTO-DETECT return(ConfigurationShared.CreateConfigurationItem(itemName, content)); } else { // **** TYPE PROVIDED return(ConfigurationShared.CreateConfigurationItem(itemName, valueTypeName, content, _Compressor)); } }
private void RecursiveSerializeGroup(IConfigurationGroup rootGroup, XmlWriter xw) { xw.WriteStartElement(_XmlElementGroupName_); xw.WriteAttributeString(_XmlElementGroupKeyName_, rootGroup.Key); if (rootGroup.Items.Count > 0) { xw.WriteStartElement(_XmlElementGroupItemsName_); foreach (var item in rootGroup.Items) { xw.WriteStartElement(_XmlElementItemName_); xw.WriteAttributeString(_XmlElementItemKeyName_, item.Key); xw.WriteAttributeString(_XmlElementItemTypeName_, ConfigurationShared.ConvertItemTypeToString(item)); xw.WriteString(ConfigurationShared.ConvertItemObjectToString(item, _Compressor)); xw.WriteEndElement(); } xw.WriteEndElement(); } if (rootGroup.Count > 0) { xw.WriteStartElement(_XmlElementGroupsName_); foreach (var subGroup in rootGroup) { RecursiveSerializeGroup(subGroup, xw); } xw.WriteEndElement(); } xw.WriteEndElement(); }
private IConfigurationItem ProcessItemSegment(XmlReader xr) { var key = xr.GetAttribute(_XmlElementItemKeyName_); var valueTypeName = xr.GetAttribute(_XmlElementItemTypeName_); var content = xr.ReadElementContentAsString(); if (string.IsNullOrWhiteSpace(valueTypeName)) { // **** AUTO-DETECT return(ConfigurationShared.CreateConfigurationItem(key, content)); } // **** TYPE PROVIDED return(ConfigurationShared.CreateConfigurationItem(key, valueTypeName, content, _Compressor)); }
// -------- private void ProcessGroup(XmlReader xr, IConfigurationGroup rootGroup, IConfigurationGroup currentGroup) { while (xr.Read()) { if (xr.IsStartElement(_XmlElementGroupItemsName_)) { while (xr.Read()) { if (xr.IsStartElement(_XmlElementItemName_)) { currentGroup.Items.Add(ProcessItemSegment(xr)); } else { break; } } } else if (xr.IsStartElement(_XmlElementGroupsName_)) { while (xr.Read()) { if (xr.IsStartElement(_XmlElementGroupName_)) { var key = xr.GetAttribute(_XmlElementGroupKeyName_); if (xr.IsEmptyElement) { currentGroup.Add(key); } else { ProcessGroup(xr, rootGroup, ConfigurationShared.FindGroup(currentGroup, key, _XmlElementGroupKeyNameSeparator_)); } } else { break; } } } else { break; } } }
private void InternalSerializeGroup(string parentGroupAddress, IConfigurationGroup group, DelimiterSeparatedValues.DsvTable table) { // get local Group Address var groupAddress = group.Key; if (!string.IsNullOrWhiteSpace(parentGroupAddress)) { groupAddress = parentGroupAddress + _CsvGroupNameSeparator_ + group.Key; } // process items if (group.Items.Count > 0) { // serialize items foreach (var item in group.Items) { var row = table.NewRow(groupAddress, item.Key, ConfigurationShared.ConvertItemTypeToString(item), ConfigurationShared.ConvertItemObjectToString(item, _Compressor)); table.Rows.Add(row); } } else { var row = table.NewRow(groupAddress); if (row != null) { if (!string.IsNullOrWhiteSpace((string)row[0])) { table.Rows.Add(row); } else if ((!string.IsNullOrWhiteSpace((string)row[1])) && (!string.IsNullOrWhiteSpace((string)row[2])) && (!string.IsNullOrWhiteSpace((string)row[3]))) { table.Rows.Add(row); } } } // process groups if (group.Count > 0) { foreach (var subGroup in group) { InternalSerializeGroup(groupAddress, subGroup, table); } } }
private StringBuilder InternalSerializeItem(IConfigurationItem item, bool includeTypeInformation) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (includeTypeInformation) { // full format var typeStr = ConfigurationShared.ConvertItemTypeToString(item); if (typeStr.Contains(_IniElementSeparator_)) { typeStr = "\"" + typeStr + "\""; } return(new StringBuilder($"{item.Key}{_IniElementSeparator_}{typeStr}{_IniElementSeparator_}{ConfigurationShared.ConvertItemObjectToString(item, _Compressor)}")); } else { // classic style return(new StringBuilder($"{item.Key}{_IniElementSeparator_}{ConfigurationShared.ConvertItemObjectToString(item, _Compressor)}")); } }
/// <summary> /// Converts the specified <paramref name="source"/>, a <see cref="StringBuilder"/> type, to an <see cref="IConfigurationGroup"/>. /// </summary> /// <param name="source">The object, a <see cref="StringBuilder"/> type, to convert into an <see cref="IConfigurationGroup"/>.</param> /// <returns>The object converted into an <see cref="IConfigurationGroup"/>.</returns> public IConfigurationGroup Deserialize(StringBuilder source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (source.Length == 0) { throw new ArgumentNullException(nameof(source), $"Parameter {nameof(source)} cannot be an empty string."); } IConfigurationGroup workGroup = new ConfigurationGroup(""); var table = new DelimiterSeparatedValues.DsvTable(_Settings); table.ReadString(source.ToString()); foreach (var row in table.Rows) { var groupName = row[0].ToString(); if (string.IsNullOrWhiteSpace(groupName)) { workGroup.Items.Add(DeserializeItem(row)); } else { var group = ConfigurationShared.FindGroup(workGroup, groupName, _CsvGroupNameSeparator_); var item = DeserializeItem(row); if (item != null) { group.Items.Add(item); } } } if ((string.IsNullOrWhiteSpace(workGroup.Key)) && (workGroup.Items.Count == 0) && (workGroup.Count == 1)) { workGroup = workGroup.ElementAt(0); } workGroup.MarkDirty(); workGroup.MarkNew(); return(workGroup); }
/// <summary> /// Converts the specified <paramref name="source"/>, a <see cref="StringBuilder"/> type, to an <see cref="IConfigurationItem"/>. /// </summary> /// <param name="source">The object, a <see cref="StringBuilder"/> type, to convert into an <see cref="IConfigurationItem"/>.</param> /// <param name="isClassicIni">if <b>true</b> the <paramref name="source"/> format will be interpreted as classic INI, {key}={value}; otherwise, <b>false</b> will interpret the file using the custom triple entry INI format, {key}={type}={value}</param> /// <returns>The object converted into an <see cref="IConfigurationItem"/>.</returns> private IConfigurationItem DeserializeItem(StringBuilder source, bool isClassicIni) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (source.Length == 0) { throw new ArgumentNullException(nameof(source), $"Parameter {nameof(source)} cannot be an empty string."); } if (!source.ToString().Contains(_IniElementSeparator_)) { throw new ArgumentException($"Parameter {nameof(source)} must contain at least one {nameof(_IniElementSeparator_)}. ({nameof(_IniElementSeparator_)}='{_IniElementSeparator_}'); (source='{source}')", nameof(source)); } var parts = new List <string>(); var index = 0; parts.Add(""); var insideQuote = false; foreach (var ch in source.ToString()) { if (insideQuote) { if (ch == '\"') { insideQuote = false; } else { parts[index] = parts[index] + ch; } } else { if (ch == '\"') { insideQuote = true; } else { if ((ch == _IniElementSeparator_) && (index < 2)) { ++index; parts.Add(""); } else { parts[index] = parts[index] + ch; } } } } if (isClassicIni) { // FYI: classic INI has a problem with correctly auto-detecting the proper types. // specifically, it thinks TYPEs are STRINGs and this is a problem for the Configuration Instantiation functions. // {key}={value} string key = parts[0]; string content = ""; if (parts?.Count == 2) { content = parts[1]; } if (parts?.Count == 3) { content = parts[1] + parts[2]; } // **** AUTO-DETECT return(ConfigurationShared.CreateConfigurationItem(key, content)); } else { if (parts?.Count == 3) { // **** TYPE PROVIDED // contains pattern: {key}={type}={value} string key = parts[0]; string valueTypeName = parts[1]; string content = parts[2]; return(ConfigurationShared.CreateConfigurationItem(key, valueTypeName, content, _Compressor)); } else if (parts?.Count == 2) { // **** AUTO-DETECT // contains pattern: {key}={value} string key = parts[0]; string content = parts[1]; return(ConfigurationShared.CreateConfigurationItem(key, content)); } } throw new ArgumentException($"Parameter {nameof(source)} format error. (source='{source}')", nameof(source)); }
/// <summary> /// Converts the specified <paramref name="source"/>, a <see cref="StringBuilder"/> type, to an <see cref="IConfigurationGroup"/>. /// </summary> /// <param name="source">The object, a <see cref="StringBuilder"/> type, to convert into an <see cref="IConfigurationGroup"/>.</param> /// <param name="includeSubgroups">True to scan group names for the Group Name Separator and create sub groups; otherwise, false will ignore the Group Name Separator and use the entire string as the group name.</param> /// <param name="isClassicIni">if <b>true</b> the <paramref name="source"/> format will be interpreted as classic INI, {key}={value}; otherwise, <b>false</b> will interpret the file using the custom triple entry INI format, {key}={type}={value}</param> /// <returns>The object converted into an <see cref="IConfigurationGroup"/>.</returns> public IConfigurationGroup Deserialize(StringBuilder source, bool includeSubgroups, bool isClassicIni) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (source.Length == 0) { throw new ArgumentNullException(nameof(source), $"Parameter {nameof(source)} cannot be an empty string."); } IConfigurationGroup rootGroup = new ConfigurationGroup(""); IConfigurationGroup currentGroup = rootGroup; string candidateRootGroupName = null; foreach (var line in from x in source.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) select x.Trim()) { if (line.StartsWith(_IniGroupNameStartCharacter_) && line.EndsWith(_IniGroupNameStopCharacter_)) { // process group var groupFullName = line.Substring(1, line.Length - 2); if (includeSubgroups) { var possibleRootGroup = groupFullName; if (possibleRootGroup.Contains(_IniGroupNameSeparator_)) { possibleRootGroup = possibleRootGroup.Substring(0, line.IndexOf(_IniGroupNameSeparator_) - 1); } if (candidateRootGroupName == null) { candidateRootGroupName = possibleRootGroup; } else if (candidateRootGroupName != possibleRootGroup) { candidateRootGroupName = ""; } // currentGroup = ConfigurationShared.FindGroup(rootGroup, groupFullName, _IniGroupNameSeparator_); } else { var newGroup = new ConfigurationGroup(groupFullName, !includeSubgroups); rootGroup.Add(newGroup); currentGroup = newGroup; } if (currentGroup == null) { currentGroup = rootGroup; } } else { // process item if (currentGroup == null) { throw new InvalidOperationException($"There is no current configuration group. Somehow the group name was missed. Check the parameter {nameof(source)} for corruption or bad form."); } currentGroup.Items.Add(DeserializeItem(new StringBuilder(line), isClassicIni)); } } if (!string.IsNullOrWhiteSpace(candidateRootGroupName)) { ((IConfigurationGroupAdvanced)rootGroup).SetKey(candidateRootGroupName); } // check for subgroup with same name as root group var foundSubGroup = (from x in rootGroup where x.Key == rootGroup.Key select x).FirstOrDefault(); if (foundSubGroup != null) { rootGroup = foundSubGroup; (rootGroup as IConfigurationGroupAdvanced).Parent = null; } // if ((rootGroup.Count == 1) && (rootGroup.ContainsKey(rootGroup.Key)) && (rootGroup[rootGroup.Key].Key == rootGroup.Key)) { } // rootGroup.ClearDirty(); rootGroup.ClearNew(); return(rootGroup); }