예제 #1
0
        public long Read(EasyBuffer sink, long byteCount)
        {
            if (sink == null)
            {
                throw new ArgumentException("sink == null");
            }
            if (byteCount < 0)
            {
                throw new ArgumentException("byteCount < 0: " + byteCount);
            }
            if (_closed)
            {
                throw new IllegalStateException("closed");
            }

            if (_easyBuffer.Size == 0)
            {
                long read = _source.Read(_easyBuffer, Segment.SIZE);
                if (read == -1)
                {
                    return(-1);
                }
            }

            long toRead = Math.Min(byteCount, _easyBuffer.Size);

            return(_easyBuffer.Read(sink, toRead));
        }
예제 #2
0
 public long Read(EasyBuffer sink, long byteCount)
 {
     if (byteCount < 0)
     {
         throw new ArgumentException("byteCount < 0: " + byteCount);
     }
     if (byteCount == 0)
     {
         return(0);
     }
     try
     {
         _timeout.ThrowIfReached();
         Segment tail      = sink.WritableSegment(1);
         int     maxToCopy = (int)Math.Min(byteCount, Segment.SIZE - tail.Limit);
         int     bytesRead = _in.Read(tail.Data, tail.Limit, maxToCopy);
         if (bytesRead <= 0)
         {
             return(-1);
         }
         tail.Limit += bytesRead;
         sink.Size  += bytesRead;
         return(bytesRead);
     }
     catch (Exception e)
     {
         throw e;
     }
 }
예제 #3
0
        public void Write(EasyBuffer source, long byteCount)
        {
            Util.CheckOffsetAndCount(source.Size, 0, byteCount);
            while (byteCount > 0)
            {
                // Share bytes from the head segment of 'source' with the deflater.
                Segment head      = source.Head;
                int     toDeflate = (int)Math.Min(byteCount, head.Limit - head.Pos);
                deflater.SetInput(head.Data, head.Pos, toDeflate);
                deflater.Flush();

                // Deflate those bytes into sink.
                Deflate();

                // Mark those bytes as read.
                source.Size -= toDeflate;
                head.Pos    += toDeflate;
                if (head.Pos == head.Limit)
                {
                    source.Head = head.Pop();
                    SegmentPool.Recycle(head);
                }

                byteCount -= toDeflate;
            }
        }
예제 #4
0
        private void assertStringEncoded(String hex, String @string)
        {
            ByteString expectedUtf8 = ByteString.DecodeHex(hex);

            // Confirm our implementation matches those expectations.
            ByteString actualUtf8 = new EasyBuffer().WriteUtf8(@string).ReadByteString();

            Assert.AreEqual(expectedUtf8, actualUtf8);

            //// Confirm our expectations are consistent with the platform.
            //ByteString platformUtf8 = ByteString.Of(Encoding.UTF8.GetBytes(@string));
            //Assert.AreEqual(expectedUtf8, platformUtf8);

            // Confirm we are consistent when writing one code point at a time.
            var bufferUtf8 = new EasyBuffer();

            for (int i = 0; i < @string.Length;)
            {
                int c = @string.CodePointAt(i);
                bufferUtf8.WriteUtf8CodePoint(c);
                i += Character.CharCount(c);
            }
            Assert.AreEqual(expectedUtf8, bufferUtf8.ReadByteString());

            // Confirm we are consistent when measuring lengths.
            Assert.AreEqual(expectedUtf8.Size(), Utf8.Size(@string));
            Assert.AreEqual(expectedUtf8.Size(), Utf8.Size(@string, 0, @string.Length()));
        }
예제 #5
0
        public string ReadUtf8LineStrict(long limit)
        {
            if (limit < 0)
            {
                throw new ArgumentException("limit < 0: " + limit);
            }
            long scanLength = limit == long.MaxValue ? long.MaxValue : limit + 1;
            long newline    = IndexOf((byte)'\n', 0, scanLength);

            if (newline != -1)
            {
                return(_easyBuffer.ReadUtf8Line(newline));
            }
            if (scanLength < long.MaxValue &&
                Request(scanLength) && _easyBuffer.GetByte(scanLength - 1) == '\r' &&
                Request(scanLength + 1) && _easyBuffer.GetByte(scanLength) == '\n')
            {
                return(_easyBuffer.ReadUtf8Line(scanLength)); // The line was 'limit' UTF-8 bytes followed by \r\n.
            }
            var data = new EasyBuffer();

            _easyBuffer.CopyTo(data, 0, Math.Min(32, _easyBuffer.Size));
            throw new IndexOutOfRangeException("\\n not found: limit=" + Math.Min(_easyBuffer.Size, limit)
                                               + " content=" + data.ReadByteString().Hex() + '…');
        }
예제 #6
0
        /** Use DeflaterOutputStream to deflate source. */
        private EasyBuffer deflate(ByteString source)
        {
            var  result = new EasyBuffer();
            Sink sink   = EasyIO.Sink(new DeflaterOutputStream(result.OutputStream()));

            sink.Write(new EasyBuffer().Write(source), source.Size());
            sink.Dispose();
            return(result);
        }
예제 #7
0
        public void gunzip()
        {
            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeader);
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #8
0
 public void Write(EasyBuffer source, long byteCount)
 {
     if (_closed)
     {
         throw new IllegalStateException("closed");
     }
     _easyBuffer.Write(source, byteCount);
     EmitCompleteSegments();
 }
예제 #9
0
        /** Returns a new buffer containing the inflated contents of {@code deflated}. */
        private EasyBuffer inflate(EasyBuffer deflated)
        {
            var            result = new EasyBuffer();
            InflaterSource source = new InflaterSource(deflated, new Inflater());

            while (source.Read(result, int.MaxValue) != -1)
            {
            }
            return(result);
        }
예제 #10
0
        private void assertCodePointDecoded(String hex, params int[] codePoints)
        {
            var buffer = new EasyBuffer().Write(ByteString.DecodeHex(hex));

            foreach (var codePoint in codePoints)
            {
                Assert.AreEqual(codePoint, buffer.ReadUtf8CodePoint());
            }
            Assert.True(buffer.Exhausted());
        }
예제 #11
0
        private EasyBuffer gunzip(EasyBuffer gzipped)
        {
            var        result = new EasyBuffer();
            GzipSource source = new GzipSource(gzipped);

            while (source.Read(result, int.MaxValue) != -1)
            {
            }
            return(result);
        }
예제 #12
0
 /// <summary>
 /// Updates the CRC with the given bytes.
 /// </summary>
 /// <param name="buffer"></param>
 /// <param name="byteCount"></param>
 private void UpdateCrc(EasyBuffer buffer, long byteCount)
 {
     for (Segment head = buffer.Head; byteCount > 0; head = head.Next)
     {
         int segmentLength = (int)Math.Min(byteCount, head.Limit - head.Pos);
         var newData       = head.Data.Copy(head.Pos, segmentLength);
         crc.Update(newData);
         byteCount -= segmentLength;
     }
 }
예제 #13
0
        public long Read(EasyBuffer sink, long byteCount)
        {
            if (byteCount < 0)
            {
                throw new ArgumentException("byteCount < 0: " + byteCount);
            }
            if (closed)
            {
                throw new IllegalStateException("closed");
            }
            if (byteCount == 0)
            {
                return(0);
            }

            while (true)
            {
                var sourceExhausted = Refill();

                // Decompress the inflater's compressed data into the sink.
                try
                {
                    Segment tail          = sink.WritableSegment(1);
                    int     toRead        = (int)Math.Min(byteCount, Segment.SIZE - tail.Limit);
                    int     bytesInflated = inflater.Inflate(tail.Data, tail.Limit, toRead);
                    if (bytesInflated > 0)
                    {
                        tail.Limit += bytesInflated;
                        sink.Size  += bytesInflated;
                        return(bytesInflated);
                    }
                    if (inflater.IsFinished || inflater.IsNeedingDictionary)
                    {
                        ReleaseInflatedBytes();
                        if (tail.Pos == tail.Limit)
                        {
                            // We allocated a tail segment, but didn't end up needing it. Recycle!
                            sink.Head = tail.Pop();
                            SegmentPool.Recycle(tail);
                        }
                        return(-1);
                    }
                    if (sourceExhausted)
                    {
                        throw new IndexOutOfRangeException("source exhausted prematurely");
                    }
                }
                catch (Exception e)
                {
                    break;
                }
            }
            return(0);
        }
예제 #14
0
        public void gunzip_withComment()
        {
            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeaderWithFlags((byte)0x10));
            gzipped.Write(Encoding.UTF8.GetBytes("rubbish"), 0, 7);
            gzipped.WriteByte(0); // zero-terminated
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #15
0
        public void gunzip_withName()
        {
            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeaderWithFlags((byte)0x08));
            gzipped.Write(Encoding.UTF8.GetBytes("foo.txt"), 0, 7);
            gzipped.WriteByte(0); // zero-terminated
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #16
0
        public void gunzip_withExtra()
        {
            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeaderWithFlags((byte)0x04));
            gzipped.WriteShort(reverseBytesShort((short)7)); // little endian extra length
            gzipped.Write(Encoding.UTF8.GetBytes("blubber"), 0, 7);
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #17
0
        public void inflateByteCount()
        {
            var inflated = new EasyBuffer();
            var deflated = decodeBase64(
                "eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
            InflaterSource source = new InflaterSource(deflated, new Inflater());

            source.Read(inflated, 11);
            source.Dispose();
            Assert.AreEqual("God help us", inflated.ReadUtf8());
            Assert.AreEqual(0, inflated.Size);
        }
예제 #18
0
        private void assertCodePointEncoded(String hex, params int[] codePoints)
        {
            var buffer = new EasyBuffer();

            foreach (var codePoint in codePoints)
            {
                buffer.WriteUtf8CodePoint(codePoint);
            }
            var b1 = buffer.ReadByteString();
            var b2 = ByteString.DecodeHex(hex);

            Assert.AreEqual(b1, b2);
        }
예제 #19
0
        public long Read(EasyBuffer sink, long byteCount)
        {
            if (byteCount < 0)
            {
                throw new ArgumentException("byteCount < 0: " + byteCount);
            }
            if (byteCount == 0)
            {
                return(0);
            }

            // If we haven't consumed the header, we must consume it before anything else.
            if (section == SECTION_HEADER)
            {
                ConsumeHeader();
                section = SECTION_BODY;
            }

            // Attempt to read at least a byte of the body. If we do, we're done.
            if (section == SECTION_BODY)
            {
                long offset = sink.Size;
                long result = inflaterSource.Read(sink, byteCount);
                if (result > 0)//!=-1
                {
                    UpdateCrc(sink, offset, result);
                    return(result);
                }
                section = SECTION_TRAILER;
            }

            // The body is exhausted; time to read the trailer. We always consume the
            // trailer before returning a -1 exhausted result; that way if you read to
            // the end of a GzipSource you guarantee that the CRC has been checked.
            if (section == SECTION_TRAILER)
            {
                ConsumeTrailer();
                section = SECTION_DONE;

                // Gzip streams self-terminate: they return -1 before their underlying
                // source returns -1. Here we attempt to force the underlying stream to
                // return -1 which may trigger it to release its resources. If it doesn't
                // return -1, then our Gzip data finished prematurely!
                if (!source.Exhausted())
                {
                    throw new Exception("gzip finished without exhausting source");
                }
            }

            return(-1);
        }
예제 #20
0
        public void Write(EasyBuffer source, long byteCount)
        {
            if (byteCount < 0)
            {
                throw new ArgumentException("byteCount < 0: " + byteCount);
            }
            if (byteCount == 0)
            {
                return;
            }

            UpdateCrc(source, byteCount);
            deflaterSink.Write(source, byteCount);
        }
예제 #21
0
 public void ReadFully(EasyBuffer sink, long byteCount)
 {
     try
     {
         Require(byteCount);
     }
     catch (IndexOutOfRangeException e)
     {
         // The underlying source is exhausted. Copy the bytes we got before rethrowing.
         sink.WriteAll(_easyBuffer);
         throw e;
     }
     _easyBuffer.ReadFully(sink, byteCount);
 }
예제 #22
0
        public void deflateWithSyncFlush()
        {
            String original = "Yes, yes, yes. That's why we're taking extreme precautions.";
            var    data     = new EasyBuffer();

            data.WriteUtf8(original);
            var          sink         = new EasyBuffer();
            DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());

            deflaterSink.Write(data, data.Size);
            deflaterSink.Flush();
            var inflated = inflate(sink);

            Assert.AreEqual(original, inflated.ReadUtf8());
        }
예제 #23
0
 public void inflateIntoNonemptySink()
 {
     for (int i = 0; i < Segment.SIZE; i++)
     {
         var inflated = new EasyBuffer().WriteUtf8(repeat('a', i));
         var deflated = decodeBase64(
             "eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
         InflaterSource source = new InflaterSource(deflated, new Inflater());
         while (source.Read(inflated, int.MaxValue) > 0)
         {
         }
         inflated.Skip(i);
         Assert.AreEqual("God help us, we're in the hands of engineers.", inflated.ReadUtf8());
     }
 }
예제 #24
0
        public void gunzip_withHCRC()
        {
            Crc32      hcrc       = new Crc32();
            ByteString gzipHeader = gzipHeaderWithFlags((byte)0x02);

            hcrc.Update(gzipHeader.ToByteArray());

            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeader);
            gzipped.WriteShort(reverseBytesShort((short)hcrc.Value)); // little endian
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #25
0
        public void gunzip_withAll()
        {
            var gzipped = new EasyBuffer();

            gzipped.Write(gzipHeaderWithFlags((byte)0x1c));
            gzipped.WriteShort(reverseBytesShort((short)7)); // little endian extra length
            gzipped.Write(Encoding.UTF8.GetBytes("blubber"), 0, 7);
            gzipped.Write(Encoding.UTF8.GetBytes("foo.txt"), 0, 7);
            gzipped.WriteByte(0); // zero-terminated
            gzipped.Write(Encoding.UTF8.GetBytes("rubbish"), 0, 7);
            gzipped.WriteByte(0); // zero-terminated
            gzipped.Write(deflated);
            gzipped.Write(gzipTrailer);
            assertGzipped(gzipped);
        }
예제 #26
0
        public void deflatePoorlyCompressed()
        {
            ByteString original = randomBytes(1024 * 1024);
            var        data     = new EasyBuffer();

            data.Write(original);
            var          sink         = new EasyBuffer();
            DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());

            deflaterSink.Write(data, data.Size);
            deflaterSink.Flush();
            deflaterSink.Dispose();
            var inflated = inflate(sink);

            Assert.AreEqual(original, inflated.ReadByteString());
        }
예제 #27
0
        public void deflateWellCompressed()
        {
            String original = repeat('a', 1024 * 1024);
            var    data     = new EasyBuffer();

            data.WriteUtf8(original);
            var          sink         = new EasyBuffer();
            DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());

            deflaterSink.Write(data, data.Size);
            deflaterSink.Flush();
            deflaterSink.Dispose();
            var inflated = inflate(sink);

            Assert.AreEqual(original, inflated.ReadUtf8());
        }
예제 #28
0
        public void deflateWithClose()
        {
            var    data     = new EasyBuffer();
            String original = "They're moving in herds. They do move in herds.";

            data.WriteUtf8(original);
            var          sink         = new EasyBuffer();
            DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());

            deflaterSink.Write(data, data.Size);
            deflaterSink.Flush();
            deflaterSink.Dispose();
            var inflated = inflate(sink);

            Assert.AreEqual(original, inflated.ReadUtf8());
        }
예제 #29
0
        public void multipleSegmentsWithoutCompression()
        {
            var      buffer   = new EasyBuffer();
            Deflater deflater = new Deflater();
            //deflater.SetLevel(Deflater.NO_COMPRESSION);//SharpZipLib 会出错~
            DeflaterSink deflaterSink = new DeflaterSink(buffer, deflater);
            int          byteCount    = Segment.SIZE * 4;
            var          data         = new EasyBuffer().WriteUtf8(repeat('a', byteCount));

            deflaterSink.Write(data, data.Size);
            deflaterSink.Flush();
            deflaterSink.Dispose();
            var test1 = repeat('a', byteCount);
            var test2 = inflate(buffer).ReadUtf8(byteCount);

            Assert.AreEqual(test1, test2);
        }
예제 #30
0
        public void gzipGunzip()
        {
            var    data     = new EasyBuffer();
            String original = "It's a UNIX system! I know this!";

            data.WriteUtf8(original);
            var      sink     = new EasyBuffer();
            GzipSink gzipSink = new GzipSink(sink);

            gzipSink.Write(data, data.Size);
            gzipSink.Flush();
            gzipSink.Dispose();
            var inflated = gunzip(sink);
            var result   = inflated.ReadUtf8();

            Assert.AreEqual(original, result);
        }