diff options
Diffstat (limited to 'connection.el')
-rw-r--r-- | connection.el | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/connection.el b/connection.el new file mode 100644 index 0000000..c83be81 --- /dev/null +++ b/connection.el @@ -0,0 +1,169 @@ +;;; connection.el -- handling a tcp based connection + +;; Author: Torsten Hilbrich <Torsten.Hilbrich@gmx.net> +;; Keywords: network +;; $Id: connection.el,v 1.6 2000/04/16 08:45:21 torsten Exp $ + +;; This file 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 2, or (at your option) +;; any later version. + +;; This file 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 GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +(eval-when-compile + (require 'cl)) + +(defcustom connection-broken-end-of-line + nil + "Set to t (on) if you use a MULE Emacsen and have problems while connecting. +Usually for the dict protocol, the end of line characters are \\r\\n. +However, some users reported problems with using Emacs 20.3 and MULE +which seems to convert the \\r\\n to \\n while inserting the text into +the buffer. If you encounter these problems please set the value to t +and try again. +" + :group 'dictionary + :type 'boolean) + +(defmacro connection-p (connection) + "Returns non-nil if `connection' is a connection object" + (list 'get connection ''connection)) + +(defmacro connection-read-point (connection) + "Return the read point of the connection object." + (list 'get connection ''connection-read-point)) + +(defmacro connection-process (connection) + "Return the process of the connection object." + (list 'get connection ''connection-process)) + +(defmacro connection-buffer (connection) + "Return the buffer of the connection object." + (list 'get connection ''connection-buffer)) + +(defmacro connection-set-read-point (connection point) + "Set the read-point for `connection' to `point'." + (list 'put connection ''connection-read-point point)) + +(defmacro connection-set-process (connection process) + "Set the process for `connection' to `process'." + (list 'put connection ''connection-process process)) + +(defmacro connection-set-buffer (connection buffer) + "Set the buffer for `connection' to `buffer'." + (list 'put connection ''connection-buffer buffer)) + +(defun connection-create-data (buffer process point) + "Create a new connection data based on `buffer', `process', and `point'." + (let ((connection (make-symbol "connection"))) + (put connection 'connection t) + (connection-set-read-point connection point) + (connection-set-process connection process) + (connection-set-buffer connection buffer) + connection)) + +(defun connection-open (server port) + "Open a connection to `server' and `port'. +A data structure identifing the connection is returned" + + (let ((process-buffer (generate-new-buffer (format " connection to %s:%s" + server + port))) + (process)) + (save-excursion + (set-buffer process-buffer) + (setq process (open-network-stream "connection" process-buffer + server port)) + (connection-create-data process-buffer process (point-min))))) + +(defun connection-status (connection) + "Return the status of the connection. +Possible return values are the symbols: +nil: argument is no connection object +'none: argument has no connection +'up: connection is open and buffer is existing +'down: connection is closed +'alone: connection is not associated with a buffer" + (if (connection-p connection) + (let ((process (connection-process connection)) + (buffer (connection-buffer connection))) + (if (not process) + 'none + (if (not (buffer-live-p buffer)) + 'alone + (if (not (eq (process-status process) 'open)) + 'down + 'up)))) + nil)) + +(defun connection-close (connection) + "Force closing of the connection." + (if (connection-p connection) + (progn + (let ((buffer (connection-buffer connection)) + (process (connection-process connection))) + (if process + (delete-process process)) + (if buffer + (kill-buffer buffer)) + + (connection-set-process connection nil) + (connection-set-buffer connection nil))))) + +(defun connection-send (connection data) + "Send `data' to the process." + (unless (eq (connection-status connection) 'up) + (error "Connection is not up")) + (save-excursion + (set-buffer (connection-buffer connection)) + (goto-char (point-max)) + (connection-set-read-point connection (point)) + (process-send-string (connection-process connection) data))) + +(defun connection-send-crlf (connection data) + "Send `data' together with CRLF to the process." + (connection-send connection (concat data "\r\n"))) + +(defun connection-read (connection delimiter) + "Read data until `delimiter' is found inside the buffer." + (unless (eq (connection-status connection) 'up) + (error "Connection is not up")) + (let ((case-fold-search nil) + match-end) + (save-excursion + (set-buffer (connection-buffer connection)) + (goto-char (connection-read-point connection)) + ;; Wait until there is enough data + (while (not (search-forward delimiter nil t)) + (accept-process-output (connection-process connection) 3) + (goto-char (connection-read-point connection))) + (setq match-end (point)) + ;; Return the result + (let ((result (buffer-substring (connection-read-point connection) + match-end))) + (connection-set-read-point connection match-end) + result)))) + +(defun connection-read-crlf (connection) + "Read until a line is completedx with CRLF" + (connection-read connection (if connection-broken-end-of-line + "\n" + "\r\n"))) + +(defun connection-read-to-point (connection) + "Read until a line is consisting of a single point" + (connection-read connection (if connection-broken-end-of-line + "\n.\n" + "\r\n.\r\n"))) + + +(provide 'connection)
\ No newline at end of file |