canon 0.3.68 → 0.3.70

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: 590320aa865898c6342d5c96566e6313e678a6d6f31a4d1e9463a50c9f434052
4
- data.tar.gz: 6daacd998c4d52ae54096bc91329cd48686d33b7942970313891f8d69edf2141
3
+ metadata.gz: 5a8ff57b9e99197b824e486af4f029cd005cce5e263cfa7433a3e7351d356d55
4
+ data.tar.gz: 9737c271ceeaa5be0358f56f86891e02cd5c34c099721b6ba3deaaf107937256
5
5
  SHA512:
6
- metadata.gz: 5d9fe69844ee374debb42557852bdcfd3d8cd3cadb30d15f01c2e2b932ad7412339107996bb2c88f04669951b88752856c56b812d2fd4ecbd3f993390b682efe
7
- data.tar.gz: bfee82458261d1b20f78d7745da3cf620ce9beff2a993c01edcf6ff1d22f2538e8ddf7c45f21237e64f41a0218d0a25432dffcf0ea6cbcff3443cd416d4a677b
6
+ metadata.gz: d2f9294a68dc860dc315331b083b62e3661c42c69b1a44ac2984b0f29f39c998b6d90464972d04bdb763d370cc1668e8245e19a0db02eee4d1907946ab529ae1
7
+ data.tar.gz: d36159fe358cef45d398c7deb0137354dbfa5f78e45850adc28cdda30f821561797340dc0f58da1c51284d6c619f5403de52f2a7b7f1549bdcaf56ec02631c6d
data/lib/canon/cache.rb CHANGED
@@ -24,7 +24,14 @@ module Canon
24
24
  # Maximum number of entries per cache category
25
25
  MAX_CACHE_SIZE = 100
26
26
 
27
- # Fetch a value from cache, or compute and cache it
27
+ LOCK = Mutex.new
28
+
29
+ # Fetch a value from cache, or compute and cache it.
30
+ #
31
+ # The lock covers the cache operations only — never the compute
32
+ # block — so concurrent parses stay parallel; duplicate computes
33
+ # for the same key may race (last write wins), which any
34
+ # check-then-compute cache accepts.
28
35
  #
29
36
  # @param category [Symbol] Cache category (:document_parse, :format_detect, etc.)
30
37
  # @param key [String] Cache key
@@ -33,24 +40,24 @@ module Canon
33
40
  def fetch(category, key)
34
41
  cache = cache_for(category)
35
42
 
36
- # Check if key exists
37
- if cache.key?(key)
38
- # Update access time for LRU
39
- cache[key][:accessed] = Time.now
40
- return cache[key][:value]
43
+ LOCK.synchronize do
44
+ if cache.key?(key)
45
+ @clock = (@clock || 0) + 1
46
+ cache[key][:accessed] = @clock
47
+ return cache[key][:value]
48
+ end
41
49
  end
42
50
 
43
- # Compute and cache the value
44
51
  value = yield
45
52
 
46
- # Evict oldest entry if cache is full
47
- if cache.size >= MAX_CACHE_SIZE
48
- oldest_key = cache.min_by { |_, v| v[:accessed] }&.first
49
- cache.delete(oldest_key) if oldest_key
53
+ LOCK.synchronize do
54
+ if cache.size >= MAX_CACHE_SIZE
55
+ oldest_key = cache.min_by { |_, v| v[:accessed] }&.first
56
+ cache.delete(oldest_key) if oldest_key
57
+ end
58
+ @clock = (@clock || 0) + 1
59
+ cache[key] = { value: value, accessed: @clock }
50
60
  end
51
-
52
- @clock = (@clock || 0) + 1
53
- cache[key] = { value: value, accessed: @clock }
54
61
  value
55
62
  end
56
63
 
@@ -58,8 +65,10 @@ module Canon
58
65
  #
59
66
  # Useful for tests or when memory needs to be freed
60
67
  def clear_all
61
- @caches&.each_value(&:clear)
62
- @caches = nil
68
+ LOCK.synchronize do
69
+ @caches&.each_value(&:clear)
70
+ @caches = nil
71
+ end
63
72
  end
64
73
 
65
74
  # Clear a specific cache category
@@ -202,16 +202,10 @@ module Canon
202
202
  def verbose_report_proven_empty?(n1, n2, opts)
203
203
  return true unless opts[:verbose]
204
204
 
205
- # Identical input parses identically — differences and
206
- # attribute order coincide by construction. Recover errors
207
- # ride the fingerprint's diag check when the engine exposes
208
- # them (libleptris 1.9.205+, #1200); otherwise the one SAX
209
- # scan covers the parse-error banner (issue #130).
210
- if n1 == n2
211
- return true if Xml::DigestGate.recover_diags_available?
212
-
213
- return !Xml::Sax.probe(n1).saw_error?
214
- end
205
+ # Identical input parses identically, and certify has
206
+ # already declined any recover-error document through the
207
+ # wrapper's parse_diagnostics — the banner cannot be lost.
208
+ return true if n1 == n2
215
209
 
216
210
  left = Xml::Sax.probe(n1)
217
211
  return false if left.saw_error?
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.68"
4
+ VERSION = "0.3.70"
5
5
  end
@@ -21,26 +21,13 @@ module Canon
21
21
  module DigestGate
22
22
  module_function
23
23
 
24
- # libleptris 1.9.205+ records duplicate-attribute recover
25
- # events on the parsed document (#1200): read through the
26
- # FFI diag counter. Evaluated lazily at call time — a load-time
27
- # constant would freeze before leptris loads (defined? never
28
- # resolves pending autoloads). When the adapter is not leptris
29
- # (or the binding predates the surface), the verbose lane
30
- # falls back to the SAX probe for its error scan.
31
- def recover_diags_available?
32
- defined?(::Leptris::XML::FFI) &&
33
- ::Leptris::XML::FFI.respond_to?(:leptris_document_parse_diag_count)
34
- rescue StandardError
35
- false
36
- end
37
-
24
+ # moxml 0.5.76+ (moxml#271) surfaces the engine's recover
25
+ # diagnostics — duplicate-attribute events and the like (#1200)
26
+ # — as Document#parse_diagnostics. The direct-leptris-FFI
27
+ # reach-in this replaced was the gate's one documented seam
28
+ # exception; the wrapper ends it.
38
29
  def recover_diags?(doc)
39
- return false unless recover_diags_available?
40
-
41
- native = doc.native
42
- native = native.c_ptr if native.respond_to?(:c_ptr)
43
- ::Leptris::XML::FFI.leptris_document_parse_diag_count(native).positive?
30
+ !doc.parse_diagnostics.empty?
44
31
  end
45
32
 
46
33
  def available?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.68
4
+ version: 0.3.70
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-22 00:00:00.000000000 Z
11
+ date: 2026-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -44,28 +44,28 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.9.222
47
+ version: 1.9.228
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.9.222
54
+ version: 1.9.228
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: moxml
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.5.73
61
+ version: 0.5.78
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.5.73
68
+ version: 0.5.78
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: paint
71
71
  requirement: !ruby/object:Gem::Requirement