const whiteSpaces = [" ", "\n", "\t"]; class StringSource{ constructor(str){ this.line = 1; this.cols = 0; this.buffer = str; //a boundary pointer to indicate where from the buffer dat should be read // data before this pointer can be deleted to free the memory this.startIndex = 0; } readCh() { return this.buffer[this.startIndex++]; } readChAt(index) { return this.buffer[this.startIndex+index]; } readStr(n,from){ if(typeof from === "undefined") from = this.startIndex; return this.buffer.substring(from, from + n); } readUpto(stopStr) { const inputLength = this.buffer.length; const stopLength = stopStr.length; for (let i = this.startIndex; i < inputLength; i++) { let match = true; for (let j = 0; j < stopLength; j++) { if (this.buffer[i + j] !== stopStr[j]) { match = false; break; } } if (match) { const result = this.buffer.substring(this.startIndex, i); this.startIndex = i + stopLength; return result; } } throw new Error(`Unexpected end of source. Reading '${stopStr}'`); } readUptoCloseTag(stopStr) { //stopStr: "'){ match = 2; //tag boundary found // this.startIndex } }else{ match = 1; for (let j = 0; j < stopLength; j++) { if (this.buffer[i + j] !== stopStr[j]) { match = 0; break; } } } if (match === 2) {//matched closing part const result = this.buffer.substring(this.startIndex, stopIndex - 1 ); this.startIndex = i + 1; return result; } } throw new Error(`Unexpected end of source. Reading '${stopStr}'`); } readFromBuffer(n, updateIndex){ let ch; if(n===1){ ch = this.buffer[this.startIndex]; // if(ch === "\n") { // this.line++; // this.cols = 1; // }else{ // this.cols++; // } }else{ ch = this.buffer.substring(this.startIndex, this.startIndex + n); // if("".indexOf("\n") !== -1){ // //TODO: handle the scenario when there are multiple lines // //TODO: col should be set to number of chars after last '\n' // // this.cols = 1; // }else{ // this.cols += n; // } } if(updateIndex) this.updateBufferBoundary(n); return ch; } //TODO: rename to updateBufferReadIndex updateBufferBoundary(n = 1) { //n: number of characters read this.startIndex += n; } canRead(n){ n = n || this.startIndex; return this.buffer.length - n + 1 > 0; } } module.exports = StringSource;