177 lines
6.7 KiB
C#
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();
|
|
} |