JsonHelper.cs
1 using System.IO; 2 using System.Text; 3 using System.Text.Json; 4 using System.Text.Json.Serialization.Metadata; 5 6 namespace Ryujinx.Common.Utilities 7 { 8 public class JsonHelper 9 { 10 private static readonly JsonNamingPolicy _snakeCasePolicy = new SnakeCaseNamingPolicy(); 11 private const int DefaultFileWriteBufferSize = 4096; 12 13 /// <summary> 14 /// Creates new serializer options with default settings. 15 /// </summary> 16 /// <remarks> 17 /// It is REQUIRED for you to save returned options statically or as a part of static serializer context 18 /// in order to avoid performance issues. You can safely modify returned options for your case before storing. 19 /// </remarks> 20 public static JsonSerializerOptions GetDefaultSerializerOptions(bool indented = true) 21 { 22 JsonSerializerOptions options = new() 23 { 24 DictionaryKeyPolicy = _snakeCasePolicy, 25 PropertyNamingPolicy = _snakeCasePolicy, 26 WriteIndented = indented, 27 AllowTrailingCommas = true, 28 ReadCommentHandling = JsonCommentHandling.Skip, 29 }; 30 31 return options; 32 } 33 34 public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) 35 { 36 return JsonSerializer.Serialize(value, typeInfo); 37 } 38 39 public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) 40 { 41 return JsonSerializer.Deserialize(value, typeInfo); 42 } 43 44 public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo) 45 { 46 using FileStream file = File.Create(filePath, DefaultFileWriteBufferSize, FileOptions.WriteThrough); 47 JsonSerializer.Serialize(file, value, typeInfo); 48 } 49 50 public static T DeserializeFromFile<T>(string filePath, JsonTypeInfo<T> typeInfo) 51 { 52 using FileStream file = File.OpenRead(filePath); 53 return JsonSerializer.Deserialize(file, typeInfo); 54 } 55 56 public static void SerializeToStream<T>(Stream stream, T value, JsonTypeInfo<T> typeInfo) 57 { 58 JsonSerializer.Serialize(stream, value, typeInfo); 59 } 60 61 private class SnakeCaseNamingPolicy : JsonNamingPolicy 62 { 63 public override string ConvertName(string name) 64 { 65 if (string.IsNullOrEmpty(name)) 66 { 67 return name; 68 } 69 70 StringBuilder builder = new(); 71 72 for (int i = 0; i < name.Length; i++) 73 { 74 char c = name[i]; 75 76 if (char.IsUpper(c)) 77 { 78 if (i == 0 || char.IsUpper(name[i - 1])) 79 { 80 builder.Append(char.ToLowerInvariant(c)); 81 } 82 else 83 { 84 builder.Append('_'); 85 builder.Append(char.ToLowerInvariant(c)); 86 } 87 } 88 else 89 { 90 builder.Append(c); 91 } 92 } 93 94 return builder.ToString(); 95 } 96 } 97 } 98 }