Ejemplo n.º 1
0
        /// <exception cref="System.IO.IOException"/>
        public static Capnproto.MessageReader Read(java.nio.channels.ReadableByteChannel bc, Capnproto.ReaderOptions options)
        {
            java.nio.ByteBuffer firstWord = makeByteBuffer(Capnproto.Constants.BYTES_PER_WORD);
            fillBuffer(firstWord, bc);
            int segmentCount = 1 + firstWord.getInt(0);
            int segment0Size = 0;

            if (segmentCount > 0)
            {
                segment0Size = firstWord.getInt(4);
            }
            int totalWords = segment0Size;

            if (segmentCount > 512)
            {
                throw new System.IO.IOException("too many segments");
            }

            //In words.
            System.Collections.Generic.List <int> moreSizes = new System.Collections.Generic.List <int>();
            if (segmentCount > 1)
            {
                java.nio.ByteBuffer moreSizesRaw = makeByteBuffer(4 * (segmentCount & ~1));
                fillBuffer(moreSizesRaw, bc);
                for (int ii = 0; ii < segmentCount - 1; ++ii)
                {
                    int size = moreSizesRaw.getInt(ii * 4);
                    moreSizes.Add(size);
                    totalWords += size;
                }
            }
            if (totalWords > options.traversalLimitInWords)
            {
                throw new Capnproto.DecodeException("Message size exceeds traversal limit.");
            }
            java.nio.ByteBuffer allSegments = makeByteBuffer(totalWords * Capnproto.Constants.BYTES_PER_WORD);
            fillBuffer(allSegments, bc);
            java.nio.ByteBuffer[] segmentSlices = new java.nio.ByteBuffer[segmentCount];
            allSegments.rewind();
            segmentSlices[0] = allSegments.slice();
            segmentSlices[0].limit(segment0Size * Capnproto.Constants.BYTES_PER_WORD);
            segmentSlices[0].order(java.nio.ByteOrder.LITTLE_ENDIAN);
            int offset = segment0Size;

            for (int ii = 1; ii < segmentCount; ++ii)
            {
                allSegments.position(offset * Capnproto.Constants.BYTES_PER_WORD);
                segmentSlices[ii] = allSegments.slice();
                segmentSlices[ii].limit(moreSizes[ii - 1] * Capnproto.Constants.BYTES_PER_WORD);
                segmentSlices[ii].order(java.nio.ByteOrder.LITTLE_ENDIAN);
                offset += moreSizes[ii - 1];
            }
            return(new Capnproto.MessageReader(segmentSlices, options));
        }
Ejemplo n.º 2
0
 internal static java.nio.ShortBuffer asShortBuffer(java.nio.ByteBuffer byteBuffer
                                                    )
 {
     java.nio.ByteBuffer slice_1 = byteBuffer.slice();
     slice_1.order(byteBuffer.order());
     return(new java.nio.ShortToByteBufferAdapter(slice_1));
 }
Ejemplo n.º 3
0
        ///Upon return, `bb.position()` will be at the end of the message.
        /// <exception cref="System.IO.IOException"/>
        public static Capnproto.MessageReader Read(java.nio.ByteBuffer bb, Capnproto.ReaderOptions options)
        {
            bb.order(java.nio.ByteOrder.LITTLE_ENDIAN);
            int segmentCount = 1 + bb.getInt();

            if (segmentCount > 512)
            {
                throw new System.IO.IOException("too many segments");
            }
            java.nio.ByteBuffer[] segmentSlices = new java.nio.ByteBuffer[segmentCount];
            int segmentSizesBase = bb.position();
            int segmentSizesSize = segmentCount * 4;
            int align            = Capnproto.Constants.BYTES_PER_WORD - 1;
            int segmentBase      = (segmentSizesBase + segmentSizesSize + align) & ~align;
            int totalWords       = 0;

            for (int ii = 0; ii < segmentCount; ++ii)
            {
                int segmentSize = bb.getInt(segmentSizesBase + ii * 4);
                bb.position(segmentBase + totalWords * Capnproto.Constants.BYTES_PER_WORD);
                segmentSlices[ii] = bb.slice();
                segmentSlices[ii].limit(segmentSize * Capnproto.Constants.BYTES_PER_WORD);
                segmentSlices[ii].order(java.nio.ByteOrder.LITTLE_ENDIAN);
                totalWords += segmentSize;
            }
            bb.position(segmentBase + totalWords * Capnproto.Constants.BYTES_PER_WORD);
            if (totalWords > options.traversalLimitInWords)
            {
                throw new Capnproto.DecodeException("Message size exceeds traversal limit.");
            }
            return(new Capnproto.MessageReader(segmentSlices, options));
        }
Ejemplo n.º 4
0
 public java.nio.ByteBuffer AsByteBuffer()
 {
     java.nio.ByteBuffer dup = this.buffer.asReadOnlyBuffer();
     dup.position(this.offset);
     java.nio.ByteBuffer result = dup.slice();
     result.limit(this.size);
     return(result);
 }
Ejemplo n.º 5
0
 public override java.nio.LongBuffer slice()
 {
     byteBuffer.limit(_limit * libcore.io.SizeOf.LONG);
     byteBuffer.position(_position * libcore.io.SizeOf.LONG);
     java.nio.ByteBuffer bb     = byteBuffer.slice().order(byteBuffer.order());
     java.nio.LongBuffer result = new java.nio.LongToByteBufferAdapter(bb);
     byteBuffer.clear();
     return(result);
 }
Ejemplo n.º 6
0
        /// <exception cref="System.IO.IOException"/>
        public int Write(java.nio.ByteBuffer src)
        {
            int available = this.buf.remaining();
            int size      = src.remaining();

            if (size <= available)
            {
                this.buf.put(src);
            }
            else if (size <= this.buf.capacity())
            {
                //# Too much for this buffer, but not a full buffer's worth,
                //# so we'll go ahead and copy.
                java.nio.ByteBuffer slice = src.slice();
                slice.limit(available);
                this.buf.put(slice);
                this.buf.rewind();
                while (this.buf.hasRemaining())
                {
                    this.inner.Write(this.buf);
                }
                this.buf.rewind();
                src.position(src.position() + available);
                this.buf.put(src);
            }
            else
            {
                //# Writing so much data that we might as well write
                //# directly to avoid a copy.
                int pos = this.buf.position();
                this.buf.rewind();
                java.nio.ByteBuffer slice = this.buf.slice();
                slice.limit(pos);
                while (slice.hasRemaining())
                {
                    this.inner.Write(slice);
                }
                while (src.hasRemaining())
                {
                    this.inner.Write(src);
                }
            }
            return(size);
        }
Ejemplo n.º 7
0
        /// <exception cref="System.IO.IOException"/>
        public int Read(java.nio.ByteBuffer outBuf)
        {
            if (outBuf.buffer == null)
            {
                outBuf.buffer = new byte[outBuf.remaining()];
            }
            int len = outBuf.remaining();

            if (len == 0)
            {
                return(0);
            }
            if (len % 8 != 0)
            {
                throw new System.Exception("PackedInputStream reads must be word-aligned");
            }
            int outPtr = outBuf.position();
            int outEnd = outPtr + len;

            java.nio.ByteBuffer inBuf = this.inner.GetReadBuffer();
            while (true)
            {
                byte tag = 0;
                if (inBuf.remaining() < 10)
                {
                    if (outBuf.remaining() == 0)
                    {
                        return(len);
                    }
                    if (inBuf.remaining() == 0)
                    {
                        inBuf = this.inner.GetReadBuffer();
                        continue;
                    }
                    //# We have at least 1, but not 10, bytes available. We need to read
                    //# slowly, doing a bounds check on each byte.
                    tag = inBuf.get();
                    for (int i = 0; i < 8; ++i)
                    {
                        if ((tag & (1 << i)) != 0)
                        {
                            if (inBuf.remaining() == 0)
                            {
                                inBuf = this.inner.GetReadBuffer();
                            }
                            outBuf.put(inBuf.get());
                        }
                        else
                        {
                            outBuf.put((byte)0);
                        }
                    }
                    if (inBuf.remaining() == 0 && (tag == 0 || tag == 0xff))
                    {
                        inBuf = this.inner.GetReadBuffer();
                    }
                }
                else
                {
                    tag = inBuf.get();
                    for (int n = 0; n < 8; ++n)
                    {
                        bool isNonzero = (tag & (1 << n)) != 0;
                        outBuf.put(unchecked ((byte)(inBuf.get() & (isNonzero? -1 : 0))));
                        inBuf.position(inBuf.position() + (isNonzero? 0 : -1));
                    }
                }
                if (tag == 0)
                {
                    if (inBuf.remaining() == 0)
                    {
                        throw new System.Exception("Should always have non-empty buffer here.");
                    }
                    int runLength = (unchecked ((int)(0xff)) & (int)inBuf.get()) * 8;
                    if (runLength > outEnd - outPtr)
                    {
                        throw new System.Exception("Packed input did not end cleanly on a segment boundary");
                    }
                    for (int i = 0; i < runLength; ++i)
                    {
                        outBuf.put((byte)0);
                    }
                }
                else if (tag == 0xff)
                {
                    int runLength = (unchecked ((int)(0xff)) & (int)inBuf.get()) * 8;
                    if (inBuf.remaining() >= runLength)
                    {
                        //# Fast path.
                        java.nio.ByteBuffer slice = inBuf.slice();
                        slice.limit(runLength);
                        outBuf.put(slice);
                        inBuf.position(inBuf.position() + runLength);
                    }
                    else
                    {
                        //# Copy over the first buffer, then do one big read for the rest.
                        runLength -= inBuf.remaining();
                        outBuf.put(inBuf);
                        java.nio.ByteBuffer slice = outBuf.slice();
                        slice.limit(runLength);
                        this.inner.Read(slice);
                        outBuf.position(outBuf.position() + runLength);
                        if (outBuf.remaining() == 0)
                        {
                            return(len);
                        }
                        inBuf = this.inner.GetReadBuffer();
                        continue;
                    }
                }
                if (outBuf.remaining() == 0)
                {
                    return(len);
                }
            }
        }
Ejemplo n.º 8
0
        /// <exception cref="System.IO.IOException"/>
        public int Write(java.nio.ByteBuffer inBuf)
        {
            int length = inBuf.remaining();

            java.nio.ByteBuffer @out       = this.inner.GetWriteBuffer();
            java.nio.ByteBuffer slowBuffer = java.nio.ByteBuffer.allocate(20);
            int inPtr = inBuf.position();
            int inEnd = inPtr + length;

            while (inPtr < inEnd)
            {
                if (@out.remaining() < 10)
                {
                    //# Oops, we're out of space. We need at least 10
                    //# bytes for the fast path, since we don't
                    //# bounds-check on every byte.
                    if (@out == slowBuffer)
                    {
                        int oldLimit = @out.limit();
                        @out.limit(@out.position());
                        @out.rewind();
                        this.inner.Write(@out);
                        @out.limit(oldLimit);
                    }
                    @out = slowBuffer;
                    @out.rewind();
                }
                int tagPos = @out.position();
                @out.position(tagPos + 1);
                byte curByte;
                curByte = inBuf.get(inPtr);
                byte bit0 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit0 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit1 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit1 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit2 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit2 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit3 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit3 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit4 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit4 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit5 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit5 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit6 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit6 - 1);
                inPtr  += 1;
                curByte = inBuf.get(inPtr);
                byte bit7 = (curByte != 0)? unchecked ((byte)1) : unchecked ((byte)0);
                @out.put(curByte);
                @out.position(@out.position() + bit7 - 1);
                inPtr += 1;
                byte tag = unchecked ((byte)((bit0 << 0) | (bit1 << 1) | (bit2 << 2) | (bit3 << 3)
                                             | (bit4 << 4) | (bit5 << 5) | (bit6 << 6) | (bit7 << 7)));
                @out.put(tagPos, tag);
                if (tag == 0)
                {
                    //# An all-zero word is followed by a count of
                    //# consecutive zero words (not including the first
                    //# one).
                    int runStart = inPtr;
                    int limit    = inEnd;
                    if (limit - inPtr > 255 * 8)
                    {
                        limit = inPtr + 255 * 8;
                    }
                    while (inPtr < limit && inBuf.getLong(inPtr) == 0)
                    {
                        inPtr += 8;
                    }
                    @out.put(unchecked ((byte)((inPtr - runStart) / 8)));
                }
                else if (tag == unchecked ((byte)unchecked ((int)(0xff))))
                {
                    //# An all-nonzero word is followed by a count of
                    //# consecutive uncompressed words, followed by the
                    //# uncompressed words themselves.
                    //# Count the number of consecutive words in the input
                    //# which have no more than a single zero-byte. We look
                    //# for at least two zeros because that's the point
                    //# where our compression scheme becomes a net win.
                    int runStart = inPtr;
                    int limit    = inEnd;
                    if (limit - inPtr > 255 * 8)
                    {
                        limit = inPtr + 255 * 8;
                    }
                    while (inPtr < limit)
                    {
                        byte c = 0;
                        for (int ii = 0; ii < 8; ++ii)
                        {
                            c     += (inBuf.get(inPtr) == 0 ? (byte)1 : (byte)0);
                            inPtr += 1;
                        }
                        if (c >= 2)
                        {
                            //# Un-read the word with multiple zeros, since
                            //# we'll want to compress that one.
                            inPtr -= 8;
                            break;
                        }
                    }
                    int count = inPtr - runStart;
                    @out.put(unchecked ((byte)(count / 8)));
                    if (count <= @out.remaining())
                    {
                        //# There's enough space to memcpy.
                        inBuf.position(runStart);
                        java.nio.ByteBuffer slice = inBuf.slice();
                        slice.limit(count);
                        @out.put(slice);
                    }
                    else
                    {
                        //# Input overruns the output buffer. We'll give it
                        //# to the output stream in one chunk and let it
                        //# decide what to do.
                        if (@out == slowBuffer)
                        {
                            int oldLimit = @out.limit();
                            @out.limit(@out.position());
                            @out.rewind();
                            this.inner.Write(@out);
                            @out.limit(oldLimit);
                        }
                        inBuf.position(runStart);
                        java.nio.ByteBuffer slice = inBuf.slice();
                        slice.limit(count);
                        while (slice.hasRemaining())
                        {
                            this.inner.Write(slice);
                        }
                        @out = this.inner.GetWriteBuffer();
                    }
                }
            }
            if (@out == slowBuffer)
            {
                @out.limit(@out.position());
                @out.rewind();
                this.inner.Write(@out);
            }
            inBuf.position(inPtr);
            return(length);
        }