| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- 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();
- }
- }
- }
- }
|