Re: The most basic File API use case

Hi Peter!

On Dec 7, 2009, at 22:51 , Peter O. Ussuri wrote:
> Fair point - playing with encoding(s) is probably not the right place here. We thus can have just a binary builder and leave text/strings out of the 'building' process altogether. FileWriter can be instructed later to write/save either a blob or a string.

Actually I've changed my mind here :)

If we have a method that can write out a text file, it simply take a string (and then indeed a global encoding to apply to all the file). But for blobs, given that you're writing out binary anyway, it is less important to control the global encoding. In fact there are probably binary formats that can only take US-ASCII in place but that might accept UTF-8 elsewhere. See below for details.

> Thus if "a proposal for binary data in ES" is nowhere near stability (I can't tell), I suggest a simple binaryBuilder/blobBuilder interface is introduced to move things forward.

Agreed. My proposal below doesn't have the full details of what can be done to add some binary, but that can easily be added.

> Regarding "continuous writing": I agree that there are use cases that would benefit a lot from it, so the behavior should be specified and implemented in some way down the road. However, as you point it out yourself, there are some open issues to be clarified/resolved around it. Thus my suggestion would be to design FileWriter in a way that would keep the continuous writing option "on the table", but have a "write-and-done" method specified now, so that vendors can implement it.

Listening to you and Jonas, that's what I've tried to do now.

Here's roughly what I propose:

First we have a FileWriter. It can save to both text (with options for encoding and line endings) and to binary (if given a blob). It is designed to look a lot like FileReader (and thus XHR). That does lead to some amount of extra verbosity, but I think that the alignment is worth it. Hopefully the general idea is clear.


[Constructor(DOMString mediaType, DOMString fileName)]
interface FileWriter {
    // saving operations
    void save (DOMString content, optional DOMString encoding, optional DOMString endings);
    void save (Blob data);
    
    // abort the save
    void abort();
    
    // state codes
    const unsigned short INITIAL = 0;
    const unsigned short WRITING = 1;
    const unsigned short DONE    = 2;
    readonly attribute unsigned short readyState;

    // error, same as FileReader but with some additions
    readonly attribute FileError error;
    
    // event handler attributes
    attribute Function onloadstart;
    attribute Function onprogress;
    attribute Function onload;
    attribute Function onabort;
    attribute Function onerror;
    attribute Function onloadend;
};
FileWriter implements EventTarget;


Then we have a WritableBlob. I'm not married to the name, I just liked the approach of having a single object which both contains the data and does the manipulation, as opposed to the builder object from which you get the content when you're done. The level of indirection didn't seem necessary, but maybe I missed something. As I said above, we can have more options as in your BlobBuilder to add content into it, and we don't have to use overloading if people don't like it (or if it doesn't scale). If we do stick to overloading I wouldn't be adverse to adding Constructor(Blob blob) and Constructor(octet val).

[Constructor]
interface WritableBlob : Blob {
    void put (Blob blob);
    void put (octet val);
    void put (DOMString string, optional DOMString encoding);
};

I've also been wondering if we should add put(Blob... blob), put(octet... val), put(Blob[] blobs), put(octet[] vals), etc. Again, those are trivial changes.

Some examples:

//  1. writing out a text file like the one in my FileWriter draft
var str = "";
for (var i = 0; i < 10; i++) str += "I am dahut number " . i . "\n";
var fw = new FileWriter("text/plain", "ten-dahuts.txt");
fw.onload = function () { alert("File has been saved!"); }
fw.onerror = function (err) { alert("Failed to save file: " + err.code); }
fw.save(str);

//  2. writing out an image -- it's very much the same
var blob = loadDVDContent("The Blob"); // a blob with some video content
var fw = new FileWriter("video/ogg", "the-blob.ogg");
fw.onload = function () { alert("Be afraid!"); }
fw.onerror = function (err) { alert("Be very afraid!"); }
fw.save(blob);

//  3. creating a blob from scratch
var blob = new WritableBlob();
for (var i = 0; i < 10; i++) blob.put(i); // a very useful binary file

Thoughts? If people like the general design, I'll make a draft of it and send it out for review. We can then tweak the various options — but what I'm most interested in first is getting some consensus around the overall shape of it.

-- 
Robin Berjon - http://berjon.com/

Received on Tuesday, 8 December 2009 17:04:17 UTC