public void CopyTo(Array array, int index)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_NeedNonNegNum);
if (array.Rank != 1)
throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, nameof(array));
Contract.EndContractBlock();
int[] intArray = array as int[];
if (intArray != null)
{
int last = GetArrayLength(m_length, BitsPerInt32) - 1;
int extraBits = m_length % BitsPerInt32;
if (extraBits == 0)
{
// we have perfect bit alignment, no need to sanitize, just copy
Array.Copy(m_array, 0, intArray, index, GetArrayLength(m_length, BitsPerInt32));
}
else
{
// do not copy the last int, as it is not completely used
Array.Copy(m_array, 0, intArray, index, GetArrayLength(m_length, BitsPerInt32) - 1);
// the last int needs to be masked
intArray[index + last] = m_array[last] & ((1 << extraBits) - 1);
}
}
else if (array is byte[])
{
int extraBits = m_length % BitsPerByte;
int arrayLength = GetArrayLength(m_length, BitsPerByte);
if ((array.Length - index) < arrayLength)
throw new ArgumentException(SR.Argument_InvalidOffLen);
if (extraBits > 0)
{
// last byte is not aligned, we will directly copy one less byte
arrayLength -= 1;
}
byte[] b = (byte[])array;
// copy all the perfectly-aligned bytes
for (int i = 0; i < arrayLength; i++)
b[index + i] = (byte)((m_array[i / 4] >> ((i % 4) * 8)) & 0x000000FF); // Shift to bring the required byte to LSB, then mask
if (extraBits > 0)
{
// mask the final byte
int i = arrayLength;
b[index + i] = (byte)((m_array[i / 4] >> ((i % 4) * 8)) & ((1 << extraBits) - 1));
}
}
else if (array is bool[])
{
if (array.Length - index < m_length)
throw new ArgumentException(SR.Argument_InvalidOffLen);
bool[] b = (bool[])array;
for (int i = 0; i < m_length; i++)
b[index + i] = ((m_array[i / 32] >> (i % 32)) & 0x00000001) != 0;
}
else
throw new ArgumentException(SR.Arg_BitArrayTypeUnsupported, nameof(array));
}