aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjduncanator <1518948+jduncanator@users.noreply.github.com>2020-03-26 08:33:18 +1100
committerGitHub <noreply@github.com>2020-03-26 08:33:18 +1100
commit82c3df83c43b32510927b7fa710eeb099067ed2e (patch)
tree437e51bfa9a2ea0cb7bfa4564730b8c9f22e839a
parent5423daea56345237cd10e02870139143d5922aa2 (diff)
prepo: Add a MessagePack object formatter (#1034)
-rw-r--r--Ryujinx.Common/Ryujinx.Common.csproj1
-rw-r--r--Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs302
-rw-r--r--Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs5
3 files changed, 305 insertions, 3 deletions
diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj
index 1b7cf8af..14f1b1e7 100644
--- a/Ryujinx.Common/Ryujinx.Common.csproj
+++ b/Ryujinx.Common/Ryujinx.Common.csproj
@@ -28,6 +28,7 @@
<ItemGroup>
<PackageReference Include="JsonPrettyPrinter" Version="1.0.1.1" />
+ <PackageReference Include="MsgPack.Cli" Version="1.0.1" />
<PackageReference Include="Utf8Json" Version="1.3.7" /><PackageReference Include="OpenTK.NetStandard" Version="1.0.5.12" />
<PackageReference Include="SharpFontCore" Version="0.1.1" />
</ItemGroup>
diff --git a/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs b/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs
new file mode 100644
index 00000000..3714bec0
--- /dev/null
+++ b/Ryujinx.Common/Utilities/MessagePackObjectFormatter.cs
@@ -0,0 +1,302 @@
+using MsgPack;
+using System;
+using System.Text;
+
+namespace Ryujinx.Common.Utilities
+{
+ public static class MessagePackObjectFormatter
+ {
+ public static string ToString(this MessagePackObject obj, bool pretty)
+ {
+ if (pretty)
+ {
+ return Format(obj);
+ }
+ else
+ {
+ return obj.ToString();
+ }
+ }
+
+ public static string Format(MessagePackObject obj)
+ {
+ var builder = new IndentedStringBuilder();
+
+ FormatMsgPackObj(obj, builder);
+
+ return builder.ToString();
+ }
+
+ private static void FormatMsgPackObj(MessagePackObject obj, IndentedStringBuilder builder)
+ {
+ if (obj.IsMap || obj.IsDictionary)
+ {
+ FormatMsgPackMap(obj, builder);
+ }
+ else if (obj.IsArray || obj.IsList)
+ {
+ FormatMsgPackArray(obj, builder);
+ }
+ else if (obj.IsNil)
+ {
+ builder.Append("null");
+ }
+ else
+ {
+ var literal = obj.ToObject();
+
+ if (literal is String)
+ {
+ builder.AppendQuotedString(obj.AsStringUtf16());
+ }
+ else if (literal is byte[] byteArray)
+ {
+ FormatByteArray(byteArray, builder);
+ }
+ else if (literal is MessagePackExtendedTypeObject extObject)
+ {
+ builder.Append('{');
+
+ // Indent
+ builder.IncreaseIndent()
+ .AppendLine();
+
+ // Print TypeCode field
+ builder.AppendQuotedString("TypeCode")
+ .Append(": ")
+ .Append(extObject.TypeCode)
+ .AppendLine(",");
+
+ // Print Value field
+ builder.AppendQuotedString("Value")
+ .Append(": ");
+
+ FormatByteArrayAsString(extObject.GetBody(), builder, true);
+
+ // Unindent
+ builder.DecreaseIndent()
+ .AppendLine();
+
+ builder.Append('}');
+ }
+ else
+ {
+ builder.Append(literal);
+ }
+ }
+ }
+
+ private static void FormatByteArray(byte[] arr, IndentedStringBuilder builder)
+ {
+ builder.Append("[ ");
+
+ foreach (var b in arr)
+ {
+ builder.Append("0x");
+ builder.Append(ToHexChar(b >> 4));
+ builder.Append(ToHexChar(b & 0xF));
+ builder.Append(", ");
+ }
+
+ // Remove trailing comma
+ builder.Remove(builder.Length - 2, 2);
+
+ builder.Append(" ]");
+ }
+
+ private static void FormatByteArrayAsString(byte[] arr, IndentedStringBuilder builder, bool withPrefix)
+ {
+ builder.Append('"');
+
+ if (withPrefix)
+ {
+ builder.Append("0x");
+ }
+
+ foreach (var b in arr)
+ {
+ builder.Append(ToHexChar(b >> 4));
+ builder.Append(ToHexChar(b & 0xF));
+ }
+
+ builder.Append('"');
+ }
+
+ private static void FormatMsgPackMap(MessagePackObject obj, IndentedStringBuilder builder)
+ {
+ var map = obj.AsDictionary();
+
+ builder.Append('{');
+
+ // Indent
+ builder.IncreaseIndent()
+ .AppendLine();
+
+ foreach (var item in map)
+ {
+ FormatMsgPackObj(item.Key, builder);
+
+ builder.Append(": ");
+
+ FormatMsgPackObj(item.Value, builder);
+
+ builder.AppendLine(",");
+ }
+
+ // Remove the trailing new line and comma
+ builder.TrimLastLine()
+ .Remove(builder.Length - 1, 1);
+
+ // Unindent
+ builder.DecreaseIndent()
+ .AppendLine();
+
+ builder.Append('}');
+ }
+
+ private static void FormatMsgPackArray(MessagePackObject obj, IndentedStringBuilder builder)
+ {
+ var arr = obj.AsList();
+
+ builder.Append("[ ");
+
+ foreach (var item in arr)
+ {
+ FormatMsgPackObj(item, builder);
+
+ builder.Append(", ");
+ }
+
+ // Remove trailing comma
+ builder.Remove(builder.Length - 2, 2);
+
+ builder.Append(" ]");
+ }
+
+ private static char ToHexChar(int b)
+ {
+ if (b < 10)
+ {
+ return unchecked((char)('0' + b));
+ }
+ else
+ {
+ return unchecked((char)('A' + (b - 10)));
+ }
+ }
+
+ internal class IndentedStringBuilder
+ {
+ const string DefaultIndent = " ";
+
+ private int _indentCount = 0;
+ private int _newLineIndex = 0;
+ private StringBuilder _builder;
+
+ public string IndentString { get; set; } = DefaultIndent;
+
+ public IndentedStringBuilder(StringBuilder builder)
+ {
+ _builder = builder;
+ }
+
+ public IndentedStringBuilder()
+ : this(new StringBuilder())
+ { }
+
+ public IndentedStringBuilder(string str)
+ : this(new StringBuilder(str))
+ { }
+
+ public IndentedStringBuilder(int length)
+ : this(new StringBuilder(length))
+ { }
+
+ public int Length { get => _builder.Length; }
+
+ public IndentedStringBuilder IncreaseIndent()
+ {
+ _indentCount++;
+
+ return this;
+ }
+
+ public IndentedStringBuilder DecreaseIndent()
+ {
+ _indentCount--;
+
+ return this;
+ }
+
+ public IndentedStringBuilder Append(char value)
+ {
+ _builder.Append(value);
+
+ return this;
+ }
+
+ public IndentedStringBuilder Append(string value)
+ {
+ _builder.Append(value);
+
+ return this;
+ }
+
+ public IndentedStringBuilder Append(object value)
+ {
+ this.Append(value.ToString());
+
+ return this;
+ }
+
+ public IndentedStringBuilder AppendQuotedString(string value)
+ {
+ _builder.Append('"');
+ _builder.Append(value);
+ _builder.Append('"');
+
+ return this;
+ }
+
+ public IndentedStringBuilder AppendLine()
+ {
+ _newLineIndex = _builder.Length;
+
+ _builder.AppendLine();
+
+ for (int i = 0; i < _indentCount; i++)
+ _builder.Append(IndentString);
+
+ return this;
+ }
+
+ public IndentedStringBuilder AppendLine(string value)
+ {
+ _builder.Append(value);
+
+ this.AppendLine();
+
+ return this;
+ }
+
+ public IndentedStringBuilder TrimLastLine()
+ {
+ _builder.Remove(_newLineIndex, _builder.Length - _newLineIndex);
+
+ return this;
+ }
+
+ public IndentedStringBuilder Remove(int startIndex, int length)
+ {
+ _builder.Remove(startIndex, length);
+
+ return this;
+ }
+
+ public override string ToString()
+ {
+ return _builder.ToString();
+ }
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs b/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs
index c6a6ac56..32a5950d 100644
--- a/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs
+++ b/Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs
@@ -2,11 +2,10 @@ using MsgPack;
using MsgPack.Serialization;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
+using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.Utilities;
-using System.IO;
using System.Text;
-using Utf8Json;
namespace Ryujinx.HLE.HOS.Services.Prepo
{
@@ -117,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Prepo
}
builder.AppendLine($" Room: {room}");
- builder.AppendLine($" Report: {deserializedReport}");
+ builder.AppendLine($" Report: {MessagePackObjectFormatter.Format(deserializedReport)}");
return builder.ToString();
}