axlsx 1.1.6 → 1.2.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.
Files changed (173) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +97 -46
  4. data/Rakefile +3 -2
  5. data/examples/basic_charts.rb +54 -0
  6. data/examples/chart_colors.rb +18 -3
  7. data/examples/example.rb +118 -42
  8. data/examples/example.xlsx +0 -0
  9. data/examples/example_streamed.xlsx +0 -0
  10. data/examples/extractive.pdf +0 -0
  11. data/examples/no-use_autowidth.xlsx +0 -0
  12. data/examples/scraping_html.rb +91 -0
  13. data/examples/shared_strings_example.xlsx +0 -0
  14. data/examples/sheet_view.rb +34 -0
  15. data/lib/axlsx/content_type/content_type.rb +2 -0
  16. data/lib/axlsx/content_type/default.rb +21 -12
  17. data/lib/axlsx/content_type/override.rb +22 -11
  18. data/lib/axlsx/doc_props/app.rb +36 -32
  19. data/lib/axlsx/doc_props/core.rb +9 -5
  20. data/lib/axlsx/drawing/ax_data_source.rb +7 -6
  21. data/lib/axlsx/drawing/axis.rb +64 -25
  22. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  23. data/lib/axlsx/drawing/bar_series.rb +1 -0
  24. data/lib/axlsx/drawing/cat_axis.rb +43 -39
  25. data/lib/axlsx/drawing/chart.rb +65 -54
  26. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  27. data/lib/axlsx/drawing/drawing.rb +7 -5
  28. data/lib/axlsx/drawing/graphic_frame.rb +2 -2
  29. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  30. data/lib/axlsx/drawing/num_data.rb +2 -2
  31. data/lib/axlsx/drawing/num_data_source.rb +1 -1
  32. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  33. data/lib/axlsx/drawing/scatter_chart.rb +2 -8
  34. data/lib/axlsx/drawing/title.rb +21 -9
  35. data/lib/axlsx/drawing/two_cell_anchor.rb +41 -9
  36. data/lib/axlsx/drawing/view_3D.rb +41 -31
  37. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  38. data/lib/axlsx/package.rb +20 -16
  39. data/lib/axlsx/rels/relationship.rb +3 -3
  40. data/lib/axlsx/stylesheet/styles.rb +1 -1
  41. data/lib/axlsx/util/constants.rb +4 -0
  42. data/lib/axlsx/util/simple_typed_list.rb +15 -8
  43. data/lib/axlsx/util/validators.rb +28 -4
  44. data/lib/axlsx/version.rb +2 -7
  45. data/lib/axlsx/workbook/defined_name.rb +174 -0
  46. data/lib/axlsx/workbook/defined_names.rb +21 -0
  47. data/lib/axlsx/workbook/workbook.rb +46 -17
  48. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  49. data/lib/axlsx/workbook/worksheet/cell.rb +28 -1
  50. data/lib/axlsx/workbook/worksheet/col.rb +15 -0
  51. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  52. data/lib/axlsx/workbook/worksheet/comments.rb +8 -0
  53. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  54. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  55. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  56. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  57. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  58. data/lib/axlsx/workbook/worksheet/page_setup.rb +10 -1
  59. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  60. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  61. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  62. data/lib/axlsx/workbook/worksheet/row.rb +1 -1
  63. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  64. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  65. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  66. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  67. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  68. data/lib/axlsx/workbook/worksheet/worksheet.rb +315 -291
  69. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  70. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  71. data/lib/axlsx.rb +24 -16
  72. data/test/content_type/tc_content_type.rb +1 -6
  73. data/test/doc_props/tc_core.rb +1 -1
  74. data/test/drawing/tc_axis.rb +27 -2
  75. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  76. data/test/drawing/tc_bar_series.rb +1 -2
  77. data/test/drawing/tc_cat_axis.rb +3 -3
  78. data/test/drawing/tc_chart.rb +8 -6
  79. data/test/drawing/tc_d_lbls.rb +47 -0
  80. data/test/drawing/tc_drawing.rb +5 -4
  81. data/test/drawing/tc_line_series.rb +1 -1
  82. data/test/drawing/tc_num_data.rb +5 -1
  83. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  84. data/test/drawing/tc_pie_series.rb +1 -1
  85. data/test/drawing/tc_scatter_series.rb +1 -1
  86. data/test/drawing/tc_series.rb +1 -1
  87. data/test/drawing/tc_title.rb +16 -0
  88. data/test/drawing/tc_view_3D.rb +18 -18
  89. data/test/tc_package.rb +41 -4
  90. data/test/util/tc_validators.rb +68 -11
  91. data/test/workbook/tc_defined_name.rb +41 -0
  92. data/test/workbook/tc_workbook.rb +5 -3
  93. data/test/workbook/worksheet/table/tc_table.rb +0 -8
  94. data/test/workbook/worksheet/tc_cell.rb +2 -4
  95. data/test/workbook/worksheet/tc_page_setup.rb +20 -3
  96. data/test/workbook/worksheet/tc_pane.rb +94 -0
  97. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  98. data/test/workbook/worksheet/tc_row.rb +2 -2
  99. data/test/workbook/worksheet/tc_selection.rb +94 -0
  100. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  101. data/test/workbook/worksheet/tc_worksheet.rb +53 -41
  102. metadata +104 -97
  103. data/examples/chart_colors.xlsx +0 -0
  104. data/examples/conditional_formatting/getting_barred.xlsx +0 -0
  105. data/examples/doc/_index.html +0 -84
  106. data/examples/doc/class_list.html +0 -47
  107. data/examples/doc/css/common.css +0 -1
  108. data/examples/doc/css/full_list.css +0 -55
  109. data/examples/doc/css/style.css +0 -322
  110. data/examples/doc/file_list.html +0 -46
  111. data/examples/doc/frames.html +0 -13
  112. data/examples/doc/index.html +0 -84
  113. data/examples/doc/js/app.js +0 -205
  114. data/examples/doc/js/full_list.js +0 -173
  115. data/examples/doc/js/jquery.js +0 -16
  116. data/examples/doc/method_list.html +0 -46
  117. data/examples/doc/top-level-namespace.html +0 -95
  118. data/examples/examples_saved.xlsx +0 -0
  119. data/examples/fish.xlsx +0 -0
  120. data/examples/pareto.rb +0 -28
  121. data/examples/pareto.xlsx +0 -0
  122. data/examples/pie_chart.rb +0 -16
  123. data/examples/pie_chart.xlsx +0 -0
  124. data/examples/pie_chart_saved.xlsx +0 -0
  125. data/examples/sheet_protection.xlsx +0 -0
  126. data/examples/two_cell_anchor_image.xlsx +0 -0
  127. data/examples/~$pie_chart_saved.xlsx +0 -0
  128. data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
  129. data/lib/axlsx/drawing/data_source.rb~ +0 -51
  130. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  131. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  132. data/lib/axlsx/drawing/num_data.rb~ +0 -51
  133. data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
  134. data/lib/axlsx/drawing/num_val.rb~ +0 -40
  135. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  136. data/lib/axlsx/drawing/ref.rb~ +0 -41
  137. data/lib/axlsx/drawing/str_data.rb~ +0 -58
  138. data/lib/axlsx/drawing/str_val.rb~ +0 -35
  139. data/lib/axlsx/drawing/vml_drawing.rb~ +0 -6
  140. data/lib/axlsx/drawing/vml_shape.rb~ +0 -61
  141. data/lib/axlsx/util/cbf.rb +0 -333
  142. data/lib/axlsx/util/cfb.rb~ +0 -201
  143. data/lib/axlsx/util/font_tables.rb~ +0 -0
  144. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  145. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  146. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  147. data/lib/axlsx/util/parser.rb~ +0 -6
  148. data/lib/axlsx/util/storage.rb~ +0 -0
  149. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  150. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  151. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  152. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  153. data/lib/axlsx/workbook/worksheet/comment.rb~ +0 -91
  154. data/lib/axlsx/workbook/worksheet/comments.rb~ +0 -86
  155. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  156. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  157. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  158. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  159. data/lib/schema/dc.xsd~ +0 -118
  160. data/lib/schema/dcterms.xsd~ +0 -331
  161. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  162. data/test/drawing/tc_data_source.rb~ +0 -30
  163. data/test/drawing/tc_num_data.rb~ +0 -35
  164. data/test/drawing/tc_num_val.rb~ +0 -29
  165. data/test/drawing/tc_str_data.rb~ +0 -30
  166. data/test/drawing/tc_str_val.rb~ +0 -26
  167. data/test/drawing/tc_vml_drawing.rb~ +0 -0
  168. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  169. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  170. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  171. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  172. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  173. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
@@ -1,333 +0,0 @@
1
- # encoding: UTF-8
2
- module Axlsx
3
-
4
- # The Cfb class is a MS-OFF-CRYPTOGRAPHY specific OLE (MS-CBF) writer implementation. No attempt is made to re-invent the wheel for read/write of compound binary files.
5
- class Cbf
6
-
7
- # the serialization for the CBF FAT
8
- FAT_PACKING = "s128"
9
-
10
- # the serialization for the MS-OFF-CRYPTO version stream
11
- VERSION_PACKING = 'l s30 l3'
12
-
13
- # The serialization for the MS-OFF-CRYPTO dataspace map stream
14
- DATA_SPACE_MAP_PACKING = 'l6 s16 l s25 x2'
15
-
16
- # The serialization for the MS-OFF-CRYPTO strong encrytion data space stream
17
- STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s26'
18
-
19
- # The serialization for the MS-OFF-CRYPTO primary stream
20
- PRIMARY_PACKING = 'l3 s38 l s40 l3 x12 l'
21
-
22
- # The cutoff size that determines if a stream should be in the mini-fat or the fat
23
- MINI_CUTOFF = 4096
24
-
25
- # The serialization for CBF header
26
- HEADER_PACKING = "q x16 l s3 x10 l l x4 l*"
27
-
28
- # Creates a new Cbf object based on the ms_off_crypto object provided.
29
- # @param [MsOffCrypto] ms_off_crypto
30
- def initialize(ms_off_crypto)
31
- @file_name = ms_off_crypto.file_name
32
- @ms_off_crypto = ms_off_crypto
33
- create_storages
34
- mini_fat_stream
35
- mini_fat
36
- fat
37
- header
38
- end
39
-
40
- # creates or returns the version storage
41
- # @return [Storage]
42
- def version
43
- @version ||= create_version
44
- end
45
-
46
- # returns the data space map storage
47
- # @return [Storage]
48
- def data_space_map
49
- @data_space_map ||= create_data_space_map
50
- end
51
-
52
- # returns the primary storage
53
- # @return [Storgae]
54
- def primary
55
- @primary ||= create_primary
56
- end
57
-
58
- # returns the summary information storage
59
- # @return [Storage]
60
- def summary_information
61
- @summary_information ||= create_summary_information
62
- end
63
-
64
- # returns the document summary information
65
- # @return [Storage]
66
- def document_summary_information
67
- @document_summary_information ||= create_document_summary_information
68
- end
69
-
70
- # returns the stream of data allocated in the fat
71
- # @return [String]
72
- def fat_stream
73
- @fat_stream ||= create_fat_stream
74
- end
75
-
76
- # returns the stream allocated in the mini fat.
77
- # return [String]
78
- def mini_fat_stream
79
- @mini_fat_stream ||= create_mini_fat_stream
80
- end
81
-
82
- # returns the mini fat
83
- # return [String]
84
- def mini_fat
85
- @mini_fat ||= create_mini_fat
86
- end
87
-
88
- # returns the fat
89
- # @return [String]
90
- def fat
91
- @fat ||= create_fat
92
- end
93
-
94
- # returns the CFB header
95
- # @return [String]
96
- def header
97
- @header ||= create_header
98
- end
99
-
100
- # returns the encryption info from the ms_off_crypt object provided during intialization
101
- # @return [String] encryption info
102
- def encryption_info
103
- @ms_off_crypto.encryption_info
104
- end
105
-
106
- # returns the encrypted package from the ms_off_crypt object provided during initalization
107
- # @return [String] encrypted package
108
- def encrypted_package
109
- @ms_off_crypto.encrypted_package
110
- end
111
-
112
- # writes the compound binary file to disk
113
- def save
114
- ole = File.open(@file_name, 'w')
115
- ole << header
116
- ole << fat
117
- @storages.each { |s| ole << s.to_s }
118
- ole << Array.new((512-(ole.pos % 512)), 0).pack('c*')
119
- ole << mini_fat
120
- ole << mini_fat_stream
121
- ole << fat_stream
122
- ole.close
123
- end
124
-
125
- private
126
-
127
- # Generates the storages required for ms-office-cryptography cfb
128
- def create_storages
129
- @storages = []
130
- @encryption_info = @ms_off_crypto.encryption_info
131
- @encrypted_package = @ms_off_crypto.encrypted_package
132
-
133
- @storages << Storage.new('EncryptionInfo', :data=>encryption_info, :left=>3, :right=>11) # example shows right child. do we need the summary info????
134
- @storages << Storage.new('EncryptedPackage', :data=>encrypted_package, :color=>Storage::COLORS[:red])
135
- @storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979)
136
- @storages << version
137
- @storages << data_space_map
138
- @storages << Storage.new('DataSpaceInfo', :right=>8, :child=>7, :created=>129685612740828880,:modified=>129685612740831800)
139
- @storages << strong_encryption_data_space
140
- @storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959)
141
- @storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280)
142
- @storages << primary
143
- # @storages << summary_information
144
- # @storages << document_summary_information
145
-
146
- # we do this at the end as we need to build the minifat stream to determine the size. #HOWEVER - it looks like the size should not include the padding?
147
- @storages.unshift Storage.new('Root Entry', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :data => mini_fat_stream)
148
-
149
- end
150
-
151
- # generates the mini fat stream
152
- # @return [String]
153
- def create_mini_fat_stream
154
- mfs = []
155
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index|
156
- puts "#{stream.name.pack('c*')}: #{stream.data.size}"
157
- mfs.concat stream.data
158
- mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64 > 0
159
- puts "mini fat stream size: #{mfs.size}"
160
- end
161
- mfs.concat(Array.new(512 - (mfs.size % 512), 0))
162
- mfs.pack 'c*'
163
- end
164
-
165
- # generates the fat stream.
166
- # @return [String]
167
- def create_fat_stream
168
- mfs = []
169
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index|
170
- mfs.concat stream.data
171
- mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512 > 0
172
- end
173
- mfs.pack 'c*'
174
- end
175
-
176
- # creates the mini fat
177
- # @return [String]
178
- def create_mini_fat
179
- v_mf = []
180
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each do |stream|
181
- allocate_stream(v_mf, stream, 64)
182
- end
183
- v_mf.concat Array.new(128 - v_mf.size, -1)
184
- v_mf.pack 'l*'
185
- end
186
-
187
- # creates the fat
188
- # @return [String]
189
- def create_fat
190
- v_fat = [-3]
191
- # storages four per sector, allocation forces directories to start at sector ID 0
192
- allocate_stream(v_fat, @storages, 4)
193
- # fat entry for minifat
194
- allocate_stream(v_fat, 0, 512)
195
- # fat entry for minifat stream
196
- @storages[0].sector = v_fat.size
197
- allocate_stream(v_fat, mini_fat_stream, 512)
198
- # fat entries for encrypted package storage
199
- # what to do about DIFAT for larger packages...
200
- if @encrypted_package.size > (109 - v_fat.size) * 512
201
- raise ArgumentError, "Your package is too big!"
202
- end
203
-
204
- if @encrypted_package.size >= MINI_CUTOFF
205
- allocate_stream(v_fat, @encrypted_package, 512)
206
- end
207
-
208
- v_fat.concat Array.new(128 - v_fat.size, -1) if v_fat.size < 128 #pack in unused sectors
209
- v_fat.pack 'l*'
210
- end
211
-
212
- # Creates the version storage
213
- # @return [Storage]
214
- def create_version
215
- v_stream= [60, "Microsoft.Container.DataSpaces".bytes.to_a, 1, 1, 1].flatten!.pack VERSION_PACKING
216
- Storage.new('Version', :data=>v_stream, :size=>v_stream.size)
217
- end
218
-
219
- # returns the strong encryption data space storage
220
- # @return [Storgae]
221
- def strong_encryption_data_space
222
- @strong_encryption_data_space ||= create_strong_encryption_data_space
223
- end
224
-
225
- # Creates the data space map storage
226
- # @return [Storgae]
227
- def create_data_space_map
228
- v_stream = [8,1,104, 1,0, 32, "EncryptedPackage".bytes.to_a, 50, "StrongEncryptionDataSpace".bytes.to_a].flatten!.pack DATA_SPACE_MAP_PACKING
229
- Storage.new('DataSpaceMap', :data=>v_stream, :left => 4, :right => 6, :size=>v_stream.size)
230
- end
231
-
232
-
233
- # creates the stron encryption data space storage
234
- # @return [Storgae]
235
- def create_strong_encryption_data_space
236
- v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a,0].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
237
- Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size)
238
- end
239
-
240
- # creates the primary storage
241
- # @return [Storgae]
242
- def create_primary
243
- v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten
244
- v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,0,1,1,1,4].flatten
245
- v_stream = v_stream.pack PRIMARY_PACKING
246
- Storage.new([6].pack("c")+"Primary", :data=>v_stream)
247
- end
248
-
249
-
250
- # creates the summary information storage
251
- # @return [Storage]
252
- def create_summary_information
253
- v_stream = []
254
- v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
255
- v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0xE085, 0x9FF2]
256
- v_stream.concat [0xF94F, 0x6810, 0xAB91, 0x0800, 0x2B27, 0xB3D9, 0x3000, 0x0000]
257
- v_stream.concat [0xAC00, 0x0000, 0x0700, 0x0000, 0x0100, 0x0000, 0x4000, 0x0000]
258
- v_stream.concat [0x0400, 0x0000, 0x4800, 0x0000, 0x0800, 0x0000, 0x5800, 0x0000]
259
- v_stream.concat [0x1200, 0x0000, 0x6800, 0x0000, 0x0C00, 0x0000, 0x8C00, 0x0000]
260
- v_stream.concat [0x0D00, 0x0000, 0x9800, 0x0000, 0x1300, 0x0000, 0xA400, 0x0000]
261
- v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
262
- v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x0800, 0x0000]
263
- v_stream.concat [0x7261, 0x6E64, 0x796D, 0x0000, 0x1E00, 0x0000, 0x1C00, 0x0000]
264
- v_stream.concat [0x4D69, 0x6372, 0x6F73, 0x6F66, 0x7420, 0x4D61, 0x6369, 0x6E74]
265
- v_stream.concat [0x6F73, 0x6820, 0x4578, 0x6365, 0x6C00, 0x0000, 0x4000, 0x0000]
266
- v_stream.concat [0x10AC, 0x5396, 0x60BC, 0xCC01, 0x4000, 0x0000, 0x40F4, 0xFDAF]
267
- v_stream.concat [0x60BC, 0xCC01, 0x0300, 0x0000, 0x0100, 0x0000]
268
-
269
- v_stream = v_stream.pack "s*"
270
-
271
- Storage.new([5].pack('c')+"SummaryInformation", :data=>v_stream, :left => 2)
272
- end
273
-
274
-
275
- # creates the document summary information storage
276
- # @return [Storage]
277
- def create_document_summary_information
278
- v_stream = []
279
- v_stream.concat [0xFEFF, 0x0000, 0x030A, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000]
280
- v_stream.concat [0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, 0x02D5, 0xCDD5]
281
- v_stream.concat [0x9C2E, 0x1B10, 0x9397, 0x0800, 0x2B2C, 0xF9AE, 0x3000, 0x0000]
282
- v_stream.concat [0xCC00, 0x0000, 0x0900, 0x0000, 0x0100, 0x0000, 0x5000, 0x0000]
283
- v_stream.concat [0x0F00, 0x0000, 0x5800, 0x0000, 0x1700, 0x0000, 0x6400, 0x0000]
284
- v_stream.concat [0x0B00, 0x0000, 0x6C00, 0x0000, 0x1000, 0x0000, 0x7400, 0x0000]
285
- v_stream.concat [0x1300, 0x0000, 0x7C00, 0x0000, 0x1600, 0x0000, 0x8400, 0x0000]
286
- v_stream.concat [0x0D00, 0x0000, 0x8C00, 0x0000, 0x0C00, 0x0000, 0x9F00, 0x0000]
287
- v_stream.concat [0x0200, 0x0000, 0xE9FD, 0x0000, 0x1E00, 0x0000, 0x0400, 0x0000]
288
- v_stream.concat [0x0000, 0x0000, 0x0300, 0x0000, 0x0000, 0x0C00, 0x0B00, 0x0000]
289
- v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x0B00, 0x0000]
290
- v_stream.concat [0x0000, 0x0000, 0x0B00, 0x0000, 0x0000, 0x0000, 0x1E10, 0x0000]
291
- v_stream.concat [0x0100, 0x0000, 0x0700, 0x0000, 0x5368, 0x6565, 0x7431, 0x000C]
292
- v_stream.concat [0x1000, 0x0002, 0x0000, 0x001E, 0x0000, 0x0013, 0x0000, 0x00E3]
293
- v_stream.concat [0x83AF, 0xE383, 0xBCE3, 0x82AF, 0xE382, 0xB7E3, 0x83BC, 0xE383]
294
- v_stream.concat [0x8800, 0x0300, 0x0000, 0x0100, 0x0000, 0x0000]
295
- v_stream = v_stream.pack 'c*'
296
- Storage.new([5].pack('c')+"DocumentSummaryInformation", :data=>v_stream)
297
- end
298
-
299
- # Creates the header
300
- # @return [String]
301
- def create_header
302
- header = []
303
- header << -2226271756974174256 # identifier pack as q
304
- header << 196670 # version pack as L
305
- header << 65534 # byte order pack as s
306
- header << 9 # sector shift
307
- header << 6 # mini-sector shift
308
- header << (fat.size/512.0).ceil # this is the number of FAT sectors in the file at index 6 pack as L
309
- header << header.last # this is the first directory sector, index of 7 pack as L
310
- header << MINI_CUTOFF # minfat cutoff pack as L
311
- # MiniFat starts after directories
312
- header << (fat.size/512.0).ceil + (@storages.size/4.0).ceil # this is the sector id for the first minifat index 10 pack as L
313
- header << (mini_fat.size/512.0).ceil # minifat sector count index 11 pack as L
314
- header << -2 # the first DIFAT - set to end of chain until we exceed a single FAT pack as L
315
- header << 0 # number of DIFAT sectors, unless we go beyond 109 FAT sectors this will always be 0 pack as L
316
- header << 0 # first FAT sector defined in the DIFAT pack as L
317
- header.concat Array.new(108, -1) # Difat sectors pack as L108
318
- header.pack(HEADER_PACKING)
319
- end
320
-
321
- # Allocates sector chains in a allocation table based on the sector size and stream provided
322
- # If a storage obeject is provided, the starting sector value for the storage is updated based on the allocation performed here.
323
- # @param [Array] table Allocation table array
324
- # @param [Storage | String] stream
325
- # @param [Integer] size The cutoff size for the stream.
326
- def allocate_stream(table, stream, size)
327
- stream.sector = table.size if stream.respond_to?(:sector)
328
- ((stream.size / size.to_f).ceil).times { table << table.size }
329
- table[table.size-1] = -2 # this is the CBF chain terminator
330
- end
331
-
332
- end
333
- end
@@ -1,201 +0,0 @@
1
- module Axlsx
2
-
3
- # The Cfb class is a MS-OFF-CRYPTOGRAPHY specific OLE (MS-CBF) writer implementation. No attempt is made to re-invent the wheel for read/write of compound binary files.
4
- class Cbf
5
-
6
- # the serialization for the CBF FAT
7
- FAT_PACKING = "s128"
8
-
9
- # the serialization for the MS-OFF-CRYPTO version stream
10
- VERSION_PACKING = 'l s30 l3'
11
-
12
- # The serialization for the MS-OFF-CRYPTO dataspace map stream
13
- DATA_SPACE_MAP_PACKING = 'l6 s16 l s25'
14
-
15
- # The serialization for the MS-OFF-CRYPTO strong encrytion data space stream
16
- STRONG_ENCRYPTION_DATA_SPACE_PACKING = 'l3 s25'
17
-
18
- # The serialization for the MS-OFF-CRYPTO primary stream
19
- PRIMARY_PACKING = 'l3 s38 l s39 l3 x12 l x2'
20
-
21
- # The cutoff size that determines if a stream should be in the mini-fat or the fat
22
- MINI_CUTOFF = 4096
23
-
24
- # Creates a new Cbf object based on a package.
25
- def initialize(ms_off_crypto)
26
- @file_name = ms_off_crypto.file_name
27
- @storages = []
28
- @encryption_info = ms_off_crypto.encryption_info
29
- @encrypted_package = ms_off_crypto.encrypted_package
30
- @storages << Storage.new('R', :type=>Storage::TYPES[:root], :color=>Storage::COLORS[:red], :child=>1, :modified=>129685612742510730)
31
- @storages.last.name_size = 2
32
- @storages << Storage.new('EncryptionInfo', :data=>@encryption_info, :left=>3, :size => @encryption_info.size) # example shows right child. do we need the summary info????
33
- @storages << Storage.new('EncryptedPackage', :data=>@encrypted_package, :color=>Storage::COLORS[:red], :size=>@encrypted_package.size)
34
- @storages << Storage.new([6].pack("c")+"DataSpaces", :child=>5, :modified =>129685612740945580, :created=>129685612740819979)
35
- @storages << version
36
- @storages << data_space_map
37
- @storages << Storage.new('DataSpaceInfo', :right=>8, :child=>7, :created=>129685612740828880,:modified=>129685612740831800)
38
- @storages << strong_encryption_data_space
39
- @storages << Storage.new('TransformInfo', :color => Storage::COLORS[:red], :child=>9, :created=>129685612740834130, :modified=>129685612740943959)
40
- @storages << Storage.new('StrongEncryptionTransform', :child=>10, :created=>129685612740834169, :modified=>129685612740942280)
41
- @storages << primary
42
- mini_fat_stream
43
- mini_fat
44
- fat
45
- header
46
- end
47
-
48
- def version
49
- @version ||= create_version
50
- end
51
-
52
- def data_space_map
53
- @data_space_map ||= create_data_space_map
54
- end
55
-
56
- def strong_encryption_data_space
57
- @strong_encryption_data_space ||= create_strong_encryption_data_space
58
- end
59
-
60
- def primary
61
- @primary ||= create_primary
62
- end
63
-
64
-
65
- def create_primary
66
- v_stream = [88,1,76,"{FF9A3F03-56EF-4613-BDD5-5A41C1D07246}".bytes.to_a].flatten
67
- v_stream.concat [78, "Microsoft.Container.EncryptionTransform".bytes.to_a,1,1,1,4].flatten
68
- v_stream = v_stream.pack PRIMARY_PACKING
69
- Storage.new([6].pack("c")+"Primary", :data=>v_stream, :size=>v_stream.size)
70
- end
71
-
72
- def create_strong_encryption_data_space
73
- v_stream = [8,1,50,"StrongEncryptionTransform".bytes.to_a].flatten.pack STRONG_ENCRYPTION_DATA_SPACE_PACKING
74
- Storage.new("StrongEncryptionDataSpace", :data=>v_stream, :size => v_stream.size)
75
- end
76
-
77
- # Create the version storage
78
- def create_version
79
- v_stream= [60, "Microsoft.Container.DataSpaces".bytes.to_a, 1, 1, 1].flatten!.pack VERSION_PACKING
80
- Storage.new('Version', :data=>v_stream, :size=>v_stream.size)
81
- end
82
-
83
- def create_data_space_map
84
- v_stream = [8,1,104, 1,0, 32, "EncryptedPackage".bytes.to_a, 50, "StrongEncryptionDataSpace".bytes.to_a].flatten!.pack DATA_SPACE_MAP_PACKING
85
- Storage.new('DataSpaceMap', :data=>v_stream, :left => 4, :right => 6, :size=>v_stream.size)
86
- end
87
-
88
- def allocate_stream(table, stream, size)
89
- stream.sector = table.size if stream.respond_to?(:sector)
90
- ((stream.size / size.to_f).ceil).times { table << table.size }
91
- table[table.size-1] = -2
92
- end
93
-
94
- def fat_stream
95
- @fat_stream ||= create_fat_stream
96
- end
97
- def create_fat_stream
98
- mfs = []
99
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size >= MINI_CUTOFF}.each_with_index do |stream, index|
100
- mfs.concat stream.data
101
- mfs.concat Array.new(512 - (mfs.size % 512), 0) if mfs.size % 512
102
- end
103
- mfs.pack 'c*'
104
- end
105
-
106
- def mini_fat_stream
107
- @mini_fat_stream ||= create_mini_fat_stream
108
- end
109
-
110
- def create_mini_fat_stream
111
- mfs = []
112
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each_with_index do |stream, index|
113
- mfs.concat stream.data
114
- mfs.concat Array.new(64 - (mfs.size % 64), 0) if mfs.size % 64
115
- end
116
- @storages[0].size = mfs.size
117
- mfs.concat(Array.new(512 - (mfs.size % 512), 0))
118
- mfs.pack 'c*'
119
- end
120
-
121
- def mini_fat
122
- @mini_fat ||= create_mini_fat
123
- end
124
-
125
- def create_mini_fat
126
- v_mf = []
127
- @storages.select{ |s| s.type == Storage::TYPES[:stream] && s.size < MINI_CUTOFF}.each do |stream|
128
- allocate_stream(v_mf, stream, 64)
129
- end
130
- v_mf.concat Array.new(128 - v_mf.size, -1)
131
- v_mf.pack 'l*'
132
- end
133
-
134
- def fat
135
- @fat ||= create_fat
136
- end
137
-
138
- def create_fat
139
- v_fat = [-3]
140
- # storages four per sector, allocation forces directories to start at sector ID 0
141
- allocate_stream(v_fat, @storages, 4)
142
- # fat entry for minifat
143
- allocate_stream(v_fat, 0, 512)
144
- # fat entry for minifat stream
145
- @storages[0].sector = v_fat.size
146
- allocate_stream(v_fat, mini_fat_stream, 512)
147
- # fat entries for encrypted package storage
148
- # what to do about DIFAT for larger packages...
149
- if @encrypted_package.size > (109 - v_fat.size) * 512
150
- raise ArgumentError, "Your package is too big!"
151
- end
152
-
153
- if @encrypted_package.size >= MINI_CUTOFF
154
- allocate_stream(v_fat, @encrypted_package, 512)
155
- end
156
-
157
- v_fat.concat Array.new(128 - v_fat.size, -1) if v_fat.size < 128 #pack in unused sectors
158
- v_fat.pack 'l*'
159
- end
160
-
161
- def header
162
- @header ||= create_header
163
- end
164
-
165
- # The serialization for CBF header
166
- HEADER_PACKING = "q x16 l s3 x10 l l x4 l*"
167
-
168
- def create_header
169
- header = []
170
- header << -2226271756974174256 # identifier pack as q
171
- header << 196670 # version pack as L
172
- header << 65534 # byte order pack as s
173
- header << 9 # sector shift
174
- header << 6 # mini-sector shift
175
- header << (fat.size/512.0).ceil # this is the number of FAT sectors in the file at index 6 pack as L
176
- header << header.last # this is the first directory sector, index of 7 pack as L
177
- header << MINI_CUTOFF # minfat cutoff pack as L
178
- # MiniFat starts after directories
179
- header << (fat.size/512.0).ceil + (@storages.size/4.0).ceil # this is the sector id for the first minifat index 10 pack as L
180
- header << (mini_fat.size/512.0).ceil # minifat sector count index 11 pack as L
181
- header << -2 # the first DIFAT - set to end of chain until we exceed a single FAT pack as L
182
- header << 0 # number of DIFAT sectors, unless we go beyond 109 FAT sectors this will always be 0 pack as L
183
- header << 0 # first FAT sector defined in the DIFAT pack as L
184
- header.concat Array.new(108, -1) # Difat sectors pack as L108
185
- end
186
-
187
- def save
188
-
189
- ole = File.open(@file_name, 'w')
190
- ole << header.pack(HEADER_PACKING)
191
- ole << fat
192
- @storages.each { |s| ole << s.to_s }
193
- ole << Array.new((512-(ole.pos % 512)), 0).pack('c*')
194
- ole << mini_fat
195
- ole << mini_fat_stream
196
- ole << fat_stream
197
- ole.close
198
- end
199
-
200
- end
201
- end
File without changes