[cxml-cvs] CVS cxml/dom
dlichteblau
dlichteblau at common-lisp.net
Wed Oct 3 15:17:08 UTC 2007
Update of /project/cxml/cvsroot/cxml/dom
In directory clnet:/tmp/cvs-serv23055
Modified Files:
dom-builder.lisp dom-impl.lisp
Log Message:
Grow a buffer for string normalization exponentially.
* dom/dom-builder.lisp (DOM-BUILDER): New slot `text-buffer'.
(SAX:START-ELEMENT, SAX:END-ELEMENT, SAX:START-CDATA,
SAX:END-CDATA, SAX:PROCESSING-INSTRUCTION, SAX:COMMENT): Call
flush-characters. (SAX:CHARACTERS): Rewritten.
(FLUSH-CHARACTERS): New, based on the old sax:characters.
* dom/dom-impl.lisp ((initialize-instance :after entity-reference)):
Call flush-characters.
--- /project/cxml/cvsroot/cxml/dom/dom-builder.lisp 2007/07/22 19:59:26 1.13
+++ /project/cxml/cvsroot/cxml/dom/dom-builder.lisp 2007/10/03 15:17:08 1.14
@@ -18,7 +18,8 @@
(defclass dom-builder ()
((document :initform nil :accessor document)
(element-stack :initform '() :accessor element-stack)
- (internal-subset :accessor internal-subset)))
+ (internal-subset :accessor internal-subset)
+ (text-buffer :initform nil :accessor text-buffer)))
(defun make-dom-builder ()
(make-instance 'dom-builder))
@@ -87,6 +88,7 @@
(defmethod sax:start-element
((handler dom-builder) namespace-uri local-name qname attributes)
(check-type qname rod) ;catch recoder/builder mismatch
+ (flush-characters handler)
(with-slots (document element-stack) handler
(let* ((nsp sax:*namespace-processing*)
(element (make-instance 'element
@@ -126,27 +128,45 @@
(defmethod sax:end-element ((handler dom-builder) namespace-uri local-name qname)
(declare (ignore namespace-uri local-name qname))
+ (flush-characters handler)
(pop (element-stack handler)))
(defmethod sax:characters ((handler dom-builder) data)
- (with-slots (document element-stack) handler
- (let* ((parent (car element-stack))
- (last-child (dom:last-child parent)))
- (cond
- ((eq (dom:node-type parent) :cdata-section)
- (setf (dom:data parent) data))
- ((and last-child (eq (dom:node-type last-child) :text))
- ;; um entities herum wird SAX:CHARACTERS mehrfach aufgerufen fuer
- ;; den gleichen Textknoten. Hier muessen wir den bestehenden Knoten
- ;; erweitern, sonst ist das Dokument nicht normalisiert.
- ;; (XXX Oder sollte man besser den Parser entsprechend aendern?)
- (dom:append-data last-child data))
- (t
- (let ((node (dom:create-text-node document data)))
- (setf (slot-value node 'parent) parent)
- (fast-push node (slot-value (car element-stack) 'children))))))))
+ (with-slots (text-buffer) handler
+ (cond
+ ((null text-buffer)
+ (setf text-buffer data))
+ (t
+ (unless (array-has-fill-pointer-p text-buffer)
+ (setf text-buffer (make-array (length text-buffer)
+ :element-type 'rune
+ :adjustable t
+ :fill-pointer t
+ :initial-contents text-buffer)))
+ (let ((n (length text-buffer))
+ (m (length data)))
+ (adjust-vector-exponentially text-buffer (+ n m) t)
+ (move data text-buffer 0 n m))))))
+
+(defun flush-characters (handler)
+ (with-slots (document element-stack text-buffer) handler
+ (let ((data text-buffer))
+ (when data
+ (when (array-has-fill-pointer-p data)
+ (setf data
+ (make-array (length data)
+ :element-type 'rune
+ :initial-contents data)))
+ (let ((parent (car element-stack)))
+ (if (eq (dom:node-type parent) :cdata-section)
+ (setf (dom:data parent) data)
+ (let ((node (dom:create-text-node document data)))
+ (setf (slot-value node 'parent) parent)
+ (fast-push node (slot-value (car element-stack) 'children)))))
+ (setf text-buffer nil)))))
(defmethod sax:start-cdata ((handler dom-builder))
+ (flush-characters handler)
(with-slots (document element-stack) handler
(let ((node (dom:create-cdata-section document #""))
(parent (car element-stack)))
@@ -155,10 +175,12 @@
(push node element-stack))))
(defmethod sax:end-cdata ((handler dom-builder))
+ (flush-characters handler)
(let ((node (pop (slot-value handler 'element-stack))))
(assert (eq (dom:node-type node) :cdata-section))))
(defmethod sax:processing-instruction ((handler dom-builder) target data)
+ (flush-characters handler)
(with-slots (document element-stack) handler
(let ((node (dom:create-processing-instruction document target data))
(parent (car element-stack)))
@@ -166,6 +188,7 @@
(fast-push node (slot-value (car element-stack) 'children)))))
(defmethod sax:comment ((handler dom-builder) data)
+ (flush-characters handler)
(with-slots (document element-stack) handler
(let ((node (dom:create-comment document data))
(parent (car element-stack)))
--- /project/cxml/cvsroot/cxml/dom/dom-impl.lisp 2006/09/10 14:52:44 1.42
+++ /project/cxml/cvsroot/cxml/dom/dom-impl.lisp 2007/10/03 15:17:08 1.43
@@ -1247,7 +1247,8 @@
(push instance (element-stack handler))
#+cxml-system::utf8dom-file
(setf handler (cxml:make-recoder handler #'cxml:rod-to-utf8-string))
- (funcall resolver (real-rod (dom:name instance)) handler)))
+ (funcall resolver (real-rod (dom:name instance)) handler)
+ (flush-characters handler)))
(labels ((walk (n)
(setf (slot-value n 'read-only-p) t)
(when (dom:element-p n)
More information about the Cxml-cvs
mailing list