COMMON-NET: Tag a couple of more exceptions and network-errors.
[lisp-utils.git] / common-net.lisp
index 00ae20d..10fc919 100644 (file)
 
 (define-condition network-error (error) ())
 
+(define-condition simple-network-error (network-error simple-error) ())
+
+(defun simple-network-error (format &rest args)
+  (error 'simple-network-error :format-control format :format-arguments args))
+
 (define-condition socket-error (socket-condition network-error) ())
 
 (define-condition address-busy (network-error)
   (declare (type stream-socket socket))
   (unless (eq (stream-socket-mode socket) :character)
     (error 'stream-mode-error :stream socket :socket socket :expected-mode :character))
-  (case (fill-char-buffer socket 1)
+  (case (fill-char-buffer socket 1 t)
     ((nil) (return-from gray-stream-read-char-no-hang :eof))
     ((:wait) (return-from gray-stream-read-char-no-hang nil)))
   (with-slots (char-buffer char-read-pos) socket
        (error "Too few octets in IPv4 address")
        buf)))
 
-(defmethod initialize-instance :after ((instance ipv4-address) &key host-bytes host-string)
+(defmethod initialize-instance :after ((instance ipv4-address) &key host-bytes host-string host-address)
   (let ((octets (or host-bytes
+                   (when host-address
+                     (check-type host-address ipv4-address)
+                     (slot-value host-address 'host-bytes))
                    (when host-string (parse-dotted-quad host-string))
                    '(0 0 0 0))))
     (assert (and (typep octets 'sequence)
            (aref host-bytes 2)
            (aref host-bytes 3))))
 
-(export '(ipv4-address make-ipv4-address parse-ipv4-address))
+(defparameter *ipv4-localhost* (make-instance 'ipv4-host-address :host-bytes '(127 0 0 1)))
+
+(export '(ipv4-address ipv4-host-address make-ipv4-address parse-ipv4-address *ipv4-localhost*))
 
 ;;; IPv6 addresses
 
   (declare (ignore string))
   (error "IPv6 parsing not implemented yet"))
 
-(defmethod initialize-instance :after ((instance ipv6-address) &key host-bytes host-string)
+(defmethod initialize-instance :after ((instance ipv6-address) &key host-bytes host-string host-address)
   (let ((octets (or host-bytes
+                   (when host-address
+                     (check-type host-address ipv6-address)
+                     (slot-value host-address 'host-bytes))
                    (when host-string (parse-ipv6-string host-string))
                    '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))))
     (assert (and (typep octets 'sequence)
 (defun parse-ipv6-host-address (string)
   (make-instance 'ipv6-host-address :host-string string))
 
-(export '(ipv6-address parse-ipv6-address))
+(defparameter *ipv6-localhost* (make-instance 'ipv6-host-address :host-bytes '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)))
+
+(export '(ipv6-address ipv6-host-address parse-ipv6-address *ipv6-localhost*))
 
 ;;; TCP code
 
 
 (defmethod connected-address-p ((address tcp-address)) t)
 
-(export '(tcp-address tcp4-address tcp6-address))
+(defun tcp-address-for (host-address port)
+  (check-type port (unsigned-byte 16))
+  (etypecase host-address
+    (ipv4-address (make-instance 'tcp4-address :host-address host-address :port port))
+    (ipv6-address (make-instance 'tcp6-address :host-address host-address :port port))))
+
+(export '(tcp-address tcp4-address tcp6-address tcp-address-for))
 
 ;;; UDP code
 
 
 (defmethod connected-address-p ((address tcp-address)) nil)
 
-(export '(udp-address udp4-address udp6-address))
+(defun udp-address-for (host-address port)
+  (check-type port (unsigned-byte 16))
+  (etypecase host-address
+    (ipv4-address (make-instance 'udp4-address :host-address host-address :port port))
+    (ipv6-address (make-instance 'udp6-address :host-address host-address :port port))))
+
+(export '(udp-address udp4-address udp6-address udp-address-for))
 
 ;;; Unix sockets