Expose getLocationLineAndColumn() as a public API

This commit is contained in:
Kyle Edwards 2021-04-08 15:23:23 -04:00
parent 94cda30dbd
commit c76c144b09
3 changed files with 53 additions and 18 deletions

View File

@ -392,6 +392,12 @@ bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root,
*/
JSON_API IStream& operator>>(IStream&, Value&);
/** Get the line and column of a character within a string.
*/
void JSON_API getLocationLineAndColumn(char const* beginDoc, char const* endDoc,
ptrdiff_t location, int& line,
int& column);
} // namespace Json
#pragma pack(pop)

View File

@ -761,24 +761,9 @@ Reader::Char Reader::getNextChar() {
void Reader::getLocationLineAndColumn(Location location, int& line,
int& column) const {
Location current = begin_;
Location lastLineStart = current;
line = 0;
while (current < location && current != end_) {
Char c = *current++;
if (c == '\r') {
if (*current == '\n')
++current;
lastLineStart = current;
++line;
} else if (c == '\n') {
lastLineStart = current;
++line;
}
}
// column & line start at 1
column = int(location - lastLineStart) + 1;
++line;
Json::getLocationLineAndColumn(document_.data(),
document_.data() + document_.length(),
location - document_.data(), line, column);
}
String Reader::getLocationLineAndColumn(Location location) const {
@ -1990,4 +1975,26 @@ IStream& operator>>(IStream& sin, Value& root) {
return sin;
}
void getLocationLineAndColumn(char const* beginDoc, char const* endDoc,
ptrdiff_t location, int& line, int& column) {
char const* current = beginDoc;
char const* lastLineStart = current;
line = 0;
while (current < beginDoc + location && current < endDoc) {
char c = *current++;
if (c == '\r') {
if (*current == '\n')
++current;
lastLineStart = current;
++line;
} else if (c == '\n') {
lastLineStart = current;
++line;
}
}
// column & line start at 1
column = int(beginDoc + location - lastLineStart) + 1;
++line;
}
} // namespace Json

View File

@ -3903,6 +3903,28 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) {
example.size()));
}
struct GetLocationLineAndColumnTest : JsonTest::TestCase {
void testLineAndColumn(const std::string& doc, ptrdiff_t location, int row,
int column) {
int actualRow;
int actualColumn;
Json::getLocationLineAndColumn(doc.data(), doc.data() + doc.length(),
location, actualRow, actualColumn);
JSONTEST_ASSERT_EQUAL(row, actualRow);
JSONTEST_ASSERT_EQUAL(column, actualColumn);
}
};
JSONTEST_FIXTURE_LOCAL(GetLocationLineAndColumnTest, test) {
const std::string example = "line 1\nline 2\r\nline 3\rline 4";
testLineAndColumn(example, 0, 1, 1);
testLineAndColumn(example, 6, 1, 7);
testLineAndColumn(example, 8, 2, 2);
testLineAndColumn(example, 14, 3, 0);
testLineAndColumn(example, 15, 3, 1);
testLineAndColumn(example, 25, 4, 4);
}
int main(int argc, const char* argv[]) {
JsonTest::Runner runner;