Repeatedly tries to read bytes from an async-io-state, and invokes a callback.
async-io-state-read-with-checking async-io-state callback &key timeout max-read error-callback user-info element-type
An async-io-state.
A function designator for a function of 3 arguments, or nil
.
nil
or a positive real.
A positive integer.
A function designator for a function of 3 arguments, or nil
.
A Lisp object.
A type specifier.
The function async-io-state-read-with-checking
repeatedly tries to read up to async-io-state-max-read more bytes from async-io-state, append them to the internal buffer and call callback like this:
callback async-io-state buffer end
async-io-state is the argument to async-io-state-read-with-checking
, buffer is a cl:simple-array
of element type element-type containing data from index 0 up to end, and end is a positive integer indicating the end of the filled part of buffer.
The buffer must not be modified or accessed outside the scope of the callback or after async-io-state-discard or async-io-state-finish have been called.
The element type of buffer is element-type, which can be base-char
, (unsigned-byte 8)
or (signed-byte 8)
. The default value of element-type is base-char
.
The callback is responsible for processing the data in the buffer and optionally indicating that the read operation is complete as follows:
async-io-state-read-with-checking
is called, it resets the old length to 0, so async-io-state-old-length returns 0 in the first invocation of callback.
If the operation does not finish within the state's async-io-state-read-timeout period then the callback is called with the state's async-io-state-read-status set to :timeout
.
If an error occurs during the I/O operation and error-callback is non-nil, then error-callback is called like this:
error-callback async-io-state buffer end
If error-callback is nil
, then callback is called, so it should check for errors using async-io-state-read-status.
If timeout, max-read or user-info are supplied then they set async-io-state-read-timeout, async-io-state-max-read and async-io-state-user-info in async-io-state for this and subsequent operations.
If another read operation is in progress on the state, an error is signaled.
Once the callback has called async-io-state-finish it can start further reading operations on async-io-state. The accessors async-io-state-read-timeout, async-io-state-max-read and async-io-state-user-info can be used to read and write the corresponding values in the callback.
Reading http headers, which are separated from the http body by two consecutive newlines. We assume these functions:
1. my-parse-http-headers
which takes a buffer, start and end and returns a parsed headers-object.
2. my-read-http-body
takes an async-io-state, headers-object and a user-defined object and reads the body via the Async-IO-State API.
3. my-record-socket-error
which takes a user defined object and the error flag and handles a socket error.
4. find-nn-in-buffer
which takes buffer, start and end and returns the index of the first two consecutive newlines if any.
The callback is defined like this:
(defun http-header-reading-callback (state buffer end)
(if-let (cannot-read
(async-io-state-read-status state))
(my-record-socket-error
(async-io-state-user-info state)
cannot-read)
(let ((start (async-io-state-old-length state)))
(let ((start-search-for-nn
(if (zerop start) 0 (1- start))))
(when-let (h-end (find-nn-in-buffer
buffer
start-search-for-nn
end))
(let ((h-object (my-parse-http-headers
buffer 0 h-end)))
(async-io-state-finish state (+ h-end 2))
(my-read-http-body
state
h-object
(async-io-state-user-info state))))))))
The callback is used like this:
(async-io-state-read-with-checking
state
'http-header-reading-callback)
LispWorks User Guide and Reference Manual - 20 Sep 2017