diff options
author | Linus Nordberg <linus@nordberg.se> | 2009-06-24 10:45:19 +0200 |
---|---|---|
committer | Linus Nordberg <linus@nordberg.se> | 2009-06-24 10:45:19 +0200 |
commit | b562dc0b5dd8cbf8bc5a64dcbc2c7f4c57bb863c (patch) | |
tree | a0f68406dd501ab32f5a2667b92c39e89217eab8 /src |
Working, kind of -- not including the enclosing tags. CXML doesn't like that.
Diffstat (limited to 'src')
-rw-r--r-- | src/util.lisp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/util.lisp b/src/util.lisp new file mode 100644 index 0000000..08f9936 --- /dev/null +++ b/src/util.lisp @@ -0,0 +1,59 @@ +(defparameter *debug* nil) + +(defun next-xml-blurb (reader tag) + "Return the next XML document in a stream that is enclosed in a given XML tag. + +READER is a function that takes one argument -- number of bytes to +read -- and returns that many octets or nil on read error or end of +stream. + +TAG is a string. + +BUGS: +- Case sensitive matching of tag. +- Opening tag must contain attributes (or at least a space after the tag). +" + (let ((start-tag (format nil "<~A " tag)) + (end-tag (format nil "</~A>" tag)) + (storing-p nil) + (match-count 0) + (acc (make-array 2048 :fill-pointer 0 :adjustable t))) + (when *debug* (format t "start-tag ~A~%, end-tag ~A~%" start-tag end-tag)) + (do ((c (funcall reader 1) (funcall reader 1))) + ((or (null c) (and storing-p (= match-count (length end-tag)))) + (if (null c) + nil + (subseq acc 0 (- (length acc) (length end-tag))))) + (when *debug* (format t "looking at ~A~%" c)) + (if storing-p + (progn + (when *debug* (format t "pushing it~%")) + (vector-push-extend c acc) + (if (eql c (char-code (aref end-tag match-count))) + (incf match-count) + (setf match-count 0)) + (when *debug* (format t "match-count ~A~%" match-count))) + (if (= match-count (length start-tag)) + (if (eql c (char-code #\>)) ; looking for '>' + (setf storing-p t)) + (progn + (when (and *debug* nil) + (format t "XXX ~A ~A " (aref start-tag match-count) + (eql c (char-code (aref start-tag match-count))))) + (if (eql c (char-code (aref start-tag match-count))) ; looking for start-tag + (incf match-count) + (setf match-count 0)) + (when *debug* (format t "match-count ~A~%" match-count)))))))) + + +(let ((sock nil)) + (defun new-reader (host port) + (when sock (close-reader)) + (setf sock (usocket:socket-connect host + port + :element-type '(unsigned-byte 8))) + (lambda (n) + (assert (= n 1)) + (read-byte (usocket:socket-stream sock) nil))) + (defun close-reader () + (usocket:socket-close sock))) |