From: Vladimir Zolotykh
Subject: stream-file-descriptor ?
Date: 
Message-ID: <3E903870.2000900@eurocom.od.ua>
Trying to write minimally sufficient CL interface to GD graphic
library I've found the following difficulty. GD has a function
gdImagePng that takes Unix file pointer (type FILE * in C) as its
second argument. So the two obvious solutions could be:

   - write a C function that takes name of a file opens it using
     fopen and passes this file pointer to gdImagePng. Call this new
     C function from CL (via FF interface)

   - call fopen from CL (using foreign functions interface), get file
     pointer and call gdImagePng (again using FF interface).

Both approaches don't seem much convenient. I'd rather do something like

   (with-open-file (p "test.png" :direction :output :if-exists :supersede)
     (gdImagePng image (stream-file-pointer p)))

if only I had stream-file-pointer function. Is something like that
possible ?

-- 
Vladimir Zolotykh

From: Russell McManus
Subject: Re: stream-file-descriptor ?
Date: 
Message-ID: <87k7e7320d.fsf@thelonious.dyndns.org>
If you can get at the file descriptor underlying the file stream
(implementation dependent), you might be able to call fdopen to turn
the fd into a FILE*, and as long as you flush output with fflush() you
should be OK.  Well, maybe not, but it's worth trying, if you don't
mind such ugliness.

-russ


Vladimir Zolotykh <······@eurocom.od.ua> writes:

> Trying to write minimally sufficient CL interface to GD graphic
> library I've found the following difficulty. GD has a function
> gdImagePng that takes Unix file pointer (type FILE * in C) as its
> second argument. So the two obvious solutions could be:
> 
>    - write a C function that takes name of a file opens it using
>      fopen and passes this file pointer to gdImagePng. Call this new
>      C function from CL (via FF interface)
> 
>    - call fopen from CL (using foreign functions interface), get file
>      pointer and call gdImagePng (again using FF interface).
> 
> Both approaches don't seem much convenient. I'd rather do something like
> 
>    (with-open-file (p "test.png" :direction :output :if-exists :supersede)
>      (gdImagePng image (stream-file-pointer p)))
> 
> if only I had stream-file-pointer function. Is something like that
> possible ?
> 
> -- 
> Vladimir Zolotykh
From: Simon Andr�s
Subject: Re: stream-file-descriptor ?
Date: 
Message-ID: <vcdr88fxo1j.fsf@tarski.math.bme.hu>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

> Trying to write minimally sufficient CL interface to GD graphic
> library I've found the following difficulty. GD has a function
> gdImagePng that takes Unix file pointer (type FILE * in C) as its
> second argument. So the two obvious solutions could be:
> 
>    - write a C function that takes name of a file opens it using
>      fopen and passes this file pointer to gdImagePng. Call this new
>      C function from CL (via FF interface)
> 
>    - call fopen from CL (using foreign functions interface), get file
>      pointer and call gdImagePng (again using FF interface).
> 
> Both approaches don't seem much convenient. I'd rather do something like
> 
>    (with-open-file (p "test.png" :direction :output :if-exists :supersede)
>      (gdImagePng image (stream-file-pointer p)))
> 
> if only I had stream-file-pointer function. Is something like that
> possible ?

Wouldn't using the more primitive gdImagePngPtr be easier?  The doc
says it's

    Identical to gdImagePng except that it returns a pointer to a
    memory area with the PNG data.

I have close to zero experience with FFIs, but I'd think that this
scenario is quite common.

Andras
From: Vladimir Zolotykh
Subject: Re: stream-file-descriptor ?
Date: 
Message-ID: <3E915AE9.4070506@eurocom.od.ua>
Simon Andr�s wrote:

> Wouldn't using the more primitive gdImagePngPtr be easier?  The doc
> says it's


It had seemed the best approach before I realized that my knowledge of
ACL FF is insufficient to deal with array dynamically allocated inside
gdImagePngPtr properly. Or at least my code appeared rather clumsy. So
at last I ended up this more familiar solution:

(defmacro with-file-pointer ((var path mode) &body body)
   (let ((fp (gensym "fp")))
     `(let* ((,fp (fopen ,path ,mode))
	    (,var ,fp))
        (unwind-protect
	   (progn ,@body)
	 (fclose ,fp)))))

-- 
Vladimir Zolotykh