Browse Source

Bug fixes related to pause/resume and preview (fixes #92)

pull/100/head
Matthew Holt 11 years ago
parent
commit
13fb8fc05f
  1. 115
      papaparse.js

115
papaparse.js

@ -394,11 +394,23 @@ @@ -394,11 +394,23 @@
var start = 0, fileSize = 0;
var aggregate = "";
var partialLine = "";
var xhr, nextChunk;
var xhr, url, nextChunk, finishedWithEntireFile;
var handle = new ParserHandle(copy(config));
handle.streamer = this;
this.stream = function(url)
this.resume = function()
{
nextChunk();
};
this.finished = function()
{
return finishedWithEntireFile;
};
this.stream = function(u)
{
url = u;
if (IS_WORKER)
{
nextChunk = function()
@ -416,10 +428,16 @@ @@ -416,10 +428,16 @@
}
nextChunk(); // Starts streaming
};
function readChunk()
{
if (finishedWithEntireFile)
{
chunkLoaded();
return;
}
xhr = new XMLHttpRequest();
if (!IS_WORKER)
{
@ -456,7 +474,7 @@ @@ -456,7 +474,7 @@
aggregate += partialLine + xhr.responseText;
partialLine = "";
var finishedWithEntireFile = !config.step || start > getFileSize(xhr);
finishedWithEntireFile = !config.step || start > getFileSize(xhr);
if (!finishedWithEntireFile)
{
@ -492,6 +510,7 @@ @@ -492,6 +510,7 @@
}
else if (isFunction(config.chunk))
{
console.log("CHUNKED");
config.chunk(results);
results = undefined;
}
@ -519,7 +538,6 @@ @@ -519,7 +538,6 @@
var contentRange = xhr.getResponseHeader("Content-Range");
return parseInt(contentRange.substr(contentRange.lastIndexOf("/") + 1));
}
};
}
@ -537,18 +555,22 @@ @@ -537,18 +555,22 @@
config.chunkSize = Papa.LocalChunkSize;
var start = 0;
var file;
var slice;
var aggregate = "";
var partialLine = "";
var reader, nextChunk, slice;
var reader, nextChunk, slice, finishedWithEntireFile;
var handle = new ParserHandle(copy(config));
handle.streamer = this;
// FileReader is better than FileReaderSync (even in worker) - see http://stackoverflow.com/q/24708649/1048862
// But Firefox is a pill, too - see issue #76: https://github.com/mholt/PapaParse/issues/76
var usingAsyncReader = typeof FileReader === 'function';
this.stream = function(file)
this.stream = function(f)
{
var slice = file.slice || file.webkitSlice || file.mozSlice;
file = f;
slice = file.slice || file.webkitSlice || file.mozSlice;
if (usingAsyncReader)
{
@ -560,10 +582,21 @@ @@ -560,10 +582,21 @@
reader = new FileReaderSync(); // Hack for running in a web worker in Firefox
nextChunk(); // Starts streaming
};
this.finished = function()
{
return finishedWithEntireFile;
};
this.resume = function()
{
nextChunk();
};
function nextChunk()
{
if (start < file.size)
if (!finishedWithEntireFile)
readChunk();
}
@ -584,7 +617,7 @@ @@ -584,7 +617,7 @@
aggregate += partialLine + event.target.result;
partialLine = "";
var finishedWithEntireFile = start >= file.size;
finishedWithEntireFile = start >= file.size;
if (!finishedWithEntireFile)
{
@ -624,7 +657,7 @@ @@ -624,7 +657,7 @@
results = undefined;
}
if (!finishedWithEntireFile && !results.meta.paused)
if (!results || !results.meta.paused)
nextChunk();
}
@ -642,7 +675,7 @@ @@ -642,7 +675,7 @@
});
}
}
};
}
@ -656,6 +689,7 @@ @@ -656,6 +689,7 @@
var FLOAT = /^\s*-?(\d*\.?\d+|\d+\.?\d*)(e[-+]?\d+)?\s*$/i;
var self = this;
var _stepCounter = 0; // Number of times step was called (number of rows parsed)
var _input; // The input being parsed
var _parser; // The core parser being used
var _paused = false; // Whether we are paused or not
@ -666,10 +700,29 @@ @@ -666,10 +700,29 @@
errors: [],
meta: {}
};
_config = copy(_config);
if (isFunction(_config.step))
{
var userStep = _config.step;
_config.step = function(results)
{
_results = results;
if (needsHeaderRow())
processResults();
else // only call user's step function after header row
{
_stepCounter += results.data.length;
if (_config.preview && _stepCounter > _config.preview)
_parser.abort();
else
userStep(processResults(), self);
}
};
}
this.parse = function(input)
{
//_stepCounter = 0;
_delimiterError = false;
if (!_config.delimiter)
{
@ -684,29 +737,17 @@ @@ -684,29 +737,17 @@
_results.meta.delimiter = _config.delimiter;
}
if (isFunction(_config.step))
{
var userStep = _config.step;
_config.step = function(results)
{
_results = results;
if (needsHeaderRow())
processResults();
else
userStep(processResults(), self);
};
}
var parserConfig = copy(_config);
if (_config.preview && _config.header)
_config.preview++; // to compensate for header row
parserConfig.preview++; // to compensate for header row
_input = input;
_parser = new Parser(_config);
_parser = new Parser(parserConfig);
_results = _parser.parse(_input);
processResults();
if (isFunction(_config.complete) && !_paused)
_config.complete(_results);
return _paused ? { meta: { paused: true } } : _results;
if (isFunction(_config.complete) && !_paused && (!self.streamer || self.streamer.finished()))
_config.complete(_results); // TODO: In some cases, when chunk is specified, this executes before the chunk function...
return _paused ? { meta: { paused: true } } : (_results || { meta: { paused: false } });
};
this.pause = function()
@ -721,8 +762,13 @@ @@ -721,8 +762,13 @@
_paused = false;
_parser = new Parser(_config);
_parser.parse(_input);
if (isFunction(_config.complete) && !_paused)
if (!_paused)
{
if (self.streamer && !self.streamer.finished())
self.streamer.resume(); // more of the file yet to come
else if (isFunction(_config.complete))
_config.complete(_results);
}
};
this.abort = function()
@ -731,7 +777,7 @@ @@ -731,7 +777,7 @@
if (isFunction(_config.complete))
_config.complete(_results);
_input = "";
}
};
function processResults()
{
@ -743,7 +789,6 @@ @@ -743,7 +789,6 @@
if (needsHeaderRow())
fillHeaderFields();
return applyHeaderAndDynamicTyping();
}
@ -770,6 +815,7 @@ @@ -770,6 +815,7 @@
for (var i = 0; i < _results.data.length; i++)
{
var row = {};
for (var j = 0; j < _results.data[i].length; j++)
{
if (_config.dynamicTyping)
@ -808,7 +854,6 @@ @@ -808,7 +854,6 @@
if (_config.header && _results.meta)
_results.meta.fields = _fields;
return _results;
}

Loading…
Cancel
Save