@@ -77,15 +77,35 @@ class LDAP
7777 # at least three places. Should do it in ONE place.
7878 class Entry
7979
80+
8081 # This constructor is not generally called by user code.
82+ #--
83+ # Originally, myhash took a block so we wouldn't have to
84+ # make sure its elements returned empty arrays when necessary.
85+ # Got rid of that to enable marshalling of Entry objects,
86+ # but that doesn't work anyway, because Entry objects have
87+ # singleton methods. So we define a custom dump and load.
8188 def initialize dn = nil # :nodoc:
82- @myhash = Hash . new { |k , v | k [ v ] = [ ] }
89+ @myhash = { } # originally: Hash.new {|k,v| k[v] = [] }
8390 @myhash [ :dn ] = [ dn ]
8491 end
8592
93+ def _dump depth
94+ to_ldif
95+ end
96+
97+ class << self
98+ def _load entry
99+ from_single_ldif_string entry
100+ end
101+ end
86102
103+ #--
104+ # Discovered bug, 26Aug06: I noticed that we're not converting the
105+ # incoming value to an array if it isn't already one.
87106 def []= name , value # :nodoc:
88107 sym = name . to_s . downcase . intern
108+ value = [ value ] unless value . is_a? ( Array )
89109 @myhash [ sym ] = value
90110 end
91111
@@ -97,12 +117,12 @@ def []= name, value # :nodoc:
97117 #
98118 def [] name # :nodoc:
99119 name = name . to_s . downcase . intern unless name . is_a? ( Symbol )
100- @myhash [ name ]
120+ @myhash [ name ] || [ ]
101121 end
102122
103123 # Returns the dn of the Entry as a String.
104124 def dn
105- self [ :dn ] [ 0 ]
125+ self [ :dn ] [ 0 ] . to_s
106126 end
107127
108128 # Returns an array of the attribute names present in the Entry.
@@ -131,6 +151,9 @@ def each
131151
132152 # Converts the Entry to a String, representing the
133153 # Entry's attributes in LDIF format.
154+ #--
155+ # TODO, this doesn't support binary representations,
156+ # nor does it break overlength lines.
134157 def to_ldif
135158 ary = [ ]
136159 ary << "dn: #{ dn } \n "
@@ -143,6 +166,30 @@ def to_ldif
143166 ary . join
144167 end
145168
169+ #--
170+ # TODO, doesn't support binary representations yet (:: notation),
171+ # and it doesn't handle broken lines.
172+ # It generates a SINGLE Entry object from an incoming LDIF stream
173+ # which is of course useless for big LDIF streams that encode
174+ # many objects.
175+ # DO NOT DOCUMENT THIS METHOD UNTIL THESE RESTRICTIONS ARE LIFTED.
176+ # As it is, it's useful for unmarshalling objects that we create,
177+ # but not for reading arbitrary LDIF files.
178+ # Eventually, we should have a class method that parses large LDIF
179+ # streams into individual LDIF blocks (delimited by blank lines)
180+ # and passes them here.
181+ class << self
182+ def from_single_ldif_string ldif
183+ entry = Entry . new
184+ ldif . split ( /\r ?\n /m ) . each { |line |
185+ break if line . length == 0
186+ if line =~ /\A ([\w ]+)::?[\s ]*/
187+ entry [ $1] = $'
188+ end
189+ }
190+ entry . dn ? entry : nil
191+ end
192+ end
146193
147194 #--
148195 # Convenience method to convert unknown method names
0 commit comments