private void WriteSegments(BitSequence bs) { foreach (QRCodeEncoder segment in _segments) { bs.Append(segment.ModeIndicator, ModeIndicator.LENGTH); bs.Append(segment.CharCount, CharCountIndicator.GetLength( _currVersion, segment.EncodingMode) ); byte[] data = segment.GetBytes(); for (int i = 0; i < data.Length - 1; ++i) { bs.Append(data[i], 8); } int codewordBitLength = segment.BitCount % 8; if (codewordBitLength == 0) { codewordBitLength = 8; } bs.Append(data[data.Length - 1] >> (8 - codewordBitLength), codewordBitLength); } }
/// <summary> /// 符号化モードを設定します。 /// </summary> /// <param name="encMode">符号化モード</param> /// <param name="c">符号化する最初の文字。この文字はシンボルに追加されません。</param> /// <returns>シンボル容量が不足している場合は false を返します。</returns> internal bool TrySetEncodingMode(EncodingMode encMode, char c) { QRCodeEncoder encoder; Encoding encoding = _parent.Encoding; switch (encMode) { case EncodingMode.NUMERIC: encoder = new NumericEncoder(encoding); break; case EncodingMode.ALPHA_NUMERIC: encoder = new AlphanumericEncoder(encoding); break; case EncodingMode.EIGHT_BIT_BYTE: encoder = new ByteEncoder(encoding); break; case EncodingMode.KANJI: if (Charset.IsJP(encoding.WebName)) { encoder = new KanjiEncoder(encoding); } else { throw new InvalidOperationException(); } break; default: throw new ArgumentOutOfRangeException(nameof(encMode)); } int bitLength = encoder.GetCodewordBitLength(c); while (_dataBitCapacity < _dataBitCounter + ModeIndicator.LENGTH + CharCountIndicator.GetLength(_currVersion, encMode) + bitLength) { if (_currVersion >= _parent.MaxVersion) { return(false); } SelectVersion(); } _dataBitCounter += ModeIndicator.LENGTH + CharCountIndicator.GetLength(_currVersion, encMode); _currEncoder = encoder; _segments.Add(_currEncoder); _segmentCounter[encMode]++; _currEncodingMode = encMode; return(true); }
/// <summary> /// 型番を決定します。 /// </summary> private void SelectVersion() { foreach (EncodingMode encMode in _segmentCounter.Keys) { int num = _segmentCounter[encMode]; _dataBitCounter += num * CharCountIndicator.GetLength(_currVersion + 1, encMode) - num * CharCountIndicator.GetLength(_currVersion + 0, encMode); } _currVersion++; _dataBitCapacity = 8 * DataCodeword.GetTotalNumber( _parent.ErrorCorrectionLevel, _currVersion); _parent.MinVersion = _currVersion; if (_parent.StructuredAppendAllowed) { _dataBitCapacity -= StructuredAppend.HEADER_LENGTH; } }