/// <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); }
/// <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); } }
/// <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)); }
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; }