I'm trying to use CXML, specifically the Klacks parser, to read streaming XML from a network socket (I'm writing a Jabber library), but I'm having problems with buffering. I'm using this code for testing:
(defun cxml-test (host port &key (buffering nil)) (let ((socket (usocket:socket-connect host port :element-type '(unsigned-byte 8)))) (cxml:make-source (usocket:socket-stream socket) :buffering buffering :pathname "foo")))
And then I run (klacks:consume src) repeatedly.
On the sending end, I use "nc -l -w 5 -p 42000", either typing in XML by hand or by redirecting a real XML file to netcat.
With buffering enabled, this basically works. However, I need to process "stanzas" (Jabber term for complete elements that are children of the root element) as soon as they come in, not when the buffer is full or when the stream or the root element is closed. But when I disable buffering, I get (using CLISP from recent CVS):
AREF: index 1 for #(60) is out of range [Condition of type SIMPLE-TYPE-ERROR]
Restarts: 0: [ABORT] Return to SLIME's top level. 1: [CLOSE-CONNECTION] Close SLIME connection
Backtrace: [ SLIME parts skipped ] 5: INVOKE-DEBUGGER 6: AREF 7: REPLACE 8: #<COMPILED-FUNCTION #:|257 305 (DEFMETHOD XSTREAM-UNDERFLOW (#) ...)-25-1-1|> 9: CXML:MAKE-SOURCE 10: CXML:MAKE-SOURCE 11: (CXML:MAKE-SOURCE (USOCKET:SOCKET-STREAM SOCKET) :BUFFERING BUFFERING :PATHNAME "foo") 12: LET 13: (CXML-TEST '"localhost" '42000 ':BUFFERING 'NIL)
SBCL 1.0.8.46 gets a similar error:
The bounding indices 0 and 2 are bad for a sequence of length 1. [Condition of type SB-KERNEL:BOUNDING-INDICES-BAD-ERROR]See also: Common Lisp Hyperspec, bounding index designator [glossary] Common Lisp Hyperspec, SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR [issue]
Restarts: 0: [ABORT] Return to SLIME's top level. 1: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (SB-IMPL::SIGNAL-BOUNDING-INDICES-BAD-ERROR #(60) 0 2) 1: (SB-IMPL::SIGNAL-BOUNDING-INDICES-BAD-ERROR #(60) 0 2) 2: ((SB-PCL::FAST-METHOD RUNES::XSTREAM-UNDERFLOW (RUNES:XSTREAM)) #<unavailable argument> #<unavailable argument> #<RUNES:XSTREAM [main document :MAIN file://+/home/foo]>) 3: (CXML:MAKE-SOURCE #<RUNES:XSTREAM [main document :MAIN file://+/home/foo]>) 4: (NIL) 5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF SRC (CXML-TEST "localhost" 42000 :BUFFERING NIL)) #<NULL-LEXENV>)
It would be nice if this worked, and if additionally KLACKS:PEEK would do a non-blocking read.
Magnus