require 'spreadsheet/encodings' module Spreadsheet module Excel module Writer ## # This Module collects writer methods such as unicode_string that are specific # to Biff8. This Module is likely to be expanded as Support for older Versions # of Excel grows and methods get moved here for disambiguation. module Biff8 include Spreadsheet::Encodings ## # Check whether the string _data_ can be compressed (i.e. every second byte # is a Null-byte) and perform compression. # Returns the data and compression_status (0/1) def compress_unicode_string data compressed = internal('') expect_null = false data.each_byte do |byte| if expect_null if byte != 0 return [data, 1] # 1 => Data consists of wide Chars end expect_null = false else compressed << byte expect_null = true end end [compressed, 0] # 0 => Data consists of compressed Chars end ## # Encode _string_ into a Biff8 Unicode String. Header and body are encoded # separately by #_unicode_string. This method simply combines the two. def unicode_string string, count_length=1 header, data, _ = _unicode_string string, count_length header << data end @@bytesize = RUBY_VERSION >= '1.9' ? :bytesize : :size ## # Encode _string_ into a Biff8 Unicode String Header and Body. def _unicode_string string, count_length=1 data = internal string size = data.send(@@bytesize) / 2 fmt = count_length == 1 ? 'C2' : 'vC' data, wide = compress_unicode_string data opts = wide header = [ size, # Length of the string (character count, ln) opts, # Option flags: # Bit Mask Contents # 0 0x01 Character compression (ccompr): # 0 = Compressed (8-bit characters) # 1 = Uncompressed (16-bit characters) # 2 0x04 Asian phonetic settings (phonetic): # 0 = Does not contain Asian phonetic settings # 1 = Contains Asian phonetic settings # 3 0x08 Rich-Text settings (richtext): # 0 = Does not contain Rich-Text settings # 1 = Contains Rich-Text settings #0x00,# (optional, only if richtext=1) Number of Rich-Text # formatting runs (rt) #0x00,# (optional, only if phonetic=1) Size of Asian phonetic # settings block (in bytes, sz) ].pack fmt data << '' # (optional, only if richtext=1) # List of rt formatting runs (➜ 3.2) data << '' # (optional, only if phonetic=1) # Asian Phonetic Settings Block (➜ 3.4.2) [header, data, wide] end end end end end