예제 #1
0
        // TODO: Should add support to force commas or not, then just use newline as a text separator

#if !WINDOWS_UWP
        /// <summary>
        /// Parses the passed in file at the given file path, and returns a non-<c>null</c> <see cref="Json"/> instance.
        /// </summary>
        /// <param name="filePath">Path of the file to parse</param>
        /// <param name="rules">Parser rules</param>
        /// <returns>A non-<c>null</c> <see cref="Json"/> instance</returns>
        public static Json ParseFile(string filePath, ParserRules rules = null)
        {
            if (PathHelpers.IsValidAsPath(filePath) && File.Exists(filePath))
            {
                return(ParseText(File.ReadAllText(filePath), rules));
            }
            else
            {
                Json jsonOutput = new Json(null);
                jsonOutput.AddError($"File path '{filePath ?? "<null>"}' does not exist on disk, or is an invalid path!");
                return(jsonOutput);
            }
        }
예제 #2
0
        private static Json RunParse(TrackedStringManager tracker, ParserRules rules)
        {
            Json output = new Json(tracker);

            try
            {
                if (tracker.Text == null)
                {
                    output.AddError("Null source text provided!");
                    tracker.HasChanges = false;
                    return(output);
                }

                JsonTextIndexer indexer = new JsonTextIndexer(tracker.Text, rules);
                // TODO: Handle case where root is document without braces( ie "item : value, item2 : value2")

                int indexOfFirstOpenBracket = indexer.NextAny(0, '{', '[');

                // ============ No Brackets ===========
                if (indexOfFirstOpenBracket == -1)
                {
                    output.Data        = new JsonValue(output.TextTracking, 0, indexer.NextAny(0, '}', ']'), false);
                    tracker.HasChanges = false;
                    return(output);
                }

                // ============ Has Brackets ===========
                char nextBracket = output.TextTracking.Text[indexOfFirstOpenBracket];
                if (nextBracket == '{')
                {
                    output.Data        = new JsonDocument(indexer, output.TextTracking, indexOfFirstOpenBracket, out int endIndex);
                    tracker.HasChanges = false;
                    return(output);
                }
                else // if(nextBracket == '[')
                {
                    output.Data        = new JsonArray(indexer, output.TextTracking, indexOfFirstOpenBracket, out int endIndex);
                    tracker.HasChanges = false;
                    return(output);
                }
            }
            catch (Exception exc)
            {
                output.AddError(exc.ToString());
            }

            return(output);
        }
예제 #3
0
        public JsonTextIndexer(string text, ParserRules rules = null)
        {
            rules = rules ?? new ParserRules();
            foreach (char separator in rules.AdditionalSeparatorChars)
            {
                m_separatorIndexTracker.Add(separator, new List <int>());
            }

            var commentStartChars = new List <char>(rules.CommentIndicators.Select(c => c.Item1.First()));

            bool   isBetweenQuoteStartAndEnd = false;
            string targetCommentEnd          = null;

            for (int currCharTargetIndex = 0; currCharTargetIndex < text.Length; ++currCharTargetIndex)
            {
                // If we're waiting for the end of a comment, then skip text until it's found
                if (targetCommentEnd != null)
                {
                    string subStr = text.Substring(currCharTargetIndex, targetCommentEnd.Length);
                    if (subStr == targetCommentEnd)
                    {
                        currCharTargetIndex += targetCommentEnd.Length - 1;
                        targetCommentEnd     = null;
                    }

                    continue;
                }

                char charInQuestion = text[currCharTargetIndex];

                // If we've started looking for a quote, skip text until end quote is found
                if (isBetweenQuoteStartAndEnd)
                {
                    if (charInQuestion == QuoteChar)
                    {
                        isBetweenQuoteStartAndEnd = false;
                        _StoreFoundSeparators(currCharTargetIndex, QuoteChar, m_separatorIndexTracker[QuoteChar]);
                    }
                }
                else
                {
                    // First, look for comments, if we're starting one of those that superceeds everything else
                    for (int index = 0; index < commentStartChars.Count; ++index)
                    {
                        char commentStart = commentStartChars[index];
                        if (charInQuestion == commentStart)
                        {
                            string commentStr = rules.CommentIndicators[index].Item1;
                            string subStr     = text.Substring(currCharTargetIndex, commentStr.Length);
                            if (subStr == commentStr)
                            {
                                targetCommentEnd = rules.CommentIndicators[index].Item2;
                                break;
                            }
                        }
                    }

                    // Second look for separators, that's the main goal!
                    if (targetCommentEnd == null)
                    {
                        foreach (var kvp in m_separatorIndexTracker)
                        {
                            if (kvp.Key == charInQuestion)
                            {
                                // Additionally, keep track of the separator is a quote, because in that case we need to ignore
                                //  everything until the end quote, so we need to go into quote searching mode.
                                if (kvp.Key == QuoteChar)
                                {
                                    isBetweenQuoteStartAndEnd = true;
                                }

                                _StoreFoundSeparators(currCharTargetIndex, charInQuestion, kvp.Value);
                                break;
                            }
                        }
                    }
                }
            }

            // Note: We're looping in order, thus all of our add calls will be putting items in index order
            //          without having to do binary searches so we'll just call add
            void _StoreFoundSeparators(int _characterIndex, char _separator, List <int> _separatorIndexTracker)
            {
                m_separatorOccurenceTracker.Add(new FoundSeparator(_characterIndex, _separator));
                _separatorIndexTracker.Add(_characterIndex);
            }
        }
예제 #4
0
 /// <summary>
 /// Parses the text from the passed in <see cref="TrackedStringManager"/>, and returns a non-<c>null</c> <see cref="Json"/> instance.
 /// </summary>
 /// <param name="jsonText">Some json text.</param>
 /// <param name="rules">Parser rules</param>
 /// <returns>A non-<c>null</c> <see cref="Json"/> instance</returns>
 public static Json ParseText(TrackedStringManager source, ParserRules rules = null)
 {
     return(RunParse(source, rules));
 }
예제 #5
0
 /// <summary>
 /// Parses the passed in text, and returns a non-<c>null</c> <see cref="Json"/> instance.
 /// </summary>
 /// <param name="jsonText">Some json text.</param>
 /// <param name="rules">Parser rules</param>
 /// <returns>A non-<c>null</c> <see cref="Json"/> instance</returns>
 public static Json ParseText(string jsonText, ParserRules rules = null)
 {
     return(RunParse(new TrackedStringManager(jsonText), rules));
 }
예제 #6
0
 /// <summary>
 /// Parses the text from an existing <see cref="FileTextTracker"/> file, and returns a non-<c>null</c> <see cref="Json"/> instance.
 /// </summary>
 /// <param name="file">A pre-made <see cref="FileTextTracker"/> to parse the contents of. Note: Will act as the returned <see cref="Json"/> instnace's TextTracking.</param>
 /// <param name="rules">Parser rules</param>
 /// <returns>A non-<c>null</c> <see cref="Json"/> instance</returns>
 public static Json ParseFile(FileTextTracker file, ParserRules rules = null)
 {
     return(RunParse(file, rules));
 }