private static JNode ParseEnumerationValue(StringBuffer buffer) { char?next; //array entry point buffer.MoveNext(); List <JNode> entries = new List <JNode>(); bool hasNextValue = true; while (hasNextValue) { var entry = ParseNodeValue(buffer); entries.Add(entry); next = buffer.MoveNextNonEmptyChar(); if (next == JConstants.EnumerationClosingToken) { hasNextValue = false; } else { JUtils.ValidateChar(next, JConstants.SeparatorToken); } } return(new JEnumerationNode(entries)); }
private static IEnumerable <JSegment> ProcessRawIndexer(string segment) { //assume starts with [ and ends with ] but may include extra segmentation '][' //multiple indexers may exist in a row var buffer = new StringBuffer(segment); var next = buffer.MoveNextNonEmptyChar(); JUtils.ValidateChar(next, JConstants.SegmentIndexerStart); List <JSegment> indexers = new List <JSegment>(); bool hasMoreSegments = true; while (hasMoreSegments) { var segmentValue = buffer.MoveNext((s, i, c) => s[i + 1] == JConstants.SegmentIndexerEnd); next = buffer.MoveNext(); indexers.Add(new JSegment(JSegment.SegmentType.Indexer, n => ExpandIndexer(n, segmentValue), segmentValue)); next = buffer.MoveNextNonEmptyChar(); if (!next.HasValue) { hasMoreSegments = false; } else { JUtils.ValidateChar(next, JConstants.SegmentIndexerStart, "Expected an indexer but got an incomplete token."); } } return(indexers); }
public static JNode ParseNodeValue(StringBuffer buffer) { var next = buffer.MoveNextNonEmptyChar(); JUtils.ValidateChar(next); buffer.MovePrev(); // ReSharper disable once PossibleInvalidOperationException - see ValidateChar switch (next.Value) { case JConstants.NodeOpeningToken: //parsing object return(ParseNode(buffer)); case JConstants.NodeClosingToken: //parsing an empty node //i came here because the node that triggered just ended without info return(new JContentNode(null)); case JConstants.EnumerationOpeningToken: //parsing array return(ParseEnumerationValue(buffer)); case JConstants.EnumerationClosingToken: //todo - i need it here return(new JEnumerationNode(null)); case JConstants.KeyValueOpeningClosingToken: //parsing string end value buffer.MoveNext(); var val = buffer.MoveNext((s, i, c) => s[i + 1] == JConstants.KeyValueOpeningClosingToken); JUtils.ValidateChar(buffer.MoveNext(), JConstants.KeyValueOpeningClosingToken); return(new JValueNode(val)); default: //parsing boolean,null, number end value return(ParseLowLevelNodeValue(buffer, next)); } }
public static JContentNode ParseNode(StringBuffer buffer) { var next = buffer.MoveNextNonEmptyChar(); JUtils.ValidateChar(next, JConstants.NodeOpeningToken); Dictionary <string, JNode> node = new Dictionary <string, JNode>(); bool hasMoreNodes = true; while (hasMoreNodes) { var key = ParseNodeKey(buffer); JUtils.ValidateChar(buffer.MoveNextNonEmptyChar(), JConstants.KeyValueSeparationToken); var value = ParseNodeValue(buffer); //value.Key = key; node.Add(key, value); next = buffer.MoveNextNonEmptyChar(); if (next == JConstants.NodeClosingToken) { hasMoreNodes = false; } else { JUtils.ValidateChar(next, JConstants.SeparatorToken); } } return(new JContentNode(node)); }
private static JNode ExpandValue(JNode node, string name) { if (node is JContentNode jcn) { return(jcn[name] as JNode); } JUtils.ValidateOutOfBounds("Cannot expand a node. Path does not exist."); throw new NotImplementedException("This exception should never be hit"); }
private static JNode ExpandIndexer(JNode node, string indexer) { if (node is JEnumerationNode jen && jen.Value is IEnumerable <JNode> itms) { if (int.TryParse(indexer, out var idx)) { return(jen[idx] as JNode); } if (indexer.Contains(":")) { int?start = null, end = null; var parts = indexer.Split(':'); if (parts.Length != 2) { JUtils.ValidateOutOfBounds("Range indexer is incorrectly formed."); } if (int.TryParse(parts[0], out var s)) { start = s; } if (int.TryParse(parts[1], out var e)) { end = e; } if (!start.HasValue) { start = 0; } if (!end.HasValue || end.Value == -1) { end = itms.Count() - 1; } List <JNode> subrange = new List <JNode>(); for (int i = start.Value; i < end; i++) { subrange.Add(itms.ElementAt(i)); } return(new JEnumerationNode(subrange)); } else if (indexer.Contains(",")) { var values = indexer.Split(',').Select(int.Parse); List <JNode> subrange = new List <JNode>(); foreach (var value in values) { subrange.Add(itms.ElementAt(value)); } return(new JEnumerationNode(subrange)); } } JUtils.ValidateOutOfBounds("Cannot expand an indexer. Path cannot be indexed."); throw new NotImplementedException("This exception should never be hit"); }
public static IEnumerable <JSegment> Parse(ITokenBuffer path) { var segments = new List <JSegment>(); var next = path.MoveNextNonEmptyChar(); if (next.HasValue && next.Value == JConstants.SegmentRootToken) { var root = new JSegment(SegmentType.Root, ExpandRoot); next = path.MoveNextNonEmptyChar(); if (!next.HasValue) { segments.Add(root); return(segments); } if (next == JConstants.ExpressionStartToken) {//i contain an expression var expr = path.MoveNext((s, i, c) => s[i + 1] == JConstants.ExpressionEndToken); if (!string.IsNullOrEmpty(expr)) { root = new JSegment(SegmentType.Root, ExpandRoot, expr); } JUtils.ValidateChar(path.MoveNext(), JConstants.ExpressionEndToken); next = path.MoveNextNonEmptyChar(); } segments.Add(root); if (!next.HasValue) { return(segments); } JUtils.ValidateChar(next, JConstants.SegmentSeparatorToken); } bool hasMoreSegments = true; while (hasMoreSegments) { var segment = path.MoveNext((s, i, c) => i == s.Length - 1 || s[i + 1] == JConstants.SegmentSeparatorToken); var processedSegments = ProcessRawSegment(segment); segments.AddRange(processedSegments); next = path.MoveNext(); if (!next.HasValue) { hasMoreSegments = false; } else { JUtils.ValidateChar(next, JConstants.SegmentSeparatorToken); } } return(segments); }
private static JNode ExpandValueRecursive(JNode node, string name) { if (node.Type == JNode.NodeType.Leaf) { JUtils.ValidateOutOfBounds("Cannot expand a node. Path does not exist."); } if (node.Type == JNode.NodeType.Enumeration) { JUtils.ValidateOutOfBounds("Cannot expand a node. Path does not exist."); } var combined = ExpandNodesRecursive(node as JContentNode, name); return(new JEnumerationNode(combined)); }
public static string ParseNodeKey(StringBuffer buffer) { var next = buffer.MoveNextNonEmptyChar(); JUtils.ValidateChar(next, JConstants.KeyValueOpeningClosingToken); var value = buffer.MoveNext(JConstants.KeyValueOpeningClosingToken); buffer.MovePrev(); value = value.Substring(0, value.Length - 1); JUtils.ValidateNonEmpty(value); next = buffer.MoveNext(); JUtils.ValidateChar(next, JConstants.KeyValueOpeningClosingToken); return(value); }
public static T Parse <T>(JNode value) { if (typeof(T) != typeof(string) && typeof(IEnumerable).IsAssignableFrom(typeof(T)) && value is JEnumerationNode enu) { //return ParseEnumerableContract<T>(value); var arg0 = JUtils.GetGenericTypeFromEnumerable <T>(); var method = JUtils.GetCastMethodForInputType <JEnumerationNode>(); var generic = method.MakeGenericMethod(arg0); var result = generic.Invoke(null, new[] { enu }); return((T)result); } else if (value is JEnumerationNode jen) { var data = jen.Cast <T>(); if (data == null) { data = Enumerable.Empty <T>(); } var enumerable = data as T[] ?? data.ToArray(); if (enumerable.Length > 1) { JUtils.ValidateOutOfBounds(); } return(enumerable.FirstOrDefault()); } else if (value is JValueNode jvn) { //return ParseObjectContract<T>(value); return(jvn.Cast <T>()); } else if (value is JContentNode jcn) { return(jcn.Cast <T>()); } else { JUtils.ValidateOutOfBounds(); } throw new NotImplementedException("This should not be hit. I'm responsible if it is."); }
private static JNode ExpandWildcard(JNode node) { throw new NotImplementedException("This feature is not implemented yet."); //TODO //all of the child nodes should be expanded into a single content node recusively //all of the immediate child nodes shoul be expanded into an enumeration #pragma warning disable 162 if (node is JEnumerationNode jen) { return(jen); } if (node is JValueNode jvn) { return(jvn); } if (node is JContentNode jcn) { return(new JEnumerationNode((jcn.Value as IDictionary <string, JNode>)?.Select(x => x.Value))); } JUtils.ValidateOutOfBounds("Cannot expand a wildcard node. Path does not conform."); throw new NotImplementedException("This exception should never be hit"); #pragma warning restore 162 }
private static JNode ParseLowLevelNodeValue(StringBuffer buffer, char?next) { if (char.IsDigit(next.Value) || next == '+' | next == '-') { //possible number var number = buffer.MoveNext((str, idx, chr) => idx + 1 < str.Length && new[] { JConstants.NodeClosingToken, JConstants.SeparatorToken, JConstants.EnumerationClosingToken } .Contains(str[idx + 1])); if (number.Contains(".") || number.Contains(",")) { if (long.TryParse(number, out var l)) { return(new JValueNode(l)); } } else { if (double.TryParse(number, out var d)) { return(new JValueNode(d)); } } JUtils.ValidateOutOfBounds(); } else { //possible boolean, null bool?token = buffer.IsNext("true", StringComparison.CurrentCultureIgnoreCase) ? true : buffer.IsNext("false", StringComparison.CurrentCultureIgnoreCase) ? false : (bool?)null; if (!token.HasValue || token.Value) { buffer.MoveNext(4); } else { buffer.MoveNext(5); } if (!token.HasValue) { return(new JValueNode(null)); } else { return(new JValueNode(token.Value)); } ; } throw new NotImplementedException("If you see this, I screwed up."); }