rqrcode_core 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -2
- data/README.md +56 -9
- data/lib/rqrcode_core/qrcode/qr_bit_buffer.rb +2 -2
- data/lib/rqrcode_core/qrcode/qr_code.rb +27 -27
- data/lib/rqrcode_core/qrcode/qr_math.rb +2 -2
- data/lib/rqrcode_core/qrcode/qr_segment.rb +2 -2
- data/lib/rqrcode_core/qrcode/qr_util.rb +79 -58
- data/lib/rqrcode_core/version.rb +1 -1
- metadata +58 -25
- data/.github/workflows/ruby.yml +0 -29
- data/.gitignore +0 -10
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -51
- data/Rakefile +0 -19
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/rqrcode_core.gemspec +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ae36b5e8654fbcb84247c8c60287e33f2104efa558e5eef0cd085fed1e51394
|
|
4
|
+
data.tar.gz: 462b3b44d61bde0d1a9e50eb617a8bd06f61297450339399f6db6377c0b9f61e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ca381a1dab19720731900ee4610053959fce0d2ddaa5132df2bda496d7b1d3a183e4413343d3ca48cd64b383aba15516200557ea1ae4af1cbe947e66822623f7
|
|
7
|
+
data.tar.gz: 75f36956b5f61f6762be2cbdd63409fd3d7b9df243cab6b8d25c7e8e64241ad148d496a386e446637518a872f9e21ca563b9df1d51819140f99bb9767fbcfc57
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
- Add comprehensive tests for QR code boundaries and encoding
|
|
11
|
+
- Performance optimisations: 80-90% faster QR code generation across all sizes
|
|
12
|
+
- Optimised demerit calculation functions (`demerit_points_1_same_color`, `demerit_points_2_full_blocks`, `demerit_points_3_dangerous_patterns`)
|
|
13
|
+
- Eliminated nested Range objects and redundant array lookups in hot paths
|
|
14
|
+
- Pre-computed frequently accessed values to reduce calculation overhead
|
|
15
|
+
- Large QR codes (v20) now generate in ~85ms vs ~154ms previously
|
|
16
|
+
- Memory optimisation: 70-76% reduction when using `RQRCODE_CORE_ARCH_BITS=32`
|
|
17
|
+
- Single large QR (v24): 8.53 MB → 2.92 MB
|
|
18
|
+
- Batch generation (100x v1): 37.91 MB → 9.10 MB
|
|
19
|
+
- Also provides 2-4% speed improvement due to better cache locality
|
|
20
|
+
- Add comprehensive benchmarking infrastructure with memory and performance profiling tools
|
|
21
|
+
|
|
22
|
+
## [2.0.1] - 2025-11-25
|
|
23
|
+
|
|
24
|
+
- Update required_ruby_version to support >= rather than ~> ready for Ruby 4
|
|
25
|
+
|
|
26
|
+
## [2.0.0] - 2025-04-24
|
|
27
|
+
|
|
28
|
+
- Various README updates
|
|
29
|
+
- Fix for issue #43
|
|
30
|
+
- Fix for issue #42
|
|
31
|
+
- Drop Ruby < 3 to keep up with dependency updates
|
|
32
|
+
- Add option to use ENV `RQRCODE_CORE_ARCH_BITS` to override the bits value (32 or 64) used during the encoding process.
|
|
33
|
+
This has been shown to greatly reduce the memory usage but I can't prove it doesn't break anything for all people.
|
|
34
|
+
Use at your own risk.
|
|
35
|
+
- Fixed the 'Do Your Own Rendering' example code to reflect the current interface.
|
|
36
|
+
|
|
10
37
|
## [1.2.0] - 2021-08-26
|
|
11
38
|
|
|
12
39
|
- Added Multi Mode Support which allows for multi-segment encoding. Thanks to [@ssayer](https://github.com/ssayer)
|
|
@@ -29,7 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
29
56
|
|
|
30
57
|
### Breaking Changes
|
|
31
58
|
|
|
32
|
-
- Very niche but a breaking change never the less. The `to_s` method
|
|
59
|
+
- Very niche but a breaking change never the less. The `to_s` method _no longer_ accepts the `:true` and `:false` arguments, but prefers `:dark` and `:light`.
|
|
33
60
|
|
|
34
61
|
## [0.2.0] - 2020-12-26
|
|
35
62
|
|
|
@@ -37,7 +64,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
37
64
|
|
|
38
65
|
- fix `required_ruby_version` for Ruby 3 support
|
|
39
66
|
|
|
40
|
-
[unreleased]: https://github.com/whomwah/rqrcode_core/compare/
|
|
67
|
+
[unreleased]: https://github.com/whomwah/rqrcode_core/compare/v2.0.1...HEAD
|
|
68
|
+
[2.0.1]: https://github.com/whomwah/rqrcode_core/compare/v2.0.0...v2.0.1
|
|
69
|
+
[2.0.0]: https://github.com/whomwah/rqrcode_core/compare/v1.2.0...v2.0.0
|
|
41
70
|
[1.2.0]: https://github.com/whomwah/rqrcode_core/compare/v1.1.0...v1.2.0
|
|
42
71
|
[1.1.0]: https://github.com/whomwah/rqrcode_core/compare/v1.0.0...v1.1.0
|
|
43
72
|
[1.0.0]: https://github.com/whomwah/rqrcode_core/compare/v0.2.0...v1.0.0
|
data/README.md
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
# RQRCodeCore
|
|
5
5
|
|
|
6
|
-
`rqrcode_core` is a library for encoding QR Codes in pure Ruby. It has a simple interface with all the standard
|
|
6
|
+
`rqrcode_core` is a library for encoding QR Codes in pure Ruby. It has a simple interface with all the standard QR Code options. It was originally adapted in 2008 from a Javascript library by [Kazuhiko Arase](https://github.com/kazuhikoarase).
|
|
7
7
|
|
|
8
8
|
Features:
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
- `rqrcode_core` is a Ruby only library. It requires no 3rd party libraries. Just Ruby!
|
|
11
|
+
- It is an encoding library. You can't decode QR Codes with it.
|
|
12
|
+
- The interface is simple and assumes you just want to encode a string into a QR Code, but also allows for encoding multiple segments.
|
|
13
|
+
- QR Code is trade marked by Denso Wave inc.
|
|
14
|
+
- Minimum Ruby version is `>= 3.2.0`
|
|
14
15
|
|
|
15
16
|
`rqrcode_core` is the basis of the popular `rqrcode` gem [https://github.com/whomwah/rqrcode]. This gem allows you to generate different renderings of your QR Code, including `png`, `svg` and `ansi`.
|
|
16
17
|
|
|
@@ -51,7 +52,11 @@ x xxx x xxxxx x xx x xxx x
|
|
|
51
52
|
|
|
52
53
|
```ruby
|
|
53
54
|
$ require "rqrcode_core"
|
|
54
|
-
$ qr = RQRCodeCore::QRCode.new([
|
|
55
|
+
$ qr = RQRCodeCore::QRCode.new([
|
|
56
|
+
{data: "byteencoded", mode: :byte_8bit},
|
|
57
|
+
{data: "A1" * 100, mode: :alphanumeric},
|
|
58
|
+
{data: "1" * 500, mode: :number}
|
|
59
|
+
])
|
|
55
60
|
```
|
|
56
61
|
|
|
57
62
|
This will create a QR Code with byte encoded, alphanumeric and number segments. Any combination of encodings/segments will work provided it fits within size limits.
|
|
@@ -62,7 +67,7 @@ This will create a QR Code with byte encoded, alphanumeric and number segments.
|
|
|
62
67
|
require "rqrcode_core"
|
|
63
68
|
|
|
64
69
|
qr = RQRCodeCore::QRCode.new("https://kyan.com")
|
|
65
|
-
qr.
|
|
70
|
+
qr.modules.each do |row|
|
|
66
71
|
row.each do |col|
|
|
67
72
|
print col ? "#" : " "
|
|
68
73
|
end
|
|
@@ -92,13 +97,12 @@ mode - the mode of the QR Code (defaults to alphanumeric or byte_8bit, depending
|
|
|
92
97
|
* :number
|
|
93
98
|
* :alphanumeric
|
|
94
99
|
* :byte_8bit
|
|
95
|
-
* :kanji
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
#### Example
|
|
99
103
|
|
|
100
104
|
```ruby
|
|
101
|
-
RQRCodeCore::QRCode.new("http://kyan.com", size:
|
|
105
|
+
RQRCodeCore::QRCode.new("http://kyan.com", size: 2, level: :m, mode: :byte_8bit)
|
|
102
106
|
```
|
|
103
107
|
|
|
104
108
|
## Development
|
|
@@ -128,6 +132,49 @@ $ rake standard # check
|
|
|
128
132
|
$ rake standard:fix # fix
|
|
129
133
|
```
|
|
130
134
|
|
|
135
|
+
## Performance Optimisation
|
|
136
|
+
|
|
137
|
+
### Reduce Memory Usage by 70-76%
|
|
138
|
+
|
|
139
|
+
**If you're running on a 64-bit system, you can dramatically reduce memory consumption by setting:**
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
ENV['RQRCODE_CORE_ARCH_BITS'] = '32'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Or from the command line:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
RQRCODE_CORE_ARCH_BITS=32 ruby your_script.rb
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Benchmark Results (64-bit vs 32-bit on 64-bit systems)
|
|
152
|
+
|
|
153
|
+
**Memory Savings:**
|
|
154
|
+
- Single small QR code: 0.38 MB → 0.10 MB (**74% reduction**)
|
|
155
|
+
- Single large QR code: 8.53 MB → 2.92 MB (**66% reduction**)
|
|
156
|
+
- 100 small QR codes: 37.91 MB → 9.10 MB (**76% reduction**)
|
|
157
|
+
- 10 large QR codes: 85.32 MB → 29.19 MB (**66% reduction**)
|
|
158
|
+
|
|
159
|
+
**Speed Improvement:**
|
|
160
|
+
- 2-4% faster across all scenarios (better cache utilization, reduced GC pressure)
|
|
161
|
+
|
|
162
|
+
**Object Allocation:**
|
|
163
|
+
- 85-87% fewer objects allocated
|
|
164
|
+
- Integer allocations nearly eliminated (from 70-76% to ~0%)
|
|
165
|
+
|
|
166
|
+
#### Why This Works
|
|
167
|
+
|
|
168
|
+
The QR code algorithm doesn't require 64-bit integers for its bit manipulation operations—32-bit is sufficient for all calculations. By default, Ruby on 64-bit systems uses 64-bit integers, which causes unnecessary memory allocation during the internal "right shift zero fill" operations.
|
|
169
|
+
|
|
170
|
+
**Recommendation:** Use `RQRCODE_CORE_ARCH_BITS=32` for production workloads, especially when:
|
|
171
|
+
- Generating QR codes in batch
|
|
172
|
+
- Running in memory-constrained environments
|
|
173
|
+
- Handling high-concurrency web requests
|
|
174
|
+
- Processing large QR codes (version 10+)
|
|
175
|
+
|
|
176
|
+
See `test/benchmarks/ARCH_BITS_ANALYSIS.md` for detailed benchmark data and analysis.
|
|
177
|
+
|
|
131
178
|
## Contributing
|
|
132
179
|
|
|
133
180
|
Bug reports and pull requests are welcome on GitHub at https://github.com/whomwah/rqrcode_core.
|
|
@@ -15,12 +15,12 @@ module RQRCodeCore
|
|
|
15
15
|
|
|
16
16
|
def get(index)
|
|
17
17
|
buf_index = (index / 8).floor
|
|
18
|
-
(
|
|
18
|
+
(QRUtil.rszf(@buffer[buf_index], 7 - index % 8) & 1) == 1
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def put(num, length)
|
|
22
22
|
(0...length).each do |i|
|
|
23
|
-
put_bit((
|
|
23
|
+
put_bit((QRUtil.rszf(num, length - i - 1) & 1) == 1)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module RQRCodeCore
|
|
4
4
|
QRMODE = {
|
|
5
|
-
mode_number: 1 << 0,
|
|
6
|
-
mode_alpha_numk: 1 << 1,
|
|
7
|
-
mode_8bit_byte: 1 << 2
|
|
5
|
+
mode_number: 1 << 0, # 1 (binary: 0001)
|
|
6
|
+
mode_alpha_numk: 1 << 1, # 2 (binary: 0010)
|
|
7
|
+
mode_8bit_byte: 1 << 2 # 4 (binary: 0100)
|
|
8
8
|
}.freeze
|
|
9
9
|
|
|
10
10
|
QRMODE_NAME = {
|
|
@@ -97,7 +97,6 @@ module RQRCodeCore
|
|
|
97
97
|
# * :number
|
|
98
98
|
# * :alphanumeric
|
|
99
99
|
# * :byte_8bit
|
|
100
|
-
# * :kanji
|
|
101
100
|
#
|
|
102
101
|
# qr = RQRCodeCore::QRCode.new('hello world', size: 1, level: :m, mode: :alphanumeric)
|
|
103
102
|
# segment_qr = QRCodeCore::QRCode.new({ data: 'foo', mode: :byte_8bit })
|
|
@@ -156,6 +155,7 @@ module RQRCodeCore
|
|
|
156
155
|
end
|
|
157
156
|
alias_method :dark?, :checked?
|
|
158
157
|
extend Gem::Deprecate
|
|
158
|
+
|
|
159
159
|
deprecate :dark?, :checked?, 2020, 1
|
|
160
160
|
|
|
161
161
|
# This is a public method that returns the QR Code you have
|
|
@@ -233,14 +233,14 @@ module RQRCodeCore
|
|
|
233
233
|
|
|
234
234
|
protected
|
|
235
235
|
|
|
236
|
-
def make
|
|
236
|
+
def make # :nodoc:
|
|
237
237
|
prepare_common_patterns
|
|
238
238
|
make_impl(false, get_best_mask_pattern)
|
|
239
239
|
end
|
|
240
240
|
|
|
241
241
|
private
|
|
242
242
|
|
|
243
|
-
def prepare_common_patterns
|
|
243
|
+
def prepare_common_patterns # :nodoc:
|
|
244
244
|
@modules.map! { |row| Array.new(@module_count) }
|
|
245
245
|
|
|
246
246
|
place_position_probe_pattern(0, 0)
|
|
@@ -252,7 +252,7 @@ module RQRCodeCore
|
|
|
252
252
|
@common_patterns = @modules.map(&:clone)
|
|
253
253
|
end
|
|
254
254
|
|
|
255
|
-
def make_impl(test, mask_pattern)
|
|
255
|
+
def make_impl(test, mask_pattern) # :nodoc:
|
|
256
256
|
@modules = @common_patterns.map(&:clone)
|
|
257
257
|
|
|
258
258
|
place_format_info(test, mask_pattern)
|
|
@@ -267,15 +267,15 @@ module RQRCodeCore
|
|
|
267
267
|
map_data(@data_cache, mask_pattern)
|
|
268
268
|
end
|
|
269
269
|
|
|
270
|
-
def place_position_probe_pattern(row, col)
|
|
270
|
+
def place_position_probe_pattern(row, col) # :nodoc:
|
|
271
271
|
(-1..7).each do |r|
|
|
272
272
|
next unless (row + r).between?(0, @module_count - 1)
|
|
273
273
|
|
|
274
274
|
(-1..7).each do |c|
|
|
275
275
|
next unless (col + c).between?(0, @module_count - 1)
|
|
276
276
|
|
|
277
|
-
is_vert_line =
|
|
278
|
-
is_horiz_line =
|
|
277
|
+
is_vert_line = r.between?(0, 6) && (c == 0 || c == 6)
|
|
278
|
+
is_horiz_line = c.between?(0, 6) && (r == 0 || r == 6)
|
|
279
279
|
is_square = r.between?(2, 4) && c.between?(2, 4)
|
|
280
280
|
|
|
281
281
|
is_part_of_probe = is_vert_line || is_horiz_line || is_square
|
|
@@ -284,11 +284,11 @@ module RQRCodeCore
|
|
|
284
284
|
end
|
|
285
285
|
end
|
|
286
286
|
|
|
287
|
-
def get_best_mask_pattern
|
|
287
|
+
def get_best_mask_pattern # :nodoc:
|
|
288
288
|
min_lost_point = 0
|
|
289
289
|
pattern = 0
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
8.times do |i|
|
|
292
292
|
make_impl(true, i)
|
|
293
293
|
lost_point = QRUtil.get_lost_points(modules)
|
|
294
294
|
|
|
@@ -300,13 +300,13 @@ module RQRCodeCore
|
|
|
300
300
|
pattern
|
|
301
301
|
end
|
|
302
302
|
|
|
303
|
-
def place_timing_pattern
|
|
303
|
+
def place_timing_pattern # :nodoc:
|
|
304
304
|
(8...@module_count - 8).each do |i|
|
|
305
305
|
@modules[i][6] = @modules[6][i] = i % 2 == 0
|
|
306
306
|
end
|
|
307
307
|
end
|
|
308
308
|
|
|
309
|
-
def place_position_adjust_pattern
|
|
309
|
+
def place_position_adjust_pattern # :nodoc:
|
|
310
310
|
positions = QRUtil.get_pattern_positions(@version)
|
|
311
311
|
|
|
312
312
|
positions.each do |row|
|
|
@@ -315,7 +315,7 @@ module RQRCodeCore
|
|
|
315
315
|
|
|
316
316
|
(-2..2).each do |r|
|
|
317
317
|
(-2..2).each do |c|
|
|
318
|
-
is_part_of_pattern =
|
|
318
|
+
is_part_of_pattern = r.abs == 2 || c.abs == 2 || (r == 0 && c == 0)
|
|
319
319
|
@modules[row + r][col + c] = is_part_of_pattern
|
|
320
320
|
end
|
|
321
321
|
end
|
|
@@ -323,22 +323,22 @@ module RQRCodeCore
|
|
|
323
323
|
end
|
|
324
324
|
end
|
|
325
325
|
|
|
326
|
-
def place_version_info(test)
|
|
326
|
+
def place_version_info(test) # :nodoc:
|
|
327
327
|
bits = QRUtil.get_bch_version(@version)
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
mod =
|
|
329
|
+
18.times do |i|
|
|
330
|
+
mod = !test && ((bits >> i) & 1) == 1
|
|
331
331
|
@modules[(i / 3).floor][ i % 3 + @module_count - 8 - 3 ] = mod
|
|
332
332
|
@modules[i % 3 + @module_count - 8 - 3][ (i / 3).floor ] = mod
|
|
333
333
|
end
|
|
334
334
|
end
|
|
335
335
|
|
|
336
|
-
def place_format_info(test, mask_pattern)
|
|
336
|
+
def place_format_info(test, mask_pattern) # :nodoc:
|
|
337
337
|
data = (@error_correct_level << 3 | mask_pattern)
|
|
338
338
|
bits = QRUtil.get_bch_format_info(data)
|
|
339
339
|
|
|
340
340
|
QRFORMATINFOLENGTH.times do |i|
|
|
341
|
-
mod =
|
|
341
|
+
mod = !test && ((bits >> i) & 1) == 1
|
|
342
342
|
|
|
343
343
|
# vertical
|
|
344
344
|
row = if i < 6
|
|
@@ -365,7 +365,7 @@ module RQRCodeCore
|
|
|
365
365
|
@modules[@module_count - 8][8] = !test
|
|
366
366
|
end
|
|
367
367
|
|
|
368
|
-
def map_data(data, mask_pattern)
|
|
368
|
+
def map_data(data, mask_pattern) # :nodoc:
|
|
369
369
|
inc = -1
|
|
370
370
|
row = @module_count - 1
|
|
371
371
|
bit_index = 7
|
|
@@ -375,7 +375,7 @@ module RQRCodeCore
|
|
|
375
375
|
col -= 1 if col <= 6
|
|
376
376
|
|
|
377
377
|
loop do
|
|
378
|
-
|
|
378
|
+
2.times do |c|
|
|
379
379
|
if @modules[row][col - c].nil?
|
|
380
380
|
dark = false
|
|
381
381
|
if byte_index < data.size && !data[byte_index].nil?
|
|
@@ -416,12 +416,12 @@ module RQRCodeCore
|
|
|
416
416
|
minimum_version(limit: limit, version: version + 1)
|
|
417
417
|
end
|
|
418
418
|
|
|
419
|
-
def extract_options!(arr)
|
|
419
|
+
def extract_options!(arr) # :nodoc:
|
|
420
420
|
arr.last.is_a?(::Hash) ? arr.pop : {}
|
|
421
421
|
end
|
|
422
422
|
|
|
423
423
|
class << self
|
|
424
|
-
def count_max_data_bits(rs_blocks)
|
|
424
|
+
def count_max_data_bits(rs_blocks) # :nodoc:
|
|
425
425
|
max_data_bytes = rs_blocks.reduce(0) do |sum, rs_block|
|
|
426
426
|
sum + rs_block.data_count
|
|
427
427
|
end
|
|
@@ -429,7 +429,7 @@ module RQRCodeCore
|
|
|
429
429
|
max_data_bytes * 8
|
|
430
430
|
end
|
|
431
431
|
|
|
432
|
-
def create_data(version, error_correct_level, data_list)
|
|
432
|
+
def create_data(version, error_correct_level, data_list) # :nodoc:
|
|
433
433
|
rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
|
|
434
434
|
max_data_bits = QRCode.count_max_data_bits(rs_blocks)
|
|
435
435
|
buffer = QRBitBuffer.new(version)
|
|
@@ -446,7 +446,7 @@ module RQRCodeCore
|
|
|
446
446
|
QRCode.create_bytes(buffer, rs_blocks)
|
|
447
447
|
end
|
|
448
448
|
|
|
449
|
-
def create_bytes(buffer, rs_blocks)
|
|
449
|
+
def create_bytes(buffer, rs_blocks) # :nodoc:
|
|
450
450
|
offset = 0
|
|
451
451
|
max_dc_count = 0
|
|
452
452
|
max_ec_count = 0
|
|
@@ -473,7 +473,7 @@ module RQRCodeCore
|
|
|
473
473
|
ecdata_block = Array.new(rs_poly.get_length - 1)
|
|
474
474
|
ecdata_block.size.times do |i|
|
|
475
475
|
mod_index = i + mod_poly.get_length - ecdata_block.size
|
|
476
|
-
ecdata_block[i] = mod_index >= 0 ? mod_poly.get(mod_index) : 0
|
|
476
|
+
ecdata_block[i] = (mod_index >= 0) ? mod_poly.get(mod_index) : 0
|
|
477
477
|
end
|
|
478
478
|
ecdata[r] = ecdata_block
|
|
479
479
|
end
|
|
@@ -6,7 +6,7 @@ module RQRCodeCore
|
|
|
6
6
|
exp_table = Array.new(256)
|
|
7
7
|
log_table = Array.new(256)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
8.times do |i|
|
|
10
10
|
exp_table[i] = 1 << i
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ module RQRCodeCore
|
|
|
17
17
|
^ exp_table[i - 8]
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
255.times do |i|
|
|
21
21
|
log_table[exp_table[i]] = i
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -8,7 +8,7 @@ module RQRCodeCore
|
|
|
8
8
|
@data = data
|
|
9
9
|
@mode = QRMODE_NAME.dig(mode&.to_sym)
|
|
10
10
|
|
|
11
|
-
# If mode is not
|
|
11
|
+
# If mode is not explicitly found choose mode according to data type
|
|
12
12
|
@mode ||= if RQRCodeCore::QRNumeric.valid_data?(@data)
|
|
13
13
|
QRMODE_NAME[:number]
|
|
14
14
|
elsif QRAlphanumeric.valid_data?(@data)
|
|
@@ -36,7 +36,7 @@ module RQRCodeCore
|
|
|
36
36
|
[1, 8, 0]
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
(data_length / chunk_size) * bit_length + ((data_length % chunk_size) == 0 ? 0 : extra)
|
|
39
|
+
(data_length / chunk_size) * bit_length + (((data_length % chunk_size) == 0) ? 0 : extra)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def writer
|
|
@@ -57,10 +57,25 @@ module RQRCodeCore
|
|
|
57
57
|
BITS_FOR_MODE = {
|
|
58
58
|
QRMODE[:mode_number] => [10, 12, 14],
|
|
59
59
|
QRMODE[:mode_alpha_numk] => [9, 11, 13],
|
|
60
|
-
QRMODE[:mode_8bit_byte] => [8, 16, 16]
|
|
61
|
-
QRMODE[:mode_kanji] => [8, 10, 12]
|
|
60
|
+
QRMODE[:mode_8bit_byte] => [8, 16, 16]
|
|
62
61
|
}.freeze
|
|
63
62
|
|
|
63
|
+
# This value is used during the right shift zero fill step (rszf method).
|
|
64
|
+
# Auto-set to 32 or 64 depending on system architecture (1.size * 8).
|
|
65
|
+
#
|
|
66
|
+
# PERFORMANCE IMPACT (64-bit vs 32-bit on 64-bit systems):
|
|
67
|
+
# - Memory: 70-76% reduction (e.g., 37.91 MB → 9.10 MB for 100 small QR codes)
|
|
68
|
+
# - Speed: 2-4% faster with 32-bit
|
|
69
|
+
# - Objects: 85-87% fewer allocations
|
|
70
|
+
# - All tests pass with ARCH_BITS=32
|
|
71
|
+
#
|
|
72
|
+
# RECOMMENDATION: Use RQRCODE_CORE_ARCH_BITS=32 even on 64-bit systems
|
|
73
|
+
# for dramatic memory savings with no downsides. The QR code algorithm
|
|
74
|
+
# doesn't require 64-bit integers—32-bit is sufficient for all operations.
|
|
75
|
+
#
|
|
76
|
+
# See test/benchmarks/ARCH_BITS_ANALYSIS.md for detailed benchmark data.
|
|
77
|
+
ARCH_BITS = ENV.fetch("RQRCODE_CORE_ARCH_BITS", nil)&.to_i || 1.size * 8
|
|
78
|
+
|
|
64
79
|
def self.max_size
|
|
65
80
|
PATTERN_POSITION_TABLE.count
|
|
66
81
|
end
|
|
@@ -74,8 +89,8 @@ module RQRCodeCore
|
|
|
74
89
|
end
|
|
75
90
|
|
|
76
91
|
def self.rszf(num, count)
|
|
77
|
-
# zero fill
|
|
78
|
-
(num >> count) & ((
|
|
92
|
+
# right shift zero fill
|
|
93
|
+
(num >> count) & ((1 << (ARCH_BITS - count)) - 1)
|
|
79
94
|
end
|
|
80
95
|
|
|
81
96
|
def self.get_bch_version(data)
|
|
@@ -102,9 +117,7 @@ module RQRCodeCore
|
|
|
102
117
|
end
|
|
103
118
|
|
|
104
119
|
def self.get_mask(mask_pattern, i, j)
|
|
105
|
-
if mask_pattern > QRMASKCOMPUTATIONS.size
|
|
106
|
-
raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}"
|
|
107
|
-
end
|
|
120
|
+
raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}" if mask_pattern > QRMASKCOMPUTATIONS.size
|
|
108
121
|
|
|
109
122
|
QRMASKCOMPUTATIONS[mask_pattern].call(i, j)
|
|
110
123
|
end
|
|
@@ -120,13 +133,9 @@ module RQRCodeCore
|
|
|
120
133
|
end
|
|
121
134
|
|
|
122
135
|
def self.get_length_in_bits(mode, version)
|
|
123
|
-
|
|
124
|
-
raise QRCodeRunTimeError, "Unknown mode: #{mode}"
|
|
125
|
-
end
|
|
136
|
+
raise QRCodeRunTimeError, "Unknown mode: #{mode}" unless QRMODE.value?(mode)
|
|
126
137
|
|
|
127
|
-
if version > 40
|
|
128
|
-
raise QRCodeRunTimeError, "Unknown version: #{version}"
|
|
129
|
-
end
|
|
138
|
+
raise QRCodeRunTimeError, "Unknown version: #{version}" if version > 40
|
|
130
139
|
|
|
131
140
|
if version.between?(1, 9)
|
|
132
141
|
# 1 - 9
|
|
@@ -156,28 +165,40 @@ module RQRCodeCore
|
|
|
156
165
|
def self.demerit_points_1_same_color(modules)
|
|
157
166
|
demerit_points = 0
|
|
158
167
|
module_count = modules.size
|
|
168
|
+
max_index = module_count - 1
|
|
159
169
|
|
|
160
170
|
# level1
|
|
161
|
-
|
|
162
|
-
|
|
171
|
+
module_count.times do |row|
|
|
172
|
+
modules_row = modules[row]
|
|
173
|
+
|
|
174
|
+
module_count.times do |col|
|
|
163
175
|
same_count = 0
|
|
164
|
-
dark =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
end
|
|
176
|
+
dark = modules_row[col]
|
|
177
|
+
|
|
178
|
+
# Check 3x3 neighborhood, but skip center cell
|
|
179
|
+
# Unroll loops and eliminate range objects for performance
|
|
180
|
+
|
|
181
|
+
# Row above (row - 1)
|
|
182
|
+
if row > 0
|
|
183
|
+
row_above = modules[row - 1]
|
|
184
|
+
same_count += 1 if col > 0 && dark == row_above[col - 1]
|
|
185
|
+
same_count += 1 if dark == row_above[col]
|
|
186
|
+
same_count += 1 if col < max_index && dark == row_above[col + 1]
|
|
176
187
|
end
|
|
177
188
|
|
|
178
|
-
|
|
179
|
-
|
|
189
|
+
# Same row
|
|
190
|
+
same_count += 1 if col > 0 && dark == modules_row[col - 1]
|
|
191
|
+
same_count += 1 if col < max_index && dark == modules_row[col + 1]
|
|
192
|
+
|
|
193
|
+
# Row below (row + 1)
|
|
194
|
+
if row < max_index
|
|
195
|
+
row_below = modules[row + 1]
|
|
196
|
+
same_count += 1 if col > 0 && dark == row_below[col - 1]
|
|
197
|
+
same_count += 1 if dark == row_below[col]
|
|
198
|
+
same_count += 1 if col < max_index && dark == row_below[col + 1]
|
|
180
199
|
end
|
|
200
|
+
|
|
201
|
+
demerit_points += (DEMERIT_POINTS_1 + same_count - 5) if same_count > 5
|
|
181
202
|
end
|
|
182
203
|
end
|
|
183
204
|
|
|
@@ -187,16 +208,19 @@ module RQRCodeCore
|
|
|
187
208
|
def self.demerit_points_2_full_blocks(modules)
|
|
188
209
|
demerit_points = 0
|
|
189
210
|
module_count = modules.size
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if
|
|
211
|
+
max_row = module_count - 1
|
|
212
|
+
|
|
213
|
+
# level 2: Check for 2x2 blocks of same color
|
|
214
|
+
# Only need to check (module_count - 1) x (module_count - 1) positions
|
|
215
|
+
max_row.times do |row|
|
|
216
|
+
row_curr = modules[row]
|
|
217
|
+
row_next = modules[row + 1]
|
|
218
|
+
|
|
219
|
+
max_row.times do |col|
|
|
220
|
+
# Check if all 4 modules in 2x2 block have same color
|
|
221
|
+
# (count == 0: all false, count == 4: all true)
|
|
222
|
+
val = row_curr[col]
|
|
223
|
+
if val == row_next[col] && val == row_curr[col + 1] && val == row_next[col + 1]
|
|
200
224
|
demerit_points += DEMERIT_POINTS_2
|
|
201
225
|
end
|
|
202
226
|
end
|
|
@@ -208,31 +232,27 @@ module RQRCodeCore
|
|
|
208
232
|
def self.demerit_points_3_dangerous_patterns(modules)
|
|
209
233
|
demerit_points = 0
|
|
210
234
|
module_count = modules.size
|
|
235
|
+
pattern_len = 7
|
|
236
|
+
max_start = module_count - pattern_len + 1
|
|
237
|
+
|
|
238
|
+
# level 3: Check for dangerous pattern [dark, light, dark, dark, dark, light, dark]
|
|
239
|
+
# Pattern: true, false, true, true, true, false, true (1:1:3:1:1 ratio)
|
|
211
240
|
|
|
212
|
-
#
|
|
241
|
+
# Check rows
|
|
213
242
|
modules.each do |row|
|
|
214
|
-
|
|
215
|
-
if row[
|
|
216
|
-
!row[
|
|
217
|
-
row[col_idx + 2] &&
|
|
218
|
-
row[col_idx + 3] &&
|
|
219
|
-
row[col_idx + 4] &&
|
|
220
|
-
!row[col_idx + 5] &&
|
|
221
|
-
row[col_idx + 6]
|
|
243
|
+
max_start.times do |col|
|
|
244
|
+
if row[col] && !row[col + 1] && row[col + 2] &&
|
|
245
|
+
row[col + 3] && row[col + 4] && !row[col + 5] && row[col + 6]
|
|
222
246
|
demerit_points += DEMERIT_POINTS_3
|
|
223
247
|
end
|
|
224
248
|
end
|
|
225
249
|
end
|
|
226
250
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
modules[row +
|
|
232
|
-
modules[row + 3][col] &&
|
|
233
|
-
modules[row + 4][col] &&
|
|
234
|
-
!modules[row + 5][col] &&
|
|
235
|
-
modules[row + 6][col]
|
|
251
|
+
# Check columns
|
|
252
|
+
module_count.times do |col|
|
|
253
|
+
max_start.times do |row|
|
|
254
|
+
if modules[row][col] && !modules[row + 1][col] && modules[row + 2][col] &&
|
|
255
|
+
modules[row + 3][col] && modules[row + 4][col] && !modules[row + 5][col] && modules[row + 6][col]
|
|
236
256
|
demerit_points += DEMERIT_POINTS_3
|
|
237
257
|
end
|
|
238
258
|
end
|
|
@@ -247,7 +267,8 @@ module RQRCodeCore
|
|
|
247
267
|
sum + col.count(true)
|
|
248
268
|
end
|
|
249
269
|
|
|
250
|
-
|
|
270
|
+
# Convert to float to prevent integer division
|
|
271
|
+
ratio = dark_count.to_f / (modules.size * modules.size)
|
|
251
272
|
ratio_delta = (100 * ratio - 50).abs / 5
|
|
252
273
|
|
|
253
274
|
ratio_delta * DEMERIT_POINTS_4
|
data/lib/rqrcode_core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rqrcode_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Duncan Robertson
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: benchmark-ips
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
@@ -25,47 +24,89 @@ dependencies:
|
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '2.0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: bundler
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
32
|
+
version: '4.0'
|
|
34
33
|
type: :development
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
39
|
+
version: '4.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: memory_profiler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.0'
|
|
41
54
|
- !ruby/object:Gem::Dependency
|
|
42
55
|
name: minitest
|
|
43
56
|
requirement: !ruby/object:Gem::Requirement
|
|
44
57
|
requirements:
|
|
45
58
|
- - "~>"
|
|
46
59
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
60
|
+
version: '6.0'
|
|
48
61
|
type: :development
|
|
49
62
|
prerelease: false
|
|
50
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
64
|
requirements:
|
|
52
65
|
- - "~>"
|
|
53
66
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
67
|
+
version: '6.0'
|
|
55
68
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
69
|
+
name: rake
|
|
57
70
|
requirement: !ruby/object:Gem::Requirement
|
|
58
71
|
requirements:
|
|
59
72
|
- - "~>"
|
|
60
73
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
74
|
+
version: '13.3'
|
|
62
75
|
type: :development
|
|
63
76
|
prerelease: false
|
|
64
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
78
|
requirements:
|
|
66
79
|
- - "~>"
|
|
67
80
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
81
|
+
version: '13.3'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: stackprof
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.2'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.2'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: standard
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '1.41'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '1.41'
|
|
69
110
|
description: |
|
|
70
111
|
rqrcode_core is a Ruby library for encoding QR Codes. The simple
|
|
71
112
|
interface (with no runtime dependencies) allows you to create QR Code data structures.
|
|
@@ -75,16 +116,9 @@ executables: []
|
|
|
75
116
|
extensions: []
|
|
76
117
|
extra_rdoc_files: []
|
|
77
118
|
files:
|
|
78
|
-
- ".github/workflows/ruby.yml"
|
|
79
|
-
- ".gitignore"
|
|
80
119
|
- CHANGELOG.md
|
|
81
|
-
- Gemfile
|
|
82
|
-
- Gemfile.lock
|
|
83
120
|
- LICENSE.txt
|
|
84
121
|
- README.md
|
|
85
|
-
- Rakefile
|
|
86
|
-
- bin/console
|
|
87
|
-
- bin/setup
|
|
88
122
|
- lib/rqrcode_core.rb
|
|
89
123
|
- lib/rqrcode_core/qrcode.rb
|
|
90
124
|
- lib/rqrcode_core/qrcode/qr_8bit_byte.rb
|
|
@@ -99,12 +133,12 @@ files:
|
|
|
99
133
|
- lib/rqrcode_core/qrcode/qr_segment.rb
|
|
100
134
|
- lib/rqrcode_core/qrcode/qr_util.rb
|
|
101
135
|
- lib/rqrcode_core/version.rb
|
|
102
|
-
- rqrcode_core.gemspec
|
|
103
136
|
homepage: https://github.com/whomwah/rqrcode_core
|
|
104
137
|
licenses:
|
|
105
138
|
- MIT
|
|
106
|
-
metadata:
|
|
107
|
-
|
|
139
|
+
metadata:
|
|
140
|
+
bug_tracker_uri: https://github.com/whomwah/rqrcode_core/issues
|
|
141
|
+
changelog_uri: https://github.com/whomwah/rqrcode_core/blob/main/CHANGELOG.md
|
|
108
142
|
rdoc_options: []
|
|
109
143
|
require_paths:
|
|
110
144
|
- lib
|
|
@@ -112,15 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
112
146
|
requirements:
|
|
113
147
|
- - ">="
|
|
114
148
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: '2
|
|
149
|
+
version: '3.2'
|
|
116
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
151
|
requirements:
|
|
118
152
|
- - ">="
|
|
119
153
|
- !ruby/object:Gem::Version
|
|
120
154
|
version: '0'
|
|
121
155
|
requirements: []
|
|
122
|
-
rubygems_version:
|
|
123
|
-
signing_key:
|
|
156
|
+
rubygems_version: 4.0.3
|
|
124
157
|
specification_version: 4
|
|
125
158
|
summary: A library to encode QR Codes
|
|
126
159
|
test_files: []
|
data/.github/workflows/ruby.yml
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
name: rqrcode_core
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
- release/*
|
|
8
|
-
pull_request:
|
|
9
|
-
branches:
|
|
10
|
-
- master
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
Build:
|
|
14
|
-
strategy:
|
|
15
|
-
fail-fast: false
|
|
16
|
-
matrix:
|
|
17
|
-
os: [ubuntu-latest, macos-latest]
|
|
18
|
-
ruby: [2.5, 2.6, 2.7, 3.0]
|
|
19
|
-
runs-on: ${{ matrix.os }}
|
|
20
|
-
steps:
|
|
21
|
-
- uses: actions/checkout@v1
|
|
22
|
-
- uses: ruby/setup-ruby@v1
|
|
23
|
-
with:
|
|
24
|
-
ruby-version: ${{ matrix.ruby }}
|
|
25
|
-
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
26
|
-
- name: Run Tests
|
|
27
|
-
run: bundle exec rake test
|
|
28
|
-
- name: StandardRB Check
|
|
29
|
-
run: bundle exec standardrb --format progress
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
rqrcode_core (1.2.0)
|
|
5
|
-
|
|
6
|
-
GEM
|
|
7
|
-
remote: https://rubygems.org/
|
|
8
|
-
specs:
|
|
9
|
-
ast (2.4.2)
|
|
10
|
-
minitest (5.14.4)
|
|
11
|
-
parallel (1.20.1)
|
|
12
|
-
parser (3.0.2.0)
|
|
13
|
-
ast (~> 2.4.1)
|
|
14
|
-
rainbow (3.0.0)
|
|
15
|
-
rake (13.0.6)
|
|
16
|
-
regexp_parser (2.1.1)
|
|
17
|
-
rexml (3.2.5)
|
|
18
|
-
rubocop (1.18.4)
|
|
19
|
-
parallel (~> 1.10)
|
|
20
|
-
parser (>= 3.0.0.0)
|
|
21
|
-
rainbow (>= 2.2.2, < 4.0)
|
|
22
|
-
regexp_parser (>= 1.8, < 3.0)
|
|
23
|
-
rexml
|
|
24
|
-
rubocop-ast (>= 1.8.0, < 2.0)
|
|
25
|
-
ruby-progressbar (~> 1.7)
|
|
26
|
-
unicode-display_width (>= 1.4.0, < 3.0)
|
|
27
|
-
rubocop-ast (1.9.1)
|
|
28
|
-
parser (>= 3.0.1.1)
|
|
29
|
-
rubocop-performance (1.11.4)
|
|
30
|
-
rubocop (>= 1.7.0, < 2.0)
|
|
31
|
-
rubocop-ast (>= 0.4.0)
|
|
32
|
-
ruby-progressbar (1.11.0)
|
|
33
|
-
standard (1.1.7)
|
|
34
|
-
rubocop (= 1.18.4)
|
|
35
|
-
rubocop-performance (= 1.11.4)
|
|
36
|
-
standardrb (1.0.0)
|
|
37
|
-
standard
|
|
38
|
-
unicode-display_width (2.0.0)
|
|
39
|
-
|
|
40
|
-
PLATFORMS
|
|
41
|
-
ruby
|
|
42
|
-
|
|
43
|
-
DEPENDENCIES
|
|
44
|
-
bundler (~> 2.0)
|
|
45
|
-
minitest (~> 5.0)
|
|
46
|
-
rake (~> 13.0)
|
|
47
|
-
rqrcode_core!
|
|
48
|
-
standardrb (~> 1.0)
|
|
49
|
-
|
|
50
|
-
BUNDLED WITH
|
|
51
|
-
2.2.22
|
data/Rakefile
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
begin
|
|
2
|
-
require "rake/testtask"
|
|
3
|
-
require "standard/rake"
|
|
4
|
-
|
|
5
|
-
Rake::TestTask.new(:test) do |t|
|
|
6
|
-
t.libs << "test"
|
|
7
|
-
t.libs << "lib"
|
|
8
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
task default: [:test, "standard:fix"]
|
|
12
|
-
|
|
13
|
-
desc "Run a simple benchmark (x1000)"
|
|
14
|
-
task :benchmark do
|
|
15
|
-
ruby "test/benchmark.rb"
|
|
16
|
-
end
|
|
17
|
-
rescue LoadError
|
|
18
|
-
# no standard/rspec available
|
|
19
|
-
end
|
data/bin/console
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require "bundler/setup"
|
|
4
|
-
require "rqrcode_core"
|
|
5
|
-
|
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
-
|
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
-
# require "pry"
|
|
11
|
-
# Pry.start
|
|
12
|
-
|
|
13
|
-
require "irb"
|
|
14
|
-
IRB.start(__FILE__)
|
data/bin/setup
DELETED
data/rqrcode_core.gemspec
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
lib = File.expand_path("../lib", __FILE__)
|
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
-
require "rqrcode_core/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "rqrcode_core"
|
|
7
|
-
spec.version = RQRCodeCore::VERSION
|
|
8
|
-
spec.platform = Gem::Platform::RUBY
|
|
9
|
-
spec.authors = ["Duncan Robertson"]
|
|
10
|
-
spec.email = ["duncan@whomwah.com"]
|
|
11
|
-
|
|
12
|
-
spec.summary = "A library to encode QR Codes"
|
|
13
|
-
spec.description = <<~EOF
|
|
14
|
-
rqrcode_core is a Ruby library for encoding QR Codes. The simple
|
|
15
|
-
interface (with no runtime dependencies) allows you to create QR Code data structures.
|
|
16
|
-
EOF
|
|
17
|
-
spec.homepage = "https://github.com/whomwah/rqrcode_core"
|
|
18
|
-
spec.license = "MIT"
|
|
19
|
-
|
|
20
|
-
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
|
21
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
22
|
-
end
|
|
23
|
-
spec.bindir = "exe"
|
|
24
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
25
|
-
spec.require_paths = ["lib"]
|
|
26
|
-
|
|
27
|
-
spec.required_ruby_version = ">= 2.3"
|
|
28
|
-
spec.add_development_dependency "bundler", "~> 2.0"
|
|
29
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
30
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
|
31
|
-
spec.add_development_dependency "standardrb", "~> 1.0"
|
|
32
|
-
end
|