Exemple #1
0
 public override void IceWritePayload(OutputStream ostr)
 {
     ostr.WriteString(Host);
     ostr.WriteInt(Port);
 }
Exemple #2
0
        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();
            }
        }
Exemple #3
0
 public override void IceWritePayload(OutputStream ostr)
 {
     base.IceWritePayload(ostr);
     ostr.WriteInt(Timeout);
     ostr.WriteBool(HasCompressionFlag);
 }