static void CheckArgsCopy(ref UnsafeBitArray dstBitArray, int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits) { if (dstPos + numBits > srcBitArray.Length) { throw new ArgumentException($"BitArray invalid arguments: Out of bounds - source position {srcPos}, numBits {numBits}, source bit array Length {srcBitArray.Length}."); } if (dstPos + numBits > dstBitArray.Length) { throw new ArgumentException($"BitArray invalid arguments: Out of bounds - destination position {dstPos}, numBits {numBits}, destination bit array Length {dstBitArray.Length}."); } }
public UnsafeBitArrayDebugView(UnsafeBitArray data) { Data = data; }
/// <summary> /// Copy block of bits from source to destination. /// </summary> /// <param name="dstPos">Destination position in bit array.</param> /// <param name="srcBitArray">Source bit array from which bits will be copied.</param> /// <param name="srcPos">Source position in bit array.</param> /// <param name="numBits">Number of bits to copy.</param> public void Copy(int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits) { if (numBits == 0) { return; } CheckArgsCopy(ref this, dstPos, ref srcBitArray, srcPos, numBits); if (numBits <= 64) // 1x CopyUlong { CopyUlong(dstPos, ref srcBitArray, srcPos, numBits); } else if (numBits <= 128) // 2x CopyUlong { CopyUlong(dstPos, ref srcBitArray, srcPos, 64); numBits -= 64; if (numBits > 0) { CopyUlong(dstPos + 64, ref srcBitArray, srcPos + 64, numBits); } } else if ((dstPos & 7) == (srcPos & 7)) // aligned copy { var dstPosInBytes = CollectionHelper.Align(dstPos, 8) >> 3; var srcPosInBytes = CollectionHelper.Align(srcPos, 8) >> 3; var numPreBits = dstPosInBytes * 8 - dstPos; if (numPreBits > 0) { CopyUlong(dstPos, ref srcBitArray, srcPos, numPreBits); } var numBitsLeft = numBits - numPreBits; var numBytes = numBitsLeft / 8; if (numBytes > 0) { unsafe { UnsafeUtility.MemMove((byte *)Ptr + dstPosInBytes, (byte *)srcBitArray.Ptr + srcPosInBytes, numBytes); } } var numPostBits = numBitsLeft & 7; if (numPostBits > 0) { CopyUlong((dstPosInBytes + numBytes) * 8, ref srcBitArray, (srcPosInBytes + numBytes) * 8, numPostBits); } } else // unaligned copy { var dstPosAligned = CollectionHelper.Align(dstPos, 64); var numPreBits = dstPosAligned - dstPos; if (numPreBits > 0) { CopyUlong(dstPos, ref srcBitArray, srcPos, numPreBits); numBits -= numPreBits; dstPos += numPreBits; srcPos += numPreBits; } for (; numBits >= 64; numBits -= 64, dstPos += 64, srcPos += 64) { Ptr[dstPos >> 6] = srcBitArray.GetBits(srcPos, 64); } if (numBits > 0) { CopyUlong(dstPos, ref srcBitArray, srcPos, numBits); } } }
internal void CopyUlong(int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits) => SetBits(dstPos, srcBitArray.GetBits(srcPos, numBits), numBits);