|
|
@ -30,7 +30,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
this.numChunksLoaded = 0; |
|
|
|
this.numChunksLoaded = 0; |
|
|
|
this.numChunks = Math.ceil(length / chunkSize); |
|
|
|
this.numChunks = Math.ceil(length / chunkSize); |
|
|
|
this.manager = manager; |
|
|
|
this.manager = manager; |
|
|
|
this.initialDataLength = 0; |
|
|
|
this.progressiveDataLength = 0; |
|
|
|
this.lastSuccessfulEnsureByteChunk = -1; // a single-entry cache
|
|
|
|
this.lastSuccessfulEnsureByteChunk = -1; // a single-entry cache
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -41,7 +41,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
getMissingChunks: function ChunkedStream_getMissingChunks() { |
|
|
|
getMissingChunks: function ChunkedStream_getMissingChunks() { |
|
|
|
var chunks = []; |
|
|
|
var chunks = []; |
|
|
|
for (var chunk = 0, n = this.numChunks; chunk < n; ++chunk) { |
|
|
|
for (var chunk = 0, n = this.numChunks; chunk < n; ++chunk) { |
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
chunks.push(chunk); |
|
|
|
chunks.push(chunk); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -73,22 +73,30 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
var curChunk; |
|
|
|
var curChunk; |
|
|
|
|
|
|
|
|
|
|
|
for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) { |
|
|
|
for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) { |
|
|
|
if (!(curChunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[curChunk]) { |
|
|
|
this.loadedChunks[curChunk] = true; |
|
|
|
this.loadedChunks[curChunk] = true; |
|
|
|
++this.numChunksLoaded; |
|
|
|
++this.numChunksLoaded; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
onReceiveInitialData: function ChunkedStream_onReceiveInitialData(data) { |
|
|
|
onReceiveProgressiveData: |
|
|
|
this.bytes.set(data); |
|
|
|
function ChunkedStream_onReceiveProgressiveData(data) { |
|
|
|
this.initialDataLength = data.length; |
|
|
|
var position = this.progressiveDataLength; |
|
|
|
var endChunk = (this.end === data.length ? |
|
|
|
var beginChunk = Math.floor(position / this.chunkSize); |
|
|
|
this.numChunks : Math.floor(data.length / this.chunkSize)); |
|
|
|
|
|
|
|
for (var i = 0; i < endChunk; i++) { |
|
|
|
this.bytes.set(new Uint8Array(data), position); |
|
|
|
this.loadedChunks[i] = true; |
|
|
|
position += data.byteLength; |
|
|
|
|
|
|
|
this.progressiveDataLength = position; |
|
|
|
|
|
|
|
var endChunk = position >= this.end ? this.numChunks : |
|
|
|
|
|
|
|
Math.floor(position / this.chunkSize); |
|
|
|
|
|
|
|
var curChunk; |
|
|
|
|
|
|
|
for (curChunk = beginChunk; curChunk < endChunk; ++curChunk) { |
|
|
|
|
|
|
|
if (!this.loadedChunks[curChunk]) { |
|
|
|
|
|
|
|
this.loadedChunks[curChunk] = true; |
|
|
|
++this.numChunksLoaded; |
|
|
|
++this.numChunksLoaded; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
ensureByte: function ChunkedStream_ensureByte(pos) { |
|
|
|
ensureByte: function ChunkedStream_ensureByte(pos) { |
|
|
@ -97,7 +105,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
throw new MissingDataException(pos, pos + 1); |
|
|
|
throw new MissingDataException(pos, pos + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
this.lastSuccessfulEnsureByteChunk = chunk; |
|
|
|
this.lastSuccessfulEnsureByteChunk = chunk; |
|
|
@ -108,7 +116,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (end <= this.initialDataLength) { |
|
|
|
if (end <= this.progressiveDataLength) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -116,7 +124,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
var beginChunk = Math.floor(begin / chunkSize); |
|
|
|
var beginChunk = Math.floor(begin / chunkSize); |
|
|
|
var endChunk = Math.floor((end - 1) / chunkSize) + 1; |
|
|
|
var endChunk = Math.floor((end - 1) / chunkSize) + 1; |
|
|
|
for (var chunk = beginChunk; chunk < endChunk; ++chunk) { |
|
|
|
for (var chunk = beginChunk; chunk < endChunk; ++chunk) { |
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
throw new MissingDataException(begin, end); |
|
|
|
throw new MissingDataException(begin, end); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -125,13 +133,13 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
nextEmptyChunk: function ChunkedStream_nextEmptyChunk(beginChunk) { |
|
|
|
nextEmptyChunk: function ChunkedStream_nextEmptyChunk(beginChunk) { |
|
|
|
var chunk, n; |
|
|
|
var chunk, n; |
|
|
|
for (chunk = beginChunk, n = this.numChunks; chunk < n; ++chunk) { |
|
|
|
for (chunk = beginChunk, n = this.numChunks; chunk < n; ++chunk) { |
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
return chunk; |
|
|
|
return chunk; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// Wrap around to beginning
|
|
|
|
// Wrap around to beginning
|
|
|
|
for (chunk = 0; chunk < beginChunk; ++chunk) { |
|
|
|
for (chunk = 0; chunk < beginChunk; ++chunk) { |
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
return chunk; |
|
|
|
return chunk; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -139,7 +147,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
hasChunk: function ChunkedStream_hasChunk(chunk) { |
|
|
|
hasChunk: function ChunkedStream_hasChunk(chunk) { |
|
|
|
return chunk in this.loadedChunks; |
|
|
|
return !!this.loadedChunks[chunk]; |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
get length() { |
|
|
|
get length() { |
|
|
@ -238,7 +246,7 @@ var ChunkedStream = (function ChunkedStreamClosure() { |
|
|
|
var endChunk = Math.floor((this.end - 1) / chunkSize) + 1; |
|
|
|
var endChunk = Math.floor((this.end - 1) / chunkSize) + 1; |
|
|
|
var missingChunks = []; |
|
|
|
var missingChunks = []; |
|
|
|
for (var chunk = beginChunk; chunk < endChunk; ++chunk) { |
|
|
|
for (var chunk = beginChunk; chunk < endChunk; ++chunk) { |
|
|
|
if (!(chunk in this.loadedChunks)) { |
|
|
|
if (!this.loadedChunks[chunk]) { |
|
|
|
missingChunks.push(chunk); |
|
|
|
missingChunks.push(chunk); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -300,28 +308,16 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { |
|
|
|
this.chunksNeededByRequest = {}; |
|
|
|
this.chunksNeededByRequest = {}; |
|
|
|
this.requestsByChunk = {}; |
|
|
|
this.requestsByChunk = {}; |
|
|
|
this.callbacksByRequest = {}; |
|
|
|
this.callbacksByRequest = {}; |
|
|
|
|
|
|
|
this.progressiveDataLength = 0; |
|
|
|
|
|
|
|
|
|
|
|
this._loadedStreamCapability = createPromiseCapability(); |
|
|
|
this._loadedStreamCapability = createPromiseCapability(); |
|
|
|
|
|
|
|
|
|
|
|
if (args.initialData) { |
|
|
|
if (args.initialData) { |
|
|
|
this.setInitialData(args.initialData); |
|
|
|
this.onReceiveData({chunk: args.initialData}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ChunkedStreamManager.prototype = { |
|
|
|
ChunkedStreamManager.prototype = { |
|
|
|
|
|
|
|
|
|
|
|
setInitialData: function ChunkedStreamManager_setInitialData(data) { |
|
|
|
|
|
|
|
this.stream.onReceiveInitialData(data); |
|
|
|
|
|
|
|
if (this.stream.allChunksLoaded()) { |
|
|
|
|
|
|
|
this._loadedStreamCapability.resolve(this.stream); |
|
|
|
|
|
|
|
} else if (this.msgHandler) { |
|
|
|
|
|
|
|
this.msgHandler.send('DocProgress', { |
|
|
|
|
|
|
|
loaded: data.length, |
|
|
|
|
|
|
|
total: this.length |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onLoadedStream: function ChunkedStreamManager_getLoadedStream() { |
|
|
|
onLoadedStream: function ChunkedStreamManager_getLoadedStream() { |
|
|
|
return this._loadedStreamCapability.promise; |
|
|
|
return this._loadedStreamCapability.promise; |
|
|
|
}, |
|
|
|
}, |
|
|
@ -459,13 +455,21 @@ var ChunkedStreamManager = (function ChunkedStreamManagerClosure() { |
|
|
|
|
|
|
|
|
|
|
|
onReceiveData: function ChunkedStreamManager_onReceiveData(args) { |
|
|
|
onReceiveData: function ChunkedStreamManager_onReceiveData(args) { |
|
|
|
var chunk = args.chunk; |
|
|
|
var chunk = args.chunk; |
|
|
|
var begin = args.begin; |
|
|
|
var isProgressive = args.begin === undefined; |
|
|
|
|
|
|
|
var begin = isProgressive ? this.progressiveDataLength : args.begin; |
|
|
|
var end = begin + chunk.byteLength; |
|
|
|
var end = begin + chunk.byteLength; |
|
|
|
|
|
|
|
|
|
|
|
var beginChunk = this.getBeginChunk(begin); |
|
|
|
var beginChunk = Math.floor(begin / this.chunkSize); |
|
|
|
var endChunk = this.getEndChunk(end); |
|
|
|
var endChunk = end < this.length ? Math.floor(end / this.chunkSize) : |
|
|
|
|
|
|
|
Math.ceil(end / this.chunkSize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isProgressive) { |
|
|
|
|
|
|
|
this.stream.onReceiveProgressiveData(chunk); |
|
|
|
|
|
|
|
this.progressiveDataLength = end; |
|
|
|
|
|
|
|
} else { |
|
|
|
this.stream.onReceiveData(begin, chunk); |
|
|
|
this.stream.onReceiveData(begin, chunk); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.stream.allChunksLoaded()) { |
|
|
|
if (this.stream.allChunksLoaded()) { |
|
|
|
this._loadedStreamCapability.resolve(this.stream); |
|
|
|
this._loadedStreamCapability.resolve(this.stream); |
|
|
|
} |
|
|
|
} |
|
|
|