[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Updating the zmq egg
From: |
Thomas Chust |
Subject: |
Re: [Chicken-users] Updating the zmq egg |
Date: |
Fri, 06 Mar 2015 12:44:09 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 |
On 2015-03-06 02:00, Matt Gushee wrote:
> [...]
> Another issue with message length is whether there should be a default
> value. There is a Scheme function that generates a buffer for both
> sending and receiving functions.
> [...]
Hello,
for sending, I wouldn't allocate a separate buffer but just pass a
pointer to the contents of a string or blob and the length of the
container to the C function.
For receiving, however, there is no way to know how large the buffer
must be without also knowing the application level protocol. Since
CHICKEN is a high level language, I would try to avoid choosing an
arbitrary buffer size or even forcing the programmer to specify some
specific buffer size, since this could lead to memory overflow errors.
I would recommend to use the zmq_msg_init and zmq_msg_recv functions to
receive a message of arbitrary length and leave the allocation problems
to 0MQ, then you can extract the actual data and its length from the
message object using zmq_msg_data and zmq_msg_size. This approach is
somewhat less efficient than receiving into a prepared buffer, but it is
much easier to implement correctly.
For efficiency, you could provide an alternative API where the
programmer passes in a buffer and optional length that would receive the
message, but that API should definitely perform bounds checking.
Everything could be wrapped into a binding like this (beware, this code
snippet is completely untested):
(define (zmq-recv sock #!optional buf ofs len)
(if buf
(let* ((ofs (or ofs 0))
(len
(cond
((string? buf)
(let ((len (or len (- (string-length buf) ofs))))
(assert (and (<= 0 ofs)
(< (+ ofs len) (string-length buf))))
len))
((blob? buf)
(let ((len (or len (- (blob-size buf) ofs))))
(assert (and (<= 0 ofs)
(< (+ ofs len) (blob-size buf))))
len))
(else
(error 'zmq-recv "unknown buffer type")))))
(if (negative?
((foreign-lambda* int ((c-pointer sock)
(scheme-pointer buf)
(size_t ofs) (size_t len)
(int flags))
"C_return(zmq_recv("
" sock, ((char *)buf) + (ptrdiff_t)ofs, len"
"));")
sock buf ofs len 0))
(error 'zmq-recv "receive failed")
buf))
(let ((msg
(make-blob (foreign-value "sizeof(zmq_msg_t)" size_t))))
(if (negative?
((foreign-lambda int "zmq_msg_init" scheme-pointer) msg))
(error 'zmq-recv "failed to initialize message")
(set-finalizer!
msg (foreign-lambda int "zmq_msg_close" scheme-pointer)))
(if (negative?
((foreign-lambda int "zmq_msg_recv"
scheme-pointer scheme-pointer int)
msg socket 0))
(error 'zmq-recv "receive failed")
(let* ((len
((foreign-lambda size_t "zmq_msg_size"
scheme-object)
msg))
(buf (make-blob len)))
(move-memory!
((foreign-lambda c-pointer "zmq_msg_data" scheme-object)
msg)
buf len)
buf)))))
I hope this helps :-)
Ciao,
Thomas
--
When C++ is your hammer, every problem looks like your thumb.
- Re: [Chicken-users] Updating the zmq egg, (continued)
- Re: [Chicken-users] Updating the zmq egg, Evan Hanson, 2015/03/05
- Re: [Chicken-users] Updating the zmq egg, Dan Leslie, 2015/03/05
- Re: [Chicken-users] Updating the zmq egg, Matt Gushee, 2015/03/05
- Re: [Chicken-users] Updating the zmq egg, Dan Leslie, 2015/03/05
- Re: [Chicken-users] Updating the zmq egg, John Cowan, 2015/03/05
- Re: [Chicken-users] Updating the zmq egg, Kristian Lein-Mathisen, 2015/03/09
- Re: [Chicken-users] Updating the zmq egg, Matt Gushee, 2015/03/09
- Re: [Chicken-users] Updating the zmq egg, Daniel Leslie, 2015/03/09
Re: [Chicken-users] Updating the zmq egg,
Thomas Chust <=