dcc 0.2.1 → 0.2.3
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/dcc.gemspec +3 -2
- data/lib/dcc/cli/cli.rb +122 -14
- data/lib/dcc/extract/formula/ast.rb +137 -0
- data/lib/dcc/extract/formula/evaluator.rb +357 -0
- data/lib/dcc/extract/formula/parser.rb +305 -0
- data/lib/dcc/extract/formula/quantity.rb +89 -0
- data/lib/dcc/extract/formula.rb +110 -0
- data/lib/dcc/quantity_math/complex.rb +252 -0
- data/lib/dcc/quantity_math/matrix.rb +217 -0
- data/lib/dcc/quantity_math.rb +30 -2
- data/lib/dcc/streaming/reader.rb +246 -0
- data/lib/dcc/streaming.rb +79 -0
- data/lib/dcc/version.rb +1 -1
- data/lib/dcc.rb +13 -3
- metadata +29 -6
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "moxml"
|
|
4
|
+
|
|
5
|
+
module Dcc
|
|
6
|
+
module Streaming
|
|
7
|
+
# SAX handler that reconstructs each matched subtree as a standalone XML
|
|
8
|
+
# fragment, parses it into the version-appropriate model, yields it, and
|
|
9
|
+
# drops it. Only one subtree is buffered at a time, so peak memory tracks
|
|
10
|
+
# the largest single subtree rather than the document.
|
|
11
|
+
#
|
|
12
|
+
# The fragment reproduces the XML infoset, not the original bytes.
|
|
13
|
+
# Entity references arrive expanded, CDATA becomes text, processing
|
|
14
|
+
# instruction spacing is normalised, and every namespace in scope is
|
|
15
|
+
# re-declared on the fragment root so prefixes still resolve once the
|
|
16
|
+
# subtree is detached.
|
|
17
|
+
class Reader < ::Moxml::SAX::Handler
|
|
18
|
+
# Stream `io`, yielding one model per matched subtree.
|
|
19
|
+
#
|
|
20
|
+
# @param io [IO, StringIO] readable XML stream.
|
|
21
|
+
# @param model_id [Symbol] registered model id, `:item` or `:quantity`.
|
|
22
|
+
# @param version [Integer, nil] major DCC version. When nil it is read
|
|
23
|
+
# from the first `schemaVersion` attribute seen outside a matched
|
|
24
|
+
# subtree before the first model is yielded, and falls back to 3.
|
|
25
|
+
# `Dcc.detect_version` instead scans the whole document lexically,
|
|
26
|
+
# because it is not restricted to a single pass.
|
|
27
|
+
# @param context [Symbol, String, nil] substitution context.
|
|
28
|
+
# @return [void]
|
|
29
|
+
# @raise [Dcc::ParseError] if the stream is not well-formed XML. A
|
|
30
|
+
# failing IO also surfaces this way, with the original IO message
|
|
31
|
+
# replaced by the parser's — libxml2 does not pass it through.
|
|
32
|
+
def self.call(io, model_id:, version:, context:, &)
|
|
33
|
+
handler = new(model_id:, version:, context:, &)
|
|
34
|
+
adapter = ::Lutaml::Model::Config.xml_adapter_type
|
|
35
|
+
::Moxml.new(adapter).sax_parse(io, handler)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# A handler carries one document's worth of state, so `.call` builds a
|
|
39
|
+
# fresh one per stream and construction stays closed.
|
|
40
|
+
private_class_method :new
|
|
41
|
+
|
|
42
|
+
def initialize(model_id:, version:, context:, &block)
|
|
43
|
+
super()
|
|
44
|
+
@model_id = model_id
|
|
45
|
+
@major = version
|
|
46
|
+
@context = context
|
|
47
|
+
@block = block
|
|
48
|
+
@scopes = [{}]
|
|
49
|
+
@subtree = nil
|
|
50
|
+
@depth = 0
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Declarations are merged and snapshotted before the element's own
|
|
54
|
+
# prefix is resolved, so an element that rebinds its prefix matches on
|
|
55
|
+
# its new binding rather than the inherited one.
|
|
56
|
+
def on_start_element(name, attributes = {}, namespaces = {})
|
|
57
|
+
# Almost no element declares a namespace, so merging every time would
|
|
58
|
+
# allocate a copy of the parent scope per element. Scopes are only
|
|
59
|
+
# ever read, so the unchanged ones can share one hash.
|
|
60
|
+
@scopes.push(
|
|
61
|
+
namespaces.empty? ? @scopes.last : @scopes.last.merge(namespaces),
|
|
62
|
+
)
|
|
63
|
+
return begin_subtree(name, attributes) unless @subtree
|
|
64
|
+
|
|
65
|
+
@depth += 1
|
|
66
|
+
@subtree.start_element(name, attributes, namespaces)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def on_end_element(name)
|
|
70
|
+
finish_element(name) if @subtree
|
|
71
|
+
@scopes.pop
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def on_characters(text)
|
|
75
|
+
@subtree&.characters(text)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def on_cdata(text)
|
|
79
|
+
@subtree&.characters(text)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def on_comment(text)
|
|
83
|
+
@subtree&.comment(text)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def on_processing_instruction(target, data)
|
|
87
|
+
@subtree&.processing_instruction(target, data)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Translated here rather than around the whole parse, so an exception
|
|
91
|
+
# raised by the consumer block travels untouched instead of being
|
|
92
|
+
# reported as malformed input.
|
|
93
|
+
def on_error(error)
|
|
94
|
+
raise ::Dcc::ParseError, error.message
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# Only elements outside a matched subtree get a say in the version, so a
|
|
100
|
+
# `schemaVersion` on a descendant — or inside an opaque `dcc:xml` blob —
|
|
101
|
+
# cannot choose the parser for the whole stream.
|
|
102
|
+
def begin_subtree(name, attributes)
|
|
103
|
+
@major ||= schema_version_major(name, attributes)
|
|
104
|
+
return unless match?(name)
|
|
105
|
+
|
|
106
|
+
@depth = 0
|
|
107
|
+
@subtree = Subtree.new(name, attributes, @scopes.last)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def finish_element(name)
|
|
111
|
+
@subtree.end_element(name)
|
|
112
|
+
if @depth.zero?
|
|
113
|
+
emit(@subtree.to_xml)
|
|
114
|
+
@subtree = nil
|
|
115
|
+
else
|
|
116
|
+
@depth -= 1
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def emit(xml)
|
|
121
|
+
@block.call(model_class.from_xml(xml, register: context_id))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def match?(name)
|
|
125
|
+
split(name).last == @model_id.to_s && dcc_element?(name)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def dcc_element?(name)
|
|
129
|
+
dcc_namespace?(@scopes.last[split(name).first])
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# `Dcc::Namespace::Dcc` also accepts the `.xsd` alias that older PTB
|
|
133
|
+
# documents bind, so streaming matches whatever `Dcc.parse` accepts.
|
|
134
|
+
def dcc_namespace?(uri)
|
|
135
|
+
namespace = ::Dcc::Namespace::Dcc
|
|
136
|
+
uri == namespace.uri || namespace.uri_aliases.include?(uri)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def split(name)
|
|
140
|
+
prefix, local = name.split(":", 2)
|
|
141
|
+
local ? [prefix, local] : [nil, prefix]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Resolved through the registry rather than referenced directly, so a
|
|
145
|
+
# configured custom model substitutes the root class too.
|
|
146
|
+
def model_class
|
|
147
|
+
@model_class ||=
|
|
148
|
+
::Lutaml::Model::GlobalContext.resolve_type(@model_id, context_id)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def context_id
|
|
152
|
+
@context_id ||= ::Dcc::ContextOptions.normalize_context_option(
|
|
153
|
+
context: @context,
|
|
154
|
+
register: nil,
|
|
155
|
+
default_context: configuration.default_context_id,
|
|
156
|
+
warning_source: "Dcc::Streaming",
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def configuration
|
|
161
|
+
::Dcc.parser_for(major)::Configuration
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# `schemaVersion` sits on the DCC root, which is not always the document
|
|
165
|
+
# root — a certificate can arrive wrapped in an envelope. Only a DCC
|
|
166
|
+
# element settles the version, so a wrapper carrying a `schemaVersion`
|
|
167
|
+
# of its own does not retype the certificate nested inside it.
|
|
168
|
+
def schema_version_major(name, attributes)
|
|
169
|
+
version = attributes["schemaVersion"]
|
|
170
|
+
return unless version && dcc_element?(name)
|
|
171
|
+
|
|
172
|
+
::Dcc.major_version_from(version)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# A document that declares `schemaVersion` nowhere falls back the way an
|
|
176
|
+
# unusable one does, so `Dcc` keeps deciding that rather than a literal
|
|
177
|
+
# repeated here. The answer is written back rather than defaulted on
|
|
178
|
+
# each read: the model class and the context are memoised off this at
|
|
179
|
+
# the first yield, so a `schemaVersion` appearing later must not move
|
|
180
|
+
# the version out from under them.
|
|
181
|
+
def major
|
|
182
|
+
@major ||= ::Dcc.major_version_from(nil)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Accumulates the raw XML of a single matched subtree.
|
|
186
|
+
#
|
|
187
|
+
# SAX hands over decoded characters, so control whitespace has to go
|
|
188
|
+
# back as character references. Written literally it would be
|
|
189
|
+
# normalised a second time on reparse — a carriage return in text
|
|
190
|
+
# would arrive as a newline, and a tab or newline in an attribute
|
|
191
|
+
# would collapse to a space.
|
|
192
|
+
#
|
|
193
|
+
# C14N mandates exactly that set of character references, so moxml's
|
|
194
|
+
# encoder is reused rather than restating the table here.
|
|
195
|
+
class Subtree
|
|
196
|
+
def initialize(name, attributes, scope)
|
|
197
|
+
@buffer = +""
|
|
198
|
+
write_start(name, attributes, scope)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def start_element(name, attributes, namespaces)
|
|
202
|
+
write_start(name, attributes, namespaces)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def end_element(name)
|
|
206
|
+
@buffer << "</#{name}>"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def characters(text)
|
|
210
|
+
@buffer << ::Moxml::C14n.escape_text(text)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def comment(text)
|
|
214
|
+
@buffer << "<!--#{text}-->"
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def processing_instruction(target, data)
|
|
218
|
+
@buffer << "<?#{target} #{data}?>"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def to_xml
|
|
222
|
+
@buffer
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
private
|
|
226
|
+
|
|
227
|
+
def write_start(name, attributes, namespaces)
|
|
228
|
+
@buffer << "<#{name}"
|
|
229
|
+
namespaces.each do |prefix, href|
|
|
230
|
+
write_attribute(prefix ? "xmlns:#{prefix}" : "xmlns", href)
|
|
231
|
+
end
|
|
232
|
+
attributes.each do |key, value|
|
|
233
|
+
write_attribute(key, value)
|
|
234
|
+
end
|
|
235
|
+
@buffer << ">"
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def write_attribute(name, value)
|
|
239
|
+
escaped = ::Moxml::C14n.escape_attribute(value)
|
|
240
|
+
@buffer << %( #{name}="#{escaped}")
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
private_constant :Subtree
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# `Dcc::Streaming` walks a DCC document one subtree at a time, so a batch
|
|
4
|
+
# pipeline can process a multi-MB certificate without holding the whole
|
|
5
|
+
# object tree in memory. Each matched subtree is reconstructed on its own,
|
|
6
|
+
# parsed into the version-appropriate model, yielded, and dropped.
|
|
7
|
+
#
|
|
8
|
+
# @example Walk every calibrated item
|
|
9
|
+
# File.open("certificate.xml") do |io|
|
|
10
|
+
# Dcc::Streaming.each_item(io) { |item| puts item.id }
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# @example Take the first two quantities without reading the whole document
|
|
14
|
+
# Dcc::Streaming.each_quantity(io).first(2)
|
|
15
|
+
#
|
|
16
|
+
# Version detection differs from `Dcc.parse`. Streaming reads `schemaVersion`
|
|
17
|
+
# off a real DCC element, so a certificate wrapped in an envelope is detected
|
|
18
|
+
# from its own root even when the envelope carries a `schemaVersion` of its
|
|
19
|
+
# own. `Dcc.detect_version` scans the document lexically instead, so it also
|
|
20
|
+
# matches a `schemaVersion=` inside a comment, inside text or CDATA, on a
|
|
21
|
+
# prefixed attribute such as `f:schemaVersion`, or on a foreign wrapper
|
|
22
|
+
# element. The two can disagree on those documents, and streaming is the one
|
|
23
|
+
# reading the schema's actual attribute. Pass `version:` to settle it.
|
|
24
|
+
module Dcc
|
|
25
|
+
module Streaming
|
|
26
|
+
autoload :Reader, "dcc/streaming/reader"
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
# Yield each `dcc:item` in document order.
|
|
30
|
+
#
|
|
31
|
+
# @param io [IO, StringIO] readable XML stream.
|
|
32
|
+
# @param version [Integer, nil] major DCC version (2 or 3). When nil it
|
|
33
|
+
# is detected from the first `schemaVersion` attribute seen outside a
|
|
34
|
+
# matched subtree before the first item is yielded, and falls back to
|
|
35
|
+
# 3. See the note on version detection above.
|
|
36
|
+
# @param context [Symbol, String, nil] substitution context. Defaults
|
|
37
|
+
# to the version's configured context.
|
|
38
|
+
# @yieldparam [Dcc::V2::Item, Dcc::V3::Item]
|
|
39
|
+
# @return [Enumerator] when no block is given.
|
|
40
|
+
# @raise [Dcc::ParseError] if the stream is not well-formed XML.
|
|
41
|
+
def each_item(io, version: nil,
|
|
42
|
+
context: ::Dcc::UNSPECIFIED_CONTEXT, &block)
|
|
43
|
+
return enum_for(:each_item, io, version:, context:) unless block
|
|
44
|
+
|
|
45
|
+
stream(io, :item, version, context, &block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Yield each outermost `dcc:quantity` in document order.
|
|
49
|
+
#
|
|
50
|
+
# A quantity nested inside another quantity's `influenceConditions` is
|
|
51
|
+
# not yielded on its own — it is reachable from the outer object.
|
|
52
|
+
#
|
|
53
|
+
# @param io [IO, StringIO] readable XML stream.
|
|
54
|
+
# @param version [Integer, nil] major DCC version (2 or 3). Detected the
|
|
55
|
+
# same way `each_item` detects it when nil.
|
|
56
|
+
# @param context [Symbol, String, nil] substitution context.
|
|
57
|
+
# @yieldparam [Dcc::V2::Quantity, Dcc::V3::Quantity]
|
|
58
|
+
# @return [Enumerator] when no block is given.
|
|
59
|
+
# @raise [Dcc::ParseError] if the stream is not well-formed XML.
|
|
60
|
+
def each_quantity(io, version: nil,
|
|
61
|
+
context: ::Dcc::UNSPECIFIED_CONTEXT, &block)
|
|
62
|
+
return enum_for(:each_quantity, io, version:, context:) unless block
|
|
63
|
+
|
|
64
|
+
stream(io, :quantity, version, context, &block)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# `version` is validated here rather than on first match, so an
|
|
70
|
+
# unsupported value raises the same way regardless of what the
|
|
71
|
+
# document happens to contain.
|
|
72
|
+
def stream(io, model_id, version, context, &)
|
|
73
|
+
::Dcc.parser_for(version) if version
|
|
74
|
+
::Dcc.load_all!
|
|
75
|
+
Reader.call(io, model_id:, version:, context:, &)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/lib/dcc/version.rb
CHANGED
data/lib/dcc.rb
CHANGED
|
@@ -41,6 +41,7 @@ module Dcc
|
|
|
41
41
|
autoload :QuantityFormat, "dcc/quantity_format"
|
|
42
42
|
autoload :QuantityMath, "dcc/quantity_math"
|
|
43
43
|
autoload :Signature, "dcc/signature"
|
|
44
|
+
autoload :Streaming, "dcc/streaming"
|
|
44
45
|
autoload :Transform, "dcc/transform"
|
|
45
46
|
autoload :Validate, "dcc/validate"
|
|
46
47
|
autoload :Server, "dcc/server"
|
|
@@ -151,9 +152,18 @@ module Dcc
|
|
|
151
152
|
# @return [Integer] 2 or 3.
|
|
152
153
|
def detect_version(input)
|
|
153
154
|
str = read_input(input)
|
|
154
|
-
match = str.match(/schemaVersion\s*=\s*["'](\d
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
match = str.match(/schemaVersion\s*=\s*["'](\d+\.)/)
|
|
156
|
+
major_version_from(match && match[1])
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Map a `schemaVersion` attribute value to its major DCC version.
|
|
160
|
+
# Only a leading run of digits followed by a dot counts; anything else
|
|
161
|
+
# (missing, malformed, or an unsupported major) resolves to 3.
|
|
162
|
+
# @param schema_version [String, nil] e.g. "2.3.0".
|
|
163
|
+
# @return [Integer] 2 or 3.
|
|
164
|
+
def major_version_from(schema_version)
|
|
165
|
+
match = schema_version.to_s.match(/\A(\d+)\./)
|
|
166
|
+
match && match[1].to_i == 2 ? 2 : 3
|
|
157
167
|
end
|
|
158
168
|
|
|
159
169
|
# Read an input that may be a String or an IO-like object.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dcc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
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-
|
|
11
|
+
date: 2026-11-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bigdecimal
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: csv
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,14 +86,14 @@ dependencies:
|
|
|
72
86
|
requirements:
|
|
73
87
|
- - "~>"
|
|
74
88
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 0.8.
|
|
89
|
+
version: 0.8.156
|
|
76
90
|
type: :runtime
|
|
77
91
|
prerelease: false
|
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
93
|
requirements:
|
|
80
94
|
- - "~>"
|
|
81
95
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 0.8.
|
|
96
|
+
version: 0.8.156
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: mml
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,14 +114,14 @@ dependencies:
|
|
|
100
114
|
requirements:
|
|
101
115
|
- - "~>"
|
|
102
116
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
117
|
+
version: 0.6.0
|
|
104
118
|
type: :runtime
|
|
105
119
|
prerelease: false
|
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
121
|
requirements:
|
|
108
122
|
- - "~>"
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
124
|
+
version: 0.6.0
|
|
111
125
|
- !ruby/object:Gem::Dependency
|
|
112
126
|
name: nokogiri
|
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -240,6 +254,11 @@ files:
|
|
|
240
254
|
- lib/dcc/error.rb
|
|
241
255
|
- lib/dcc/extract.rb
|
|
242
256
|
- lib/dcc/extract/file.rb
|
|
257
|
+
- lib/dcc/extract/formula.rb
|
|
258
|
+
- lib/dcc/extract/formula/ast.rb
|
|
259
|
+
- lib/dcc/extract/formula/evaluator.rb
|
|
260
|
+
- lib/dcc/extract/formula/parser.rb
|
|
261
|
+
- lib/dcc/extract/formula/quantity.rb
|
|
243
262
|
- lib/dcc/extract/ring.rb
|
|
244
263
|
- lib/dcc/i18n.rb
|
|
245
264
|
- lib/dcc/i18n/text_lookup.rb
|
|
@@ -260,6 +279,8 @@ files:
|
|
|
260
279
|
- lib/dcc/quantity_format.rb
|
|
261
280
|
- lib/dcc/quantity_format/formatter.rb
|
|
262
281
|
- lib/dcc/quantity_math.rb
|
|
282
|
+
- lib/dcc/quantity_math/complex.rb
|
|
283
|
+
- lib/dcc/quantity_math/matrix.rb
|
|
263
284
|
- lib/dcc/quantity_math/quantity.rb
|
|
264
285
|
- lib/dcc/quantity_math/real.rb
|
|
265
286
|
- lib/dcc/schema.rb
|
|
@@ -363,6 +384,8 @@ files:
|
|
|
363
384
|
- lib/dcc/signature/result.rb
|
|
364
385
|
- lib/dcc/signature/signer.rb
|
|
365
386
|
- lib/dcc/signature/verifier.rb
|
|
387
|
+
- lib/dcc/streaming.rb
|
|
388
|
+
- lib/dcc/streaming/reader.rb
|
|
366
389
|
- lib/dcc/transform.rb
|
|
367
390
|
- lib/dcc/transform/result.rb
|
|
368
391
|
- lib/dcc/transform/xslt.rb
|