Fix compilation issues

pull/82/head
fwcd 6 years ago
parent dac60dacee
commit 05410d240f

@ -26,7 +26,7 @@ public struct BitBuffer {
public var bits: [Bool] public var bits: [Bool]
public var count: UInt { UInt(bits.count) } public var count: UInt { UInt(bits.count) }
public init(bits: [Bool]) { public init(_ bits: [Bool] = []) {
self.bits = bits self.bits = bits
} }
@ -35,6 +35,6 @@ public struct BitBuffer {
/// Requires len &#x2264; 31 and val &lt; 2<sup>len</sup>. /// Requires len &#x2264; 31 and val &lt; 2<sup>len</sup>.
public mutating func appendBits(_ value: UInt32, _ length: Int) { public mutating func appendBits(_ value: UInt32, _ length: Int) {
assert(length <= 31 && (value >> length) == 0, "Value out of range") assert(length <= 31 && (value >> length) == 0, "Value out of range")
bits.append((0..<length).reversed().map { getBit(value, $0) }) bits += (0..<length).reversed().map { getBit(value, Int32($0)) }
} }
} }

@ -74,7 +74,7 @@ struct QRCode {
/// Returns a wrapped `QrCode` if successful, or `Err` if the /// Returns a wrapped `QrCode` if successful, or `Err` if the
/// data is too long to fit in any version at the given ECC level. /// data is too long to fit in any version at the given ECC level.
public static func encode(binary data: [UInt8], ecl: QRCodeECC) throws -> Self { public static func encode(binary data: [UInt8], ecl: QRCodeECC) throws -> Self {
let segs = [QRSegment.make(bytes: data)] let segs = [QRSegment.makeBytes(data)]
return try QRCode.encode(segments: segs, ecl: ecl) return try QRCode.encode(segments: segs, ecl: ecl)
} }
@ -111,13 +111,14 @@ struct QRCode {
/// long to fit in any version in the given range at the given ECC level. /// long to fit in any version in the given range at the given ECC level.
public static func encodeAdvanced(segments: [QRSegment], ecl: QRCodeECC, minVersion: QRCodeVersion, maxVersion: QRCodeVersion, mask: QRCodeMask? = nil, boostECL: Bool) throws -> Self { public static func encodeAdvanced(segments: [QRSegment], ecl: QRCodeECC, minVersion: QRCodeVersion, maxVersion: QRCodeVersion, mask: QRCodeMask? = nil, boostECL: Bool) throws -> Self {
assert(minVersion <= maxVersion, "Invalid value") assert(minVersion <= maxVersion, "Invalid value")
var mutECL = ecl
// Find the minimal version number to use // Find the minimal version number to use
var version = minVersion var version = minVersion
var dataUsedBits: UInt! var dataUsedBits: UInt!
while true { while true {
// Number of data bits available // Number of data bits available
let dataCapacityBits: UInt = QRCode.getNumDataCodewords(version: version, ecl: ecl) * 8 let dataCapacityBits: UInt = QRCode.getNumDataCodewords(version: version, ecl: mutECL) * 8
let dataUsed: UInt? = QRSegment.getTotalBits(segments: segments, version: version) let dataUsed: UInt? = QRSegment.getTotalBits(segments: segments, version: version)
if let used = dataUsed, used <= dataCapacityBits { if let used = dataUsed, used <= dataCapacityBits {
// The version number is found to be suitable // The version number is found to be suitable
@ -130,6 +131,7 @@ struct QRCode {
} else { } else {
msg = "Segment too long" msg = "Segment too long"
} }
throw QRCodeError.dataTooLong(msg)
} else { } else {
version = QRCodeVersion(version.value + 1) version = QRCodeVersion(version.value + 1)
} }
@ -138,34 +140,34 @@ struct QRCode {
// Increase error correction level while the data still fits in the current version number // Increase error correction level while the data still fits in the current version number
for newECL in [QRCodeECC.medium, QRCodeECC.quartile, QRCodeECC.high] { for newECL in [QRCodeECC.medium, QRCodeECC.quartile, QRCodeECC.high] {
if boostECL && dataUsedBits <= QRCode.getNumDataCodewords(version: version, ecl: newECL) * 8 { if boostECL && dataUsedBits <= QRCode.getNumDataCodewords(version: version, ecl: newECL) * 8 {
ecl = newECL mutECL = newECL
} }
} }
// Concatenate all segments to create the data bit string // Concatenate all segments to create the data bit string
var bb = BitBuffer() var bb = BitBuffer()
for seg in segments { for seg in segments {
bb.appendBits(seg.mode.modeBits(), 4) bb.appendBits(seg.mode.modeBits, 4)
bb.appendBits(UInt32(seg.numChars), seg.mode.numCharCountBits(version: version)) bb.appendBits(UInt32(seg.numChars), Int(seg.mode.numCharCountBits(version: version)))
bb.values += seg.data bb.bits += seg.data
} }
assert(bb.count == dataUsedBits) assert(bb.count == dataUsedBits)
// Add terminator and pad up to a byte if applicable // Add terminator and pad up to a byte if applicable
let dataCapacityBits: UInt = QRCode.getNumDataCodewords(version: version, ecl: ecl) let dataCapacityBits: UInt = QRCode.getNumDataCodewords(version: version, ecl: mutECL)
assert(bb.count <= dataCapacityBits) assert(bb.count <= dataCapacityBits)
var numZeroBits = min(4, dataCapacityBits - bb.count) var numZeroBits = min(4, dataCapacityBits - bb.count)
bb.appendBits(0, UInt8(numZeroBits)) bb.appendBits(0, Int(numZeroBits))
numZeroBits = (0 &- bb.count) & 7 numZeroBits = (0 &- bb.count) & 7
bb.appendBits(0, UInt8(numZeroBits)) bb.appendBits(0, Int(numZeroBits))
assert(bb.count % 8 == 0) assert(bb.count % 8 == 0)
// Pad with alternating bytes until data capacity is reached // Pad with alternating bytes until data capacity is reached
let padBytes = [0xEC, 0x11] let padBytes = [0xEC, 0x11]
var i = 0 var i = 0
while bb.count < dataCapacityBits { while bb.count < dataCapacityBits {
bb.appendBits(padBytes[i], 8) bb.appendBits(UInt32(padBytes[i]), 8)
i += 1 i += 1
if i >= padBytes.count { if i >= padBytes.count {
i = 0 i = 0
@ -173,13 +175,13 @@ struct QRCode {
} }
// Pack bits into bytes in big endian // Pack bits into bytes in big endian
var dataCodeWords = [UInt8](repeating: 0, bb.count / 8) var dataCodeWords = [UInt8](repeating: 0, count: Int(bb.count / 8))
for (i, bit) in bb.values.enumerated() { for (i, bit) in bb.bits.enumerated() {
dataCodeWords[i >> 3] |= UInt8(bit) << (7 - (i & 7)) dataCodeWords[i >> 3] |= (bit ? 1 : 0) << (7 - (i & 7))
} }
// Create the QRCode object // Create the QRCode object
return QRCode.encodeCodewords(version: version, ecl: ecl, dataCodeWords: dataCodeWords, mask: mask) return QRCode.encodeCodewords(version: version, ecl: mutECL, dataCodeWords: dataCodeWords, mask: mask)
} }
/*---- Constructor (low level) ----*/ /*---- Constructor (low level) ----*/
@ -197,25 +199,25 @@ struct QRCode {
var result = Self( var result = Self(
version: version, version: version,
size: Int(size), size: Int(size),
mask: QRCodeMask(0), // Dummy value
errorCorrectionLevel: ecl, errorCorrectionLevel: ecl,
modules: Array(repeating: false, count: size * size), // Initially all white mask: QRCodeMask(0), // Dummy value
isFunction: Array(repeating: false, count: size * size) modules: Array(repeating: false, count: Int(size * size)), // Initially all white
isFunction: Array(repeating: false, count: Int(size * size))
) )
// Compute ECC, draw modules // Compute ECC, draw modules
result.drawFunctionPatterns() result.drawFunctionPatterns()
let allCodeWords = result.addECCAndInterleave(dataCodeWords: dataCodeWords) let allCodeWords = result.addECCAndInterleave(data: dataCodeWords)
result.drawCodewords(data: allCodeWords) result.drawCodewords(data: allCodeWords)
// Do masking // Do masking
if mask == nil { // Automatically choose best mask if mutMask == nil { // Automatically choose best mask
var minPenalty = Int32.max var minPenalty = Int32.max
for i in UInt8(0)..<8 { for i in UInt8(0)..<8 {
let newMask = QRCodeMask(i) let newMask = QRCodeMask(i)
result.apply(mask: newMask) result.apply(mask: newMask)
result.drawFormatBits(mask: newMask) result.drawFormatBits(mask: newMask)
let penalty = result.getPenaltyScore() let penalty = Int32(result.getPenaltyScore())
if penalty < minPenalty { if penalty < minPenalty {
mutMask = newMask mutMask = newMask
minPenalty = penalty minPenalty = penalty
@ -223,10 +225,10 @@ struct QRCode {
result.apply(mask: newMask) // Undoes mask due to XOR result.apply(mask: newMask) // Undoes mask due to XOR
} }
} }
let mask: QRCodeMask = mask! let resMask: QRCodeMask = mutMask!
result.mask = mask result.mask = resMask
result.apply(mask: mask) // Apply the final choice of mask result.apply(mask: resMask) // Apply the final choice of mask
result.drawFormatBits(mask: mask) result.drawFormatBits(mask: resMask)
result.isFunction = [] result.isFunction = []
return result return result
@ -265,7 +267,7 @@ struct QRCode {
: "" : ""
} }
} }
var result = """ return """
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 \(dimension) \(dimension)" stroke="none"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 \(dimension) \(dimension)" stroke="none">
@ -274,7 +276,6 @@ struct QRCode {
<path d="\(path)" fill="#000000"/> <path d="\(path)" fill="#000000"/>
</svg> </svg>
""" """
return result
} }
/*---- Private helper methods for constructor: Drawing function modules ----*/ /*---- Private helper methods for constructor: Drawing function modules ----*/
@ -315,30 +316,30 @@ struct QRCode {
// Calculate error correction code and pack bits // Calculate error correction code and pack bits
// Error correction level is uint2, mask is uint3 // Error correction level is uint2, mask is uint3
let data: UInt32 = errorCorrectionLevel.formatBits() << 3 | UInt32(mask.value) let data: UInt32 = errorCorrectionLevel.formatBits << 3 | UInt32(mask.value)
var rem: UInt32 = data var rem: UInt32 = data
for _ in 0..<10 { for _ in 0..<10 {
rem = (rem << 1) ^ ((rem > 9) * 0x537) rem = (rem << 1) ^ ((rem >> 9) * 0x537)
} }
let bits: UInt32 = (data << 10 | rem) ^ 0x5412 // uint15 let bits: UInt32 = (data << 10 | rem) ^ 0x5412 // uint15
// Draw first copy // Draw first copy
for i in 0..<6 { for i in 0..<6 {
setFunctionModule(x: 8, y: i, isBlack: getBit(bits, i)) setFunctionModule(x: 8, y: i, isBlack: getBit(bits, Int32(i)))
} }
setFunctionModule(x: 8, y: 7, isBlack: getBit(bits, 6)) setFunctionModule(x: 8, y: 7, isBlack: getBit(bits, 6))
setFunctionModule(x: 8, y: 8, isBlack: getBit(bits, 7)) setFunctionModule(x: 8, y: 8, isBlack: getBit(bits, 7))
setFunctionModule(x: 7, y: 8, isBlack: getBit(bits, 8)) setFunctionModule(x: 7, y: 8, isBlack: getBit(bits, 8))
for i in 9..<15 { for i in 9..<15 {
setFunctionModule(x: 14 - i, y: 8, isBlack: getBit(bits, i)) setFunctionModule(x: 14 - i, y: 8, isBlack: getBit(bits, Int32(i)))
} }
// Draw second copy // Draw second copy
for i in 0..<8 { for i in 0..<8 {
setFunctionModule(x: size - 1 - i, y: 8, isBlack: getBit(bits, i)) setFunctionModule(x: size - 1 - i, y: 8, isBlack: getBit(bits, Int32(i)))
} }
for i in 0..<15 { for i in 0..<15 {
setFunctionModule(x: 8, y: size - 15 + i, isBlack: getBit(bits, i)) setFunctionModule(x: 8, y: size - 15 + i, isBlack: getBit(bits, Int32(i)))
} }
setFunctionModule(x: 8, y: size - 8, isBlack: true) // Always black setFunctionModule(x: 8, y: size - 8, isBlack: true) // Always black
} }
@ -359,7 +360,7 @@ struct QRCode {
// Draw two copies // Draw two copies
for i in 0..<18 { for i in 0..<18 {
let bit = getBit(bits, i) let bit = getBit(bits, Int32(i))
let a: Int = size - 11 + i % 3 let a: Int = size - 11 + i % 3
let b: Int = i / 3 let b: Int = i / 3
setFunctionModule(x: a, y: b, isBlack: bit) setFunctionModule(x: a, y: b, isBlack: bit)
@ -421,7 +422,7 @@ struct QRCode {
var k: UInt = 0 var k: UInt = 0
for i in 0..<numBlocks { for i in 0..<numBlocks {
let datLen: UInt = shortBlockLen - blockECCLen + (i >= numShortBlocks ? 1 : 0) let datLen: UInt = shortBlockLen - blockECCLen + (i >= numShortBlocks ? 1 : 0)
var dat = Array(d[k..<(k + datLen)]) var dat = Array(data[Int(k)..<Int(k + datLen)])
k += datLen k += datLen
let ecc: [UInt8] = QRCode.reedSolomonComputeRemainder(data: dat, divisor: rsDiv) let ecc: [UInt8] = QRCode.reedSolomonComputeRemainder(data: dat, divisor: rsDiv)
if i < numShortBlocks { if i < numShortBlocks {
@ -437,7 +438,7 @@ struct QRCode {
for (j, block) in blocks.enumerated() { for (j, block) in blocks.enumerated() {
// Skip the padding byte in short blocks // Skip the padding byte in short blocks
if i != shortBlockLen - blockECCLen || j >= numShortBlocks { if i != shortBlockLen - blockECCLen || j >= numShortBlocks {
result.push(block[i]) result.append(block[Int(i)])
} }
} }
} }
@ -493,8 +494,9 @@ struct QRCode {
case 5: invert = x * y % 2 + x * y % 3 == 0 case 5: invert = x * y % 2 + x * y % 3 == 0
case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0 case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0
case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0 case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0
default: fatalError("Unreachable")
} }
self[x, y] ^= invert & !isFunction[y * size + x] self[x, y] = self[x, y] != (invert && !isFunction[y * size + x])
} }
} }
} }
@ -565,7 +567,7 @@ struct QRCode {
} }
// Balance of black and white modules // Balance of black and white modules
let black: Int = modules.map(Int.init).sum() let black: Int = modules.map { $0 ? 1 : 0 }.reduce(0, +)
let total: Int = size * size // Note that size is odd, so black/total != 1/2 let total: Int = size * size // Note that size is odd, so black/total != 1/2
// Compute the smallest integer k >= 0 such that (45 - 5k)% <= black/total <= (55+5k)% // Compute the smallest integer k >= 0 such that (45 - 5k)% <= black/total <= (55+5k)%
let k: Int = (abs(black * 20 - total * 10) + total - 1) / total - 1 let k: Int = (abs(black * 20 - total * 10) + total - 1) / total - 1
@ -595,7 +597,7 @@ struct QRCode {
/// Returns the number of data bits that can be stored in a QR Code of the given version number, after /// Returns the number of data bits that can be stored in a QR Code of the given version number, after
/// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. /// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
/// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. /// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
private func getNumRawDataModules(version: QRCodeVersion) -> UInt { private static func getNumRawDataModules(version: QRCodeVersion) -> UInt {
let ver = UInt(version.value) let ver = UInt(version.value)
var result: UInt = (16 * ver + 128) * ver + 64 var result: UInt = (16 * ver + 128) * ver + 64
if ver >= 2 { if ver >= 2 {
@ -612,15 +614,15 @@ struct QRCode {
/// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any /// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
/// QR Code of the given version number and error correction level, with remainder bits discarded. /// QR Code of the given version number and error correction level, with remainder bits discarded.
/// This stateless pure function could be implemented as a (40*4)-cell lookup table. /// This stateless pure function could be implemented as a (40*4)-cell lookup table.
private func getNumDataCodewords(version: QRCodeVersion, ecc: QRCodeECC) -> UInt { private static func getNumDataCodewords(version: QRCodeVersion, ecl: QRCodeECC) -> UInt {
QRCode.getNumRawDataModules(version: ver) / 8 QRCode.getNumRawDataModules(version: version) / 8
- QRCode.tableGet(eccCodewordsPerBlock, version: version, ecc: ecc) - QRCode.tableGet(eccCodewordsPerBlock, version: version, ecl: ecl)
* QRCode.tableGet(numErrorCorrectionBlocks, version: version, ecc: ecc) * QRCode.tableGet(numErrorCorrectionBlocks, version: version, ecl: ecl)
} }
/// Returns an entry from the given table based on the given values. /// Returns an entry from the given table based on the given values.
private func table_get(_ table: [[Int]], version: QRCodeVersion, ecl: QRCodeECC) -> UInt { private static func tableGet(_ table: [[Int]], version: QRCodeVersion, ecl: QRCodeECC) -> UInt {
UInt(table[ecl.ordinal][Int(version.value)]) UInt(table[Int(ecl.ordinal)][Int(version.value)])
} }
/// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials. /// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
@ -637,7 +639,7 @@ struct QRCode {
var root: UInt8 = 1 var root: UInt8 = 1
for _ in 0..<degree { for _ in 0..<degree {
// Multiply the current product by (x - r^i) // Multiply the current product by (x - r^i)
for j in 0..<degree { for j in 0..<Int(degree) {
result[j] = QRCode.reedSolomonMultiply(x: result[j], y: root) result[j] = QRCode.reedSolomonMultiply(x: result[j], y: root)
if j + 1 < result.count { if j + 1 < result.count {
result[j] ^= result[j + 1] result[j] ^= result[j + 1]
@ -653,7 +655,7 @@ struct QRCode {
private static func reedSolomonComputeRemainder(data: [UInt8], divisor: [UInt8]) -> [UInt8] { private static func reedSolomonComputeRemainder(data: [UInt8], divisor: [UInt8]) -> [UInt8] {
var result = [UInt8](repeating: 0, count: divisor.count) var result = [UInt8](repeating: 0, count: divisor.count)
for b in data { // Polynomial divison for b in data { // Polynomial divison
let factor: UInt8 = b ^ result.popFirst()! let factor: UInt8 = b ^ result[...].popFirst()!
result.append(0) result.append(0)
for (i, y) in divisor.enumerated() { for (i, y) in divisor.enumerated() {
result[i] = QRCode.reedSolomonMultiply(x: y, y: factor) result[i] = QRCode.reedSolomonMultiply(x: y, y: factor)
@ -678,7 +680,7 @@ struct QRCode {
private struct FinderPenalty { private struct FinderPenalty {
let qrSize: Int let qrSize: Int
let runHistory: [Int] var runHistory: [Int]
init(_ qrSize: Int) { init(_ qrSize: Int) {
self.qrSize = qrSize self.qrSize = qrSize
@ -716,7 +718,7 @@ struct QRCode {
} }
currentRunLength += qrSize // Add white border to final run currentRunLength += qrSize // Add white border to final run
addHistory(runLength: currentRunLength) addHistory(runLength: currentRunLength)
countPatterns() return countPatterns()
} }
} }
} }

@ -25,7 +25,7 @@
public struct QRCodeVersion: Hashable, Comparable { public struct QRCodeVersion: Hashable, Comparable {
public let value: UInt8 public let value: UInt8
public init(value: UInt8) { public init(_ value: UInt8) {
assert(1 <= value && value <= 40, "Version number out of range") assert(1 <= value && value <= 40, "Version number out of range")
self.value = value self.value = value
} }
@ -39,7 +39,7 @@ public struct QRCodeVersion: Hashable, Comparable {
public struct QRCodeMask: Hashable { public struct QRCodeMask: Hashable {
public let value: UInt8 public let value: UInt8
public init(value: UInt8) { public init(_ value: UInt8) {
assert(value <= 7, "Mask value out of range") assert(value <= 7, "Mask value out of range")
self.value = value self.value = value
} }

@ -21,6 +21,8 @@
* Software. * Software.
*/ */
import Foundation
/// The set of all legal characters in alphanumeric mode, /// The set of all legal characters in alphanumeric mode,
/// where each character value maps to the index in the string. /// where each character value maps to the index in the string.
fileprivate let alphanumericCharset: [Character] = [ fileprivate let alphanumericCharset: [Character] = [
@ -61,23 +63,24 @@ public struct QRSegment: Hashable {
/// ///
/// Any text string can be converted to UTF-8 bytes and encoded as a byte mode segment. /// Any text string can be converted to UTF-8 bytes and encoded as a byte mode segment.
public static func makeBytes(_ data: [UInt8]) -> Self { public static func makeBytes(_ data: [UInt8]) -> Self {
var bb = BitBuffer([]) var bb = BitBuffer()
for b in data { for b in data {
bb.appendBits(UInt32(b), 8) bb.appendBits(UInt32(b), 8)
} }
return QRSegment(mode: .byte, numChars: data.count, data: bb.bits) return QRSegment(mode: .byte, numChars: UInt(data.count), data: bb.bits)
} }
/// Returns a segment representing the given string of decimal digits encoded in numeric mode. /// Returns a segment representing the given string of decimal digits encoded in numeric mode.
/// ///
/// Panics if the string contains non-digit characters. /// Panics if the string contains non-digit characters.
public static func makeNumeric(_ text: [Character]) -> Self { public static func makeNumeric(_ text: [Character]) -> Self {
var bb = BitBuffer([]) var bb = BitBuffer()
var accumData: UInt32 = 0 var accumData: UInt32 = 0
var accumCount: UInt8 = 0 var accumCount: UInt8 = 0
for c in text { for c in text {
assert(c.isNumber && c.isASCII, "String contains non-numeric characters") assert(c.isNumber && c.isASCII, "String contains non-numeric characters")
accumData = accumData * 10 + (UInt32(c.asciiValue!) - UInt32("0".asciiValue!)) let zero: Character = "0"
accumData = accumData * 10 + (UInt32(c.asciiValue!) - UInt32(zero.asciiValue!))
accumCount += 1 accumCount += 1
if accumCount == 3 { if accumCount == 3 {
bb.appendBits(accumData, 10) bb.appendBits(accumData, 10)
@ -86,9 +89,9 @@ public struct QRSegment: Hashable {
} }
} }
if accumCount > 0 { // 1 or 2 digits remaining if accumCount > 0 { // 1 or 2 digits remaining
bb.appendBits(accumData, accumCount * 3 + 1) bb.appendBits(accumData, Int(accumCount * 3 + 1))
} }
return QRSegment(mode: .numeric, numChars: text.count, data: bb.bits) return QRSegment(mode: .numeric, numChars: UInt(text.count), data: bb.bits)
} }
/// Returns a segment representing the given text string encoded in alphanumeric mode. /// Returns a segment representing the given text string encoded in alphanumeric mode.
@ -98,7 +101,7 @@ public struct QRSegment: Hashable {
/// ///
/// Panics if the string contains non-encodable characters. /// Panics if the string contains non-encodable characters.
public static func makeAlphanumeric(_ text: [Character]) -> Self { public static func makeAlphanumeric(_ text: [Character]) -> Self {
var bb = BitBuffer([]) var bb = BitBuffer()
var accumData: UInt32 = 0 var accumData: UInt32 = 0
var accumCount: UInt32 = 0 var accumCount: UInt32 = 0
for c in text { for c in text {
@ -116,14 +119,14 @@ public struct QRSegment: Hashable {
if accumCount > 0 { // 1 character remaining if accumCount > 0 { // 1 character remaining
bb.appendBits(accumData, 6) bb.appendBits(accumData, 6)
} }
return QRSegment(mode: .alphanumeric, numChars: text.count, data: bb.bits) return QRSegment(mode: .alphanumeric, numChars: UInt(text.count), data: bb.bits)
} }
/// Returns a list of zero or more segments to represent the given Unicode text string. /// Returns a list of zero or more segments to represent the given Unicode text string.
/// ///
/// The result may use various segment modes and switch /// The result may use various segment modes and switch
/// modes to optimize the length of the bit stream. /// modes to optimize the length of the bit stream.
public static func makeSegments(_ text: [Character]) -> Self { public static func makeSegments(_ text: [Character]) -> [Self] {
if text.isEmpty { if text.isEmpty {
return [] return []
} else if QRSegment.isNumeric(text) { } else if QRSegment.isNumeric(text) {
@ -139,7 +142,7 @@ public struct QRSegment: Hashable {
/// Returns a segment representing an Extended Channel Interpretation /// Returns a segment representing an Extended Channel Interpretation
/// (ECI) designator with the given assignment value. /// (ECI) designator with the given assignment value.
public static func makeECI(assignVal: UInt32) -> Self { public static func makeECI(assignVal: UInt32) -> Self {
var bb = BitBuffer([]) var bb = BitBuffer()
if assignVal < (1 << 7) { if assignVal < (1 << 7) {
bb.appendBits(assignVal, 8) bb.appendBits(assignVal, 8)
} else if assignVal < (1 << 14) { } else if assignVal < (1 << 14) {
@ -178,7 +181,7 @@ public struct QRSegment: Hashable {
guard seg.numChars < (1 << ccBits) else { guard seg.numChars < (1 << ccBits) else {
return nil // The segment"s length doesn't fit the field's bit width return nil // The segment"s length doesn't fit the field's bit width
} }
result += 4 + UInt(ccBits) + seg.data.count result += 4 + UInt(ccBits) + UInt(seg.data.count)
} }
return result return result
} }
@ -227,7 +230,7 @@ public struct QRSegment: Hashable {
case .kanji: v = [8, 10, 12] case .kanji: v = [8, 10, 12]
case .eci: v = [0, 0, 0] case .eci: v = [0, 0, 0]
} }
return v[(version.value + 7) / 17] return v[(Int(version.value) + 7) / 17]
} }
} }
} }

Loading…
Cancel
Save