can_messenger 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15f09405e67a906115972dc84790769875d1dcdb5cbd78a57827ccdf910d7e05
4
- data.tar.gz: faa23fc30c89b5a81875ff2664e5f97cac2970cb6161599887a1c02da9b5f36c
3
+ metadata.gz: b79b0febdca3de5f068c142413eef6f959461518e3928cd9beed52b14ee8ceef
4
+ data.tar.gz: aca5cf8fde09f75b6f0d7a81ab1bca9e6a59fc2d3d811a72321eb6b9d6b88ba9
5
5
  SHA512:
6
- metadata.gz: bb33fdda392ca2acaea5357a661b5b9dda245c41db5b000802e4d12886d58b16c49d5238312aa254f062fdc9f46c9f05b9f140f202a0ad73e1ceda9b81d397ca
7
- data.tar.gz: 4823263138efc7d61756d473e2e6235487921f7d8e6d8350260dcd80d491bee6927cbf5606671a242576fdb3f3fb5437212f77c008856c3bfa1d2b9a5b5d4924
6
+ metadata.gz: 864bd3e56da612dee5e02bd6e575eff32adab311c3090e2a874704ee7fb6f84895146294a83362be40faef5477e3951c69203f6ecd4ad094a79067d4a5928d1e
7
+ data.tar.gz: c1bc154e2b42b3373aadd0e27572d66221d3859fb5272f0594fc5d1adb1a4e1382de1e04e02e7e2171bf28b6f2a1cfc33500b4c4af0f0acd3edf35ea3b87c1f4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.1.0] - 2026-02-23
4
+
5
+ ### Changed
6
+
7
+ - Promote the first stable docs snapshot version to `2.1.0`.
8
+ - Tighten DBC signal bounds validation and report exact out-of-range bit positions.
9
+
10
+ ### Fixed
11
+
12
+ - Fix DBC big-endian (`@0`) bit mapping for multi-byte signals.
13
+ - Reject unsigned DBC signal values that exceed the field's bit-length range instead of silently wrapping.
14
+ - Align `Messenger` RBS signatures with runtime behavior (`adapter:` support and correct private method surface).
15
+ - Update DBC specs to cover the corrected big-endian behavior and unsigned overflow errors.
16
+
3
17
  ## [2.0.0] - 2026-02-02
4
18
 
5
19
  ### Changed
@@ -150,6 +164,8 @@
150
164
  ## [0.1.0] - 2024-11-10
151
165
 
152
166
  - Initial release
167
+ [Unreleased]: https://github.com/fk1018/can_messenger/compare/v2.1.0...HEAD
168
+ [2.1.0]: https://github.com/fk1018/can_messenger/compare/v2.0.0...v2.1.0
153
169
  [2.0.0]: https://github.com/fk1018/can_messenger/compare/v1.3.0...v2.0.0
154
170
  [1.3.0]: https://github.com/fk1018/can_messenger/compare/v1.2.1...v1.3.0
155
171
  [1.2.1]: https://github.com/fk1018/can_messenger/compare/v1.2.0...v1.2.1
data/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
  ## Requirements
14
14
 
15
15
  - Ruby 4.0.1 or higher.
16
+ - Docker (optional, for containerized development without installing Ruby locally).
16
17
 
17
18
  ## Installation
18
19
 
@@ -206,7 +207,58 @@ Before using `can_messenger`, please note the following:
206
207
 
207
208
  ## Development
208
209
 
209
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test:rspec` to execute the test suite.
210
+ ### Docker-first workflow (no local Ruby required)
211
+
212
+ Build the development image:
213
+
214
+ ```bash
215
+ docker compose build app
216
+ ```
217
+
218
+ Run RuboCop:
219
+
220
+ ```bash
221
+ docker compose run --rm lint
222
+ ```
223
+
224
+ Run the test suite:
225
+
226
+ ```bash
227
+ docker compose run --rm test
228
+ ```
229
+
230
+ Build the gem:
231
+
232
+ ```bash
233
+ docker compose run --rm build
234
+ ```
235
+
236
+ Install docs dependencies (Docusaurus):
237
+
238
+ ```bash
239
+ docker compose run --rm docs npm ci
240
+ ```
241
+
242
+ Build the docs site:
243
+
244
+ ```bash
245
+ docker compose run --rm docs npm run build
246
+ ```
247
+
248
+ Preview docs locally:
249
+
250
+ ```bash
251
+ docker compose run --rm --service-ports docs npm run start
252
+ ```
253
+
254
+ ### Local Ruby workflow
255
+
256
+ If you already have Ruby installed locally, you can still use:
257
+
258
+ ```bash
259
+ bin/setup
260
+ bundle exec rake test:rspec
261
+ ```
210
262
 
211
263
  ## Contributing
212
264
 
@@ -283,15 +283,15 @@ module CanMessenger
283
283
  # @return [void]
284
284
  # @raise [ArgumentError] If signal bits exceed message boundaries or start_bit is negative
285
285
  def validate_signal_bounds(message_size_bytes)
286
- max_bit = start_bit + length - 1
287
- max_allowed_bit = (message_size_bytes * 8) - 1
288
-
289
286
  raise ArgumentError, "Signal #{name}: start_bit (#{start_bit}) cannot be negative" if start_bit.negative?
287
+ raise ArgumentError, "Signal #{name}: length (#{length}) must be positive" if length <= 0
290
288
 
291
- return unless max_bit > max_allowed_bit
289
+ max_allowed_bit = max_allowed_bit_for(message_size_bytes)
290
+ invalid_position = invalid_bit_position(max_allowed_bit)
291
+ return unless invalid_position
292
292
 
293
293
  raise ArgumentError,
294
- "Signal #{name}: signal bits #{start_bit}..#{max_bit} exceed message size " \
294
+ "Signal #{name}: bit position #{invalid_position} exceeds message size " \
295
295
  "(#{message_size_bytes} bytes = #{max_allowed_bit + 1} bits)"
296
296
  end
297
297
 
@@ -328,9 +328,15 @@ module CanMessenger
328
328
  # @return [void]
329
329
  # @raise [ArgumentError] If an unsigned value is negative
330
330
  def validate_unsigned_value(raw)
331
- return unless sign == :unsigned && raw.negative?
331
+ return unless sign == :unsigned
332
+
333
+ raise ArgumentError, "Unsigned value cannot be negative: #{raw}" if raw.negative?
332
334
 
333
- raise ArgumentError, "Unsigned value cannot be negative: #{raw}"
335
+ max_val = (1 << length) - 1
336
+ return if raw <= max_val
337
+
338
+ raise ArgumentError,
339
+ "Unsigned value #{raw} out of range [0..#{max_val}] for #{length}-bit field"
334
340
  end
335
341
 
336
342
  # Validates signed values to ensure they fit in the signal's bit range.
@@ -396,19 +402,12 @@ module CanMessenger
396
402
  if endianness == :little
397
403
  start_bit + bit_offset
398
404
  else
399
- # For big-endian signals, the bit numbering within a byte follows MSB-first
400
- # ordering. This means that the most significant bit (MSB) is numbered 7,
401
- # and the least significant bit (LSB) is numbered 0. To calculate the absolute
402
- # bit position, we first determine the position of the MSB in the starting byte.
403
- #
404
- # The formula ((start_bit / 8) * 8) calculates the starting byte's base bit
405
- # position (aligned to the nearest multiple of 8). Adding (7 - (start_bit % 8))
406
- # adjusts this base position to point to the MSB of the starting byte.
407
- #
408
- # Finally, we subtract the bit offset to account for the signal's length and
409
- # position within the message.
410
- base = ((start_bit / 8) * 8) + (7 - (start_bit % 8))
411
- base - bit_offset
405
+ # DBC big-endian (`@0`) start_bit is in sawtooth numbering and points at the
406
+ # signal MSB. Convert to sequential network numbering, move toward the LSB,
407
+ # then convert back to the little-endian bit index used by byte writes.
408
+ network_start = sawtooth_to_network_bitnum(start_bit)
409
+ network_bit = network_start + (length - 1 - bit_offset)
410
+ sawtooth_to_network_bitnum(network_bit)
412
411
  end
413
412
  end
414
413
 
@@ -511,5 +510,22 @@ module CanMessenger
511
510
  msb_set = (value >> (length - 1)).allbits?(1)
512
511
  msb_set ? value - (1 << length) : value
513
512
  end
513
+
514
+ def sawtooth_to_network_bitnum(bitnum)
515
+ (8 * (bitnum / 8)) + (7 - (bitnum % 8))
516
+ end
517
+
518
+ def invalid_bit_position(max_allowed_bit)
519
+ length.times do |i|
520
+ bit_pos = calculate_bit_position(i)
521
+ return bit_pos if bit_pos.negative? || bit_pos > max_allowed_bit
522
+ end
523
+
524
+ nil
525
+ end
526
+
527
+ def max_allowed_bit_for(message_size_bytes)
528
+ (message_size_bytes * 8) - 1
529
+ end
514
530
  end
515
531
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CanMessenger
4
- VERSION = "2.0.0"
4
+ VERSION = "2.1.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: can_messenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fk1018