[gambit-list] newbie question: output from one port as input to another port

Marc Feeley feeley at iro.umontreal.ca
Sun Mar 12 08:43:26 EST 2006


On 11-Mar-06, at 10:40 PM, Samuel Montgomery-Blinn wrote:

> So, I have been trying to learn Gambit-C's port mechanisms. This is  
> likely an infantile question, but it seems that it should be the  
> most basic thing to be able to take one input port and "connect" it  
> to an output port. The specific use for me is sending the contents  
> of a file over a network (tcp) port. I have tried a few methods,  
> mostly "busy" and likely lossy methods.
>
> 1. read the entire contents of the file port, then output the file  
> to the network port. (wastes time in which earlier parts of the  
> file could be written to the network port)
> 2. read a line from the file port, and output the line to the  
> network port. repeat until eof. (wastes time for many reasons)
>
> I was guessing that something to do with the procedures "call-with- 
> input-file" or "with-output-to-file" might be something towards  
> what might be most succinctly expressed as some sort of UNIX  
> "sendfile" functionality, but as I am new both to Scheme (or any  
> Lisp for that matter) and Gambit-C, I thought I would both say  
> "hello" to this list and ask for its help and guidance. If this  
> sort of question is not a faux pas, I certainly have more!
>
> -Sam
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> http://mailman.iro.umontreal.ca/mailman/listinfo/gambit-list

Well, Christian just beat me to it, but here's my version anyway  
(which shows off binary I/O as well as text I/O which is useful if  
you are converting character and end-of-line encodings).

Marc

(define (copy-octet-port-to-octet-port in out)
   (let ((buf (make-u8vector 4096)))
     (let loop ()
       (let ((n (read-subu8vector buf 0 (u8vector-length buf) in)))
         (if (> n 0)
             (begin
               (write-subu8vector buf 0 n out)
               (loop)))))))

(define (copy-char-port-to-char-port in out)
   (let ((buf (make-string 4096)))
     (let loop ()
       (let ((n (read-substring buf 0 (string-length buf) in)))
         (if (> n 0)
             (begin
               (write-substring buf 0 n out)
               (loop)))))))

(define (copy-binary-file in-filename out-filename)
   (call-with-input-file in-filename
     (lambda (in)
       (call-with-output-file out-filename
         (lambda (out)
           (copy-octet-port-to-octet-port in out))))))

(define (copy-text-file in-filename out-filename)
   (call-with-input-file in-filename
     (lambda (in)
       (call-with-output-file out-filename
         (lambda (out)
           (copy-char-port-to-char-port in out))))))

(define (test)

   ; binary copy gsi/gsi -> gsi2

   (time (copy-binary-file "gsi/gsi" "gsi2"))

   ; copy text file a.txt to b.txt, converting from UTF-8 character
   ; encoding (and any end-of-line encoding) to UCS-2 character
   ; encoding with BOM and DOS end-of-line encoding (compatible with
   ; Windows)

   (time (copy-text-file
          (list path: "a.txt" char-encoding: 'utf8 eol-encoding: 'cr-lf)
          (list path: "b.txt" char-encoding: 'ucs2 eol-encoding: 'cr- 
lf))))

(test)




More information about the Gambit-list mailing list