Last active
August 17, 2024 10:43
-
-
Save peteroupc/b79a42fffe07c2a87c28 to your computer and use it in GitHub Desktop.
JavaScript class for reading files line by line in HTML5 apps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Written by Peter O. | |
Any copyright to this work is released to the Public Domain. | |
In case this is not possible, this work is also | |
licensed under Creative Commons Zero (CC0): | |
https://creativecommons.org/publicdomain/zero/1.0/ | |
*/ | |
function LineReader(file){ | |
this.file=file; | |
this.reader=new FileReader(); | |
this.offset=0; | |
this.currentLine=""; | |
this.bufferOffset=0; | |
this.lastBuffer=null; | |
this.callback=null; | |
this.omittedCR=false; | |
this.sawCR=false; | |
this.endCallback=null; | |
this.decodeOptions={"stream":true} | |
this.decoder=new TextDecoder("utf-8",{"ignoreBOM":true}); | |
this.reader.addEventListener("load",this._viewLoaded.bind(this)); | |
this.reader.addEventListener("error",this._error.bind(this)); | |
} | |
LineReader.prototype._error=function(e){ | |
throw e; | |
} | |
LineReader.prototype._readFromView=function(a,offset){ | |
for(var i=offset;i<a.length;i++){ | |
// Treats LF and CRLF as line breaks | |
if(a[i]==0x0A){ | |
// Line feed read | |
var lineEnd=(this.sawCR ? i-1 : i); | |
if(lineEnd>0){ | |
this.currentLine+=this.decoder.decode(a.slice(this.bufferOffset,lineEnd),this.decodeOptions); | |
} | |
if(this.callback)this.callback(this.currentLine) | |
this.decoder.decode(new Uint8Array([])) | |
this.currentLine=""; | |
this.sawCR=false; | |
this.bufferOffset=i+1; | |
this.lastBuffer=a; | |
} else if(a[i]==0x0D){ | |
if(this.omittedCR)this.currentLine+="\r"; | |
this.sawCR=true; | |
} else if(this.sawCR){ | |
if(this.omittedCR)this.currentLine+="\r"; | |
this.sawCR=false; | |
} | |
this.omittedCR=false; | |
} | |
if(this.bufferOffset!=a.length){ | |
// Decode the end of the line if no current line was reached | |
var lineEnd=(this.sawCR ? a.length-1 : a.length); | |
if(lineEnd>0){ | |
this.currentLine+=this.decoder.decode(a.slice(this.bufferOffset,lineEnd),this.decodeOptions); | |
} | |
this.omittedCR=this.sawCR; | |
} | |
} | |
LineReader.prototype._viewLoaded=function(){ | |
var a=new Uint8Array(this.reader.result); | |
if(a.length>0){ | |
this.bufferOffset=0; | |
this._readFromView(a,0); | |
this.offset+=a.length; | |
var s=this.file.slice(this.offset,this.offset+256); | |
this.reader.readAsArrayBuffer(s); | |
} else { | |
if(this.callback && this.currentLine.length>0){ | |
this.callback(this.currentLine); | |
} | |
this.decoder.decode(new Uint8Array([])) | |
this.currentLine=""; | |
this.sawCR=false; | |
if(this.endCallback){ | |
this.endCallback(); | |
} | |
} | |
} | |
LineReader.prototype.readLines=function(callback,endCallback){ | |
this.callback=callback; | |
this.endCallback=endCallback; | |
var s=this.file.slice(this.offset,this.offset+8192); | |
this.reader.readAsArrayBuffer(s); | |
} | |
if(typeof exports!="undefined")exports.LineReader=LineReader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment