You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.9 KiB
JavaScript

6 years ago
var COMMENT_START_MARK = '/*';
function QuoteScanner(data) {
this.data = data;
}
var findQuoteEnd = function (data, matched, cursor, oldCursor) {
var commentEndMark = '*/';
var escapeMark = '\\';
var blockEndMark = '}';
var dataPrefix = data.substring(oldCursor, cursor);
var commentEndedAt = dataPrefix.lastIndexOf(commentEndMark, cursor);
var commentStartedAt = findLastCommentStartedAt(dataPrefix, cursor);
var commentStarted = false;
if (commentEndedAt >= cursor && commentStartedAt > -1)
commentStarted = true;
if (commentStartedAt < cursor && commentStartedAt > commentEndedAt)
commentStarted = true;
if (commentStarted) {
var commentEndsAt = data.indexOf(commentEndMark, cursor);
if (commentEndsAt > -1)
return commentEndsAt;
commentEndsAt = data.indexOf(blockEndMark, cursor);
return commentEndsAt > -1 ? commentEndsAt - 1 : data.length;
}
while (true) {
if (data[cursor] === undefined)
break;
if (data[cursor] == matched && (data[cursor - 1] != escapeMark || data[cursor - 2] == escapeMark))
break;
cursor++;
}
return cursor;
};
function findLastCommentStartedAt(data, cursor) {
var position = cursor;
while (position > -1) {
position = data.lastIndexOf(COMMENT_START_MARK, position);
if (position > -1 && data[position - 1] != '*') {
break;
} else {
position--;
}
}
return position;
}
function findNext(data, mark, startAt) {
var escapeMark = '\\';
var candidate = startAt;
while (true) {
candidate = data.indexOf(mark, candidate + 1);
if (candidate == -1)
return -1;
if (data[candidate - 1] != escapeMark)
return candidate;
}
}
QuoteScanner.prototype.each = function (callback) {
var data = this.data;
var tempData = [];
var nextStart = 0;
var nextEnd = 0;
var cursor = 0;
var matchedMark = null;
var singleMark = '\'';
var doubleMark = '"';
var dataLength = data.length;
for (; nextEnd < data.length;) {
var nextStartSingle = findNext(data, singleMark, nextEnd);
var nextStartDouble = findNext(data, doubleMark, nextEnd);
if (nextStartSingle == -1)
nextStartSingle = dataLength;
if (nextStartDouble == -1)
nextStartDouble = dataLength;
if (nextStartSingle < nextStartDouble) {
nextStart = nextStartSingle;
matchedMark = singleMark;
} else {
nextStart = nextStartDouble;
matchedMark = doubleMark;
}
if (nextStart == -1)
break;
nextEnd = findQuoteEnd(data, matchedMark, nextStart + 1, cursor);
if (nextEnd == -1)
break;
var text = data.substring(nextStart, nextEnd + 1);
tempData.push(data.substring(cursor, nextStart));
if (text.length > 0)
callback(text, tempData, nextStart);
cursor = nextEnd + 1;
}
return tempData.length > 0 ?
tempData.join('') + data.substring(cursor, data.length) :
data;
};
module.exports = QuoteScanner;