Class: ConfigToolkit::KeyValueReader::ContainerParsingFrame

Inherits:
Object
  • Object
show all
Defined in:
lib/configtoolkit/keyvaluereader.rb

Overview

This class is not meant to be accessed by KeyValueReader users; it solely is to be used internally.

This class represents a nesting level while parsing a container. When a container is encountered (perhaps within another container), one of these frames is pushed onto a stack. After the container has been completed, this frame is popped off the stack.

A lot of logic of the form: if the contaier is an Array

do something

else if the container is a Hash

do something else

… lives within this class, and so it is messy. If more containers are added, some kind of interface over a container could be developed to replace the conditionals with polymorphism.

Right now, the following containers are supported:

  • Array (elements can be Strings or other containers)

  • Hash (values are Strings or other containers; the curr_element

    attribute is a HashEntry).
    

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(container, config) ⇒ ContainerParsingFrame

Description:

This initializes a frame for parsing container, given key-value config config.

Parameters:

container

The container to parse

config

The KeyValueConfig for the configuration being parsed



220
221
222
223
224
# File 'lib/configtoolkit/keyvaluereader.rb', line 220

def initialize(container, config)
  @container = container
  @config = config
  @curr_element = nil
end

Instance Attribute Details

#containerObject (readonly)

The container being parsed.



199
200
201
# File 'lib/configtoolkit/keyvaluereader.rb', line 199

def container
  @container
end

#curr_elementObject

The current container element being parsed. A setter actually exists for this, but it is implemented by hand in order to take into account the differences in assigning to Array and Hash elements.



207
208
209
# File 'lib/configtoolkit/keyvaluereader.rb', line 207

def curr_element
  @curr_element
end

Instance Method Details

#append_char_to_curr_element(char) ⇒ Object

Description:

This method appends char to the container element currently being parsed.

Parameters:

char

The character to be appended to the container element currently being parsed.



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/configtoolkit/keyvaluereader.rb', line 269

def append_char_to_curr_element(char)
  #
  # Create an element of the appropriate type if a new
  # element is being parsed.
  #
  if(@curr_element == nil)
    if(@container.is_a?(Array))
      @curr_element = ""
    else @container.is_a?(Hash)
      @curr_element = HashEntry.new(@config.hash_key_value_delimiter)
    end
  end

  #
  # It only makes sense to append characters to String values.
  #
  if(@curr_element.is_a?(String) ||
     (@curr_element.is_a?(HashEntry) && @curr_element.value.is_a?(String)))
    @curr_element << char
  else
    raise ParsingError, "extraneous character '#{char}' after container"
  end
end

#curr_element_empty?Boolean

Returns:

Returns true if and only if the currently parsed element is empty, which will be the case if no non-whitespace characters have been appended yet.

Returns:



315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/configtoolkit/keyvaluereader.rb', line 315

def curr_element_empty?
  if(@curr_element == nil)
    return true
  end

  if(@curr_element.is_a?(String))
    return @curr_element.match(/^\s*$/)
  elsif(@curr_element.is_a?(HashEntry))
    return @curr_element.key.match(/^\s*$/)
  else
    return false
  end
end

#finish_curr_elementObject

Description:

This method should be called when done parsing the current container element; it causes the current element to be added to the container and readies the frame to parse a new element.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/configtoolkit/keyvaluereader.rb', line 233

def finish_curr_element
  if(@container.is_a?(Array))
    if(@curr_element.is_a?(String))
      @curr_element.strip!()
    end
    
    @container.push(@curr_element)
  else # @container.is_a?(Hash)
    @curr_element.key.strip!()

    if(@curr_element.value.is_a?(String))
      @curr_element.value.strip!()

      #
      # String values that are empty are not allowed.
      #
      if(@curr_element.value.empty?())
        raise ParsingError, "hash key '#{@curr_element.key}' is missing a value"
      end
    end

    @container[@curr_element.key.to_sym()] = @curr_element.value
  end

  @curr_element = nil
end