Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 1 addition & 35 deletions QRCoder/QRCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -163,40 +163,6 @@ static int Throw(ECCLevel eccLevel, EncodingMode encoding, int version)
}
}

/// <summary>
/// Builds a complete BitArray from a data segment for a specific QR code version.
/// </summary>
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;
}

/// <summary>
/// Calculates the Micro QR code data which then can be used in one of the rendering classes to generate a graphical representation.
/// </summary>
Expand Down
49 changes: 49 additions & 0 deletions QRCoder/QRCodeGenerator/DataSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ private readonly struct DataSegment
/// </summary>
public readonly EciMode EciMode;

/// <summary>
/// Initializes a new instance of the DataSegment struct.
/// </summary>
/// <param name="encodingMode">The encoding mode for this segment (Numeric, Alphanumeric, Byte, etc.)</param>
/// <param name="characterCount">The character count (or byte count for byte mode)</param>
/// <param name="data">The encoded data as a BitArray</param>
/// <param name="eciMode">The ECI mode value (use EciMode.Default if not using ECI)</param>
public DataSegment(EncodingMode encodingMode, int characterCount, BitArray data, EciMode eciMode)
{
EncodingMode = encodingMode;
Expand All @@ -51,5 +58,47 @@ public int GetBitLength(int version)
int countIndicatorLength = GetCountIndicatorLength(version, EncodingMode);
return modeIndicatorLength + countIndicatorLength + Data.Length;
}

/// <summary>
/// Builds a complete BitArray from this data segment for a specific QR code version.
/// </summary>
/// <param name="version">The QR code version (1-40, or -1 to -4 for Micro QR)</param>
/// <returns>A BitArray containing the complete encoded segment including mode indicator, count indicator, and data</returns>
public BitArray ToBitArray(int version)
{
var bitArray = new BitArray(GetBitLength(version));
WriteTo(bitArray, 0, version);
return bitArray;
}

/// <summary>
/// Writes this data segment to an existing BitArray at the specified index for a specific QR code version.
/// </summary>
/// <param name="bitArray">The target BitArray to write to</param>
/// <param name="startIndex">The starting index in the BitArray where writing should begin</param>
/// <param name="version">The QR code version (1-40, or -1 to -4 for Micro QR)</param>
/// <returns>The next index in the BitArray after the last bit written</returns>
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;
}
}
}