[e-lang] Sending files with E?

Jimmy Wylie Jr. jwylie at uno.edu
Mon Sep 29 00:31:09 CDT 2008


Hi all,

I've been playing around with the persistent chat program provided by E in a
Walnut towards the end.  I wanted to add to the program, the ability to send
a file and receive files.  However, I'm not exactly sure how to do this.  I
have written something, but it only works on small files, when I try to send
something like a jpeg, I get a stack overflow error.  Is it possible to just
send a reference to a file? and then copy it?  I tried to do something like
that but I didn't see any applicable methods in the Elib, so I ended up
writing this deciding to wrap a file in a new object, a FileDispenser, that
holds an inputStream for the file being sent:

# this object is used to dispense a file across network
def makeFileDispenser(file){
    def myFile := file
    def makeInputStream := <import:java.io.makeFileInputStream>
    def input := makeInputStream(myFile)
    def fileDispenser {
        to read() :int {
            return input.read()
        }

        to available() :int {
            return input.available()
        }

        to close() {
            input.close()
        }
    }
    return fileDispenser
}

Then I wrote a copy method:
#copies a file from network given a FileDispenser,
# outputstream, and available bytes in file
def copy(dispenser, output, available){
    var avail := available
    if(avail > 0) {
        def charVow := dispenser <- read()
        when(charVow) -> {
              output.write(charVow)
        } catch problem {
             println("something went horribly wrong")
             traceline(problem)
        }
        avail := avail - 1
        copy(dispenser, output,    avail)
    } else {
      return
    }
}

After the sender sends a file by calling friend <-
receiveFile(fileDispenser) with the Dispenser wrapping a file reference ...
the receiver executes the following basically creating an outputStream, and
requesting one byte from the file dispenser at a time, and writing it to the
output stream:
 to receiveFile(dispenser) {
         traceline("receiveFile")
         def copyFile := requestSaveFile(chatUI.getChatWin())
         if (copyFile != null) {
             def makeOutputStream := <import:java.io.makeFileOutputStream>
             def output := makeOutputStream(copyFile)
             def available := dispenser <- available()
             when (available) -> {
                copy(dispenser, output, available)
              } catch problem {traceline("problem with copy");
traceline(problem)}
         } else {
                   showMessage("System", "You have rejected the file
transfer")
                    myFriend <- receive("File Transfer Rejected"); #notify
friend of rejected transfer
         }
      }

Anyone have any suggestions on how to improve this, or perhaps an easier
way?
I would like to be able to send bigger files without getting a
<StackOverFlowError>.
Also, I want both participants in the transfer to be notified of the
transfer.  The copy method doesn't currently return a promise, but I know by
using Ref.promise() I could create a [promise, resolver] pair, but I'm not
sure if that will work either, since the copy method will keep recursively
returning promises. Would that hog too much memory?

Thanks for your help,
Jimmy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.eros-os.org/pipermail/e-lang/attachments/20080929/05897812/attachment.html 


More information about the e-lang mailing list