Project

General

Profile

Bug #9847 ยป strbug.rb

Feldmarschal (Kenneth Guerin), 05/17/2014 06:04 PM

 
#!/usr/bin/env ruby

#### This script tests for a bug in File.read where
#### supplying a buffer to File.read inhibits the
#### creation of new strings. This behavior is dependent
#### on the size of the string due to Ruby's internal
#### optimization on short (<24 bytes) strings.

def cache_display(cache)
## Display the Cache contents.
puts " - Cache Size: #{cache.length}"
cache.length.times { |i| puts " - Size: #{cache[i].length} --> Contents: [#{cache[i][0,4]}...]" }
end

def slot_test(slotsz)

puts "Slot Test: (slotsz=#{slotsz})"

filename = "strbug-#{slotsz}.dat"

## Write 13 strings of size SLOTSZ to strbug.dat
## The strings values are "AAA..", "BBB..", etc.
## There are no newlines. This file mimics a record-
## based structure.
File.open(filename, "w") do |io|
base = "A"
13.times do
io.write(base * slotsz)
base.succ!
end
end

## First Test: Read the Contents of the strbug file
## using File.read(slotsz). A unique string will be
## returned on each successful read.

puts "- File.read(slotsz) Test:"
cache = Array.new # Collect the unique strings
buffer = String.new # Redundant due to io.read action
File.open(filename, "r") do |io|
done = false
until done
buffer = io.read(slotsz)
if buffer.nil?
done = true
puts " > Null buffer" if ! io.eof?
elsif buffer.length != slotsz
done = true
puts " > Not enough data"
else
cache << buffer
end
end
end

## Display the Cache contents.
cache_display(cache)

## First Test: Read the Contents of the strbug file
## using File.read(slotsz). A unique string will be
## returned on each successful read.

puts "- File.read(slotsz, buffer) Test:"
cache = Array.new
buffer = String.new # Redundant due to io.read action?
File.open(filename, "r") do |io|
while ! io.read(slotsz, buffer).nil?
cache << String.new(buffer) # Collect unique strings based on each read
end
end

## Display the Cache contents.
cache_display(cache)

puts ""
end

## Maine. (Yeah, I'm a quirky C programmer at heart.)

[ 23, 24 ].each { |slotsz| slot_test(slotsz) }
    (1-1/1)