def write_changes reader, endpos, sst_status
reader.seek @worksheet.offset
blocks = row_blocks
lastpos = reader.pos
offsets = {}
row_offsets = []
changes = @worksheet.changes
@worksheet.offsets.each do |key, pair|
if changes.include?(key) \
|| (sst_status == :complete_update && key.is_a?(Integer))
offsets.store pair, key
end
end
work = offsets.invert
work.each do |key, (pos, len)|
case key
when Integer
row_offsets.push [key, [pos, len]]
when :dimensions
row_offsets.push [-1, [pos, len]]
end
end
row_offsets.sort!
row_offsets.reverse!
control = changes.size
@worksheet.each do |row|
key = row.idx
if changes.include?(key) && !work.include?(key)
row, pair = row_offsets.find do |idx, _| idx <= key end
work.store key, pair
end
end
if changes.size > control
warn "Your Worksheet was modified while it was being written. This should not happen.\nPlease contact the author (hannes dot wyss at gmail dot com) with a sample file\nand minimal code that generates this warning. Thanks!\n"
end
work = work.sort_by do |key, (pos, len)|
[pos, key.is_a?(Integer) ? key : -1]
end
work.each do |key, (pos, len)|
@io.write reader.read(pos - lastpos) if pos > lastpos
if key.is_a?(Integer)
if block = blocks.find do |rows| rows.any? do |row| row.idx == key end end
write_rowblock block
blocks.delete block
end
else
send "write_#{key}"
end
lastpos = pos + len
reader.seek lastpos
end
@io.write reader.read(endpos - lastpos)
end