/// <summary> /// Open file and get new reader. /// </summary> /// <returns></returns> /// <exception cref="FileNotFoundException">if ThrowIfNotFound and not found</exception> IEnumerator <ILineTree> IEnumerable <ILineTree> .GetEnumerator() { try { IFileInfo fi = FileProvider.GetFileInfo(FilePath); if (!ThrowIfNotFound && !fi.Exists) { return(empty.GetEnumerator()); } using (Stream s = fi.CreateReadStream()) { ILineTree tree = FileFormat.ReadLineTree(s, LineFormat); if (tree == null) { return(empty.GetEnumerator()); } ILineTree[] trees = new ILineTree[] { tree }; return(((IEnumerable <ILineTree>)trees).GetEnumerator()); } } catch (FileNotFoundException) when(!ThrowIfNotFound) { return(empty.GetEnumerator()); } }
/// <summary> /// Open file and get new reader. /// </summary> /// <returns></returns> /// <exception cref="FileNotFoundException">if ThrowIfNotFound and not found</exception> public override IEnumerator GetEnumerator() { ILineTree tree = LineReaderExtensions.ReadLineTree(FileFormat, FilePath, LineFormat, ThrowIfNotFound); ILineTree[] trees = tree == null ? no_trees : new ILineTree[] { tree }; return(((IEnumerable <ILineTree>)trees).GetEnumerator()); }
/// <summary> /// Reads <paramref name="element"/>, and adds as a subnode to <paramref name="parent"/> node. /// </summary> /// <param name="element"></param> /// <param name="parent"></param> /// <param name="correspondenceContext">(optional) Correspondence to write element-tree mappings</param> /// <param name="_lineFactory">line factory to use.</param> /// <returns>parent</returns> public ILineTree ReadElement(XElement element, ILineTree parent, XmlCorrespondence correspondenceContext, ILineFactory _lineFactory) { ILine key = ReadKey(element, parent, _lineFactory); if (key != null) { ILineTree node = parent.CreateChild(); node.Key = key; if (correspondenceContext != null) { correspondenceContext.Nodes.Put(node, element); } foreach (XNode nn in element.Nodes()) { if (nn is XText text) { string trimmedXmlValue = Trim(text?.Value); if (!string.IsNullOrEmpty(trimmedXmlValue)) { ILine lineValue = Append(parent, _lineFactory, null, "String", trimmedXmlValue); node.Values.Add(lineValue); if (correspondenceContext != null) { correspondenceContext.Values[new LineTreeValue(node, lineValue, node.Values.Count - 1)] = text; } } } } if (element.HasElements) { foreach (XElement e in element.Elements()) { ReadElement(e, node, correspondenceContext, _lineFactory); } } } else { if (element.HasElements) { foreach (XElement e in element.Elements()) { ReadElement(e, parent, correspondenceContext, _lineFactory); } } } return(parent); }
/// <summary> /// Add lines of key,value pairs to tree. Lines will be added as flat first level nodes /// </summary> /// <param name="tree"></param> /// <param name="lines"></param> /// <returns></returns> public static ILineTree AddRange(this ILineTree tree, IEnumerable <ILine> lines) { foreach (var line in lines) { ILineTree subtree = tree.GetOrCreate(line); ILine valueClone; if (line.TryCloneValue(out valueClone)) { subtree.Values.Add(valueClone); } } return(tree); }
/// <summary> /// Read key from <paramref name="element"/>. /// </summary> /// <param name="element"></param> /// <param name="parent"></param> /// <param name="_lineFactory"></param> /// <returns>key or null</returns> public ILine ReadKey(XElement element, ILineTree parent, ILineFactory _lineFactory) { ILine result = null; // <line type="MyClass" type="something" key="something"> if (element.Name == NameLine || element.Name == NameRoot) { result = null; } // <type:MyClass> else if (element.Name.NamespaceName != null && element.Name.NamespaceName.StartsWith(URN_)) { string parameterName = element.Name.NamespaceName.Substring(URN_.Length); string parameterValue = element.Name.LocalName; result = Append(parent, _lineFactory, result, parameterName, parameterValue); } else { return(null); } // Read attributes if (element.HasAttributes) { foreach (XAttribute attribute in element.Attributes()) { if (string.IsNullOrEmpty(attribute.Name.NamespaceName)) { string parameterName = attribute.Name.LocalName; string parameterValue = attribute.Value; if (parameterName.StartsWith("xml")) { continue; } Match m = occuranceIndexParser.Match(parameterName); Group g_name = m.Groups["name"]; if (m.Success && g_name.Success) { parameterName = g_name.Value; } // Append parameter result = Append(parent, _lineFactory, result, parameterName, parameterValue); } } } return(result); }
/// <summary> /// Tests if <paramref name="tree"/> has a child with key <paramref name="key"/>. /// /// If <paramref name="key"/> is null, then returns always false. /// </summary> /// <param name="tree"></param> /// <param name="key"></param> /// <returns></returns> public static bool HasChild(this ILineTree tree, ILine key) { if (key == null) { return(false); } if (!tree.HasChildren) { return(false); } IEnumerable <ILineTree> children = tree.GetChildren(key); if (children == null) { return(false); } return(children.Count() > 0); }
/// <summary> /// Append value to <paramref name="prev"/>> /// </summary> /// <param name="parent"></param> /// <param name="_lineFactory"></param> /// <param name="prev">(optional)</param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <returns></returns> ILine Append(ILineTree parent, ILineFactory _lineFactory, ILine prev, string parameterName, string parameterValue) { if (parameterName == "String") { IStringFormat stringFormat; if (parent.TryGetStringFormat(resolver, out stringFormat)) { IString valueString = stringFormat.Parse(parameterValue); return(LineFactory.Create <ILineString, IString>(prev, valueString)); } else { return(LineFactory.Create <ILineHint, string, string>(prev, "String", parameterValue)); } } else { return(LineFactory.Create <ILineParameter, string, string>(prev, parameterName, parameterValue)); } }
/// <summary> /// Tests if <paramref name="tree"/> has a <paramref name="value"/>. /// /// If <paramref name="value"/> is null, then returns always false. /// </summary> /// <param name="tree"></param> /// <param name="value"></param> /// <returns></returns> public static bool HasValue(this ILineTree tree, IString value) { if (value == null) { return(false); } if (!tree.HasValues) { return(false); } string str; foreach (ILine linevalue in tree.Values) { if (linevalue is ILineString part && part.String != null) { if (FormatStringComparer.Default.Equals(part.String, value)) { return(true); } }
/// <summary> /// Flatten <paramref name="node"/> to key lines. /// </summary> /// <param name="node"></param> /// <param name="lineAppender">(optional) overriding appender</param> /// <returns></returns> public static IEnumerable <ILine> ToLines(this ILineTree node, ILineFactory lineAppender = default) { Queue <(ILineTree, ILine)> queue = new Queue <(ILineTree, ILine)>(); queue.Enqueue((node, node.Key)); while (queue.Count > 0) { // Next element (ILineTree, ILine)current = queue.Dequeue(); // Yield values if (current.Item2 != null && current.Item1.HasValues) { foreach (ILine value in current.Item1.Values) { yield return(current.Item2.Concat(value)); } } // Enqueue children if (current.Item1.HasChildren) { foreach (ILineTree child in current.Item1.Children) { if (lineAppender != null) { ILine childKey = lineAppender.Concat(lineAppender.Clone(current.Item2), child.Key); queue.Enqueue((child, childKey)); } else { ILine childKey = current.Item2 == null ? child.Key : current.Item2.Concat(child.Key); queue.Enqueue((child, childKey)); } } } } }
/// <summary> /// Open file and get new reader. /// </summary> /// <returns></returns> /// <exception cref="FileNotFoundException">if ThrowIfNotFound and not found</exception> IEnumerator <ILineTree> IEnumerable <ILineTree> .GetEnumerator() { try { using (Stream s = Assembly.GetManifestResourceStream(ResourceName)) { if (s == null) { return(!ThrowIfNotFound?empty.GetEnumerator() : throw new FileNotFoundException(ResourceName)); } ILineTree tree = FileFormat.ReadLineTree(s, LineFormat); if (tree == null) { return(empty.GetEnumerator()); } return(((IEnumerable <ILineTree>) new ILineTree[] { tree }).GetEnumerator()); } } catch (FileNotFoundException) when(!ThrowIfNotFound) { return(empty.GetEnumerator()); } }
/// <summary> /// Add an enumeration of key,value pairs. Each key will constructed a new node. /// /// If <paramref name="groupingRule"/> the nodes are laid out in the order occurance of name pattern parts. /// /// For example grouping pattern "{Type}/{Culture}{anysection}{Key}" would order nodes as following: /// <code> /// "type:MyController": { /// "key:Success": "Success", /// "culture:en:key:Success": "Success", /// } /// </code> /// /// Non-capture parts such as "/" in pattern "{Section}/{Culture}", specify separator of tree node levels. /// /// </summary> /// <param name="tree"></param> /// <param name="lines"></param> /// <param name="groupingRule"></param> /// <param name="parameterInfos"></param> /// <returns></returns> public static ILineTree AddRange(this ILineTree tree, IEnumerable <ILine> lines, ILinePattern groupingRule, IParameterInfos parameterInfos) // Todo separate to sortRule + groupingRule { // Use another method //if (groupingRule == null) { node.AddRange(lines); return node; } StructList16 <ILineParameter> parameters = new StructList16 <ILineParameter>(null); foreach (var line in lines) { parameters.Clear(); line.GetParameterParts(ref parameters); parameterListSorter.Reverse(ref parameters); // Key for the current level. ILine levelKey = null; // Build levels with this collection List <ILine> key_levels = new List <ILine>(); // Visit both lists concurrently ILineParameter next_parameter = default; if (groupingRule != null) { foreach (var part in groupingRule.AllParts) { // Is not a capture part if (part.CaptureIndex < 0) { // Non-capture part has "/", go to next level. eg. "{nn}/{nn}" if (part.Text != null && part.Text.Contains("/")) { if (levelKey != null) { key_levels.Add(levelKey); } levelKey = null; } // Next part continue; } // Capture part has "/" in prefix, start next level if (levelKey != null && part.PrefixSeparator.Contains("/")) { if (levelKey != null) { key_levels.Add(levelKey); } levelKey = null; } // Look ahead to see if there is a parameter that matches this capture part int next_parameter_ix = -1; for (int ix = 0; ix < parameters.Count; ix++) { // Copy next_parameter = parameters[ix]; // Already added before if (next_parameter.ParameterName == null) { continue; } // Get name string parameter_name = next_parameter.ParameterName; // Parameter matches the name in the pattern's capture part if (parameter_name == part.ParameterName) { next_parameter_ix = ix; break; } // Matches with "anysection" //IParameterInfo info; //if (part.ParameterName == "anysection" && ParameterInfos.Default.TryGetValue(parameter_name, out info) && info.IsSection) { next_parameter_ix = ix; break; } } // No matching parameter for this capture part if (next_parameter_ix < 0) { continue; } // This part is canonical, hint, or parameter. if (!next_parameter.IsNonCanonicalKey(parameterInfos)) { // There (may be) are other canonical parts between part_ix and next_part_is. We have to add them here. for (int ix = 0; ix < next_parameter_ix; ix++) { // Copy ILineParameter parameter = parameters[ix]; // Has been added before if ((parameter.ParameterName == null) || parameter.IsNonCanonicalKey(parameterInfos)) { continue; } // Append to level's key levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(parameter)); // Mark handled parameters[ix] = unused; } } // Append to level's key levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(next_parameter)); // Mark handled parameters[next_parameter_ix] = unused; // Yield level if (part.PostfixSeparator.Contains("/")) { key_levels.Add(levelKey); levelKey = null; } } } // Append rest of the parameters for (int ix = 0; ix < parameters.Count; ix++) { // Copy ILineParameter parameter = parameters[ix]; if (parameter.ParameterName != null && parameter.ParameterName != "String") { levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(parameter)); } } // yield levelKey if (levelKey != null) { key_levels.Add(levelKey); levelKey = null; } // Yield line tree.AddRecursive(key_levels, line.GetString()); key_levels.Clear(); parameters.Clear(); } return(tree); }
/// <summary> /// Read ini token stream into <paramref name="root"/> /// </summary> /// <param name="ini">ini token stream. </param> /// <param name="root">parent node to under which add nodes</param> /// <param name="lineFormat">unused</param> /// <param name="correspondence">(optional) if set tokens are associated to key tree. If <paramref name="correspondence"/> is provided, then <paramref name="ini"/> must be a linked list. See <see cref="IniTokenizer.ToLinkedList"/></param> /// <returns><paramref name="root"/></returns> public ILineTree ReadIniIntoTree(IEnumerable <IniToken> ini, ILineTree root, ILineFormat lineFormat, IniCorrespondence correspondence) { ILineFactory tmp; ILineFormat _escaper_section = lineFormat.TryGetLineFactory(out tmp) && tmp != LineFactory ? new LineFormat("\\:[]", true, "\\:[]", true, tmp, null) : this.escaper_section; ILineFormat _escaper_key = lineFormat.TryGetLineFactory(out tmp) && tmp != LineFactory ? new LineFormat("\\:= ", true, "\\:= ", true, tmp, null) : this.escaper_key; ILineTree section = null; foreach (IniToken token in ini) { switch (token.Type) { case IniTokenType.Section: ILine key = null; if (_escaper_section.TryParse(token.ValueText, out key)) { section = key == null ? null : root.Create(key); if (section != null && correspondence != null) { correspondence.Nodes.Put(section, token); } } else { section = null; } break; case IniTokenType.KeyValue: ILine key_ = null; if (_escaper_key.TryParse(token.KeyText, out key_)) { if (key_ == null) { key_ = LineFactory.Create <ILinePart>(null); } ILineTree current = (section ?? root).GetOrCreate(key_); string value = escaper_value.UnescapeLiteral(token.ValueText); if (value != null) { IStringFormat stringFormat; ILine lineValue; if (current.TryGetStringFormat(resolver, out stringFormat)) { // Append FormatString IString valueString = stringFormat.Parse(value); lineValue = LineFactory.Create <ILineString, IString>(null, valueString); } else { // Append Hint lineValue = LineFactory.Create <ILineHint, string, string>(null, "String", value); } int ix = current.Values.Count; current.Values.Add(lineValue); if (correspondence != null) { correspondence.Values[new LineTreeValue(current, lineValue, ix)] = token; } } } break; case IniTokenType.Comment: break; case IniTokenType.Text: break; } } return(root); }
/// <summary> /// Convert <paramref name="tree"/> to <see cref="IAssetSource"/>.. /// </summary> /// <param name="tree"></param> /// <returns></returns> public static IAssetSource ToAssetSource(ILineTree tree) => new LineTreeSource(tree == null ? new ILineTree[0] : new ILineTree[] { tree });
/// <summary> /// Create an asset that uses <paramref name="tree"/>. /// /// Trees are reloaded into the asset if <see cref="IAssetExtensions.Reload(IAsset)"/> is called. /// </summary> /// <param name="tree"></param> /// <returns></returns> public static IAsset ToAsset(this ILineTree tree) => new StringAsset().Add(new ILineTree[] { tree }).Load();
public static void Main(string[] args) { { #region Snippet_0a ILineFileFormat format = LineReaderMap.Default["ini"]; #endregion Snippet_0a } { #region Snippet_0b ILineFileFormat format = IniLinesReader.Default; #endregion Snippet_0b ILineFileFormat format2a = LineReaderMap.Default["json"]; ILineFileFormat format2b = JsonLinesReader.Default; ILineFileFormat format3a = LineReaderMap.Default["xml"]; ILineFileFormat format3b = XmlLinesReader.Default; ILineFileFormat format4a = LineReaderMap.Default["resx"]; ILineFileFormat format4b = ResxLinesReader.Default; ILineFileFormat format5a = LineReaderMap.Default["resources"]; ILineFileFormat format5b = ResourcesLineReader.Default; } { #region Snippet_1a IEnumerable <ILine> key_lines = LineReaderMap.Default.ReadLines( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_1a } { #region Snippet_1b IEnumerable <KeyValuePair <string, IString> > string_lines = LineReaderMap.Default.ReadStringLines( filename: "localization.ini", lineFormat: LineFormat.Parameters, throwIfNotFound: true); #endregion Snippet_1b } { #region Snippet_1c ILineTree tree = LineReaderMap.Default.ReadLineTree( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_1c } { #region Snippet_2a IEnumerable <ILine> key_lines_reader = LineReaderMap.Default.FileReader( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_2a } { #region Snippet_2b IEnumerable <KeyValuePair <string, IString> > string_lines_reader = LineReaderMap.Default.FileReaderAsStringLines( filename: "localization.ini", lineFormat: LineFormat.Parameters, throwIfNotFound: true); #endregion Snippet_2b var lines = string_lines_reader.ToArray(); } { #region Snippet_2c IEnumerable <ILineTree> tree_reader = LineReaderMap.Default.FileReaderAsLineTree( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_2c var lines = tree_reader.ToArray(); } { #region Snippet_3a Assembly asm = typeof(LocalizationReader_Examples).Assembly; IEnumerable <ILine> key_lines_reader = LineReaderMap.Default.EmbeddedReader( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_3a var lines = key_lines_reader.ToArray(); } { Assembly asm = typeof(LocalizationReader_Examples).Assembly; #region Snippet_3b IEnumerable <KeyValuePair <string, IString> > string_lines_reader = LineReaderMap.Default.EmbeddedReaderAsStringLines( assembly: asm, resourceName: "docs.localization.ini", lineFormat: LineFormat.Parameters, throwIfNotFound: true); #endregion Snippet_3b var lines = string_lines_reader.ToArray(); } { Assembly asm = typeof(LocalizationReader_Examples).Assembly; #region Snippet_3c IEnumerable <ILineTree> tree_reader = LineReaderMap.Default.EmbeddedReaderAsLineTree( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_3c var lines = tree_reader.ToArray(); } { #region Snippet_4a IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IEnumerable <ILine> key_lines_reader = LineReaderMap.Default.FileProviderReader( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_4a var lines = key_lines_reader.ToArray(); } { #region Snippet_4b IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IEnumerable <KeyValuePair <string, IString> > string_lines_reader = LineReaderMap.Default.FileProviderReaderAsStringLines( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_4b var lines = string_lines_reader.ToArray(); } { #region Snippet_4c IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IEnumerable <ILineTree> tree_reader = LineReaderMap.Default.FileProviderReaderAsLineTree( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_4c var lines = tree_reader.ToArray(); } { #region Snippet_5a using (Stream s = new FileStream("localization.ini", FileMode.Open, FileAccess.Read)) { IEnumerable <ILine> key_lines = IniLinesReader.Default.ReadLines(s); } #endregion Snippet_5a } { #region Snippet_5b using (Stream s = new FileStream("localization.ini", FileMode.Open, FileAccess.Read)) { IEnumerable <KeyValuePair <string, IString> > string_lines = IniLinesReader.Default.ReadStringLines( stream: s, lineFormat: LineFormat.Parameters); } #endregion Snippet_5b } { #region Snippet_5c using (Stream s = new FileStream("localization.ini", FileMode.Open, FileAccess.Read)) { ILineTree tree = IniLinesReader.Default.ReadLineTree(s); } #endregion Snippet_5c } { #region Snippet_6a string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; using (TextReader tr = new StringReader(text)) { IEnumerable <ILine> key_lines = IniLinesReader.Default.ReadLines(tr); } #endregion Snippet_6a } { string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; #region Snippet_6b using (TextReader tr = new StringReader(text)) { IEnumerable <KeyValuePair <string, IString> > string_lines = IniLinesReader.Default.ReadStringLines( srcText: tr, lineFormat: LineFormat.Parameters); } #endregion Snippet_6b } { string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; #region Snippet_6c using (TextReader tr = new StringReader(text)) { ILineTree tree = IniLinesReader.Default.ReadLineTree(tr); } #endregion Snippet_6c } { #region Snippet_7a string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; IEnumerable <ILine> key_lines = IniLinesReader.Default.ReadString( srcText: text); #endregion Snippet_7a } { string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; #region Snippet_7b IEnumerable <KeyValuePair <string, IString> > string_lines = IniLinesReader.Default.ReadStringAsStringLines( srcText: text, lineFormat: LineFormat.Parameters); #endregion Snippet_7b } { string text = "Culture:en:Type:MyController:Key:Hello = Hello World!\n"; #region Snippet_7c ILineTree tree = IniLinesReader.Default.ReadStringAsLineTree( srcText: text); #endregion Snippet_7c } { #region Snippet_10a IAsset asset = IniLinesReader.Default.FileAsset( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_10a } { #region Snippet_10b Assembly asm = typeof(LocalizationReader_Examples).Assembly; IAsset asset = IniLinesReader.Default.EmbeddedAsset( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_10b } { #region Snippet_10c IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IAsset asset = IniLinesReader.Default.FileProviderAsset( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_10c } { Assembly asm = typeof(LocalizationReader_Examples).Assembly; IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); #region Snippet_10a2 IAsset asset = LineReaderMap.Default.FileAsset( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_10a2 #region Snippet_10b2 asset = LineReaderMap.Default.EmbeddedAsset( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_10b2 #region Snippet_10c2 asset = LineReaderMap.Default.FileProviderAsset( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_10c2 } { #region Snippet_11a IAssetSource assetSource = IniLinesReader.Default.FileAssetSource( filename: "localization.ini", throwIfNotFound: true); IAssetBuilder assetBuilder = new AssetBuilder().AddSource(assetSource); IAsset asset = assetBuilder.Build(); #endregion Snippet_11a } { #region Snippet_11b Assembly asm = typeof(LocalizationReader_Examples).Assembly; IAssetSource assetSource = IniLinesReader.Default.EmbeddedAssetSource( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_11b } { #region Snippet_11c IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IAssetSource assetSource = IniLinesReader.Default.FileProviderAssetSource( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_11c } { #region Snippet_11a2 IAssetSource assetSource = LineReaderMap.Default.FileAssetSource( filename: "localization.ini", throwIfNotFound: true); #endregion Snippet_11a2 } { Assembly asm = typeof(LocalizationReader_Examples).Assembly; #region Snippet_11b2 IAssetSource assetSource = LineReaderMap.Default.EmbeddedAssetSource( assembly: asm, resourceName: "docs.localization.ini", throwIfNotFound: true); #endregion Snippet_11b2 } { IFileProvider fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); #region Snippet_11c2 IAssetSource assetSource = LineReaderMap.Default.FileProviderAssetSource( fileProvider: fileProvider, filepath: "localization.ini", throwIfNotFound: true); #endregion Snippet_11c2 } { #region Snippet_7 #endregion Snippet_7 } { #region Snippet_8 #endregion Snippet_8 } { #region Snippet_9 #endregion Snippet_9 } { #region Snippet_12 #endregion Snippet_12 } { #region Snippet_13 #endregion Snippet_13 } { #region Snippet_14 #endregion Snippet_14 } { #region Snippet_15 #endregion Snippet_15 } { #region Snippet_16 #endregion Snippet_16 } { #region Snippet_17 #endregion Snippet_17 } { #region Snippet_18 #endregion Snippet_18 } { #region Snippet_30a // Create writer ILineReader format = new ExtFileFormatReader(); // Clone formats LineFileFormatMap formats = LineReaderMap.Default.Clone(); // Add to clone formats.Add(format); // Or if in deploying application project, format can be added to the global singleton (LineReaderMap.Default as IDictionary <string, ILineFileFormat>).Add(format); #endregion Snippet_30a } }
/// <summary> /// Search child by key. /// </summary> /// <param name="tree"></param> /// <param name="key"></param> /// <returns>child node or null if was not found</returns> public static ILineTree GetChild(this ILineTree tree, ILine key) => tree.GetChildren(key)?.FirstOrDefault();
/// <summary> /// Line value tree. /// </summary> /// <param name="tree"></param> /// <param name="value"></param> /// <param name="valueIndex"></param> public LineTreeValue(ILineTree tree, IString value, int valueIndex) { this.tree = tree ?? throw new ArgumentNullException(nameof(tree)); this.value = new LineStringPart(null, null, value); this.valueIndex = valueIndex; }
/// <summary> /// Line value tree. /// </summary> /// <param name="tree"></param> /// <param name="value"></param> /// <param name="valueIndex"></param> public LineTreeValue(ILineTree tree, ILine value, int valueIndex) { this.tree = tree ?? throw new ArgumentNullException(nameof(tree)); this.value = value; this.valueIndex = valueIndex; }
/// <summary> /// List all children of <paramref name="element"/> with a readable <see cref="ILine"/>. /// </summary> /// <param name="element"></param> /// <param name="node"></param> /// <param name="_lineFactory"></param> /// <returns></returns> public IEnumerable <KeyValuePair <ILine, XElement> > ListChildrenWithKeys(XElement element, ILineTree node, ILineFactory _lineFactory) => element.Elements().Select(e => new KeyValuePair <ILine, XElement>(ReadKey(e, node, _lineFactory), e)).Where(line => line.Key != null);
/// <summary> /// Read json token stream into <paramref name="node"/> /// </summary> /// <param name="json"></param> /// <param name="node">parent node to under which add nodes</param> /// <param name="lineFormat">unused</param> /// <param name="correspondenceContext">(optional) place to update correspondence. If set <paramref name="json"/> must implement <see cref="JTokenReader"/>.</param> /// <returns></returns> public ILineTree ReadJsonIntoTree(JsonReader json, ILineTree node, ILineFormat lineFormat, JsonCorrespondence correspondenceContext) { ILineFactory tmp; ILineFormat _lineFormat = lineFormat.TryGetLineFactory(out tmp) && tmp != LineFactory ? new LineFormat(" :\\", false, " :\\", false, tmp, null) : this.lineFormat; ILineTree current = node; Stack <ILineTree> stack = new Stack <ILineTree>(); JTokenReader tokenReader = json as JTokenReader; bool updateCorrespondence = correspondenceContext != null && tokenReader != null; while (json.Read()) { switch (json.TokenType) { case JsonToken.StartObject: stack.Push(current); if (updateCorrespondence) { correspondenceContext.Nodes.Put(current, tokenReader.CurrentToken); } break; case JsonToken.EndObject: current = stack.Pop(); break; case JsonToken.PropertyName: ILine key = null; if (_lineFormat.TryParse(json.Value?.ToString(), out key)) { current = key == null?stack.Peek() : stack.Peek()?.Create(key); if (current != null && updateCorrespondence && !correspondenceContext.Nodes.ContainsLeft(current)) { correspondenceContext.Nodes.Put(current, tokenReader.CurrentToken); } } else { current = null; } break; case JsonToken.Raw: case JsonToken.Date: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Float: case JsonToken.Integer: if (current != null) { string value = json.Value?.ToString(); if (value != null) { int ix = current.Values.Count; IStringFormat stringFormat; if (current.TryGetStringFormat(resolver, out stringFormat)) { // Append FormatString IString valueString = stringFormat.Parse(value); ILineString lineValue = LineFactory.Create <ILineString, IString>(null, valueString); current.Values.Add(lineValue); if (updateCorrespondence) { correspondenceContext.Values[new LineTreeValue(current, lineValue, ix)] = (JValue)tokenReader.CurrentToken; } } else { // Append Hint ILineHint lineValue = LineFactory.Create <ILineHint, string, string>(null, "String", value); current.Values.Add(lineValue); if (updateCorrespondence) { correspondenceContext.Values[new LineTreeValue(current, lineValue, ix)] = (JValue)tokenReader.CurrentToken; } } } } break; case JsonToken.StartArray: if (updateCorrespondence) { correspondenceContext.Nodes.Put(current, tokenReader.CurrentToken); } break; case JsonToken.EndArray: break; } } return(node); }
/// <summary> /// Flatten <paramref name="LineTree"/> to string lines. /// </summary> /// <param name="LineTree"></param> /// <param name="policy"></param> /// <returns></returns> public static IEnumerable <KeyValuePair <string, IString> > ToStringLines(this ILineTree LineTree, ILineFormat policy) => LineTree.ToLines(LineAppender.NonResolving).ToStringLines(policy);