private byte[] GetOnlyRelevantSourceBytes(byte[] sourceBits, int sourceArrayBitIndex, int numBits,
                                                  int firstByteIndexInSource, int lastByteIndexInSource, int lastSourceBitIndex,
                                                  int numBitPositionsToShiftSourceBy)
        {
            if (numBits == 0)
            {
                return(new byte[0]);
            }


            // A copy of the source array allows us to mask-out bits before sourceArrayBitIndex and after the last
            // bit (sourceArrayBitIndex + numBits) so we don't accidently "borrow" bits we're not supposed to --
            // without modifying the array passed in as a reference.
            var nominalNumberOfBytesForCopy      = GetByteIndexFromBitIndex(sourceArrayBitIndex % 8 + numBits - 1) + 1;
            var numBitsAvailableInLastSourceByte =
                duoBitArrayUtilities.GetNumUnusedBitsInByteArray(sourceArrayBitIndex + numBits);
            var extraByteNeededForBorrowBits = (numBitPositionsToShiftSourceBy > numBitsAvailableInLastSourceByte);
            var arrayCopySize  = nominalNumberOfBytesForCopy + (extraByteNeededForBorrowBits ? 1 : 0);
            var sourceBitsCopy = new byte[arrayCopySize];

            for (var i = 1; i < sourceBitsCopy.Length - 1; i++)
            {
                sourceBitsCopy[i] = sourceBits[firstByteIndexInSource + i];
            }

            sourceBitsCopy[0] = GetLsbMaskedSourceByte(sourceBits[firstByteIndexInSource]);

            if (lastByteIndexInSource > 0)
            {
                sourceBitsCopy[sourceBitsCopy.Length - 1] =
                    GetMsbMaskedSourceByte(sourceBits[lastByteIndexInSource]);
            }

            return(sourceBitsCopy);



            // These are C# 7 "local functions"; if porting to another language, make them private methods.
            byte GetMsbMaskedSourceByte(byte candidateDestinationByte)
            {
                var numBitsInLastSourceByteToKeep =
                    duoBitArrayUtilities.GetNumBitsInUseInLastByte(lastSourceBitIndex + 1);
                var sourceByteMask   = duoBitArrayUtilities.GetByteMsbMask(numBitsInLastSourceByteToKeep);
                var maskedSourceByte = (byte)(candidateDestinationByte & sourceByteMask);

                return(maskedSourceByte);
            }

            byte GetLsbMaskedSourceByte(byte candidateDestinationByte)
            {
                var numBitsInFirstSourceByteToKeep = 8 - sourceArrayBitIndex;
                var sourceByteMask   = duoBitArrayUtilities.GetByteLsbMask(numBitsInFirstSourceByteToKeep);
                var maskedSourceByte = (byte)(candidateDestinationByte & sourceByteMask);

                return(maskedSourceByte);
            }
        }
Ejemplo n.º 2
0
        private byte[] GetMaskForConsecutiveLeftBits(int numBits)
        {
            var numBytes      = duoBitArrayUtilities.GetMinNumBytesToStoreBits(numBits);
            var generatedMask = new byte[numBytes];

            generatedMask[numBytes - 1] =
                duoBitArrayUtilities.GetByteMsbMask(duoBitArrayUtilities.GetNumBitsInUseInLastByte(numBits));

            for (var i = 0; i < numBytes - 2; i++)
            {
                generatedMask[i] = 0xFF;
            }

            return(generatedMask);
        }