<commit_before>(in-package :cl-async)

(define-condition tcp-info (event-info)
  ((socket :initarg :socket :accessor tcp-socket :initform nil))
  (:report (lambda (c s)
             (print-unreadable-object (c s :type t :identity t)
               (format s "~a" (tcp-socket c)))))
  (:documentation "Base TCP condition. Holds the socket object."))

(define-condition tcp-error (event-error tcp-info) ()
  (:report (lambda (c s)
             (print-unreadable-object (c s :type t :identity t)
               (format s "~a: ~a: ~a" (tcp-socket c) (event-errcode c) (event-errmsg c)))))
  (:documentation "Describes a general TCP connection error."))

(define-condition tcp-eof (tcp-info) ()
  (:documentation "Passed to an event callback when a peer closes a TCP connection."))

(define-condition tcp-reset (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection times out."))

(define-condition tcp-timeout (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection times out."))

(define-condition tcp-refused (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection is refused."))

(define-condition tcp-accept-error (tcp-error)
  ((listener :accessor tcp-accept-error-listener :initarg :listener :initform (cffi:null-pointer))
   (tcp-server :accessor tcp-accept-error-tcp-server :initarg :tcp-server :initform nil))
  (:report (lambda (c s) (format s "Error accepting TCP connection: ~a" (tcp-accept-error-listener c))))
  (:documentation "Passed to a TCP server's event-cb when there's an error accepting a connection."))

(define-condition socket-closed (tcp-error) ()
  (:report (lambda (c s) (format s "Closed TCP socket being operated on: ~a." (tcp-socket c))))
  (:documentation "Thrown when a closed socket is being operated on."))

(define-condition tcp-server-bind-error (tcp-error)
  ((addr :accessor tcp-server-bind-error-addr :initarg :addr :initform nil)
   (port :accessor tcp-server-bind-error-port :initarg :port :initform nil))
  (:report (lambda (c s) (format s "Error binding TCP server (~a:~a)"
                                 (tcp-server-bind-error-addr c)
                                 (tcp-server-bind-error-port c))))
  (:documentation "Thrown when a server fails to bind (generally, the port is already in use)."))

(defclass socket ()
  ((c :accessor socket-c :initarg :c :initform (cffi:null-pointer))
   (data :accessor socket-data :initarg data :initform nil
     :documentation "Used to store arbitrary (app-defined) data with a socket.")
   (buffer :accessor socket-buffer :initarg :buffer :initform (make-buffer)
     :documentation "Holds data sent on the socket before it's connected.")
   (connected :accessor socket-connected :initarg :connected :initform nil)
   (closed :accessor socket-closed :initarg :closed :initform nil)
   (direction :accessor socket-direction :initarg :direction :initform nil)
   (drain-read-buffer :accessor socket-drain-read-buffer :initarg :drain-read-buffer :initform t))
  (:documentation "Wraps around a libevent bufferevent socket."))

(defclass tcp-server ()
  ((c :accessor tcp-server-c :initarg :c :initform (cffi:null-pointer))
   (closed :accessor tcp-server-closed :initarg :closed :initform nil)
   (stream :accessor tcp-server-stream :initarg :stream :initform nil))
  (:documentation "Wraps around a libevent connection listener."))

(defun get-last-tcp-err ()
  "Since libevent provides a macro but not a function for getting the last error
   code, we have to essentially rebuild that macro here.

   NOTE: As libevent says, this function cannot be considered idempotent. In
   other words, it can become hideously turgid whe...what's that? OH IDEMpotent,
   that makes more sense. Yes, calling it more than once may result in different
   values returned. So, call once and save the result until the next time an
   error happens."
  #+(or :windows :win32 :win64)
    (let ((code (cffi:foreign-funcall "WSAGetLastError" :int)))
      (values code
              (cffi:foreign-funcall "evutil_socket_error_to_string" :int code :string)))
  #-(or :windows :win32 :win64)
    (let ((code (cffi:mem-aref (cffi:foreign-symbol-pointer "errno") :int)))
      (values code
              (cffi:foreign-funcall "strerror" :int code :string))))

(defun check-socket-open (socket)
  "Throw a socket-closed condition if given a socket that's closed."
  (when (and (typep socket 'socket)
             (or (socket-closed socket)))
    (error 'socket-closed :code -1 :msg "Trying to operate on a closed socket" :socket socket)))

(defun socket-closed-p (socket)
  "Return whether a socket is closed or not."
  (socket-closed socket))<commit_msg>remove libevent specific code (wasnt being called, buts its vestigial dead weight.<commit_after>(in-package :cl-async)

(define-condition tcp-info (event-info)
  ((socket :initarg :socket :accessor tcp-socket :initform nil))
  (:report (lambda (c s)
             (print-unreadable-object (c s :type t :identity t)
               (format s "~a" (tcp-socket c)))))
  (:documentation "Base TCP condition. Holds the socket object."))

(define-condition tcp-error (event-error tcp-info) ()
  (:report (lambda (c s)
             (print-unreadable-object (c s :type t :identity t)
               (format s "~a: ~a: ~a" (tcp-socket c) (event-errcode c) (event-errmsg c)))))
  (:documentation "Describes a general TCP connection error."))

(define-condition tcp-eof (tcp-info) ()
  (:documentation "Passed to an event callback when a peer closes a TCP connection."))

(define-condition tcp-reset (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection times out."))

(define-condition tcp-timeout (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection times out."))

(define-condition tcp-refused (tcp-error) ()
  (:documentation "Passed to an event callback when a TCP connection is refused."))

(define-condition tcp-accept-error (tcp-error)
  ((listener :accessor tcp-accept-error-listener :initarg :listener :initform (cffi:null-pointer))
   (tcp-server :accessor tcp-accept-error-tcp-server :initarg :tcp-server :initform nil))
  (:report (lambda (c s) (format s "Error accepting TCP connection: ~a" (tcp-accept-error-listener c))))
  (:documentation "Passed to a TCP server's event-cb when there's an error accepting a connection."))

(define-condition socket-closed (tcp-error) ()
  (:report (lambda (c s) (format s "Closed TCP socket being operated on: ~a." (tcp-socket c))))
  (:documentation "Thrown when a closed socket is being operated on."))

(define-condition tcp-server-bind-error (tcp-error)
  ((addr :accessor tcp-server-bind-error-addr :initarg :addr :initform nil)
   (port :accessor tcp-server-bind-error-port :initarg :port :initform nil))
  (:report (lambda (c s) (format s "Error binding TCP server (~a:~a)"
                                 (tcp-server-bind-error-addr c)
                                 (tcp-server-bind-error-port c))))
  (:documentation "Thrown when a server fails to bind (generally, the port is already in use)."))

(defclass socket ()
  ((c :accessor socket-c :initarg :c :initform (cffi:null-pointer))
   (data :accessor socket-data :initarg data :initform nil
     :documentation "Used to store arbitrary (app-defined) data with a socket.")
   (buffer :accessor socket-buffer :initarg :buffer :initform (make-buffer)
     :documentation "Holds data sent on the socket before it's connected.")
   (connected :accessor socket-connected :initarg :connected :initform nil)
   (closed :accessor socket-closed :initarg :closed :initform nil)
   (direction :accessor socket-direction :initarg :direction :initform nil)
   (drain-read-buffer :accessor socket-drain-read-buffer :initarg :drain-read-buffer :initform t))
  (:documentation "Wraps around a libevent bufferevent socket."))

(defclass tcp-server ()
  ((c :accessor tcp-server-c :initarg :c :initform (cffi:null-pointer))
   (closed :accessor tcp-server-closed :initarg :closed :initform nil)
   (stream :accessor tcp-server-stream :initarg :stream :initform nil))
  (:documentation "Wraps around a libevent connection listener."))

(defun check-socket-open (socket)
  "Throw a socket-closed condition if given a socket that's closed."
  (when (and (typep socket 'socket)
             (or (socket-closed socket)))
    (error 'socket-closed :code -1 :msg "Trying to operate on a closed socket" :socket socket)))

(defun socket-closed-p (socket)
  "Return whether a socket is closed or not."
  (socket-closed socket))
{'fraction_non_alphanumeric': 0.12683952347582342, 'fraction_numerical': 0.00116795141322121, 'mean_word_length': 3.8378531073446327, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4162979', 'n_tokens_mistral': 2636, 'n_tokens_neox': 2540, 'n_words': 931}