Changeset 191285 in webkit


Ignore:
Timestamp:
Oct 19, 2015 3:09:07 AM (9 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Streams API] Implement ReadableStream tee
https://bugs.webkit.org/show_bug.cgi?id=146315

Reviewed by Darin Adler.

Source/WebCore:

Covered by rebased test.

  • Modules/streams/ReadableStream.js:

(tee): Removing not implemented exception throwing.

  • Modules/streams/ReadableStreamInternals.js:

(teeReadableStream): Implementing as per spec.
(teeReadableStreamPullFunction): Ditto.
(teeReadableStreamBranch2CancelFunction): Ditto.

LayoutTests:

  • streams/reference-implementation/readable-stream-tee-expected.txt:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r191283 r191285  
     12015-10-19  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement ReadableStream tee
     4        https://bugs.webkit.org/show_bug.cgi?id=146315
     5
     6        Reviewed by Darin Adler.
     7
     8        * streams/reference-implementation/readable-stream-tee-expected.txt:
     9
    1102015-10-19  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    211
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-tee-expected.txt

    r190401 r191285  
    11
    2 FAIL ReadableStream teeing: rs.tee() returns an array of two ReadableStreams tee is not implemented
    3 FAIL ReadableStream teeing: should be able to read one branch to the end without affecting the other tee is not implemented
    4 FAIL ReadableStream teeing: values should be equal across each branch tee is not implemented
    5 FAIL ReadableStream teeing: errors in the source should propagate to both branches tee is not implemented
    6 FAIL ReadableStream teeing: canceling branch1 should not impact branch2 tee is not implemented
    7 FAIL ReadableStream teeing: canceling branch2 should not impact branch1 tee is not implemented
    8 FAIL ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array tee is not implemented
    9 FAIL ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches tee is not implemented
    10 FAIL ReadableStream teeing: closing the original should immediately close the branches tee is not implemented
    11 FAIL ReadableStream teeing: erroring the original should immediately error the branches tee is not implemented
     2PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams
     3PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other
     4PASS ReadableStream teeing: values should be equal across each branch
     5PASS ReadableStream teeing: errors in the source should propagate to both branches
     6PASS ReadableStream teeing: canceling branch1 should not impact branch2
     7PASS ReadableStream teeing: canceling branch2 should not impact branch1
     8PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array
     9PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches
     10PASS ReadableStream teeing: closing the original should immediately close the branches
     11PASS ReadableStream teeing: erroring the original should immediately error the branches
    1212
  • trunk/Source/WebCore/ChangeLog

    r191283 r191285  
     12015-10-19  Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement ReadableStream tee
     4        https://bugs.webkit.org/show_bug.cgi?id=146315
     5
     6        Reviewed by Darin Adler.
     7
     8        Covered by rebased test.
     9
     10        * Modules/streams/ReadableStream.js:
     11        (tee): Removing not implemented exception throwing.
     12        * Modules/streams/ReadableStreamInternals.js:
     13        (teeReadableStream): Implementing as per spec.
     14        (teeReadableStreamPullFunction): Ditto.
     15        (teeReadableStreamBranch2CancelFunction): Ditto.
     16
    1172015-10-19  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    218
  • trunk/Source/WebCore/Modules/streams/ReadableStream.js

    r190794 r191285  
    122122        throw new @TypeError("Function should be called on a ReadableStream");
    123123
    124     throw new @TypeError("tee is not implemented");
     124    return @teeReadableStream(this, false);
    125125}
    126126
  • trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js

    r190794 r191285  
    7979    "use strict";
    8080
    81     throw new @TypeError("tee is not implemented");
     81    // TODO: Assert: IsReadableStream(stream) is true.
     82    // TODO: Assert: Type(shouldClone) is Boolean.
     83
     84    let reader = stream.getReader();
     85
     86    let teeState = {
     87        closedOrErrored: false,
     88        canceled1: false,
     89        canceled2: false,
     90        reason1: undefined,
     91        reason: undefined,
     92    };
     93
     94    teeState.cancelPromise = new @InternalPromise(function(resolve, reject) {
     95       teeState.resolvePromise = resolve;
     96       teeState.rejectPromise = reject;
     97    });
     98
     99    let pullFunction = @teeReadableStreamPullFunction(teeState, reader, shouldClone);
     100
     101    let underlyingSource1 = {
     102        "pull": pullFunction,
     103        "cancel": @teeReadableStreamBranch1CancelFunction(teeState, stream)
     104    };
     105
     106    let underlyingSource2 = {
     107        "pull": pullFunction,
     108        "cancel": @teeReadableStreamBranch2CancelFunction(teeState, stream)
     109    };
     110
     111    let branch1 = new ReadableStream(underlyingSource1);
     112    let branch2 = new ReadableStream(underlyingSource2);
     113
     114    reader.closed.catch(function(e) {
     115        if (teeState.closedOrErrored)
     116            return;
     117        @errorReadableStream(branch1, e);
     118        @errorReadableStream(branch2, e);
     119        teeState.closedOrErrored = true;
     120    });
     121
     122    // Additional fields compared to the spec, as they are needed within pull/cancel functions.
     123    teeState.branch1 = branch1;
     124    teeState.branch2 = branch2;
     125
     126    return [branch1, branch2];
     127}
     128
     129function teeReadableStreamPullFunction(teeState, reader, shouldClone)
     130{
     131    return function() {
     132        reader.read().then(function(result) {
     133            if (result.done && !teeState.closedOrErrored) {
     134                @closeReadableStream(teeState.branch1);
     135                @closeReadableStream(teeState.branch2);
     136                teeState.closedOrErrored = true;
     137            }
     138            if (teeState.closedOrErrored)
     139                return;
     140            if (!teeState.canceled1) {
     141                // TODO: Implement cloning if shouldClone is true
     142                @enqueueInReadableStream(teeState.branch1, result.value);
     143            }
     144            if (!teeState.canceled2) {
     145                // TODO: Implement cloning if shouldClone is true
     146                @enqueueInReadableStream(teeState.branch2, result.value);
     147            }
     148        });
     149    }
     150}
     151
     152function teeReadableStreamBranch1CancelFunction(teeState, stream)
     153{
     154    return function(r) {
     155        teeState.canceled1 = true;
     156        teeState.reason1 = r;
     157        if (teeState.canceled2) {
     158            @cancelReadableStream(stream, [teeState.reason1, teeState.reason2]).then(teeState.resolvePromise, teeState.rejectPromise);
     159        }
     160        return teeState.cancelPromise;
     161    }
     162}
     163
     164function teeReadableStreamBranch2CancelFunction(teeState, stream)
     165{
     166    return function(r) {
     167        teeState.canceled2 = true;
     168        teeState.reason2 = r;
     169        if (teeState.canceled1) {
     170            @cancelReadableStream(stream, [teeState.reason1, teeState.reason2]).then(teeState.resolvePromise, teeState.rejectPromise);
     171        }
     172        return teeState.cancelPromise;
     173    }
    82174}
    83175
Note: See TracChangeset for help on using the changeset viewer.