//
// Copyright (c) Scratch Foundation. All rights reserved.
//
namespace ScratchLink;
using System.Text;
using System.Text.Json;
using ScratchLink.JsonRpc;
///
/// Helpers for interacting with Scratch Link's message buffers.
/// A Scratch Link message buffer has a message property and optionally an encoding property.
/// If the encoding property is missing, null, or empty, the message is a Unicode string.
/// If the encoding property is "base64" then the message is a string in Base64 format.
/// No other encodings are supported at this time.
///
public static class EncodingHelpers
{
///
/// Decode the "message" property of into bytes.
/// If has an "encoding" property, use that encoding.
/// Otherwise, assume the message is Unicode text.
///
/// A JSON object containing a "message" property and optionally an "encoding" property.
/// An array of bytes containing the decoded data.
/// Thrown if the "message" property is missing or the message could not be decoded.
public static byte[] DecodeBuffer(JsonElement jsonBuffer)
{
if (!jsonBuffer.TryGetProperty("message", out var jsonMessage) || jsonMessage.ValueKind != JsonValueKind.String)
{
throw new JsonRpc2Exception(JsonRpc2Error.InvalidParams("missing or invalid 'message' property"));
}
jsonBuffer.TryGetProperty("encoding", out var encoding);
if (encoding.ValueEquals("base64"))
{
if (jsonMessage.TryGetBytesFromBase64(out var messageBytes))
{
return messageBytes;
}
throw new JsonRpc2Exception(JsonRpc2Error.ParseError("failed to parse base64 message"));
}
else if (encoding.ValueKind == JsonValueKind.Undefined || encoding.ValueKind == JsonValueKind.Null)
{
// message is a Unicode string with no additional encoding
return Encoding.UTF8.GetBytes(jsonMessage.GetString());
}
throw new JsonRpc2Exception(JsonRpc2Error.InvalidParams($"unsupported encoding: {encoding}"));
}
///
/// Encode using and return the result as a string.
///
/// The bytes to encode.
/// The encoding format, or null to "encode" UTF-8 data as a Unicode string.
/// A string containing the encoded data.
/// Thrown if the data could not be encoded, including if the encoding is not supported.
public static string EncodeBuffer(byte[] data, string encoding)
{
switch (encoding)
{
case "base64":
return Convert.ToBase64String(data);
case null:
return Encoding.UTF8.GetString(data);
default:
throw new JsonRpc2Exception(JsonRpc2Error.InvalidParams($"unsupported encoding: {encoding}"));
}
}
}