writeexcel 0.5.0 → 0.6.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 (130) hide show
  1. data/.gitattributes +1 -1
  2. data/.gitignore +24 -24
  3. data/README.rdoc +34 -55
  4. data/VERSION +1 -1
  5. data/charts/chartex.rb +316 -316
  6. data/charts/demo1.rb +46 -46
  7. data/charts/demo2.rb +65 -65
  8. data/charts/demo3.rb +117 -117
  9. data/charts/demo4.rb +119 -119
  10. data/charts/demo5.rb +48 -48
  11. data/examples/a_simple.rb +43 -43
  12. data/examples/autofilter.rb +265 -265
  13. data/examples/bigfile.rb +30 -30
  14. data/examples/chart_area.rb +121 -121
  15. data/examples/chart_bar.rb +120 -120
  16. data/examples/chart_column.rb +120 -120
  17. data/examples/chart_line.rb +120 -120
  18. data/examples/chart_pie.rb +108 -108
  19. data/examples/chart_scatter.rb +121 -121
  20. data/examples/chart_stock.rb +148 -148
  21. data/examples/chess.rb +142 -142
  22. data/examples/colors.rb +129 -129
  23. data/examples/comments1.rb +27 -27
  24. data/examples/comments2.rb +352 -352
  25. data/examples/copyformat.rb +52 -52
  26. data/examples/data_validate.rb +279 -279
  27. data/examples/date_time.rb +87 -87
  28. data/examples/defined_name.rb +32 -32
  29. data/examples/demo.rb +124 -124
  30. data/examples/diag_border.rb +36 -36
  31. data/examples/formats.rb +490 -490
  32. data/examples/formula_result.rb +30 -30
  33. data/examples/header.rb +137 -137
  34. data/examples/hide_sheet.rb +29 -29
  35. data/examples/hyperlink.rb +43 -43
  36. data/examples/images.rb +63 -63
  37. data/examples/indent.rb +31 -31
  38. data/examples/merge1.rb +40 -40
  39. data/examples/merge2.rb +45 -45
  40. data/examples/merge3.rb +66 -66
  41. data/examples/merge4.rb +83 -83
  42. data/examples/merge5.rb +80 -80
  43. data/examples/merge6.rb +67 -67
  44. data/examples/outline.rb +255 -255
  45. data/examples/outline_collapsed.rb +209 -209
  46. data/examples/panes.rb +113 -113
  47. data/examples/properties.rb +34 -34
  48. data/examples/properties_jp.rb +33 -33
  49. data/examples/protection.rb +47 -47
  50. data/examples/regions.rb +53 -53
  51. data/examples/repeat.rb +43 -43
  52. data/examples/right_to_left.rb +27 -27
  53. data/examples/row_wrap.rb +53 -53
  54. data/examples/stats.rb +74 -74
  55. data/examples/stocks.rb +81 -81
  56. data/examples/tab_colors.rb +31 -31
  57. data/examples/utf8.rb +15 -15
  58. data/examples/write_arrays.rb +83 -83
  59. data/lib/writeexcel/biffwriter.rb +232 -232
  60. data/lib/writeexcel/caller_info.rb +12 -12
  61. data/lib/writeexcel/chart.rb +2190 -2177
  62. data/lib/writeexcel/charts/area.rb +154 -154
  63. data/lib/writeexcel/charts/bar.rb +177 -177
  64. data/lib/writeexcel/charts/column.rb +156 -156
  65. data/lib/writeexcel/charts/external.rb +66 -66
  66. data/lib/writeexcel/charts/line.rb +154 -154
  67. data/lib/writeexcel/charts/pie.rb +169 -169
  68. data/lib/writeexcel/charts/scatter.rb +192 -192
  69. data/lib/writeexcel/charts/stock.rb +213 -213
  70. data/lib/writeexcel/colors.rb +64 -64
  71. data/lib/writeexcel/compatibility.rb +0 -255
  72. data/lib/writeexcel/debug_info.rb +37 -33
  73. data/lib/writeexcel/excelformulaparser.rb +587 -587
  74. data/lib/writeexcel/format.rb +13 -4
  75. data/lib/writeexcel/formula.rb +26 -9
  76. data/lib/writeexcel/helper.rb +68 -64
  77. data/lib/writeexcel/olewriter.rb +311 -311
  78. data/lib/writeexcel/properties.rb +242 -240
  79. data/lib/writeexcel/storage_lite.rb +984 -978
  80. data/lib/writeexcel/workbook.rb +3210 -3192
  81. data/lib/writeexcel/worksheet.rb +143 -51
  82. data/lib/writeexcel/write_file.rb +44 -40
  83. data/lib/writeexcel.rb +1159 -1159
  84. data/test/helper.rb +31 -28
  85. data/test/perl_output/README +31 -31
  86. data/test/test_00_IEEE_double.rb +13 -13
  87. data/test/test_01_add_worksheet.rb +10 -10
  88. data/test/test_02_merge_formats.rb +53 -53
  89. data/test/test_04_dimensions.rb +392 -392
  90. data/test/test_05_rows.rb +179 -179
  91. data/test/test_06_extsst.rb +77 -77
  92. data/test/test_11_date_time.rb +479 -479
  93. data/test/test_12_date_only.rb +501 -501
  94. data/test/test_13_date_seconds.rb +481 -481
  95. data/test/test_21_escher.rb +637 -637
  96. data/test/test_22_mso_drawing_group.rb +745 -745
  97. data/test/test_23_note.rb +73 -73
  98. data/test/test_24_txo.rb +75 -75
  99. data/test/test_25_position_object.rb +84 -84
  100. data/test/test_26_autofilter.rb +314 -314
  101. data/test/test_27_autofilter.rb +131 -131
  102. data/test/test_28_autofilter.rb +161 -161
  103. data/test/test_29_process_jpg.rb +683 -683
  104. data/test/test_30_validation_dval.rb +77 -77
  105. data/test/test_31_validation_dv_strings.rb +126 -126
  106. data/test/test_32_validation_dv_formula.rb +206 -206
  107. data/test/test_40_property_types.rb +188 -188
  108. data/test/test_41_properties.rb +235 -235
  109. data/test/test_42_set_properties.rb +437 -437
  110. data/test/test_50_name_stored.rb +299 -299
  111. data/test/test_51_name_print_area.rb +357 -357
  112. data/test/test_52_name_print_titles.rb +454 -454
  113. data/test/test_53_autofilter.rb +203 -203
  114. data/test/test_60_chart_generic.rb +578 -578
  115. data/test/test_61_chart_subclasses.rb +95 -95
  116. data/test/test_62_chart_formats.rb +272 -272
  117. data/test/test_63_chart_area_formats.rb +649 -649
  118. data/test/test_biff.rb +75 -75
  119. data/test/test_compatibility.rb +12 -627
  120. data/test/test_example_match.rb +3144 -3144
  121. data/test/test_formula.rb +61 -61
  122. data/test/test_ole.rb +106 -106
  123. data/test/test_storage_lite.rb +125 -125
  124. data/test/test_workbook.rb +139 -139
  125. data/test/test_worksheet.rb +110 -110
  126. data/utils/add_magic_comment.rb +80 -80
  127. data/writeexcel.gemspec +4 -6
  128. data/writeexcel.rdoc +58 -15
  129. metadata +9 -6
  130. data/test/test_new_encoding.rb +0 -205
@@ -1,311 +1,311 @@
1
- # -*- coding: utf-8 -*-
2
- ###############################################################################
3
- #
4
- # BIFFwriter - An abstract base class for Excel workbooks and worksheets.
5
- #
6
- #
7
- # Used in conjunction with WriteExcel
8
- #
9
- # Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
10
- #
11
- # original written in Perl by John McNamara
12
- # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
13
- #
14
- class MaxSizeError < StandardError; end #:nodoc:
15
-
16
- class OLEWriter #:nodoc:
17
-
18
- # Not meant for public consumption
19
- MaxSize = 7087104 # Use WriteExcel::Big to exceed this
20
- BlockSize = 4096
21
- BlockDiv = 512
22
- ListBlocks = 127
23
-
24
- attr_reader :biff_size, :book_size, :big_blocks, :list_blocks
25
- attr_reader :root_start, :size_allowed
26
- attr_accessor :biff_only, :internal_fh
27
-
28
- # Accept an IO or IO-like object or a filename (as a String)
29
- def initialize(arg)
30
- if arg.respond_to?(:to_str)
31
- @io = File.open(arg, "w")
32
- else
33
- @io = arg
34
- end
35
- @io.binmode if @io.respond_to?(:binmode)
36
-
37
- @filehandle = ""
38
- @fileclosed = false
39
- @internal_fh = 0
40
- @biff_only = 0
41
- @size_allowed = true
42
- @biff_size = 0
43
- @book_size = 0
44
- @big_blocks = 0
45
- @list_blocks = 0
46
- @root_start = 0
47
- @block_count = 4
48
- end
49
-
50
- # Imitate IO.open behavior
51
-
52
- ###############################################################################
53
- #
54
- # _initialize()
55
- #
56
- # Create a new filehandle or use the provided filehandle.
57
- #
58
- def _initialize
59
- olefile = @olefilename
60
-
61
- # If the filename is a reference it is assumed that it is a valid
62
- # filehandle, if not we create a filehandle.
63
- #
64
-
65
- # Create a new file, open for writing
66
- fh = open(olefile, "wb")
67
-
68
- # Workbook.pm also checks this but something may have happened since
69
- # then.
70
- raise "Can't open olefile. It may be in use or protected.\n" unless fh
71
-
72
- @internal_fh = 1
73
-
74
- # Store filehandle
75
- @filehandle = fh
76
- end
77
-
78
- def self.open(arg)
79
- if block_given?
80
- ole = self.new(arg)
81
- result = yield(ole)
82
- ole.close
83
- result
84
- else
85
- self.new(arg)
86
- end
87
- end
88
-
89
- ###############################################################################
90
- #
91
- # write($data)
92
- #
93
- # Write BIFF data to OLE file.
94
- #
95
- def write(data)
96
- @io.write(data)
97
- end
98
-
99
- ###############################################################################
100
- #
101
- # set_size($biffsize)
102
- #
103
- # Set the size of the data to be written to the OLE stream
104
- #
105
- # $big_blocks = (109 depot block x (128 -1 marker word)
106
- # - (1 x end words)) = 13842
107
- # $maxsize = $big_blocks * 512 bytes = 7087104
108
- #
109
- def set_size(size = BlockSize)
110
- if size > MaxSize
111
- return @size_allowed = false
112
- end
113
-
114
- @biff_size = size
115
-
116
- if biff_size > BlockSize
117
- @book_size = size
118
- else
119
- @book_size = BlockSize
120
- end
121
-
122
- @size_allowed = true
123
- end
124
-
125
- ###############################################################################
126
- #
127
- # _calculate_sizes()
128
- #
129
- # Calculate various sizes needed for the OLE stream
130
- #
131
- def calculate_sizes
132
- @big_blocks = (@book_size.to_f/BlockDiv.to_f).ceil
133
- @list_blocks = (@big_blocks / ListBlocks) + 1
134
- @root_start = @big_blocks
135
- end
136
-
137
- ###############################################################################
138
- #
139
- # close()
140
- #
141
- # Write root entry, big block list and close the filehandle.
142
- # This routine is used to explicitly close the open filehandle without
143
- # having to wait for DESTROY.
144
- #
145
- def close
146
- if @size_allowed == true
147
- write_padding if @biff_only == 0
148
- write_property_storage if @biff_only == 0
149
- write_big_block_depot if @biff_only == 0
150
- end
151
- @io.close
152
- end
153
-
154
- ###############################################################################
155
- #
156
- # write_header()
157
- #
158
- # Write OLE header block.
159
- #
160
- def write_header
161
- return if @biff_only == 1
162
- calculate_sizes
163
- root_start = @root_start
164
- num_lists = @list_blocks
165
-
166
- id = [0xD0CF11E0, 0xA1B11AE1].pack("NN")
167
- unknown1 = [0x00, 0x00, 0x00, 0x00].pack("VVVV")
168
- unknown2 = [0x3E, 0x03].pack("vv")
169
- unknown3 = [-2].pack("v")
170
- unknown4 = [0x09].pack("v")
171
- unknown5 = [0x06, 0x00, 0x00].pack("VVV")
172
- num_bbd_blocks = [num_lists].pack("V")
173
- root_startblock = [root_start].pack("V")
174
- unknown6 = [0x00, 0x1000].pack("VV")
175
- sbd_startblock = [-2].pack("V")
176
- unknown7 = [0x00, -2 ,0x00].pack("VVV")
177
-
178
- write(id)
179
- write(unknown1)
180
- write(unknown2)
181
- write(unknown3)
182
- write(unknown4)
183
- write(unknown5)
184
- write(num_bbd_blocks)
185
- write(root_startblock)
186
- write(unknown6)
187
- write(sbd_startblock)
188
- write(unknown7)
189
-
190
- unused = [-1].pack("V")
191
-
192
- 1.upto(num_lists){
193
- root_start += 1
194
- write([root_start].pack("V"))
195
- }
196
-
197
- num_lists.upto(108){
198
- write(unused)
199
- }
200
- end
201
-
202
- ###############################################################################
203
- #
204
- # _write_big_block_depot()
205
- #
206
- # Write big block depot.
207
- #
208
- def write_big_block_depot
209
- num_blocks = @big_blocks
210
- num_lists = @list_blocks
211
- total_blocks = num_lists * 128
212
- used_blocks = num_blocks + num_lists + 2
213
-
214
- marker = [-3].pack("V")
215
- end_of_chain = [-2].pack("V")
216
- unused = [-1].pack("V")
217
-
218
- 1.upto(num_blocks-1){|n|
219
- write([n].pack("V"))
220
- }
221
-
222
- write end_of_chain
223
- write end_of_chain
224
-
225
- 1.upto(num_lists){ write(marker) }
226
-
227
- used_blocks.upto(total_blocks){ write(unused) }
228
-
229
- end
230
-
231
- ###############################################################################
232
- #
233
- # _write_property_storage()
234
- #
235
- # Write property storage. TODO: add summary sheets
236
- #
237
- def write_property_storage
238
-
239
- ######### name type dir start size
240
- write_pps('Root Entry', 0x05, 1, -2, 0x00)
241
- write_pps('Workbook', 0x02, -1, 0x00, @book_size)
242
- write_pps("", 0x00, -1, 0x00, 0x0000)
243
- write_pps("", 0x00, -1, 0x00, 0x0000)
244
- end
245
-
246
- ###############################################################################
247
- #
248
- # _write_pps()
249
- #
250
- # Write property sheet in property storage
251
- #
252
- def write_pps(name, type, dir, start, size)
253
- length = 0
254
- ord_name = []
255
- unless name.empty?
256
- name = name + "\0"
257
- ord_name = name.unpack("c*")
258
- length = name.bytesize * 2
259
- end
260
-
261
- rawname = ord_name.pack("v*")
262
- zero = [0].pack("C")
263
-
264
- pps_sizeofname = [length].pack("v") #0x40
265
- pps_type = [type].pack("v") #0x42
266
- pps_prev = [-1].pack("V") #0x44
267
- pps_next = [-1].pack("V") #0x48
268
- pps_dir = [dir].pack("V") #0x4c
269
-
270
- unknown = [0].pack("V")
271
-
272
- pps_ts1s = [0].pack("V") #0x64
273
- pps_ts1d = [0].pack("V") #0x68
274
- pps_ts2s = [0].pack("V") #0x6c
275
- pps_ts2d = [0].pack("V") #0x70
276
- pps_sb = [start].pack("V") #0x74
277
- pps_size = [size].pack("V") #0x78
278
-
279
- write(rawname)
280
- write(zero * (64 - length)) if 64 - length >= 1
281
- write(pps_sizeofname)
282
- write(pps_type)
283
- write(pps_prev)
284
- write(pps_next)
285
- write(pps_dir)
286
- write(unknown * 5)
287
- write(pps_ts1s)
288
- write(pps_ts1d)
289
- write(pps_ts2s)
290
- write(pps_ts2d)
291
- write(pps_sb)
292
- write(pps_size)
293
- write(unknown)
294
- end
295
-
296
- ###############################################################################
297
- #
298
- # _write_padding()
299
- #
300
- # Pad the end of the file
301
- #
302
- def write_padding
303
- min_size = 512
304
- min_size = BlockSize if @biff_size < BlockSize
305
-
306
- if @biff_size % min_size != 0
307
- padding = min_size - (@biff_size % min_size)
308
- write("\0" * padding)
309
- end
310
- end
311
- end
1
+ # -*- coding: utf-8 -*-
2
+ ###############################################################################
3
+ #
4
+ # BIFFwriter - An abstract base class for Excel workbooks and worksheets.
5
+ #
6
+ #
7
+ # Used in conjunction with WriteExcel
8
+ #
9
+ # Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
10
+ #
11
+ # original written in Perl by John McNamara
12
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
13
+ #
14
+ class MaxSizeError < StandardError; end #:nodoc:
15
+
16
+ class OLEWriter #:nodoc:
17
+
18
+ # Not meant for public consumption
19
+ MaxSize = 7087104 # Use WriteExcel::Big to exceed this
20
+ BlockSize = 4096
21
+ BlockDiv = 512
22
+ ListBlocks = 127
23
+
24
+ attr_reader :biff_size, :book_size, :big_blocks, :list_blocks
25
+ attr_reader :root_start, :size_allowed
26
+ attr_accessor :biff_only, :internal_fh
27
+
28
+ # Accept an IO or IO-like object or a filename (as a String)
29
+ def initialize(arg)
30
+ if arg.respond_to?(:to_str)
31
+ @io = File.open(arg, "w")
32
+ else
33
+ @io = arg
34
+ end
35
+ @io.binmode if @io.respond_to?(:binmode)
36
+
37
+ @filehandle = ""
38
+ @fileclosed = false
39
+ @internal_fh = 0
40
+ @biff_only = 0
41
+ @size_allowed = true
42
+ @biff_size = 0
43
+ @book_size = 0
44
+ @big_blocks = 0
45
+ @list_blocks = 0
46
+ @root_start = 0
47
+ @block_count = 4
48
+ end
49
+
50
+ # Imitate IO.open behavior
51
+
52
+ ###############################################################################
53
+ #
54
+ # _initialize()
55
+ #
56
+ # Create a new filehandle or use the provided filehandle.
57
+ #
58
+ def _initialize
59
+ olefile = @olefilename
60
+
61
+ # If the filename is a reference it is assumed that it is a valid
62
+ # filehandle, if not we create a filehandle.
63
+ #
64
+
65
+ # Create a new file, open for writing
66
+ fh = open(olefile, "wb")
67
+
68
+ # Workbook.pm also checks this but something may have happened since
69
+ # then.
70
+ raise "Can't open olefile. It may be in use or protected.\n" unless fh
71
+
72
+ @internal_fh = 1
73
+
74
+ # Store filehandle
75
+ @filehandle = fh
76
+ end
77
+
78
+ def self.open(arg)
79
+ if block_given?
80
+ ole = self.new(arg)
81
+ result = yield(ole)
82
+ ole.close
83
+ result
84
+ else
85
+ self.new(arg)
86
+ end
87
+ end
88
+
89
+ ###############################################################################
90
+ #
91
+ # write($data)
92
+ #
93
+ # Write BIFF data to OLE file.
94
+ #
95
+ def write(data)
96
+ @io.write(data)
97
+ end
98
+
99
+ ###############################################################################
100
+ #
101
+ # set_size($biffsize)
102
+ #
103
+ # Set the size of the data to be written to the OLE stream
104
+ #
105
+ # $big_blocks = (109 depot block x (128 -1 marker word)
106
+ # - (1 x end words)) = 13842
107
+ # $maxsize = $big_blocks * 512 bytes = 7087104
108
+ #
109
+ def set_size(size = BlockSize)
110
+ if size > MaxSize
111
+ return @size_allowed = false
112
+ end
113
+
114
+ @biff_size = size
115
+
116
+ if biff_size > BlockSize
117
+ @book_size = size
118
+ else
119
+ @book_size = BlockSize
120
+ end
121
+
122
+ @size_allowed = true
123
+ end
124
+
125
+ ###############################################################################
126
+ #
127
+ # _calculate_sizes()
128
+ #
129
+ # Calculate various sizes needed for the OLE stream
130
+ #
131
+ def calculate_sizes
132
+ @big_blocks = (@book_size.to_f/BlockDiv.to_f).ceil
133
+ @list_blocks = (@big_blocks / ListBlocks) + 1
134
+ @root_start = @big_blocks
135
+ end
136
+
137
+ ###############################################################################
138
+ #
139
+ # close()
140
+ #
141
+ # Write root entry, big block list and close the filehandle.
142
+ # This routine is used to explicitly close the open filehandle without
143
+ # having to wait for DESTROY.
144
+ #
145
+ def close
146
+ if @size_allowed == true
147
+ write_padding if @biff_only == 0
148
+ write_property_storage if @biff_only == 0
149
+ write_big_block_depot if @biff_only == 0
150
+ end
151
+ @io.close
152
+ end
153
+
154
+ ###############################################################################
155
+ #
156
+ # write_header()
157
+ #
158
+ # Write OLE header block.
159
+ #
160
+ def write_header
161
+ return if @biff_only == 1
162
+ calculate_sizes
163
+ root_start = @root_start
164
+ num_lists = @list_blocks
165
+
166
+ id = [0xD0CF11E0, 0xA1B11AE1].pack("NN")
167
+ unknown1 = [0x00, 0x00, 0x00, 0x00].pack("VVVV")
168
+ unknown2 = [0x3E, 0x03].pack("vv")
169
+ unknown3 = [-2].pack("v")
170
+ unknown4 = [0x09].pack("v")
171
+ unknown5 = [0x06, 0x00, 0x00].pack("VVV")
172
+ num_bbd_blocks = [num_lists].pack("V")
173
+ root_startblock = [root_start].pack("V")
174
+ unknown6 = [0x00, 0x1000].pack("VV")
175
+ sbd_startblock = [-2].pack("V")
176
+ unknown7 = [0x00, -2 ,0x00].pack("VVV")
177
+
178
+ write(id)
179
+ write(unknown1)
180
+ write(unknown2)
181
+ write(unknown3)
182
+ write(unknown4)
183
+ write(unknown5)
184
+ write(num_bbd_blocks)
185
+ write(root_startblock)
186
+ write(unknown6)
187
+ write(sbd_startblock)
188
+ write(unknown7)
189
+
190
+ unused = [-1].pack("V")
191
+
192
+ 1.upto(num_lists){
193
+ root_start += 1
194
+ write([root_start].pack("V"))
195
+ }
196
+
197
+ num_lists.upto(108){
198
+ write(unused)
199
+ }
200
+ end
201
+
202
+ ###############################################################################
203
+ #
204
+ # _write_big_block_depot()
205
+ #
206
+ # Write big block depot.
207
+ #
208
+ def write_big_block_depot
209
+ num_blocks = @big_blocks
210
+ num_lists = @list_blocks
211
+ total_blocks = num_lists * 128
212
+ used_blocks = num_blocks + num_lists + 2
213
+
214
+ marker = [-3].pack("V")
215
+ end_of_chain = [-2].pack("V")
216
+ unused = [-1].pack("V")
217
+
218
+ 1.upto(num_blocks-1){|n|
219
+ write([n].pack("V"))
220
+ }
221
+
222
+ write end_of_chain
223
+ write end_of_chain
224
+
225
+ 1.upto(num_lists){ write(marker) }
226
+
227
+ used_blocks.upto(total_blocks){ write(unused) }
228
+
229
+ end
230
+
231
+ ###############################################################################
232
+ #
233
+ # _write_property_storage()
234
+ #
235
+ # Write property storage. TODO: add summary sheets
236
+ #
237
+ def write_property_storage
238
+
239
+ ######### name type dir start size
240
+ write_pps('Root Entry', 0x05, 1, -2, 0x00)
241
+ write_pps('Workbook', 0x02, -1, 0x00, @book_size)
242
+ write_pps("", 0x00, -1, 0x00, 0x0000)
243
+ write_pps("", 0x00, -1, 0x00, 0x0000)
244
+ end
245
+
246
+ ###############################################################################
247
+ #
248
+ # _write_pps()
249
+ #
250
+ # Write property sheet in property storage
251
+ #
252
+ def write_pps(name, type, dir, start, size)
253
+ length = 0
254
+ ord_name = []
255
+ unless name.empty?
256
+ name = name + "\0"
257
+ ord_name = name.unpack("c*")
258
+ length = name.bytesize * 2
259
+ end
260
+
261
+ rawname = ord_name.pack("v*")
262
+ zero = [0].pack("C")
263
+
264
+ pps_sizeofname = [length].pack("v") #0x40
265
+ pps_type = [type].pack("v") #0x42
266
+ pps_prev = [-1].pack("V") #0x44
267
+ pps_next = [-1].pack("V") #0x48
268
+ pps_dir = [dir].pack("V") #0x4c
269
+
270
+ unknown = [0].pack("V")
271
+
272
+ pps_ts1s = [0].pack("V") #0x64
273
+ pps_ts1d = [0].pack("V") #0x68
274
+ pps_ts2s = [0].pack("V") #0x6c
275
+ pps_ts2d = [0].pack("V") #0x70
276
+ pps_sb = [start].pack("V") #0x74
277
+ pps_size = [size].pack("V") #0x78
278
+
279
+ write(rawname)
280
+ write(zero * (64 - length)) if 64 - length >= 1
281
+ write(pps_sizeofname)
282
+ write(pps_type)
283
+ write(pps_prev)
284
+ write(pps_next)
285
+ write(pps_dir)
286
+ write(unknown * 5)
287
+ write(pps_ts1s)
288
+ write(pps_ts1d)
289
+ write(pps_ts2s)
290
+ write(pps_ts2d)
291
+ write(pps_sb)
292
+ write(pps_size)
293
+ write(unknown)
294
+ end
295
+
296
+ ###############################################################################
297
+ #
298
+ # _write_padding()
299
+ #
300
+ # Pad the end of the file
301
+ #
302
+ def write_padding
303
+ min_size = 512
304
+ min_size = BlockSize if @biff_size < BlockSize
305
+
306
+ if @biff_size % min_size != 0
307
+ padding = min_size - (@biff_size % min_size)
308
+ write("\0" * padding)
309
+ end
310
+ end
311
+ end