Exemple #1
0
        public static bool TryToRestoreDamagedJsonFile(string filename, JObjectRestorationScheme scheme) {
            var data = File.ReadAllText(filename);
            var jObject = JsonExtension.TryToRestore(data, scheme);
            if (jObject == null) return false;

            FileUtils.Recycle(filename);
            File.WriteAllText(filename, jObject.ToString());
            return true;
        }
Exemple #2
0
        public static JObject TryToRestore([LocalizationRequired(false)] string damagedJson, JObjectRestorationScheme scheme)
        {
            var result = new JObject();

            var input = Regex.Replace(damagedJson, @"\r?\n|\n", "\n").Trim();

            foreach (var field in scheme.Fields)
            {
                var match = Regex.Match(input, $@"(?:""\s*{field.Name}\s*""|'\s*{field.Name}\s*'|{field.Name})\s*:\s*([\s\S]+)");
                if (!match.Success)
                {
                    continue;
                }

                var value = match.Groups[1].Value.Trim();

                if (!field.IsMultiline)
                {
                    value = value.Split('\n')[0];
                    value = Regex.Replace(value, @"\s*,?\s*(""\s*\w+\s*""|'\s*\w+\s*'|\w+)\s*:[\s\S]+|\s*}", "");
                }

                value = Regex.Replace(value, @"(?:\n?\s*,?\s*(""\s*\w+\s*""|'\s*\w+\s*'|\w+)\s*:|\s*})[\s\S]*$", "");
                value = Regex.Replace(value.Trim(), @",$", "");

                JToken processedValue;

                if (value == "null")
                {
                    processedValue = null;
                }
                else
                {
                    switch (field.Type)
                    {
                    case JObjectRestorationScheme.FieldType.String:
                    case JObjectRestorationScheme.FieldType.NonNullString:
                    case JObjectRestorationScheme.FieldType.StringMultiline:
                        processedValue = DequoteString(value);
                        break;

                    case JObjectRestorationScheme.FieldType.Number:
                        var doubleValue = FlexibleParser.ParseDouble(value);
                        if (Equals(doubleValue % 1.0, 0.0))
                        {
                            processedValue = (long)doubleValue;
                        }
                        else
                        {
                            processedValue = doubleValue;
                        }
                        break;

                    case JObjectRestorationScheme.FieldType.Boolean:
                        processedValue = Regex.IsMatch(value, @"\b(true|on|yes|1)\b", RegexOptions.IgnoreCase);
                        break;

                    case JObjectRestorationScheme.FieldType.StringsArray:
                        processedValue = new JArray(
                            Regex.Split(value, @"^\s*\[|(?<!\\)""\s*,?\s*""|\s*(?:,\s*\n|\n\s*,?)\s*|\]\s*$")
                            .Select(DequoteString)
                            .Where(x => x.Length > 0 && x != "[" && x != "]")
                            .Cast <object>().ToArray());
                        break;

                    case JObjectRestorationScheme.FieldType.PairsArray:
                        processedValue = new JArray(
                            Regex.Split(value, @"^\s*\[|(?<!\\)""\s*\]?\s*,\s*\[??\s*""|\s*\]?\s*(?:,\s*\n|\n\s*,?)\s*\[?\s*|\]\s*$")
                            .Select(DequoteString)
                            .Where(x => x.Length > 0 && x != "[" && x != "]")
                            .Partition(2)
                            .Where(x => x.Length == 2)
                            .Select(x => new JArray(x.ToArray <object>()))
                            .Cast <object>().ToArray());
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                if (field.ParentName != null)
                {
                    if (!(result[field.ParentName] is JObject obj))
                    {
                        result[field.ParentName] = obj = new JObject();
                    }

                    obj[field.Name] = processedValue;
                }
                else
                {
                    result[field.Name] = processedValue;
                }
            }

            foreach (var field in scheme.Fields.Where(x => x.Type == JObjectRestorationScheme.FieldType.NonNullString && !result.TryGetValue(x.Name, out _)))
            {
                if (field.ParentName != null)
                {
                    if (!(result[field.ParentName] is JObject obj))
                    {
                        result[field.ParentName] = obj = new JObject();
                    }

                    obj[field.Name] = "";
                }
                else
                {
                    result[field.Name] = "";
                }
            }

            return(result);
        }
Exemple #3
0
        public static JObject TryToRestore([LocalizationRequired(false)] string damagedJson, JObjectRestorationScheme scheme) {
            var result = new JObject();

            var input = Regex.Replace(damagedJson, @"\r?\n|\n", "\n").Trim();
            foreach (var field in scheme.Fields) {
                var match = Regex.Match(input, $@"(?:""\s*{field.Name}\s*""|'\s*{field.Name}\s*'|{field.Name})\s*:\s*([\s\S]+)");
                if (!match.Success) continue;

                var value = match.Groups[1].Value.Trim();

                if (!field.IsMultiline) {
                    value = value.Split('\n')[0];
                    value = Regex.Replace(value, @"\s*,?\s*(""\s*\w+\s*""|'\s*\w+\s*'|\w+)\s*:[\s\S]+|\s*}", "");
                }

                value = Regex.Replace(value, @"(?:\n?\s*,?\s*(""\s*\w+\s*""|'\s*\w+\s*'|\w+)\s*:|\s*})[\s\S]*$", "");
                value = Regex.Replace(value.Trim(), @",$", "");

                JToken processedValue;

                if (value == "null") {
                    processedValue = null;
                } else {
                    switch (field.Type) {
                        case JObjectRestorationScheme.FieldType.String:
                        case JObjectRestorationScheme.FieldType.NonNullString:
                        case JObjectRestorationScheme.FieldType.StringMultiline:
                            processedValue = DequoteString(value);
                            break;

                        case JObjectRestorationScheme.FieldType.Number:
                            var doubleValue = FlexibleParser.ParseDouble(value);
                            if (Equals(doubleValue % 1.0, 0.0)) {
                                processedValue = (long)doubleValue;
                            } else {
                                processedValue = doubleValue;
                            }
                            break;

                        case JObjectRestorationScheme.FieldType.Boolean:
                            processedValue = Regex.IsMatch(value, @"\b(true|on|yes|1)\b", RegexOptions.IgnoreCase);
                            break;

                        case JObjectRestorationScheme.FieldType.StringsArray:
                            processedValue = new JArray(
                                    Regex.Split(value, @"^\s*\[|(?<!\\)""\s*,?\s*""|\s*(?:,\s*\n|\n\s*,?)\s*|\]\s*$")
                                         .Select(DequoteString)
                                         .Where(x => x.Length > 0 && x != "[" && x != "]")
                                         .Cast<object>().ToArray());
                            break;

                        case JObjectRestorationScheme.FieldType.PairsArray:
                            processedValue = new JArray(
                                    Regex.Split(value, @"^\s*\[|(?<!\\)""\s*\]?\s*,\s*\[??\s*""|\s*\]?\s*(?:,\s*\n|\n\s*,?)\s*\[?\s*|\]\s*$")
                                         .Select(DequoteString)
                                         .Where(x => x.Length > 0 && x != "[" && x != "]")
                                         .Partition(2)
                                         .Where(x => x.Length == 2)
                                         .Select(x => new JArray(x.Cast<object>().ToArray()))
                                         .Cast<object>().ToArray());
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }

                if (field.ParentName != null) {
                    var obj = result[field.ParentName] as JObject;
                    if (obj == null) {
                        result[field.ParentName] = obj = new JObject();
                    }

                    obj[field.Name] = processedValue;
                } else {
                    result[field.Name] = processedValue;
                }
            }

            JToken temp;
            foreach (var field in scheme.Fields.Where(x => x.Type == JObjectRestorationScheme.FieldType.NonNullString && !result.TryGetValue(x.Name, out temp))) {
                if (field.ParentName != null) {
                    var obj = result[field.ParentName] as JObject;
                    if (obj == null) {
                        result[field.ParentName] = obj = new JObject();
                    }

                    obj[field.Name] = "";
                } else {
                    result[field.Name] = "";
                }
            }

            return result;
        }