From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Panicz Maciej Godek Newsgroups: gmane.lisp.guile.user Subject: Re: Converting a part of byte vector to UTF-8 string Date: Wed, 15 Jan 2014 16:27:50 +0100 Message-ID: References: <1389761956.20078.27.camel@Renee-desktop.suse> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=f46d0421a639ad004404f003f328 X-Trace: ger.gmane.org 1389799680 27704 80.91.229.3 (15 Jan 2014 15:28:00 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 15 Jan 2014 15:28:00 +0000 (UTC) Cc: "guile-user@gnu.org" To: Nala Ginrut Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Wed Jan 15 16:28:08 2014 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1W3SNy-0007Kp-CK for guile-user@m.gmane.org; Wed, 15 Jan 2014 16:28:06 +0100 Original-Received: from localhost ([::1]:55503 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W3SNx-0002gK-Vt for guile-user@m.gmane.org; Wed, 15 Jan 2014 10:28:05 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W3SNn-0002fX-CA for guile-user@gnu.org; Wed, 15 Jan 2014 10:27:56 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W3SNl-0007V8-Ge for guile-user@gnu.org; Wed, 15 Jan 2014 10:27:55 -0500 Original-Received: from mail-we0-x22f.google.com ([2a00:1450:400c:c03::22f]:47642) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W3SNl-0007UT-5L for guile-user@gnu.org; Wed, 15 Jan 2014 10:27:53 -0500 Original-Received: by mail-we0-f175.google.com with SMTP id p61so1895443wes.6 for ; Wed, 15 Jan 2014 07:27:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=KUzj2Tr+H/WPIDugEXEcwUwjv2RuUM2WiaLkwFpDc8M=; b=vI/iP6iHSz6w+Zmol6u3L/pbbGDUUIuCr6KolWSAXIHLIF3GYNBNml7qGNHPcbq/Zy TzLoENMyrz7/Yl0X7rEqbPrQQmZHsyVWqTMib6flegaFOIkmApWWuj/f28P2NC42OjZn eYQeEMDyit3bwhyeLgo3DTTW0lcst3qW9HhWnMZ/y/NPSDdfY8etgpkQYMJ4kQ+ApGiD GalqH2WT/Ddjd8ExIuxu87rhYrav7Sv+l7WN2pc6kInLolW9w+NTcAtOlafkF2JLPHdU d3UoUijIjU94sncdzm7bk/W5mgQ1CeyXZMJqaeko8AOFp6PnpUw96su+utdJDb5ykLZK 1NvA== X-Received: by 10.180.79.106 with SMTP id i10mr2886321wix.23.1389799670610; Wed, 15 Jan 2014 07:27:50 -0800 (PST) Original-Received: by 10.194.178.134 with HTTP; Wed, 15 Jan 2014 07:27:50 -0800 (PST) In-Reply-To: <1389761956.20078.27.camel@Renee-desktop.suse> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c03::22f X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:10999 Archived-At: --f46d0421a639ad004404f003f328 Content-Type: text/plain; charset=ISO-8859-1 hello :) [...] But I have a give a warning again, when you try to avoid allocation > overhead, you have to face the risk of the side-effect. To me, I'd > prefer pure-functional. ;-P > > Your solution seems reasonable, but I have found another way, which lead me to some new problems. I realised that since sockets are ports in guile, I could process them with the plain "read" (which is what I have been using them for anyway). However, this approach caused some new problems. The thing is that if I'm trying to read some message from port, and that message does not end with a delimiter (like a whitespace or a balancing, closing parenthesis), then the read would wait forever, possibly gluing its arguments. The solution I came up with is through soft ports. The idea is to have a port proxy, that -- if it would block -- would return an eof-object instead. The current implementation is rather straightforward: (define (nonblocking port) "returns a port proxy that returns eof-object on read attempt \ if a read would block" (make-soft-port (vector ;; 0. procedure accepting one character for output (lambda(c) (write c port)) ;; 1. procedure accepting a string for output (lambda(s) (display s port)) ;; 2. thunk for flushing output (lambda () (force-output port)) ;; 3. thunk for getting one character (lambda () (and (char-ready? port) (read-char port))) ;; 4. thunk for closing port (not by garbage collection) (lambda () (close-port port)) ;; 5. (if present and not `#f') thunk for computing the number of ;; characters that can be read from the port without blocking (lambda () (if (char-ready? port) 1 0))) (string-append (if (input-port? port) "r" "") (if (output-port? port) "w" "")))) One problem is that two messages, if not formatted properly, can still be glued together (although they no longer cause read to hang). The other thing that puzzles me is the last function provided to the soft port vector -- the one that computes the number of characters that can be read. Its only public interface I know of is through the "char-ready?" procedure. So there is no way for me to check the number of characters available in the original port. This is strange. The other thing is that I would like to have some means to make sure that an eof object is emited after reading each package sent through the socket, so that it wouldn't be possible to glue together data sent in two separate packages. I could of course create a more sophisticated soft-port, that would be implemented entirely using send and recv!, but I wonder if there's any simpler way. Thanks! --f46d0421a639ad004404f003f328 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
hell= o :)

<= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pa= dding-left:1ex"> [...]=A0
But I have a give a warning again, when you try to avoid allocation
overhead, you have to face the risk of the side-effect. To me, I'd
prefer pure-functional. ;-P


Your so= lution seems reasonable, but I have found another way, which lead me to som= e new problems.
I realised that since sockets are ports in guile,= I could process them with the plain "read" (which is what I have= been using them for anyway).

However, this approach caused some new problems. The t= hing is that if I'm trying to read some message from port, and that mes= sage does not end with a delimiter (like a whitespace or a balancing, closi= ng parenthesis), then the read would wait forever, possibly gluing its argu= ments.

The solutio= n I came up with is through soft ports. The idea is to have a port proxy, t= hat -- if it would block -- would return an eof-object instead.

The current implementation is rather s= traightforward:
= (define (nonblocking port)
=A0 "return= s a port proxy that returns eof-object on read attempt \
if a read would block"
=A0 (make-soft-port
=A0 =A0(vec= tor
=A0 =A0 ;; 0. procedure accepting one c= haracter for output
=A0 =A0 =A0(lambda(c) (write c port))
=A0 =A0 =A0;; 1. procedure accepting a string for out= put =A0 =A0 =A0
=A0 =A0 =A0(lambda(s) (disp= lay s port))
=A0 =A0 =A0;; 2. thunk for flushing output
= =A0 =A0 =A0(lambda () (force-output port))
= =A0 =A0 =A0;; 3. thunk for getting one character
=A0 =A0 =A0(lambda () (and (char-ready? port)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(read= -char port)))
=A0 =A0 =A0;; 4. thunk for cl= osing port (not by garbage collection)
=A0 = =A0 =A0(lambda () (close-port port))
=A0 =A0 =A0;; 5. (if present and not `#f') t= hunk for computing the number of
=A0 =A0 = =A0;; =A0 =A0characters that can be read from the port without blocking
=A0 =A0 =A0(lambda () (if (char-ready? port)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 1
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 0)))
=A0 =A0(string-append (if (input-port? port) "r" "")=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (if (output-= port? port) "w" ""))))
=
One problem is that two messages, if n= ot formatted properly, can still be glued together (although they no longer= cause read to hang).

The other t= hing that puzzles me is the last function provided to the soft port vector = -- the one that computes the number of characters that can be read.

Its only public interface I know of is= through the "char-ready?" procedure. So there is no way for me t= o check the number of characters available in the original port. This is st= range.

The other t= hing is that I would like to have some means to make sure that an eof objec= t is emited after reading each package sent through the socket, so that it = wouldn't be possible to glue together data sent in two separate package= s.

I could of = course create a more sophisticated soft-port, that would be implemented ent= irely using send and recv!, but I wonder if there's any simpler way.

Thanks!

--f46d0421a639ad004404f003f328--