/usr/lib/ruby/vendor_ruby/iniparse/line_collection.rb is in ruby-iniparse 1.4.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | module IniParse
# Represents a collection of lines in an INI document.
#
# LineCollection acts a bit like an Array/Hash hybrid, allowing arbitrary
# lines to be added to the collection, but also indexes the keys of Section
# and Option lines to enable O(1) lookup via LineCollection#[].
#
# The lines instances are stored in an array, +@lines+, while the index of
# each Section/Option is held in a Hash, +@indicies+, keyed with the
# Section/Option#key value (see LineCollection#[]=).
#
module LineCollection
include Enumerable
def initialize
@lines = []
@indicies = {}
end
# Retrive a value identified by +key+.
def [](key)
has_key?(key) ? @lines[ @indicies[key] ] : nil
end
# Set a +value+ identified by +key+.
#
# If a value with the given key already exists, the value will be replaced
# with the new one, with the new value taking the position of the old.
#
def []=(key, value)
key = key.to_s
if has_key?(key)
@lines[ @indicies[key] ] = value
else
@lines << value
@indicies[key] = @lines.length - 1
end
end
# Appends a line to the collection.
#
# Note that if you pass a line with a key already represented in the
# collection, the old item will be replaced.
#
def <<(line)
line.blank? ? (@lines << line) : (self[line.key] = line) ; self
end
alias_method :push, :<<
# Enumerates through the collection.
#
# By default #each does not yield blank and comment lines.
#
# ==== Parameters
# include_blank<Boolean>:: Include blank/comment lines?
#
def each(include_blank = false)
@lines.each do |line|
if include_blank || ! (line.is_a?(Array) ? line.empty? : line.blank?)
yield(line)
end
end
end
# Removes the value identified by +key+.
def delete(key)
key = key.key if key.respond_to?(:key)
unless (idx = @indicies[key]).nil?
@indicies.delete(key)
@indicies.each { |k,v| @indicies[k] = v -= 1 if v > idx }
@lines.delete_at(idx)
end
end
# Returns whether +key+ is in the collection.
def has_key?(*args)
@indicies.has_key?(*args)
end
# Return an array containing the keys for the lines added to this
# collection.
def keys
map { |line| line.key }
end
# Returns this collection as an array. Includes blank and comment lines.
def to_a
@lines.dup
end
# Returns this collection as a hash. Does not contain blank and comment
# lines.
def to_hash
Hash[ *(map { |line| [line.key, line] }).flatten ]
end
alias_method :to_h, :to_hash
end
# A implementation of LineCollection used for storing (mostly) Option
# instances contained within a Section.
#
# Since it is assumed that an INI document will only represent a section
# once, if SectionCollection encounters a Section key already held in the
# collection, the existing section is merged with the new one (see
# IniParse::Lines::Section#merge!).
class SectionCollection
include LineCollection
def <<(line)
if line.kind_of?(IniParse::Lines::Option)
option = line
line = IniParse::Lines::AnonymousSection.new
line.lines << option if option
end
if line.blank? || (! has_key?(line.key))
super # Adding a new section, comment or blank line.
else
self[line.key].merge!(line)
end
self
end
end
# A implementation of LineCollection used for storing (mostly) Option
# instances contained within a Section.
#
# Whenever OptionCollection encounters an Option key already held in the
# collection, it treats it as a duplicate. This means that instead of
# overwriting the existing value, the value is changed to an array
# containing the previous _and_ the new Option instances.
class OptionCollection
include LineCollection
# Appends a line to the collection.
#
# If you push an Option with a key already represented in the collection,
# the previous Option will not be overwritten, but treated as a duplicate.
#
# ==== Parameters
# line<IniParse::LineType::Line>:: The line to be added to this section.
#
def <<(line)
if line.kind_of?(IniParse::Lines::Section)
raise IniParse::LineNotAllowed,
"You can't add a Section to an OptionCollection."
end
if line.blank? || (! has_key?(line.key))
super # Adding a new option, comment or blank line.
else
self[line.key] = [self[line.key], line].flatten
end
self
end
# Return an array containing the keys for the lines added to this
# collection.
def keys
map { |line| line.kind_of?(Array) ? line.first.key : line.key }
end
end
end
|