1. Kaspar Schiess
  2. iscsi-tools

Commits

Kaspar Schiess  committed 956633d

First working HashParser

  • Participants
  • Parent commits 3b48821
  • Branches master

Comments (0)

Files changed (2)

File lib/iscsi/hash_parser.rb

View file
 module ISCSI
+  class Node
+    attr_reader :key, :value
+    attr_accessor :parent
+    attr_reader :children
+    attr_reader :indent
+    
+    def initialize(indent, key=nil, value=nil)
+      @indent = indent
+      @key = key
+      @value = value
+      @children = []
+    end
+    
+    def add_child child
+      @children << child
+      child.parent = self
+    end
+    
+    def pretty_print q
+      q.object_address_group(self) do
+        if key
+          q.text ' '
+          q.text key.inspect
+          q.text ' => '
+          q.text value.inspect
+        end
+        
+        unless children.empty?
+          q.text ' childs: '
+          q.group 1, '[', ']' do
+            children.each do |child| 
+              q.breakable
+              child.pretty_print q
+            end
+          end
+        end
+      end
+    end
+
+    def [] k
+      children.find { |c| c.key == k }
+    end
+    def size
+      children.size
+    end
+  end
+  
   class HashParser
     def parse(str)
-      current = {}
-      result = [current]
-      last_indent = nil
+      # Every time we indent once, we'll push a new result array onto this 
+      # stack. Every time we pop the stack, we'll assign the array to the 
+      # last ParsedEntity.
+      root = Node.new(-1)
+      
+      insertion_point = root
+      last = nil
       
       str.lines do |line| 
         line.chomp!
         if md=line.match(/^(?<indent>\s*)(?<key>(\w|\s)+)\s*: (?<val>.*)$/)
           indent = md[:indent].size
           
-          # Reset the current hash?
-          if last_indent && indent < last_indent
-            current = {}
-            result << current
+          # One level up: 
+          if last && indent < last.indent
+            insertion_point = insertion_point.parent
+            fail "Assertion failed: Popped beyond root node." unless insertion_point
           end
-
-          current[transform_key(md[:key])] = md[:val]
           
-          last_indent = indent
+          # One level deeper: 
+          if last && indent > last.indent
+            insertion_point = last
+          end
+          
+          current = Node.new(indent, transform_key(md[:key]), md[:val])
+          insertion_point.add_child current
+          
+          last = current
         end
       end
 
-      result
+      return root.children
     end
     
     def transform_key(str)

File spec/lib/iscsi/hash_parser_spec.rb

View file
 require 'spec_helper'
 
+require 'pp'
 require 'iscsi'
 
 describe ISCSI::HashParser do
     
     it "contains two toplevel targets" do
       result.size.should == 2
-      result[0][:target].should == 'iqn.2010-08.org.illumos:02:6140505e-fb64-6670-b44d-c3395b9bb201'
-      result[1][:target].should == 'iqn.2010-08.org.illumos:02:6140505e-fb64-6670-b412321321312121'
+      result[0].value.should == 'iqn.2010-08.org.illumos:02:6140505e-fb64-6670-b44d-c3395b9bb201'
+      result[1].value.should == 'iqn.2010-08.org.illumos:02:6140505e-fb64-6670-b412321321312121'
     end
-    describe 'first result' do
+    describe 'result[0]' do
       slet(:first) { result.first }
       
       it "contains a :provider_name" do
-        p first
-        first[:provider_name].should == 'iscsit' 
+        first[:provider_name].value.should == 'iscsit' 
       end 
     end 
+    describe 'result[1]' do
+      slet(:second) { result[1] }
+      
+      it "should have one session stored" do
+        second[:sessions].size.should == 1
+        s = second[:sessions].children.first
+        
+        s.value.should == 'iqn.1986-03.com.sun:01:40f581320dff.506ef076'
+        s[:alias].value.should == 'machine1'
+      end 
+    end
   end
 end