public override void IceWritePayload(OutputStream ostr) { ostr.WriteString(Host); ostr.WriteInt(Port); }
internal static List <ArraySegment <byte> >?Compress( List <ArraySegment <byte> > data, int size, int headerSize, int compressionLevel) { Debug.Assert(IsLoaded); // Compress the frame body, but not the header. int decompressedLen = size - headerSize; // Compress the frame body, but not the header. byte[] compressed = new byte[(int)((decompressedLen * 1.01) + 600)]; // Prevent GC from moving the byte array, this allow to take the object address and pass it to bzip2 calls. var compressedHandle = GCHandle.Alloc(compressed, GCHandleType.Pinned); var bzStream = new BZStream(compressedHandle.AddrOfPinnedObject(), (uint)compressed.Length); ArraySegment <byte> headerSegment = data[0]; BzStatus rc; try { rc = (BzStatus)BZ2_bzCompressInit(ref bzStream, compressionLevel, 0, 0); if (rc != BzStatus.Ok) { throw new TransportException($"bzip2 compression failed: {rc}"); } // Slice the first segment to skip the header, the header is never compressed Debug.Assert(headerSegment.Offset == 0); data[0] = headerSegment.Slice(headerSize); rc = BzStatus.RunOk; for (int i = 0; rc == BzStatus.RunOk && i < data.Count; i++) { ArraySegment <byte> segment = data[i]; var segmentHandle = GCHandle.Alloc(segment.Array, GCHandleType.Pinned); bzStream.NextIn = segmentHandle.AddrOfPinnedObject() + segment.Offset; bzStream.AvailIn = (uint)segment.Count; Debug.Assert(bzStream.AvailIn > 0); do { rc = (BzStatus)BZ2_bzCompress(ref bzStream, (int)BzAction.Run); }while (rc == BzStatus.RunOk && bzStream.AvailIn > 0); segmentHandle.Free(); } if (rc != BzStatus.RunOk) { throw new TransportException($"bzip2 compression failed: {rc}"); } do { rc = (BzStatus)BZ2_bzCompress(ref bzStream, (int)BzAction.Finish); }while (rc == BzStatus.FinishOk); if (rc != BzStatus.StreamEnd) { throw new TransportException($"bzip2 compression failed: {rc}"); } int compressedLen = compressed.Length - (int)bzStream.AvailOut; // Don't bother if the compressed data is larger than the decompressed data. if (compressedLen >= decompressedLen) { return(null); } // Copy the header from the decompressed stream to the compressed one, we use headerSize + 4 to ensure // there is room for the size of the decompressed stream in the first segment. ArraySegment <byte> compressedHeader = new byte[headerSize + 4]; headerSegment.AsSpan(0, headerSize).CopyTo(compressedHeader); int compressedSize = compressedLen + compressedHeader.Count; // Write the compression status and the size of the compressed stream into the header. compressedHeader[9] = 2; OutputStream.WriteInt(compressedSize, compressedHeader.AsSpan(10, 4)); // Write the compression status and size of the compressed stream into the header of the decompressed // stream -- we need this to trace requests correctly. headerSegment[9] = 2; OutputStream.WriteInt(compressedSize, headerSegment.AsSpan(10, 4)); // Add the size of the decompressed stream before the frame body. OutputStream.WriteInt(size, compressedHeader.AsSpan(headerSize, 4)); return(new List <ArraySegment <byte> >(2) { compressedHeader, new ArraySegment <byte>(compressed, 0, compressedLen) }); } finally { // Restore the first segment that was Sliced above to skip the header data[0] = headerSegment; rc = (BzStatus)BZ2_bzCompressEnd(ref bzStream); Debug.Assert(rc == BzStatus.Ok); compressedHandle.Free(); } }
public override void IceWritePayload(OutputStream ostr) { base.IceWritePayload(ostr); ostr.WriteInt(Timeout); ostr.WriteBool(HasCompressionFlag); }