Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A bit of overdue housekeeping #22

Merged
merged 9 commits into from Jul 1, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Add a basic benchmark file
- Add standardRB badge
- Add `.freeze` on `CONST` lookup objects
- Remove unused `@mode` instance variable
- A batch of small refactors and optimizations

## [1.0.0] - 2021-04-23

### Changed
Expand Down
1 change: 1 addition & 0 deletions README.md
@@ -1,4 +1,5 @@
![](https://github.com/whomwah/rqrcode_core/actions/workflows/ruby.yml/badge.svg)
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)

# RQRCodeCore

Expand Down
5 changes: 5 additions & 0 deletions Rakefile
Expand Up @@ -9,6 +9,11 @@ begin
end

task default: [:test, "standard:fix"]

desc "Run a simple benchmark (x1000)"
task :benchmark do
ruby "test/benchmark.rb"
end
rescue LoadError
# no standard/rspec available
end
10 changes: 2 additions & 8 deletions lib/rqrcode_core/qrcode/qr_8bit_byte.rb
Expand Up @@ -2,19 +2,13 @@

module RQRCodeCore
class QR8bitByte
attr_reader :mode

def initialize(data)
@mode = QRMODE[:mode_8bit_byte]
@data = data
end

def get_length
@data.bytesize
end

def write(buffer)
buffer.byte_encoding_start(get_length)
buffer.byte_encoding_start(@data.bytesize)

@data.each_byte do |b|
buffer.put(b, 8)
end
Expand Down
27 changes: 11 additions & 16 deletions lib/rqrcode_core/qrcode/qr_alphanumeric.rb
@@ -1,32 +1,27 @@
# frozen_string_literal: true

module RQRCodeCore
ALPHANUMERIC = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "$", "%", "*", "+", "-", ".", "/", ":"]
ALPHANUMERIC = [
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "$",
"%", "*", "+", "-", ".", "/", ":"
].freeze

class QRAlphanumeric
attr_reader :mode

def initialize(data)
@mode = QRMODE[:mode_alpha_numk]

raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`" unless QRAlphanumeric.valid_data?(data)
unless QRAlphanumeric.valid_data?(data)
raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`"
end

@data = data
end

def get_length
@data.size
end

def self.valid_data? data
data.each_char do |s|
return false if ALPHANUMERIC.index(s).nil?
end
true
def self.valid_data?(data)
(data.chars - ALPHANUMERIC).empty?
end

def write(buffer)
buffer.alphanumeric_encoding_start(get_length)
buffer.alphanumeric_encoding_start(@data.size)

@data.size.times do |i|
if i % 2 == 0
Expand Down
4 changes: 2 additions & 2 deletions lib/rqrcode_core/qrcode/qr_bit_buffer.rb
Expand Up @@ -64,8 +64,8 @@ def pad_until(prefered_size)

# Pad with padding code words
while get_length_in_bits < prefered_size
put(QRBitBuffer::PAD0, 8)
put(QRBitBuffer::PAD1, 8) if get_length_in_bits < prefered_size
put(PAD0, 8)
put(PAD1, 8) if get_length_in_bits < prefered_size
end
end

Expand Down
16 changes: 8 additions & 8 deletions lib/rqrcode_core/qrcode/qr_code.rb
Expand Up @@ -5,20 +5,20 @@ module RQRCodeCore
mode_number: 1 << 0,
mode_alpha_numk: 1 << 1,
mode_8bit_byte: 1 << 2
}
}.freeze

QRMODE_NAME = {
number: :mode_number,
alphanumeric: :mode_alpha_numk,
byte_8bit: :mode_8bit_byte
}
}.freeze

QRERRORCORRECTLEVEL = {
l: 1,
m: 0,
q: 3,
h: 2
}
}.freeze

QRMASKPATTERN = {
pattern000: 0,
Expand All @@ -29,7 +29,7 @@ module RQRCodeCore
pattern101: 5,
pattern110: 6,
pattern111: 7
}
}.freeze

QRMASKCOMPUTATIONS = [
proc { |i, j| (i + j) % 2 == 0 },
Expand All @@ -40,7 +40,7 @@ module RQRCodeCore
proc { |i, j| (i * j) % 2 + (i * j) % 3 == 0 },
proc { |i, j| ((i * j) % 2 + (i * j) % 3) % 2 == 0 },
proc { |i, j| ((i * j) % 3 + (i + j) % 2) % 2 == 0 }
]
].freeze

QRPOSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
QRFORMATINFOLENGTH = 15
Expand Down Expand Up @@ -132,7 +132,7 @@ module RQRCodeCore
790, 842, 898, 958, 983, 1051, 1093, 1139, 1219, 1273
]
}
}
}.freeze

# StandardErrors

Expand Down Expand Up @@ -314,7 +314,7 @@ def make #:nodoc:

private

def prepare_common_patterns
def prepare_common_patterns #:nodoc:
@modules.map! { |row| Array.new(@module_count) }

place_position_probe_pattern(0, 0)
Expand Down Expand Up @@ -490,7 +490,7 @@ def extract_options!(arr) #:nodoc:
end

class << self
def count_max_data_bits(rs_blocks)
def count_max_data_bits(rs_blocks) #:nodoc:
max_data_bytes = rs_blocks.reduce(0) do |sum, rs_block|
sum + rs_block.data_count
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rqrcode_core/qrcode/qr_math.rb
Expand Up @@ -21,8 +21,8 @@ class QRMath
log_table[exp_table[i]] = i
end

const_set(:EXP_TABLE, exp_table)
const_set(:LOG_TABLE, log_table)
const_set(:EXP_TABLE, exp_table).freeze
const_set(:LOG_TABLE, log_table).freeze
}

class << self
Expand Down
19 changes: 4 additions & 15 deletions lib/rqrcode_core/qrcode/qr_numeric.rb
@@ -1,32 +1,21 @@
# frozen_string_literal: true

module RQRCodeCore
NUMERIC = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].freeze
NUMERIC = %w[0 1 2 3 4 5 6 7 8 9].freeze

class QRNumeric
attr_reader :mode

def initialize(data)
@mode = QRMODE[:mode_number]

raise QRCodeArgumentError, "Not a numeric string `#{data}`" unless QRNumeric.valid_data?(data)

@data = data
end

def get_length
@data.size
end

def self.valid_data? data
data.each_char do |s|
return false if NUMERIC.index(s).nil?
end
true
def self.valid_data?(data)
(data.chars - NUMERIC).empty?
end

def write(buffer)
buffer.numeric_encoding_start(get_length)
buffer.numeric_encoding_start(@data.size)

@data.size.times do |i|
if i % 3 == 0
Expand Down
4 changes: 2 additions & 2 deletions lib/rqrcode_core/qrcode/qr_rs_block.rb
Expand Up @@ -10,7 +10,7 @@ def initialize(total_count, data_count)
end

# http://www.thonky.com/qr-code-tutorial/error-correction-table/
RQRCodeCore::QRRSBlock::RS_BLOCK_TABLE = [
RS_BLOCK_TABLE = [
# L
# M
# Q
Expand Down Expand Up @@ -256,7 +256,7 @@ def initialize(total_count, data_count)
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16]

]
].freeze

def self.get_rs_blocks(version, error_correct_level)
rs_block = QRRSBlock.get_rs_block_table(version, error_correct_level)
Expand Down
4 changes: 2 additions & 2 deletions lib/rqrcode_core/qrcode/qr_util.rb
Expand Up @@ -43,7 +43,7 @@ class QRUtil
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
]
].freeze

G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0
G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0
Expand All @@ -59,7 +59,7 @@ class QRUtil
QRMODE[:mode_alpha_numk] => [9, 11, 13],
QRMODE[:mode_8bit_byte] => [8, 16, 16],
QRMODE[:mode_kanji] => [8, 10, 12]
}
}.freeze

def self.max_size
PATTERN_POSITION_TABLE.count
Expand Down
11 changes: 11 additions & 0 deletions test/benchmark.rb
@@ -0,0 +1,11 @@
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "rqrcode_core"
require "benchmark"

Benchmark.bm do |benchmark|
benchmark.report("RQRCode") do
1000.times do
RQRCodeCore::QRCode.new("https://kyan.com").to_s
end
end
end