+# elements look like: ['name', {attr: value, attr2: value2,...}, [contents]]
+# text nodes look like elements with blank names: ['', {}, 'foo']
+# so <foo bar="baz">qux<quux></quux>corge</foo> -> ['foo', {bar:'baz'}, [['',{},'qux'], ['cuux', {}, []], ['',{},'corge']]]
+# callback(err, array)
+parse_xml = (str, callback) ->
+ done = false
+ nests = [[]]
+ huh = ->
+ # FIXME switch to an xml parser that will tell me when it's done
+ unless done
+ done = true
+ callback "xml parser failed to do anything with login server response"
+ console.log "xml parser didn't exit: #{str}"
+ parser = new xml.SaxParser (cb) ->
+ cb.onStartElementNS (name, attr_tuples, prefix, uri, namespaces) ->
+ attrs = {}
+ for tuple in attr_tuples
+ attrs[tuple[0]] = tuple[1]
+ element = [name, attrs, []]
+ nests[0].push element
+ nests.unshift element[2]
+ cb.onCharacters (str) ->
+ if nests[0][nests[0].length - 1]?[0] is ''
+ nests[0][nests[0].length - 1][2] += str
+ else
+ nests[0].push ['', {}, str]
+ cb.onEndElementNS (name, attrs, prefix, uri, namespaces) ->
+ nests.shift()
+ if nests.length is 1
+ done = true
+ callback null, nests[0]
+ cb.onEndDocument huh
+ parser.parseString str
+ timeout 1, huh
+
+exports.parse_xml = parse_xml
+
+# returns just the "lfm" element of xml (as described in parse_xml) or fires an error
+# callback(err, array)
+parse_lfm_xml = (text, callback) ->
+ parse_xml text, (err, parsed) ->
+ if err
+ # parse error
+ callback err
+ return
+ for element in parsed
+ if element[0] is 'lfm'
+ callback null, element
+ return
+ callback "Couldn't find lfm element in server response"
+ return
+ return
+