diff --git a/QRCoder/QRCodeGenerator.cs b/QRCoder/QRCodeGenerator.cs index 09b681aa..2229cc0e 100644 --- a/QRCoder/QRCodeGenerator.cs +++ b/QRCoder/QRCodeGenerator.cs @@ -116,7 +116,7 @@ public static QRCodeData GenerateQrCode(string plainText, ECCLevel eccLevel, boo // Determine the appropriate version based on segment bit length int version = DetermineVersion(segment, eccLevel, requestedVersion); // Build the complete bit array for the determined version - var completeBitArray = BuildBitArrayFromSegment(segment, version); + var completeBitArray = segment.ToBitArray(version); return GenerateQrCode(completeBitArray, eccLevel, version); } @@ -163,40 +163,6 @@ static int Throw(ECCLevel eccLevel, EncodingMode encoding, int version) } } - /// - /// Builds a complete BitArray from a data segment for a specific QR code version. - /// - private static BitArray BuildBitArrayFromSegment(DataSegment segment, int version) - { - // todo in subsequent PR: eliminate these local variables and directly access the struct - var eciMode = segment.EciMode; - var encoding = segment.EncodingMode; - int dataInputLength = segment.CharacterCount; - var codedText = segment.Data; - int completeBitArrayLength = segment.GetBitLength(version); - int countIndicatorLength = GetCountIndicatorLength(version, segment.EncodingMode); - - var completeBitArray = new BitArray(completeBitArrayLength); - - // write mode indicator - var completeBitArrayIndex = 0; - if (eciMode != EciMode.Default) - { - completeBitArrayIndex = DecToBin((int)EncodingMode.ECI, 4, completeBitArray, completeBitArrayIndex); - completeBitArrayIndex = DecToBin((int)eciMode, 8, completeBitArray, completeBitArrayIndex); - } - completeBitArrayIndex = DecToBin((int)encoding, 4, completeBitArray, completeBitArrayIndex); - // write count indicator - completeBitArrayIndex = DecToBin(dataInputLength, countIndicatorLength, completeBitArray, completeBitArrayIndex); - // write data - for (int i = 0; i < codedText.Length; i++) - { - completeBitArray[completeBitArrayIndex++] = codedText[i]; - } - - return completeBitArray; - } - /// /// Calculates the Micro QR code data which then can be used in one of the rendering classes to generate a graphical representation. /// diff --git a/QRCoder/QRCodeGenerator/DataSegment.cs b/QRCoder/QRCodeGenerator/DataSegment.cs index 0769d26b..94d77d51 100644 --- a/QRCoder/QRCodeGenerator/DataSegment.cs +++ b/QRCoder/QRCodeGenerator/DataSegment.cs @@ -32,6 +32,13 @@ private readonly struct DataSegment /// public readonly EciMode EciMode; + /// + /// Initializes a new instance of the DataSegment struct. + /// + /// The encoding mode for this segment (Numeric, Alphanumeric, Byte, etc.) + /// The character count (or byte count for byte mode) + /// The encoded data as a BitArray + /// The ECI mode value (use EciMode.Default if not using ECI) public DataSegment(EncodingMode encodingMode, int characterCount, BitArray data, EciMode eciMode) { EncodingMode = encodingMode; @@ -51,5 +58,47 @@ public int GetBitLength(int version) int countIndicatorLength = GetCountIndicatorLength(version, EncodingMode); return modeIndicatorLength + countIndicatorLength + Data.Length; } + + /// + /// Builds a complete BitArray from this data segment for a specific QR code version. + /// + /// The QR code version (1-40, or -1 to -4 for Micro QR) + /// A BitArray containing the complete encoded segment including mode indicator, count indicator, and data + public BitArray ToBitArray(int version) + { + var bitArray = new BitArray(GetBitLength(version)); + WriteTo(bitArray, 0, version); + return bitArray; + } + + /// + /// Writes this data segment to an existing BitArray at the specified index for a specific QR code version. + /// + /// The target BitArray to write to + /// The starting index in the BitArray where writing should begin + /// The QR code version (1-40, or -1 to -4 for Micro QR) + /// The next index in the BitArray after the last bit written + public int WriteTo(BitArray bitArray, int startIndex, int version) + { + var index = startIndex; + + // write eci mode if present + if (HasEciMode) + { + index = DecToBin((int)EncodingMode.ECI, 4, bitArray, index); + index = DecToBin((int)EciMode, 8, bitArray, index); + } + // write mode indicator + index = DecToBin((int)EncodingMode, 4, bitArray, index); + + // write count indicator + int countIndicatorLength = GetCountIndicatorLength(version, EncodingMode); + index = DecToBin(CharacterCount, countIndicatorLength, bitArray, index); + + // write data + Data.CopyTo(bitArray, 0, index, Data.Length); + + return index + Data.Length; + } } }