using System.IO;

using System.IO.Compression;

using System.Text;


struct DeflateUTF8

{

    string msg; byte[] zip;

    public static implicit operator DeflateUTF8(string msg) => new() { msg = msg, zip = Compress(e.GetBytes(msg)) };

    public static implicit operator DeflateUTF8(byte[] zip) => new() { zip = zip, msg = e.GetString(Decompress(zip)) };

    public static implicit operator string(DeflateUTF8 c) => c.msg;

    public static implicit operator byte[](DeflateUTF8 c) => c.zip;

    public override string ToString() => msg;


    static readonly Encoding e = Encoding.UTF8;

    static byte[] Compress(byte[] data)

    {

        using MemoryStream output = new();

        using (DeflateStream dstream = new(output, CompressionLevel.Optimal))

            dstream.Write(data);

        return output.ToArray();

    }

    static byte[] Decompress(byte[] data)

    {

        using MemoryStream output = new(), input = new(data);

        using (DeflateStream dstream = new(input, CompressionMode.Decompress))

            dstream.CopyTo(output);

        return output.ToArray();

    }

}


struct BrotliUTF8

{

    string msg; byte[] zip;

    public static implicit operator BrotliUTF8(string msg) => new() { msg = msg, zip = Compress(e.GetBytes(msg)) };

    public static implicit operator BrotliUTF8(byte[] zip) => new() { zip = zip, msg = e.GetString(Decompress(zip)) };

    public static implicit operator string(BrotliUTF8 c) => c.msg;

    public static implicit operator byte[](BrotliUTF8 c) => c.zip;

    public override string ToString() => msg;


    static readonly Encoding e = Encoding.UTF8;

    static byte[] Compress(byte[] data)

    {

        using MemoryStream output = new();

        using (BrotliStream dstream = new(output, CompressionLevel.Optimal))

            dstream.Write(data);

        return output.ToArray();

    }

    static byte[] Decompress(byte[] data)

    {

        using MemoryStream output = new(), input = new(data);

        using (BrotliStream dstream = new(input, CompressionMode.Decompress))

            dstream.CopyTo(output);

        return output.ToArray();

    }

}


코드갖다씀 : https://stackoverflow.com/questions/39191950/how-to-compress-a-byte-array-without-stream-or-system-io


별도의 타입으로 만들어주고서 캐스팅을 통해 인코딩및 압축/해제를 암시하게된다.

좀더 리팩토링 하고싶은데 일단 나중으로 미룸.


테스트 해보니 아주 짧은 문자열을 제외하고는 Deflate보다 Brotli가 압축률이 확실히 좋은듯 함.

JSON이라던가 반복해서 쓰는 문자가 정해져있어서 그런지 압축률이 디게 좋은데 인제 TCP로 JSON주고받을때, 어차피 유효성검사는 TCP가 해주고, 압축을 안할 이유가 없는듯 함.


아예 genericType - serializing - encoding - compress 전체를 타입캐스팅으로 묶어버리는건 어떨까 싶은데, json만들때 옵셔널한부분이 많아 코드한줄로 퉁치기는 어려우니 뇌절선을 잘 맞춰봐야될듯


기존에 올린것들 github gist로 만들지 고민중.