diff --git a/contrib/sockets/sockets.lisp b/contrib/sockets/sockets.lisp index 97f1364cc..8138c276b 100755 --- a/contrib/sockets/sockets.lisp +++ b/contrib/sockets/sockets.lisp @@ -1180,7 +1180,8 @@ also known as unix-domain sockets.")) (defun dup (fd) (ffi:c-inline (fd) (:int) :int "dup(#0)" :one-liner t)) -(defun make-stream-from-fd (fd mode &key buffering external-format (name "FD-STREAM")) +(defun make-stream-from-fd (fd mode &key buffering element-type external-format + (name "FD-STREAM")) (assert (stringp name) (name) "name must be a string.") (let* ((smm-mode (ecase mode (:input (c-constant "smm_input")) @@ -1193,9 +1194,13 @@ also known as unix-domain sockets.")) #+:wsock (:input-output-wsock (c-constant "smm_io_wsock")) )) - (stream (ffi:c-inline (name fd smm-mode) (t :int :int) t - "ecl_make_stream_from_fd(#0,#1,(enum ecl_smmode)#2,8, - ECL_STREAM_DEFAULT_FORMAT,Cnil)" + (stream (ffi:c-inline (name fd smm-mode element-type) + (t :int :int t) + t + " +ecl_make_stream_from_fd(#0,#1,(enum ecl_smmode)#2, + ecl_normalize_stream_element_type(#3), + ECL_STREAM_DEFAULT_FORMAT,Cnil)" :one-liner t))) (when buffering (si::set-buffering-mode stream buffering)) @@ -1209,7 +1214,7 @@ also known as unix-domain sockets.")) "(#0)->stream.flags |= ECL_STREAM_CLOSE_COMPONENTS" :one-liner t)) -(defun socket-make-stream-inner (fd input output buffering external-format) +(defun socket-make-stream-inner (fd input output buffering element-type external-format) ;; In Unix we have to create one stream per channel. The reason is ;; that buffered I/O is done using ANSI C FILEs which do not support ;; concurrent reads and writes -- if one thread is listening to the @@ -1221,25 +1226,36 @@ also known as unix-domain sockets.")) (cond ((and input output) #+wsock (make-stream-from-fd fd :input-output-wsock - :buffering buffering :external-format external-format) + :buffering buffering + :element-type element-type + :external-format external-format) #-wsock - (let* ((in (socket-make-stream-inner (dup fd) t nil buffering external-format)) - (out (socket-make-stream-inner fd nil t buffering external-format)) + (let* ((in (socket-make-stream-inner (dup fd) t nil buffering + element-type external-format)) + (out (socket-make-stream-inner fd nil t buffering + element-type external-format)) (stream (make-two-way-stream in out))) (auto-close-two-way-stream stream) stream)) (input (make-stream-from-fd fd #-wsock :input #+wsock :input-wsock - :buffering buffering :external-format external-format)) + :buffering buffering + :element-type element-type + :external-format external-format)) (output (make-stream-from-fd fd #-wsock :output #+wsock :output-wsock - :buffering buffering :external-format external-format)) + :buffering buffering + :element-type element-type + :external-format external-format)) (t (error "SOCKET-MAKE-STREAM: at least one of :INPUT or :OUTPUT has to be true.")))) (defmethod socket-make-stream ((socket socket) - &key (input nil input-p) (output nil output-p) - (buffering :full) (external-format :default)) + &key (input nil input-p) + (output nil output-p) + (buffering :full) + (element-type 'base-char) + (external-format :default)) (let ((stream (and (slot-boundp socket 'stream) (slot-value socket 'stream)))) (unless stream @@ -1248,7 +1264,8 @@ also known as unix-domain sockets.")) (unless (or input-p output-p) (setf input t output t)) (setf stream (socket-make-stream-inner (socket-file-descriptor socket) - input output buffering external-format)) + input output buffering element-type + external-format)) (setf (slot-value socket 'stream) stream) #+ ignore (sb-ext:cancel-finalization socket)) diff --git a/src/CHANGELOG b/src/CHANGELOG index 86ffe264d..64a4a3501 100755 --- a/src/CHANGELOG +++ b/src/CHANGELOG @@ -152,6 +152,8 @@ ECL 11.1.2 * Bugs fixed: + - Fixed several dozens of typos. + - ENSURE-DIRECTORIES-EXIST did not work properly with logical pathnames. - EXT:SET-LIMIT with option EXT:FRAME-STACK corrupted the frame stack. @@ -167,6 +169,7 @@ ECL 11.1.2 the one stored in *COMMAND-ARGS*, and this may be "cleared" by the user. + - SOCKET-MAKE-STREAM now accepts an :ELEMENT-TYPE argument. ;;; Local Variables: *** ;;; mode:text *** diff --git a/src/c/file.d b/src/c/file.d index 3bdd783d0..8ab178dd2 100755 --- a/src/c/file.d +++ b/src/c/file.d @@ -4432,12 +4432,22 @@ si_copy_stream(cl_object in, cl_object out) * FILE OPENING AND CLOSING */ -static cl_fixnum -normalize_stream_element_type(cl_object element_type) +cl_fixnum +ecl_normalize_stream_element_type(cl_object element_type) { cl_fixnum sign = 0; cl_index size; - if (funcall(3, @'subtypep', element_type, @'unsigned-byte') != Cnil) { + if (element_type == @'signed-byte') { + return -8; + } else if (element_type == @'unsigned-byte') { + return 8; + } else if (element_type == @':default') { + return 0; + } else if (element_type == @'base-char' || element_type == @'character') { + return 0; + } else if (funcall(3, @'subtypep', element_type, @'character') != Cnil) { + return 0; + } else if (funcall(3, @'subtypep', element_type, @'unsigned-byte') != Cnil) { sign = +1; } else if (funcall(3, @'subtypep', element_type, @'signed-byte') != Cnil) { sign = -1; @@ -4640,19 +4650,7 @@ ecl_open_stream(cl_object fn, enum ecl_smmode smm, cl_object if_exists, FEerror("~S is an illegal DIRECTION for OPEN.", 1, direction); } - if (element_type == @'signed-byte') { - byte_size = -8; - } else if (element_type == @'unsigned-byte') { - byte_size = 8; - } else if (element_type == @':default') { - byte_size = 0; - } else if (element_type == @'base-char' || element_type == @'character') { - byte_size = 0; - } else if (funcall(3, @'subtypep', element_type, @'character') != Cnil) { - byte_size = 0; - } else { - byte_size = normalize_stream_element_type(element_type); - } + byte_size = ecl_normalize_stream_element_type(element_type); if (byte_size != 0) { if (flags & ECL_STREAM_FORMAT) { FEerror("Cannot specify a character external format for binary streams.", 0); diff --git a/src/h/external.h b/src/h/external.h index d5a053952..b845d499c 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -714,6 +714,7 @@ extern ECL_API cl_object ecl_file_position(cl_object strm); extern ECL_API cl_object ecl_file_position_set(cl_object strm, cl_object disp); extern ECL_API cl_object ecl_file_length(cl_object strm); extern ECL_API int ecl_file_column(cl_object strm); +extern ECL_API cl_fixnum ecl_normalize_stream_element_type(cl_object element); extern ECL_API cl_object ecl_make_stream_from_fd(cl_object fname, int fd, enum ecl_smmode smm, cl_fixnum byte_size, int flags, cl_object external_format); extern ECL_API cl_object ecl_make_stream_from_FILE(cl_object fname, void *fd, enum ecl_smmode smm, cl_fixnum byte_size, int flags, cl_object external_format); extern ECL_API cl_object si_file_stream_fd(cl_object s);