xlsxrb 0.1.7 → 0.1.9

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -2
  3. data/README.md +125 -36
  4. data/Rakefile +36 -7
  5. data/benchmark.rb +32 -4
  6. data/docs/ARCHITECTURE.md +32 -30
  7. data/docs/DEVELOPMENT.md +11 -3
  8. data/docs/QUALITY_ASSURANCE.md +3 -4
  9. data/docs/SPEC_SOURCES.md +7 -1
  10. data/docs/visual/VisualGallery.md +157 -157
  11. data/docs/wasm/ruby.wasm +0 -0
  12. data/lib/ruby_lsp/xlsxrb/addon.rb +1 -1
  13. data/lib/ruby_lsp/xlsxrb/completion_listener.rb +11 -13
  14. data/lib/xlsxrb/elements/coordinate_access.rb +101 -0
  15. data/lib/xlsxrb/elements/row.rb +2 -2
  16. data/lib/xlsxrb/elements/workbook.rb +20 -2
  17. data/lib/xlsxrb/elements/worksheet.rb +94 -124
  18. data/lib/xlsxrb/elements.rb +1 -0
  19. data/lib/xlsxrb/ooxml/cfb.rb +490 -0
  20. data/lib/xlsxrb/ooxml/crypto/agile.rb +285 -0
  21. data/lib/xlsxrb/ooxml/crypto/standard.rb +152 -0
  22. data/lib/xlsxrb/ooxml/crypto.rb +60 -0
  23. data/lib/xlsxrb/ooxml/worksheet_parser.rb +21 -15
  24. data/lib/xlsxrb/stream_row.rb +181 -0
  25. data/lib/xlsxrb/version.rb +1 -1
  26. data/lib/xlsxrb.rb +271 -122
  27. data/sig/generated/xlsxrb/elements/coordinate_access.rbs +70 -0
  28. data/sig/generated/xlsxrb/elements/worksheet.rbs +119 -14
  29. data/sig/generated/xlsxrb/ooxml/cfb.rbs +121 -0
  30. data/sig/generated/xlsxrb/ooxml/crypto/agile.rbs +46 -0
  31. data/sig/generated/xlsxrb/ooxml/crypto/standard.rbs +28 -0
  32. data/sig/generated/xlsxrb/ooxml/crypto.rbs +17 -0
  33. data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +2 -0
  34. data/sig/generated/xlsxrb/stream_row.rbs +127 -0
  35. data/sig/generated/xlsxrb.rbs +135 -71
  36. data/vendor/sdk_runner/Program.cs +3 -1
  37. metadata +13 -1
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module Xlsxrb
6
+ # Streaming row implementation that parses cells on-demand / lazily.
7
+ # Provides O(1) memory consumption even for rows with tens of thousands of columns.
8
+ #
9
+ # @example Streaming cells one-by-one (O(1) memory)
10
+ # row.each_cell do |cell|
11
+ # puts "#{cell.ref}: #{cell.value}"
12
+ # end
13
+ #
14
+ # @example Random access or array conversion (cached on-demand)
15
+ # cell = row[0]
16
+ # values = row.to_a
17
+ #
18
+ # @api public
19
+ class StreamRow
20
+ [Enumerable].each { |m| include m }
21
+
22
+ attr_reader :index, :height, :hidden, :custom_height, :outline_level
23
+
24
+ # @param index [Integer] 0-based row index.
25
+ # @param xml_bytes [String] Raw ASCII-8BIT XML bytes.
26
+ # @param from [Integer] Byte offset where cells start.
27
+ # @param to [Integer] Byte offset where cells end.
28
+ # @param shared_strings [Array<String>] Shared strings table.
29
+ # @param height [Float, Integer, nil] Row height in points.
30
+ # @param hidden [Boolean] Whether the row is hidden.
31
+ # @param custom_height [Boolean] Whether custom height is set.
32
+ # @param outline_level [Integer, nil] Grouping/outline level.
33
+ #: (index: Integer, xml_bytes: String, from: Integer, to: Integer, shared_strings: Array[String], ?height: Float | Integer | nil, ?hidden: bool, ?custom_height: bool, ?outline_level: Integer | nil) -> void
34
+ def initialize(index:, xml_bytes:, from:, to:, shared_strings:, height: nil, hidden: false,
35
+ custom_height: false, outline_level: nil)
36
+ @index = index
37
+ @xml = xml_bytes
38
+ @from = from
39
+ @to = to
40
+ @shared_strings = shared_strings
41
+ @height = height
42
+ @hidden = hidden
43
+ @custom_height = custom_height
44
+ @outline_level = outline_level
45
+ @cells_cache = nil
46
+ end
47
+
48
+ # Iterate over cells in this streaming row one by one.
49
+ #
50
+ # @yield [cell]
51
+ # @yieldparam cell [Elements::Cell]
52
+ # @return [Enumerator, void]
53
+ # @api public
54
+ #: () { (Elements::Cell) -> void } -> void
55
+ #: () -> Enumerator[Elements::Cell, void]
56
+ def each_cell(&)
57
+ return enum_for(:each_cell) unless block_given?
58
+
59
+ if @cells
60
+ @cells.each(&)
61
+ else
62
+ Ooxml::WorksheetParser.fast_scan_cells_direct(@xml, @from, @to, @shared_strings, { row: @index }, &)
63
+ end
64
+ end
65
+
66
+ # Iterate over cells in this streaming row.
67
+ #
68
+ # @yield [cell]
69
+ # @yieldparam cell [Elements::Cell]
70
+ # @return [Enumerator, void]
71
+ # @api public
72
+ #: () { (Elements::Cell) -> void } -> void
73
+ #: () -> Enumerator[Elements::Cell, void]
74
+ def each(&)
75
+ each_cell(&)
76
+ end
77
+
78
+ # Returns all cells as an Array. Cached on first access.
79
+ #
80
+ # @return [Array<Elements::Cell>]
81
+ # @api public
82
+ #: () -> Array[Elements::Cell]
83
+ def cells
84
+ @cells ||= each_cell.to_a.freeze
85
+ end
86
+
87
+ # Access a cell by 0-based column index, or access row attributes via Symbol.
88
+ #
89
+ # @param col_index [Integer, Symbol] Column index or attribute symbol.
90
+ # @return [Elements::Cell, Object, nil]
91
+ # @api public
92
+ #: (Integer | Symbol col_index) -> untyped
93
+ def [](col_index)
94
+ case col_index
95
+ when Symbol
96
+ case col_index
97
+ when :cells then cells
98
+ when :index then index
99
+ when :height then height
100
+ when :hidden then hidden
101
+ when :custom_height then custom_height
102
+ when :outline_level then outline_level
103
+ when :attrs then { height: height, hidden: hidden, custom_height: custom_height, outline_level: outline_level }
104
+ end
105
+ else
106
+ cells[col_index]
107
+ end
108
+ end
109
+
110
+ # Access a cell by 0-based column index.
111
+ #
112
+ # @param col_index [Integer] 0-based column index.
113
+ # @return [Elements::Cell, nil]
114
+ # @api public
115
+ #: (Integer col_index) -> Elements::Cell?
116
+ def cell_at(col_index)
117
+ cells.find { |c| c.column_index == col_index }
118
+ end
119
+
120
+ # Convert row cells to an Array of raw values (sparse columns get nil).
121
+ #
122
+ # @return [Array<Object>]
123
+ # @api public
124
+ #: () -> Array[untyped]
125
+ def to_a
126
+ return [] if cells.empty?
127
+
128
+ max_col = cells.map(&:column_index).max || 0
129
+ arr = Array.new(max_col + 1)
130
+ cells.each do |cell|
131
+ arr[cell.column_index] = cell.value
132
+ end
133
+ arr
134
+ end
135
+
136
+ # Returns cell values as an Array.
137
+ #
138
+ # @return [Array<Object>]
139
+ # @api public
140
+ #: () -> Array[untyped]
141
+ def values
142
+ to_a
143
+ end
144
+
145
+ # Returns whether the row is valid according to OOXML specifications.
146
+ #
147
+ # @return [Boolean]
148
+ # @api public
149
+ #: () -> bool
150
+ def valid?
151
+ true
152
+ end
153
+
154
+ # Unmapped metadata for compatibility with Elements::Row.
155
+ #
156
+ # @return [Hash]
157
+ # @api public
158
+ #: () -> Hash[untyped, untyped]
159
+ def unmapped_data
160
+ Elements::EMPTY_HASH
161
+ end
162
+
163
+ # Validation errors for compatibility with Elements::Row.
164
+ #
165
+ # @return [Array<String>]
166
+ # @api public
167
+ #: () -> Array[String]
168
+ def errors
169
+ Elements::EMPTY_ERRORS
170
+ end
171
+
172
+ # Human-readable representation.
173
+ #
174
+ # @return [String]
175
+ # @api public
176
+ #: () -> String
177
+ def inspect
178
+ "#<#{self.class.name} index=#{index} height=#{height.inspect} hidden=#{hidden}>"
179
+ end
180
+ end
181
+ end
@@ -3,5 +3,5 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  module Xlsxrb
6
- VERSION = "0.1.7"
6
+ VERSION = "0.1.9"
7
7
  end