public static void WriteCompressedData <TStream, TObject>(this TStream stream, TObject encodingSwitch, IEnumerator <TObject> enumerator, TextCompressionMethods tMethod, ByteCompressionMethods bMethod = ByteCompressionMethods.None, Dictionary <TObject, BitCode64> dictionary = null, int predictCount = 0) where TStream : Stream, IBitStream { if (bMethod != ByteCompressionMethods.None) { var ms = new MemoryStream(); var bs = new ForwardBitStream(ms, false); bs._innerWriteCompressedData <ForwardBitStream, TObject> (enumerator, encodingSwitch, tMethod, dictionary, predictCount); bs.Flush(); var buffer = ms.ToArray().Compress(ref bMethod); byte algTag = 0; algTag = algTag.SetBitsAtLeft(4, (byte)tMethod); algTag = algTag.SetBitsAtRight(4, (byte)bMethod); stream.WriteByte(algTag); if (bMethod == ByteCompressionMethods.None) { stream.WriteBytes(buffer); } else { stream.WriteByteArray(buffer); } } else { byte algTag = 0; algTag = algTag.SetBitsAtLeft(4, (byte)tMethod); algTag = algTag.SetBitsAtRight(4, (byte)bMethod); stream.WriteByte(algTag); stream._innerWriteCompressedData <TStream, TObject> (enumerator, encodingSwitch, tMethod, dictionary, predictCount); } }
/// <summary> /// Writes a string instance to this stream. /// </summary> /// <param name="stream">The stream to write to.</param> /// <param name="str">The System.String object.</param> /// <param name="encoder">The character encoding for the string.</param> /// <param name="compressionMethod">The compression algorithm used to compress the string.</param> /// <param name="headCompression">Indicates whether to compress the head section.</param> /// <param name="validityCheck">Indicates whether to write /// a validity-check code before the string.</param> public static void WriteString(this Stream stream, string str, Encoding encoder = null, ByteCompressionMethods compressionMethod = ByteCompressionMethods.None, bool headCompression = false, bool validityCheck = false) { if (validityCheck) { stream.WriteCheckCode((Int64)17); } if (str.IsNullOrEmpty()) { stream.WriteByte(byte.MaxValue); return; } if (encoder == null) { encoder = _bestEncoder(str); } byte[] b = encoder.GetBytes(str); b = b.Compress(ref compressionMethod); byte para = (byte)compressionMethod; if (headCompression) { byte cp = _getCP(encoder); if (b.Length <= byte.MaxValue) { stream.WriteByte((byte)(para.SetBitOne(6) | cp)); stream.WriteByte((byte)b.Length); } else if (b.Length <= UInt16.MaxValue) { stream.WriteByte((byte)(para.SetBitOne(7) | cp)); stream.WriteUInt16((UInt16)b.Length); } else if (b.Length <= Int32.MaxValue) { stream.WriteByte((byte)(para | cp)); stream.WriteUInt32((UInt32)b.Length); } else { throw (new ArgumentException(IOResources.ERR_Text4GLimit)); } if (cp == 0x00) { stream.WriteUInt16((UInt16)encoder.CodePage); } } else if (b.Length <= Int32.MaxValue) { stream.WriteByte(para); stream.WriteUInt32((UInt32)b.Length); stream.WriteUInt16((UInt16)encoder.CodePage); } else { throw (new ArgumentException(IOResources.ERR_Text4GLimit)); } stream.WriteBytes(b); }
public unsafe static void WriteString(this Stream stream, string str, int startIndex, int length, Encoding encoder = null, ByteCompressionMethods compressionMethod = ByteCompressionMethods.None, bool metaCompression = false, bool validityCheck = false) { if (startIndex + length > str.Length) { throw new ArgumentException(); } if (validityCheck) { stream.WriteCheckCode((Int64)17); } if (str.IsNullOrEmpty()) { stream.WriteByte(byte.MaxValue); return; } if (encoder == null) { encoder = _bestEncoder(str, startIndex, length); fixed(char *sptr = str) { char *sptr2 = startIndex + sptr; var bcount = encoder.GetByteCount(sptr2, length); var b = new byte[bcount]; fixed(byte *bptr = b) encoder.GetBytes(sptr2, length, bptr, bcount); b = b.Compress(ref compressionMethod); byte para = (byte)compressionMethod; if (metaCompression) { byte cp = _getCP(encoder); if (b.Length <= byte.MaxValue) { stream.WriteByte((byte)(para.SetBitOneAt6() | cp)); stream.WriteByte((byte)b.Length); } else if (b.Length <= UInt16.MaxValue) { stream.WriteByte((byte)(para.SetBitOneAt7() | cp)); stream.WriteUInt16((UInt16)b.Length); } else if (b.Length <= Int32.MaxValue) { stream.WriteByte((byte)(para | cp)); stream.WriteUInt32((UInt32)b.Length); } else { throw (new ArgumentException(IOResources.ERR_Text4GLimit)); } if (cp == 0x00) { stream.WriteUInt16((UInt16)encoder.CodePage); } } else if (b.Length <= Int32.MaxValue) { stream.WriteByte(para); stream.WriteUInt32((UInt32)b.Length); stream.WriteUInt16((UInt16)encoder.CodePage); } else { throw (new ArgumentException(IOResources.ERR_Text4GLimit)); } stream.WriteBytes(b); } }
/// <summary> /// Compresses a byte array using a specified algorithm. /// </summary> /// <param name="dataToCompress">The byte array to compress.</param> /// <param name="startIndex">The zero-based position in the array where the compression begins.</param> /// <param name="algorithm">The algorithm used to compress the array. /// This method will check the compression rate after the compression is done, /// and if it is not smaller than 1 (indicating the "compressed" data takes even more space than the original data and the compression is ineffective), /// the original data will be returned and this argument will be set <c>ByteCompressionMethods.None</c>.</param> /// <returns> /// The compressed byte array if the compression is successful; /// or the bytes in the original byte array from <paramref name="startIndex"/> to the end if the compression is ineffective. /// </returns> public static byte[] Compress(this byte[] dataToCompress, int startIndex, ref ByteCompressionMethods algorithm) { byte[] compressedData; using (MemoryStream compressedMs = new MemoryStream()) { switch (algorithm) { case ByteCompressionMethods.GZipOptimal: { using (GZipStream gzs = new GZipStream(compressedMs, CompressionLevel.Optimal)) gzs.Write(dataToCompress, startIndex, dataToCompress.Length - startIndex); compressedData = compressedMs.ToArray(); break; } case ByteCompressionMethods.GZipFast: { using (GZipStream gzs = new GZipStream(compressedMs, CompressionLevel.Fastest)) gzs.Write(dataToCompress, startIndex, dataToCompress.Length - startIndex); compressedData = compressedMs.ToArray(); break; } case ByteCompressionMethods.DeflateOptimal: { using (DeflateStream ds = new DeflateStream(compressedMs, CompressionLevel.Optimal)) ds.Write(dataToCompress, startIndex, dataToCompress.Length - startIndex); compressedData = compressedMs.ToArray(); break; } case ByteCompressionMethods.DeflateFast: { using (DeflateStream ds = new DeflateStream(compressedMs, CompressionLevel.Fastest)) ds.Write(dataToCompress, startIndex, dataToCompress.Length - startIndex); compressedData = compressedMs.ToArray(); break; } default: { var tmpMs = new MemoryStream(dataToCompress, startIndex, dataToCompress.Length - startIndex); return(tmpMs.ToArray()); } } } if (compressedData.Length < dataToCompress.Length) { return(compressedData); } else { algorithm = ByteCompressionMethods.None; return(dataToCompress); } }
/// <summary> /// Compresses a byte array using a specified algorithm. /// </summary> /// <param name="dataToCompress">The byte array to compress.</param> /// <param name="algorithm">The algorithm used to compress the array. /// This method will check the compression rate after the compression is done, /// and if it is not smaller than 1 (indicating the "compressed" data takes even more space than the original data and the compression is ineffective), /// the original data will be returned and this argument will be set <c>ByteCompressionMethods.None</c>.</param> /// <returns> /// The compressed byte array if the compression is successful; /// or the original bytes if the compression is ineffective. /// </returns> public static byte[] Compress(this byte[] dataToCompress, ref ByteCompressionMethods algorithm) { return(Compress(dataToCompress, 0, ref algorithm)); }
/// <summary> /// Decompresses a byte array using a specified algorithm. /// </summary> /// <param name="dataToDecompress">The byte array to decompress.</param> /// <param name="startIndex">The zero-based position in the array where the decompression begins.</param> /// <param name="algorithm">The algorithm used to decompress the array.</param> /// <returns>The decompressed byte array.</returns> public static byte[] DeCompress(this byte[] dataToDecompress, int startIndex, ByteCompressionMethods algorithm) { byte[] decompressedData; int tmp; using (MemoryStream compressedMs = new MemoryStream(dataToDecompress, startIndex, dataToDecompress.Length - startIndex)) { switch (algorithm) { case ByteCompressionMethods.GZipOptimal: case ByteCompressionMethods.GZipFast: { using (Stream gzs = new GZipStream(compressedMs, CompressionMode.Decompress), decompressedMs = new MemoryStream()) { while ((tmp = ((GZipStream)gzs).ReadByte()) != -1) { decompressedMs.WriteByte((byte)tmp); } decompressedData = ((MemoryStream)decompressedMs).ToArray(); } break; } case ByteCompressionMethods.DeflateOptimal: case ByteCompressionMethods.DeflateFast: { compressedMs.SeekForward(startIndex); using (Stream ds = new DeflateStream(compressedMs, CompressionMode.Decompress), decompressedMs = new MemoryStream()) { while ((tmp = ((DeflateStream)ds).ReadByte()) != -1) { decompressedMs.WriteByte((byte)tmp); } decompressedData = ((MemoryStream)decompressedMs).ToArray(); } break; } default: { decompressedData = compressedMs.ToArray(); break; } } return(decompressedData); } }
/// <summary> /// Decompresses a byte array using a specified algorithm. /// </summary> /// <param name="dataToDecompress">The byte array to decompress.</param> /// <param name="algorithm">The algorithm used to decompress the array.</param> /// <returns>The decompressed byte array.</returns> public static byte[] DeCompress(this byte[] dataToDecompress, ByteCompressionMethods algorithm) { return(DeCompress(dataToDecompress, 0, algorithm)); }