;;; rudel-xmpp-util.el --- Miscellaneous functions for the Rudel XMPP backend -*- lexical-binding:t -*- ;; ;; Copyright (C) 2009, 2010, 2014, 2016 Free Software Foundation, Inc. ;; ;; Author: Jan Moringen ;; Keywords: rudel, xmpp, backend, miscellaneous ;; X-RCS: $Id:$ ;; ;; This file is part of Rudel. ;; ;; Rudel is free software: you can redistribute it and/or modify it ;; under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; Rudel is distributed in the hope that it will be useful, but ;; WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with Rudel. If not, see . ;;; Commentary: ;; ;; This file contains the assemble function ;; `rudel-xmpp-assemble-stream' which is used by ;; `rudel-xmpp-make-transport-filter-stack' to parametrize assembling ;; and parsing transport filters to handle XML data transparently. ;;; History: ;; ;; 0.1 - Initial version ;;; Code: ;; (require 'cl-lib) (require 'rudel-xml) (require 'rudel-transport-util) ;;; Fragmentation and assembling functions. ;; (defun rudel-xmpp-assemble-stream (data storage) "Extract complete XML stanzas from DATA and STORAGE. Return a list the first element of which is a list of strings that contain the serialized forms of the stanzas. The second element is a string containing the rest of the data or nil DATA does not contains any incomplete stanzas." ;; TODO mention limitations ;; Form a string by concatenating STORAGE and DATA. Form the stream ;; header, find the end of stream:features. (let* ((string (concat storage data)) (end (or (cl-search "" string) (cl-search "" string))) (end (when end (+ end 18)))) ;; If the end of stream:features has been found, artificially ;; close stream:stream, then find top-level tags. (if (not end) ;; No end, put everything into storage. (list nil string) ;; Otherwise find top-level tags. This can still leave ;; incomplete tags. (pcase-let ((`(,tags ,buffer) (rudel-xml-toplevel-tags (concat (substring string 0 end) "" (replace-regexp-in-string "" "" (substring string end)))))) (list ;; Remove processing instructions. (cl-remove-if (lambda (tag) (= (aref tag 1) ??)) tags) buffer)))) ;; TODO wrong ) ;; One problem: peer can send ;; ;; and then ;; ;; we cannot assemble this properly; look into the RFC ;;; Transport filter stack construction ;; (defun rudel-xmpp-make-transport-filter-stack (transport) "Construct an XMPP protocol filter stack on top of TRANSPORT." (rudel-transport-make-filter-stack transport '((rudel-assembling-transport-filter :assembly-function rudel-xmpp-assemble-stream) (rudel-parsing-transport-filter :parse-function string->xml :generate-function xml->string)))) (provide 'rudel-xmpp-util) ;;; rudel-xmpp-util.el ends here