Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
コード例 #1
0
 /// <summary>
 /// Copies the entire byte array to the destination array provided at the offset specified.
 /// </summary>
 public void CopyTo(byte[] array, int position)
 {
     ByteArray.Copy(bytes, 0, array, position, bytes.Length);
 }
コード例 #2
0
        /// <summary>
        /// Reads a fixed size of bytes from the input.
        /// </summary>
        /// <exception cref="InvalidProtocolBufferException">
        /// the end of the stream or the current limit was reached
        /// </exception>
        internal byte[] ReadRawBytes(int size)
        {
            if (size < 0)
            {
                throw InvalidProtocolBufferException.NegativeSize();
            }

            if (totalBytesRetired + bufferPos + size > currentLimit)
            {
                // Read to the end of the stream (up to the current limit) anyway.
                SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
                // Then fail.
                throw InvalidProtocolBufferException.TruncatedMessage();
            }

            if (size <= bufferSize - bufferPos)
            {
                // We have all the bytes we need already.
                byte[] bytes = new byte[size];
                ByteArray.Copy(buffer, bufferPos, bytes, 0, size);
                bufferPos += size;
                return(bytes);
            }
            else if (size < buffer.Length)
            {
                // Reading more bytes than are in the buffer, but not an excessive number
                // of bytes.  We can safely allocate the resulting array ahead of time.

                // First copy what we have.
                byte[] bytes = new byte[size];
                int    pos   = bufferSize - bufferPos;
                ByteArray.Copy(buffer, bufferPos, bytes, 0, pos);
                bufferPos = bufferSize;

                // We want to use RefillBuffer() and then copy from the buffer into our
                // byte array rather than reading directly into our byte array because
                // the input may be unbuffered.
                RefillBuffer(true);

                while (size - pos > bufferSize)
                {
                    Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize);
                    pos      += bufferSize;
                    bufferPos = bufferSize;
                    RefillBuffer(true);
                }

                ByteArray.Copy(buffer, 0, bytes, pos, size - pos);
                bufferPos = size - pos;

                return(bytes);
            }
            else
            {
                // The size is very large.  For security reasons, we can't allocate the
                // entire byte array yet.  The size comes directly from the input, so a
                // maliciously-crafted message could provide a bogus very large size in
                // order to trick the app into allocating a lot of memory.  We avoid this
                // by allocating and reading only a small chunk at a time, so that the
                // malicious message must actually *be* extremely large to cause
                // problems.  Meanwhile, we limit the allowed size of a message elsewhere.

                // Remember the buffer markers since we'll have to copy the bytes out of
                // it later.
                int originalBufferPos  = bufferPos;
                int originalBufferSize = bufferSize;

                // Mark the current buffer consumed.
                totalBytesRetired += bufferSize;
                bufferPos          = 0;
                bufferSize         = 0;

                // Read all the rest of the bytes we need.
                int           sizeLeft = size - (originalBufferSize - originalBufferPos);
                List <byte[]> chunks   = new List <byte[]>();

                while (sizeLeft > 0)
                {
                    byte[] chunk = new byte[Math.Min(sizeLeft, buffer.Length)];
                    int    pos   = 0;
                    while (pos < chunk.Length)
                    {
                        int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
                        if (n <= 0)
                        {
                            throw InvalidProtocolBufferException.TruncatedMessage();
                        }
                        totalBytesRetired += n;
                        pos += n;
                    }
                    sizeLeft -= chunk.Length;
                    chunks.Add(chunk);
                }

                // OK, got everything.  Now concatenate it all into one buffer.
                byte[] bytes = new byte[size];

                // Start by copying the leftover bytes from this.buffer.
                int newPos = originalBufferSize - originalBufferPos;
                ByteArray.Copy(buffer, originalBufferPos, bytes, 0, newPos);

                // And now all the chunks.
                foreach (byte[] chunk in chunks)
                {
                    Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length);
                    newPos += chunk.Length;
                }

                // Done.
                return(bytes);
            }
        }
コード例 #3
0
 /// <summary>
 /// Constructs a <see cref="ByteString" /> from a portion of a byte array.
 /// </summary>
 public static ByteString CopyFrom(byte[] bytes, int offset, int count)
 {
     byte[] portion = new byte[count];
     ByteArray.Copy(bytes, offset, portion, 0, count);
     return(new ByteString(portion));
 }
コード例 #4
0
        internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
        {
            if (count > 12)
            {
                goto IL_6D;
            }
            goto IL_C6;
            uint arg_91_0;
            int  num3;

            while (true)
            {
IL_8C:
                uint num;
                switch ((num = (arg_91_0 ^ 1930007156u)) % 10u)
                {
                case 0u:
                    return;

                case 1u:
                    ByteArray.smethod_0(src, srcOffset, dst, dstOffset, count);
                    arg_91_0 = (num * 413042327u ^ 1632786903u);
                    continue;

                case 2u:
                    goto IL_6D;

                case 3u:
                {
                    int num2;
                    num2++;
                    arg_91_0 = (num * 2391009160u ^ 1725920377u);
                    continue;
                }

                case 4u:
                    goto IL_C6;

                case 6u:
                {
                    int num2 = srcOffset;
                    arg_91_0 = (num * 2783204400u ^ 4161099569u);
                    continue;
                }

                case 7u:
                {
                    int num2;
                    arg_91_0 = ((num2 >= num3) ? 1788008595u : 1153902532u);
                    continue;
                }

                case 8u:
                {
                    int num2;
                    dst[dstOffset++] = src[num2];
                    arg_91_0         = 1859355451u;
                    continue;
                }

                case 9u:
                    arg_91_0 = (num * 245412605u ^ 736293232u);
                    continue;
                }
                break;
            }
            return;

IL_6D:
            arg_91_0 = 1312584901u;
            goto IL_8C;
IL_C6:
            num3     = srcOffset + count;
            arg_91_0 = 912022232u;
            goto IL_8C;
        }