axlsx 1.1.7 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/README.md +41 -5
  2. data/Rakefile +3 -2
  3. data/examples/chart_colors.rb +18 -3
  4. data/examples/example.rb +100 -46
  5. data/examples/extractive.pdf +0 -0
  6. data/lib/axlsx.rb +7 -6
  7. data/lib/axlsx/content_type/content_type.rb +2 -0
  8. data/lib/axlsx/content_type/default.rb +21 -12
  9. data/lib/axlsx/content_type/override.rb +22 -11
  10. data/lib/axlsx/doc_props/app.rb +36 -32
  11. data/lib/axlsx/doc_props/core.rb +9 -5
  12. data/lib/axlsx/drawing/ax_data_source.rb +7 -6
  13. data/lib/axlsx/drawing/axis.rb +48 -27
  14. data/lib/axlsx/drawing/bar_3D_chart.rb +47 -37
  15. data/lib/axlsx/drawing/bar_series.rb +1 -0
  16. data/lib/axlsx/drawing/cat_axis.rb +42 -38
  17. data/lib/axlsx/drawing/chart.rb +34 -27
  18. data/lib/axlsx/drawing/drawing.rb +5 -4
  19. data/lib/axlsx/drawing/line_3D_chart.rb +1 -1
  20. data/lib/axlsx/drawing/num_data_source.rb +1 -1
  21. data/lib/axlsx/drawing/pie_3D_chart.rb +7 -7
  22. data/lib/axlsx/drawing/two_cell_anchor.rb +3 -8
  23. data/lib/axlsx/drawing/view_3D.rb +41 -31
  24. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  25. data/lib/axlsx/package.rb +11 -11
  26. data/lib/axlsx/rels/relationship.rb +3 -3
  27. data/lib/axlsx/stylesheet/styles.rb +1 -1
  28. data/lib/axlsx/util/constants.rb +4 -0
  29. data/lib/axlsx/util/simple_typed_list.rb +2 -2
  30. data/lib/axlsx/util/validators.rb +2 -2
  31. data/lib/axlsx/version.rb +1 -1
  32. data/lib/axlsx/workbook/workbook.rb +1 -2
  33. data/lib/axlsx/workbook/worksheet/cell.rb +1 -1
  34. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  35. data/lib/axlsx/workbook/worksheet/page_setup.rb +9 -0
  36. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  37. data/lib/axlsx/workbook/worksheet/worksheet.rb +180 -56
  38. data/test/content_type/tc_content_type.rb +1 -6
  39. data/test/doc_props/tc_core.rb +1 -1
  40. data/test/drawing/tc_axis.rb +8 -0
  41. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  42. data/test/drawing/tc_bar_series.rb +0 -1
  43. data/test/drawing/tc_chart.rb +1 -5
  44. data/test/drawing/tc_pie_3D_chart.rb +3 -7
  45. data/test/drawing/tc_view_3D.rb +18 -18
  46. data/test/tc_package.rb +2 -0
  47. data/test/workbook/worksheet/tc_page_setup.rb +20 -3
  48. data/test/workbook/worksheet/tc_protected_range.rb +18 -0
  49. data/test/workbook/worksheet/tc_selection.rb +1 -1
  50. data/test/workbook/worksheet/tc_worksheet.rb +39 -18
  51. metadata +54 -103
  52. data/examples/axis-titles.xlsx +0 -0
  53. data/examples/basic_charts.xlsx +0 -0
  54. data/examples/chart_colors.xlsx +0 -0
  55. data/examples/charts.xlsx +0 -0
  56. data/examples/conditional_formatting/getting_barred.xlsx +0 -0
  57. data/examples/doc/_index.html +0 -84
  58. data/examples/doc/class_list.html +0 -47
  59. data/examples/doc/css/common.css +0 -1
  60. data/examples/doc/css/full_list.css +0 -55
  61. data/examples/doc/css/style.css +0 -322
  62. data/examples/doc/file_list.html +0 -46
  63. data/examples/doc/frames.html +0 -13
  64. data/examples/doc/index.html +0 -84
  65. data/examples/doc/js/app.js +0 -205
  66. data/examples/doc/js/full_list.js +0 -173
  67. data/examples/doc/js/jquery.js +0 -16
  68. data/examples/doc/method_list.html +0 -46
  69. data/examples/doc/top-level-namespace.html +0 -95
  70. data/examples/example.xlsx +0 -0
  71. data/examples/example_streamed.xlsx +0 -0
  72. data/examples/examples_saved.xlsx +0 -0
  73. data/examples/extractive.xlsx +0 -0
  74. data/examples/fish.xlsx +0 -0
  75. data/examples/no-use_autowidth.xlsx +0 -0
  76. data/examples/pareto.rb +0 -28
  77. data/examples/pareto.xlsx +0 -0
  78. data/examples/pie_chart_excel.xlsx +0 -0
  79. data/examples/pie_chart_saved.xlsx +0 -0
  80. data/examples/shared_strings_example.xlsx +0 -0
  81. data/examples/sheet_protection.xlsx +0 -0
  82. data/examples/sheet_view.xlsx +0 -0
  83. data/examples/two_cell_anchor_image.xlsx +0 -0
  84. data/examples/~$example.xlsx +0 -0
  85. data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
  86. data/lib/axlsx/drawing/data_source.rb~ +0 -51
  87. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  88. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  89. data/lib/axlsx/drawing/num_data.rb~ +0 -51
  90. data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
  91. data/lib/axlsx/drawing/num_val.rb~ +0 -40
  92. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  93. data/lib/axlsx/drawing/ref.rb~ +0 -41
  94. data/lib/axlsx/drawing/str_data.rb~ +0 -58
  95. data/lib/axlsx/drawing/str_val.rb~ +0 -35
  96. data/lib/axlsx/drawing/vml_drawing.rb~ +0 -6
  97. data/lib/axlsx/drawing/vml_shape.rb~ +0 -61
  98. data/lib/axlsx/util/cbf.rb +0 -333
  99. data/lib/axlsx/util/cfb.rb~ +0 -201
  100. data/lib/axlsx/util/font_tables.rb~ +0 -0
  101. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  102. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  103. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  104. data/lib/axlsx/util/parser.rb~ +0 -6
  105. data/lib/axlsx/util/storage.rb~ +0 -0
  106. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  107. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  108. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  109. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  110. data/lib/axlsx/workbook/worksheet/comment.rb~ +0 -91
  111. data/lib/axlsx/workbook/worksheet/comments.rb~ +0 -86
  112. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  113. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  114. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  115. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  116. data/lib/schema/dc.xsd~ +0 -118
  117. data/lib/schema/dcterms.xsd~ +0 -331
  118. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  119. data/test/drawing/tc_data_source.rb~ +0 -30
  120. data/test/drawing/tc_num_data.rb~ +0 -35
  121. data/test/drawing/tc_num_val.rb~ +0 -29
  122. data/test/drawing/tc_str_data.rb~ +0 -30
  123. data/test/drawing/tc_str_val.rb~ +0 -26
  124. data/test/drawing/tc_vml_drawing.rb~ +0 -0
  125. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  126. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  127. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  128. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  129. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  130. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
@@ -1,40 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- module Axlsx
3
-
4
- #This class specifies data for a particular data point.
5
- class NumVal < StrVal
6
-
7
- # A string representing the format code to apply. For more information see see the SpreadsheetML numFmt element's (§18.8.30) formatCode attribute.
8
- # @return [String]
9
- attr_reader :format_code
10
-
11
- # creates a new NumVal object
12
- # @option options [String] formatCode
13
- # @option options [Integer] v
14
- def initialize(options={})
15
- @format_code = "General"
16
- @v = @idx = 0
17
- options.each do |o|
18
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
19
- end
20
- end
21
-
22
- # @see format_code
23
- def format_code=(v='General')
24
- Axlsx::validate_string(v)
25
- @format_code = v
26
- end
27
-
28
- # @see v
29
- def v=(v)
30
- Axlsx::validate_int(v)
31
- @v = v
32
- end
33
-
34
- # serialize the object
35
- def to_xml_string(idx, str = "")
36
- Axlsx::validate_unsigned_int(idx)
37
- str << '<c:pt idx="' << idx.to_s << '" formatCode="' << format_code << '"><c:v>' << v.to_s << '</c:v></c:pt>'
38
- end
39
- end
40
- end
@@ -1,36 +0,0 @@
1
- module Axlsx
2
- # The picture locking class defines the locking properties for pictures in your workbook.
3
- class PictureLocking
4
-
5
-
6
- attr_reader :noGrp
7
- attr_reader :noSelect
8
- attr_reader :noRot
9
- attr_reader :noChangeAspect
10
- attr_reader :noMove
11
- attr_reader :noResize
12
- attr_reader :noEditPoints
13
- attr_reader :noAdjustHandles
14
- attr_reader :noChangeArrowheads
15
- attr_reader :noChangeShapeType
16
-
17
- # Creates a new PictureLocking object
18
- # @option options [Boolean] noGrp
19
- # @option options [Boolean] noSelect
20
- # @option options [Boolean] noRot
21
- # @option options [Boolean] noChangeAspect
22
- # @option options [Boolean] noMove
23
- # @option options [Boolean] noResize
24
- # @option options [Boolean] noEditPoints
25
- # @option options [Boolean] noAdjustHandles
26
- # @option options [Boolean] noChangeArrowheads
27
- # @option options [Boolean] noChangeShapeType
28
- def initialize(options={})
29
- options.each do |o|
30
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
31
- end
32
- end
33
-
34
-
35
- end
36
- end
@@ -1,41 +0,0 @@
1
- module Axlsx
2
-
3
- # Base class for xVal, yVal and val data sources
4
- class DataSource
5
-
6
- def self.allowed_tag_names
7
- [:yVal, :xVal, :val]
8
- end
9
-
10
- def self.allowed_types
11
- [NumData, StrData]
12
- end
13
-
14
- attr_reader :tag_name
15
-
16
- attr_reader :data
17
-
18
- def initialize(type, data=[])
19
- Axlsx::RestrictionValidator.validate "#{self.class.name}", self.class.allowed_types, type
20
- @data = type.new
21
- end
22
-
23
- def f
24
-
25
- end
26
-
27
- def is_literal?
28
-
29
- end
30
-
31
- def is_reference?
32
-
33
- end
34
-
35
- def to_xml_string(str = '')
36
-
37
- end
38
-
39
- end
40
-
41
- end
@@ -1,58 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- module Axlsx
3
-
4
- #This specifies the last string data used for a chart. (e.g. strLit and strCache)
5
- # This class is extended for NumData to include the formatCode attribute required for numLit and numCache
6
- class StrData
7
-
8
- def self.allowed_tag_names
9
- [:strCache, :strLit]
10
- end
11
-
12
- # A list of NumVal objects
13
- # @return [SimpleTypedList]
14
- attr_reader :pt
15
-
16
- # The tag name to use when serializing this object.
17
- # this is restricted to the values returnd by self.allowed_tag_names
18
- attr_reader :tag_name
19
-
20
- # creates a new StrVal object
21
- # @option options [Array] :data
22
- # @option options [String] :tag_name
23
- def initialize(options={})
24
- @tag_prefix = :str
25
- @type = StrVal
26
- @pt = SimpleTypedList.new(@type)
27
- options.each do |o|
28
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
29
- end
30
- end
31
-
32
- def data=(values)
33
- # raise ArgumentError, 'data assignation must be done with an array' unless values.is_a?(Array)
34
- @tag_name = values.first.is_a?(Cell) ? "#{@tag_prefix.to_s}Cache".to_sym : "#{@tag_prefix.to_s}Lit".to_sym
35
- values.each do |value|
36
- v = value.is_a?(Cell)? v.value : value
37
- @pt << @type.new(:v => v)
38
- end
39
- end
40
-
41
- def tag_name=(v)
42
- Axlsx::RestrictionValidator.validate "#{self.class.name}.tag_name", self.class.allowed_tag_names, v
43
- @tag_name = v
44
- end
45
-
46
- # serialize the object
47
- def to_xml_string(idx, str = "")
48
- str << '<c:' << tag_name.to_s << '>'
49
- str << '<c:ptCount val="' << @pt.size.to_s << '"/>'
50
- pt.each_with_index do |value, index|
51
- value.to_xml_string index, str
52
- end
53
- str << '</c:' << tag_name.to_s << '>'
54
- end
55
-
56
- end
57
-
58
- end
@@ -1,35 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- module Axlsx
3
-
4
- #This class specifies data for a particular data point.
5
- class StrVal
6
-
7
- # a string value.
8
- # @return [String]
9
- attr_reader :v
10
-
11
- # creates a new StrVal object
12
- # @option options [String] v
13
- def initialize(options={})
14
- @v = ""
15
- @idx = 0
16
- options.each do |o|
17
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
18
- end
19
-
20
- end
21
- # @see v
22
- def v=(v)
23
- Axlsx::validate_string(v)
24
- @v = v
25
- end
26
-
27
- # serialize the object
28
- def to_xml_string(idx, str = "")
29
- Axlsx::validate_unsigned_int(idx)
30
- str << '<c:pt idx="' << idx.to_s << '"><c:v>' << v.to_s << '</c:v></c:pt>'
31
- end
32
-
33
- end
34
-
35
- end
@@ -1,6 +0,0 @@
1
- module Axlsx
2
-
3
-
4
- class VmlDrawing
5
- end
6
- end
@@ -1,61 +0,0 @@
1
- module Axlsx
2
- class VmlShape
3
-
4
- attr_reader :row
5
-
6
- attr_reader :column
7
-
8
- attr_reader :left_column
9
- attr_reader :left_offset
10
- attr_reader :top_row
11
- attr_reader :top_offset
12
- attr_reader :right_column
13
- attr_reader :right_offset
14
- attr_reader :bottom_row
15
- attr_reader :bottom_offset
16
-
17
- def initialize(comment, options={})
18
- @row = @column = 0
19
- @left_column = 0
20
- @left_offset = 15
21
- @top_row = 0
22
- @top_offset = 2
23
- @right_column = 0
24
- @right_offset = 50
25
- @bottom_row = 0
26
- @bottom_offset = 5
27
- options.each do |o|
28
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
29
- end
30
-
31
-
32
- end
33
-
34
- def xml_to_string(str ='') str << <<SHAME_ON_YOU
35
-
36
- <v:shape id="_x0000_s#{@comments.worksheet.index+1}07#{index+1}" type="#_x0000_t202"
37
- style='position:absolute;margin-left:104pt;margin-top:2pt;width:800px;height:27pt;z-index:1;mso-wrap-style:tight'
38
- fillcolor="#ffffa1 [80]" o:insetmode="auto">
39
- <v:fill color2="#ffffa1 [80]"/>
40
- <v:shadow on="t" obscured="t"/>
41
- <v:path o:connecttype="none"/>
42
- <v:textbox style='mso-fit-text-with-word-wrap:t'>
43
- <div style='text-align:left'></div>
44
- </v:textbox>
45
-
46
- <x:ClientData ObjectType="Note">
47
- <x:MoveWithCells/>
48
- <x:SizeWithCells/>
49
- # LeftColumn, LeftOffset, TopRow, TopOffset, RightColumn, RightOffset, BottomRow, BottomOffset.
50
- <x:Anchor>#{comment.comments.worksheet[comment.ref].index + 1}, 15, #{comment.comments.worksheet[comment.ref].row.index}, 2, #{comment.comments.worksheet[comment.ref].index + 5}, 50, #{comment.comments.worksheet[comment.ref].row.index + 5}, 5</x:Anchor>
51
- <x:AutoFill>False</x:AutoFill>
52
- <x:Row>#{comment.comments.worksheet[comment.ref].row.index}</x:Row>
53
- <x:Column>#{comment.comments.worksheet[comment.ref].index}</x:Column>
54
- <x:Visible/>
55
- </x:ClientData>
56
- </v:shape>
57
- SHAME_ON_YOU
58
-
59
- end
60
- end
61
- end
@@ -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