2022-12-05 18:29:49 +08:00

177 lines
6.7 KiB
C#

using System;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
public static class EncoderUtils
{
public static string FromBase64ZlibCompressedString(string text)
{
if (text == null)
return (string)null;
using (StringReaderStream stringReaderStream = new StringReaderStream(text, Encoding.ASCII))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)stringReaderStream, (ICryptoTransform)new FromBase64Transform(), CryptoStreamMode.Read))
{
cryptoStream.ReadByte();
cryptoStream.ReadByte();
using (DeflateStream deflateStream = new DeflateStream((Stream)cryptoStream, CompressionMode.Decompress, true))
{
using (StreamReader streamReader = new StreamReader((Stream)deflateStream, Encoding.ASCII))
return streamReader.ReadToEnd();
}
}
}
}
public static byte[] FromBase64String(string text) => text == null ? (byte[])null : Convert.FromBase64String(text);
public static string ToBase64String(byte[] bytes) => bytes == null ? (string)null : Convert.ToBase64String(bytes);
public static string ToBase64GzipString(Action<GZipStream> writeAction)
{
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)stream, (ICryptoTransform)new ToBase64Transform(), CryptoStreamMode.Write))
{
using (GZipStream gzipStream = new GZipStream((Stream)cryptoStream, CompressionMode.Compress, true))
writeAction(gzipStream);
cryptoStream.FlushFinalBlock();
return EncoderUtils.MemoryStreamToString(stream, Encoding.ASCII);
}
}
}
public static string FromBase64GzipString(string text) => EncoderUtils.UncompressGzipToString(EncoderUtils.FromBase64String(text));
public static byte[] ToGzipBytes(Action<GZipStream> writeAction)
{
using (MemoryStream stream = new MemoryStream())
{
using (GZipStream gzipStream = new GZipStream((Stream)stream, CompressionMode.Compress, true))
writeAction(gzipStream);
return EncoderUtils.MemoryStreamToByteArray(stream);
}
}
public static string ToBase64GzipString(string str, Encoding encoding = null) => str == null ? (string)null : EncoderUtils.ToBase64GzipString((Action<GZipStream>)(s => EncoderUtils.WriteStringToStream(str, (Stream)s, encoding)));
public static byte[] ToGzipBytes(string str, Encoding encoding = null) => str == null ? (byte[])null : EncoderUtils.ToGzipBytes((Action<GZipStream>)(s => EncoderUtils.WriteStringToStream(str, (Stream)s, encoding)));
public static void WriteStringToStream(string str, Stream stream, Encoding encoding = null)
{
using (StreamWriter streamWriter = encoding == null ? new StreamWriter(stream) : new StreamWriter(stream, encoding))
streamWriter.Write(str);
}
public static void UncompressGzipToStream(byte[] bytes, Stream stream)
{
if (bytes == null)
return;
using (MemoryStream memoryStream = new MemoryStream(bytes))
{
using (GZipStream gzipStream = new GZipStream((Stream)memoryStream, CompressionMode.Decompress))
gzipStream.CopyTo(stream);
}
}
public static string UncompressGzipToString(byte[] bytes)
{
if (bytes == null)
return (string)null;
using (MemoryStream stream = new MemoryStream())
{
EncoderUtils.UncompressGzipToStream(bytes, (Stream)stream);
return EncoderUtils.MemoryStreamToString(stream);
}
}
public static string StreamToString(Stream stream, Encoding encoding = null)
{
if (stream == null)
return (string)null;
using (StreamReader streamReader = encoding == null ? new StreamReader(stream) : new StreamReader(stream, encoding))
return streamReader.ReadToEnd();
}
public static string MemoryStreamToString(MemoryStream stream, Encoding encoding = null)
{
if (stream == null)
return (string)null;
stream.Position = 0L;
return EncoderUtils.StreamToString((Stream)stream, encoding);
}
public static byte[] MemoryStreamToByteArray(MemoryStream stream)
{
if (stream == null)
return (byte[])null;
stream.Position = 0L;
using (BinaryReader binaryReader = new BinaryReader((Stream)stream))
return binaryReader.ReadBytes((int)stream.Length);
}
}
public class StringReaderStream : Stream
{
private string input;
private readonly Encoding encoding;
private int maxBytesPerChar;
private int inputLength;
private int inputPosition;
private readonly long length;
private long position;
public StringReaderStream(string input)
: this(input, Encoding.UTF8)
{
}
public StringReaderStream(string input, Encoding encoding)
{
this.encoding = encoding ?? throw new ArgumentNullException(nameof(encoding));
this.input = input;
this.inputLength = input == null ? 0 : input.Length;
if (!string.IsNullOrEmpty(input))
this.length = (long)encoding.GetByteCount(input);
this.maxBytesPerChar = encoding == Encoding.ASCII ? 1 : encoding.GetMaxByteCount(1);
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => this.length;
public override long Position
{
get => this.position;
set => throw new NotImplementedException();
}
public override void Flush()
{
}
public override int Read(byte[] buffer, int offset, int count)
{
if (this.inputPosition >= this.inputLength)
return 0;
if (count < this.maxBytesPerChar)
throw new ArgumentException("count has to be greater or equal to max encoding byte count per char");
int charCount = Math.Min(this.inputLength - this.inputPosition, count / this.maxBytesPerChar);
int bytes = this.encoding.GetBytes(this.input, this.inputPosition, charCount, buffer, offset);
this.inputPosition += charCount;
this.position += (long)bytes;
return bytes;
}
public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
public override void SetLength(long value) => throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
}