source: OpenRLabs-Git/web2py/applications/rlabs/static/js/guacamole-common-js/modules/BlobWriter.js

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20var Guacamole = Guacamole || {};
21
22/**
23 * A writer which automatically writes to the given output stream with the
24 * contents of provided Blob objects.
25 *
26 * @constructor
27 * @param {Guacamole.OutputStream} stream
28 *     The stream that data will be written to.
29 */
30Guacamole.BlobWriter = function BlobWriter(stream) {
31
32    /**
33     * Reference to this Guacamole.BlobWriter.
34     *
35     * @private
36     * @type {Guacamole.BlobWriter}
37     */
38    var guacWriter = this;
39
40    /**
41     * Wrapped Guacamole.ArrayBufferWriter which will be used to send any
42     * provided file data.
43     *
44     * @private
45     * @type {Guacamole.ArrayBufferWriter}
46     */
47    var arrayBufferWriter = new Guacamole.ArrayBufferWriter(stream);
48
49    // Initially, simply call onack for acknowledgements
50    arrayBufferWriter.onack = function(status) {
51        if (guacWriter.onack)
52            guacWriter.onack(status);
53    };
54
55    /**
56     * Browser-independent implementation of Blob.slice() which uses an end
57     * offset to determine the span of the resulting slice, rather than a
58     * length.
59     *
60     * @private
61     * @param {Blob} blob
62     *     The Blob to slice.
63     *
64     * @param {Number} start
65     *     The starting offset of the slice, in bytes, inclusive.
66     *
67     * @param {Number} end
68     *     The ending offset of the slice, in bytes, exclusive.
69     *
70     * @returns {Blob}
71     *     A Blob containing the data within the given Blob starting at
72     *     <code>start</code> and ending at <code>end - 1</code>.
73     */
74    var slice = function slice(blob, start, end) {
75
76        // Use prefixed implementations if necessary
77        var sliceImplementation = (
78                blob.slice
79             || blob.webkitSlice
80             || blob.mozSlice
81        ).bind(blob);
82
83        var length = end - start;
84
85        // The old Blob.slice() was length-based (not end-based). Try the
86        // length version first, if the two calls are not equivalent.
87        if (length !== end) {
88
89            // If the result of the slice() call matches the expected length,
90            // trust that result. It must be correct.
91            var sliceResult = sliceImplementation(start, length);
92            if (sliceResult.size === length)
93                return sliceResult;
94
95        }
96
97        // Otherwise, use the most-recent standard: end-based slice()
98        return sliceImplementation(start, end);
99
100    };
101
102    /**
103     * Sends the contents of the given blob over the underlying stream.
104     *
105     * @param {Blob} blob
106     *     The blob to send.
107     */
108    this.sendBlob = function sendBlob(blob) {
109
110        var offset = 0;
111        var reader = new FileReader();
112
113        /**
114         * Reads the next chunk of the blob provided to
115         * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The chunk itself
116         * is read asynchronously, and will not be available until
117         * reader.onload fires.
118         *
119         * @private
120         */
121        var readNextChunk = function readNextChunk() {
122
123            // If no further chunks remain, inform of completion and stop
124            if (offset >= blob.size) {
125
126                // Fire completion event for completed blob
127                if (guacWriter.oncomplete)
128                    guacWriter.oncomplete(blob);
129
130                // No further chunks to read
131                return;
132
133            }
134
135            // Obtain reference to next chunk as a new blob
136            var chunk = slice(blob, offset, offset + arrayBufferWriter.blobLength);
137            offset += arrayBufferWriter.blobLength;
138
139            // Attempt to read the blob contents represented by the blob into
140            // a new array buffer
141            reader.readAsArrayBuffer(chunk);
142
143        };
144
145        // Send each chunk over the stream, continue reading the next chunk
146        reader.onload = function chunkLoadComplete() {
147
148            // Send the successfully-read chunk
149            arrayBufferWriter.sendData(reader.result);
150
151            // Continue sending more chunks after the latest chunk is
152            // acknowledged
153            arrayBufferWriter.onack = function sendMoreChunks(status) {
154
155                if (guacWriter.onack)
156                    guacWriter.onack(status);
157
158                // Abort transfer if an error occurs
159                if (status.isError())
160                    return;
161
162                // Inform of blob upload progress via progress events
163                if (guacWriter.onprogress)
164                    guacWriter.onprogress(blob, offset - arrayBufferWriter.blobLength);
165
166                // Queue the next chunk for reading
167                readNextChunk();
168
169            };
170
171        };
172
173        // If an error prevents further reading, inform of error and stop
174        reader.onerror = function chunkLoadFailed() {
175
176            // Fire error event, including the context of the error
177            if (guacWriter.onerror)
178                guacWriter.onerror(blob, offset, reader.error);
179
180        };
181
182        // Begin reading the first chunk
183        readNextChunk();
184
185    };
186
187    /**
188     * Signals that no further text will be sent, effectively closing the
189     * stream.
190     */
191    this.sendEnd = function sendEnd() {
192        arrayBufferWriter.sendEnd();
193    };
194
195    /**
196     * Fired for received data, if acknowledged by the server.
197     *
198     * @event
199     * @param {Guacamole.Status} status
200     *     The status of the operation.
201     */
202    this.onack = null;
203
204    /**
205     * Fired when an error occurs reading a blob passed to
206     * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The transfer for the
207     * the given blob will cease, but the stream will remain open.
208     *
209     * @event
210     * @param {Blob} blob
211     *     The blob that was being read when the error occurred.
212     *
213     * @param {Number} offset
214     *     The offset of the failed read attempt within the blob, in bytes.
215     *
216     * @param {DOMError} error
217     *     The error that occurred.
218     */
219    this.onerror = null;
220
221    /**
222     * Fired for each successfully-read chunk of data as a blob is being sent
223     * via [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}.
224     *
225     * @event
226     * @param {Blob} blob
227     *     The blob that is being read.
228     *
229     * @param {Number} offset
230     *     The offset of the read that just succeeded.
231     */
232    this.onprogress = null;
233
234    /**
235     * Fired when a blob passed to
236     * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob} has finished being
237     * sent.
238     *
239     * @event
240     * @param {Blob} blob
241     *     The blob that was sent.
242     */
243    this.oncomplete = null;
244
245};
Note: See TracBrowser for help on using the repository browser.