| 3 | tab: 9 |
| 4 | } |
| 5 | export default class BufferSource{ |
| 6 | constructor(bytesArr){ |
| 7 | this.line = 1; |
| 8 | this.cols = 0; |
| 9 | this.buffer = bytesArr; |
| 10 | this.startIndex = 0; |
| 11 | } |
| 12 | |
| 13 | |
| 14 | |
| 15 | readCh() { |
| 16 | return String.fromCharCode(this.buffer[this.startIndex++]); |
| 17 | } |
| 18 | |
| 19 | readChAt(index) { |
| 20 | return String.fromCharCode(this.buffer[this.startIndex+index]); |
| 21 | } |
| 22 | |
| 23 | readStr(n,from){ |
| 24 | if(typeof from === "undefined") from = this.startIndex; |
| 25 | return this.buffer.slice(from, from + n).toString(); |
| 26 | } |
| 27 | |
| 28 | readUpto(stopStr) { |
| 29 | const inputLength = this.buffer.length; |
| 30 | const stopLength = stopStr.length; |
| 31 | const stopBuffer = Buffer.from(stopStr); |
| 32 | |
| 33 | for (let i = this.startIndex; i < inputLength; i++) { |
| 34 | let match = true; |
| 35 | for (let j = 0; j < stopLength; j++) { |
| 36 | if (this.buffer[i + j] !== stopBuffer[j]) { |
| 37 | match = false; |
| 38 | break; |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | if (match) { |
| 43 | const result = this.buffer.slice(this.startIndex, i).toString(); |
| 44 | this.startIndex = i + stopLength; |
| 45 | return result; |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | throw new Error(`Unexpected end of source. Reading '${stopStr}'`); |
| 50 | } |
| 51 | |
| 52 | readUptoCloseTag(stopStr) { //stopStr: "</tagname" |
| 53 | const inputLength = this.buffer.length; |
| 54 | const stopLength = stopStr.length; |
| 55 | const stopBuffer = Buffer.from(stopStr); |
| 56 | let stopIndex = 0; |
| 57 | //0: non-matching, 1: matching stop string, 2: matching closing |
| 58 | let match = 0; |
| 59 | |
| 60 | for (let i = this.startIndex; i < inputLength; i++) { |
| 61 | if(match === 1){//initial part matched |
| 62 | if(stopIndex === 0) stopIndex = i; |
nothing calls this directly
no outgoing calls
no test coverage detected