// Copyright Epic Games, Inc. All Rights Reserved. using System.Buffers; using System.Text.Json; using System.Text.Json.Nodes; using EpicGames.Core; namespace HordeAgent.Utility { using JsonObject = System.Text.Json.Nodes.JsonObject; /// /// Utility class for making localized changes to JSON config files /// static class JsonConfig { /// /// Read a JSON config file from disk /// public static async Task ReadAsync(FileReference file) { byte[] data = await FileReference.ReadAllBytesAsync(file); JsonObject? obj = JsonNode.Parse(data, new JsonNodeOptions { PropertyNameCaseInsensitive = true }, new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }) as JsonObject; return obj ?? new JsonObject(); } /// /// Writes the config file to disk /// public static async Task WriteAsync(FileReference file, JsonObject root) { ArrayBufferWriter buffer = new ArrayBufferWriter(); using (Utf8JsonWriter writer = new Utf8JsonWriter(buffer, new JsonWriterOptions { Indented = true })) { root.WriteTo(writer); } await FileReference.WriteAllBytesAsync(file, buffer.WrittenMemory.ToArray()); } /// /// Read a node by name /// public static T FindOrAddNode(JsonObject obj, string name, Func factory) where T : JsonNode { JsonNode? node = obj[name]; if (node != null) { if (node is T existingTypedNode) { return existingTypedNode; } else { obj.Remove(name); } } T newTypedNode = factory(); obj.Add(name, newTypedNode); return newTypedNode; } /// /// Find or adds an array element with a particular key /// public static JsonObject FindOrAddElementByKey(JsonArray array, string key, string name) { foreach (JsonNode? element in array) { if (element is JsonObject obj) { JsonNode? node = obj[key]; if (node != null && (string?)node.AsValue() == name) { return obj; } } } JsonObject newObj = new JsonObject(); newObj[key] = name; array.Add(newObj); return newObj; } } }