Class: BIFFWriter
- Includes:
- CallerInfo
- Defined in:
- lib/writeexcel/biffwriter.rb,
lib/writeexcel/debug_info.rb
Overview
:nodoc:
Direct Known Subclasses
Constant Summary collapse
- BIFF_Version =
0x0600
- BigEndian =
[1].pack("I") == [1].pack("N")
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#datasize ⇒ Object
readonly
Returns the value of attribute datasize.
Instance Method Summary collapse
-
#add_continue(data) ⇒ Object
_add_continue().
- #add_mso_generic(type, version, instance, data, length = nil) ⇒ Object
- #append(*args) ⇒ Object
-
#cleanup ⇒ Object
:nodoc:.
-
#clear_data_for_test ⇒ Object
:nodoc:.
-
#get_data ⇒ Object
get_data().
-
#initialize ⇒ BIFFWriter
constructor
The args here aren’t used by BIFFWriter, but they are needed by its subclasses.
-
#inspect ⇒ Object
override Object#inspect.
- #not_using_tmpfile ⇒ Object
- #prepend(*args) ⇒ Object
- #print_caller_info(data, param = {}) ⇒ Object
-
#set_byte_order ⇒ Object
_set_byte_order().
-
#store_bof(type = 0x0005) ⇒ Object
_store_bof($type).
-
#store_eof ⇒ Object
_store_eof().
-
#unpack_record(data) ⇒ Object
:nodoc:.
Methods included from CallerInfo
Constructor Details
#initialize ⇒ BIFFWriter
The args here aren’t used by BIFFWriter, but they are needed by its subclasses. I don’t feel like creating multiple constructors.
31 32 33 34 35 |
# File 'lib/writeexcel/biffwriter.rb', line 31 def initialize super set_byte_order @ignore_continue = false end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
24 25 26 |
# File 'lib/writeexcel/biffwriter.rb', line 24 def data @data end |
#datasize ⇒ Object (readonly)
Returns the value of attribute datasize.
24 25 26 |
# File 'lib/writeexcel/biffwriter.rb', line 24 def datasize @datasize end |
Instance Method Details
#add_continue(data) ⇒ Object
_add_continue()
Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In Excel 97 the limit is 8228 bytes. Records that are longer than these limits must be split up into CONTINUE blocks.
This function take a long BIFF record and inserts CONTINUE records as necessary.
Some records have their own specialised Continue blocks so there is also an option to bypass this function.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/writeexcel/biffwriter.rb', line 151 def add_continue(data) # Skip this if another method handles the continue blocks. return data if @ignore_continue record = 0x003C # Record identifier header = [record, @limit].pack("vv") # The first 2080/8224 bytes remain intact. However, we have to change # the length field of the record. # data_array = split_by_length(data, @limit) first_data = data_array.shift last_data = data_array.pop || '' first_data[2, 2] = [@limit-4].pack('v') first_data << data_array.join(header) << [record, last_data.bytesize].pack('vv') << last_data end |
#add_mso_generic(type, version, instance, data, length = nil) ⇒ Object
_add_mso_generic()
my $type = $_[0];
my $version = $_[1];
my $instance = $_[2];
my $data = $_[3];
Create a mso structure that is part of an Escher drawing object. These are are used for images, comments and filters. This generic method is used by other methods to create specific mso records.
Returns the packed record.
185 186 187 188 189 190 191 192 |
# File 'lib/writeexcel/biffwriter.rb', line 185 def add_mso_generic(type, version, instance, data, length = nil) length ||= data.bytesize # The header contains version and instance info packed into 2 bytes. header = version | (instance << 4) [header, type, length].pack('vvV') + data end |
#append(*args) ⇒ Object
9 10 11 12 13 14 15 |
# File 'lib/writeexcel/debug_info.rb', line 9 def append(*args) data = ruby_18 { args.join } || ruby_19 { args.collect{ |arg| arg.dup.force_encoding('ASCII-8BIT') }.join } print_caller_info(data, :method => 'append') super end |
#cleanup ⇒ Object
:nodoc:
204 205 206 |
# File 'lib/writeexcel/biffwriter.rb', line 204 def cleanup # :nodoc: @filehandle.close(true) if @filehandle end |
#clear_data_for_test ⇒ Object
:nodoc:
200 201 202 |
# File 'lib/writeexcel/biffwriter.rb', line 200 def clear_data_for_test # :nodoc: @data = '' end |
#get_data ⇒ Object
get_data().
Retrieves data from memory in one chunk, or from disk in $buffer sized chunks.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/writeexcel/biffwriter.rb', line 70 def get_data buflen = 4096 # Return data stored in memory unless @data.nil? tmp = @data @data = nil if @using_tmpfile @filehandle.open @filehandle.binmode end return tmp end # Return data stored on disk if @using_tmpfile return @filehandle.read(buflen) end # No data to return nil end |
#inspect ⇒ Object
override Object#inspect
209 210 211 |
# File 'lib/writeexcel/biffwriter.rb', line 209 def inspect # :nodoc: to_s end |
#not_using_tmpfile ⇒ Object
194 195 196 197 198 |
# File 'lib/writeexcel/biffwriter.rb', line 194 def not_using_tmpfile @filehandle.close(true) if @filehandle @filehandle = nil @using_tmpfile = nil end |
#prepend(*args) ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/writeexcel/debug_info.rb', line 17 def prepend(*args) data = ruby_18 { args.join } || ruby_19 { args.collect{ |arg| arg.dup.force_encoding('ASCII-8BIT') }.join } print_caller_info(data, :method => 'prepend') super end |
#print_caller_info(data, param = {}) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/writeexcel/debug_info.rb', line 25 def print_caller_info(data, param = {}) infos = caller_info print "#{param[:method]}\n" if param[:method] infos.each do |info| print "#{info[:file]}:#{info[:line]}" print " in #{info[:method]}" if info[:method] print "\n" end print unpack_record(data) + "\n\n" end |
#set_byte_order ⇒ Object
_set_byte_order()
Determine the byte order and store it as class data to avoid recalculating it for each call to new().
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/writeexcel/biffwriter.rb', line 44 def set_byte_order # Check if "pack" gives the required IEEE 64bit float teststr = [1.2345].pack("d") hexdata = [0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F] number = hexdata.pack("C8") if number == teststr @byte_order = false # Little Endian elsif number == teststr.reverse @byte_order = true # Big Endian else # Give up. I'll fix this in a later version. raise( "Required floating point format not supported " + "on this platform. See the portability section " + "of the documentation." ) end end |
#store_bof(type = 0x0005) ⇒ Object
_store_bof($type)
$type = 0x0005, Workbook $type = 0x0010, Worksheet $type = 0x0020, Chart
Writes Excel BOF record to indicate the beginning of a stream or sub-stream in the BIFF file.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/writeexcel/biffwriter.rb', line 104 def store_bof(type = 0x0005) record = 0x0809 # Record identifier length = 0x0010 # Number of bytes to follow # According to the SDK $build and $year should be set to zero. # However, this throws a warning in Excel 5. So, use these # magic numbers. build = 0x0DBB year = 0x07CC bfh = 0x00000041 sfo = 0x00000006 header = [record,length].pack("vv") data = [BIFF_Version,type,build,year,bfh,sfo].pack("vvvvVV") prepend(header, data) end |
#store_eof ⇒ Object
_store_eof()
Writes Excel EOF record to indicate the end of a BIFF stream.
129 130 131 132 133 134 135 |
# File 'lib/writeexcel/biffwriter.rb', line 129 def store_eof record = 0x000A length = 0x0000 header = [record,length].pack("vv") append(header) end |
#unpack_record(data) ⇒ Object
:nodoc:
37 38 39 |
# File 'lib/writeexcel/debug_info.rb', line 37 def unpack_record(data) # :nodoc: data.unpack('C*').map! {|c| sprintf("%02X", c) }.join(' ') end |