Skip to content

Commit

Permalink
Make reading quoted headers actually work.
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed Jun 12, 2020
1 parent 8155f2b commit 78c6515
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 22 deletions.
12 changes: 8 additions & 4 deletions doc/stages/readers.text.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ in each subsequent line. There are two types of header lines.
Quoted dimension names
----------------------
When the first character of the header is a double quote, each dimension name
is assumed to be surrounded by double quotes. Any text following a quoted
dimension name and the start of the next dimension name is ignored. The
`separator`_ option can't be used with quoted dimension names.
is assumed to be surrounded by double quotes. A single separator character
is expected between the dimension names (spaces are stripped). If no separator
character is found, a space is assumed. You can set the `separator`_ character
if it differs from that in the header. Note that PDAL requires dimension
names that consist only of alphabetic characters and underscores. Edit
the header line or use the `header`_ option to set the dimension names to
ones that PDAL understands.

Unquoted dimension names
------------------------
Expand Down Expand Up @@ -104,7 +108,7 @@ filename

.. include:: reader_opts.rst

header
_`header`
String to use as the file header. All lines in the file are assumed to be
records containing point data unless skipped with the `skip`_ option.
[Default: None]
Expand Down
16 changes: 12 additions & 4 deletions io/TextReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ void TextReader::parseHeader(const std::string& header)

void TextReader::parseQuotedHeader(const std::string& header)
{
if (m_separatorArg->set())
throwError("Separator option not supported with a header line "
"containing quoted dimension names.");

// We know there's a double quote at position 0.
std::string::size_type pos = 1;
while (true)
Expand All @@ -132,6 +128,18 @@ void TextReader::parseQuotedHeader(const std::string& header)

// Skip everything other than a double quote.
count = Utils::extract(header, pos, [](char c){ return c != '"'; });

// Find a separator.
if (!m_separatorArg->set())
{
std::string sep = header.substr(pos, count);
Utils::trim(sep);
if (sep.size() > 1)
throwError("Found separator longer than a single character.");
if (sep.size() == 0)
sep = ' ';
m_separatorArg->setValue(sep);
}
pos += count;
if (header[pos++] != '"')
break;
Expand Down
18 changes: 9 additions & 9 deletions test/data/text/quoted.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"X","Y","Z"
0 1 2
15 1 2
25 1 2
17 18 2
27 14 2
3 17 2
6 22 2
12 25 2
29 22 2
0,1,2
15,1,2
25,1,2
17,18,2
27,14,2
3,17,2
6,22,2
12,25,2
29,22,2
10 changes: 10 additions & 0 deletions test/data/text/quoted2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"X","Y","Z"
0 1 2
15 1 2
25 1 2
17 18 2
27 14 2
3 17 2
6 22 2
12 25 2
29 22 2
24 changes: 19 additions & 5 deletions test/unit/io/TextReaderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,11 @@ TEST(TextReaderTest, insertHeader)

TEST(TextReaderTest, quotedHeader)
{
auto testme = [](Options& options)
auto testme = [](Options& options,
const std::string& filename = "text/quoted.txt")
{
TextReader reader;
options.add("filename", Support::datapath("text/quoted.txt"));
options.add("filename", Support::datapath(filename));
reader.setOptions(options);

PointTable table;
Expand All @@ -315,22 +316,35 @@ TEST(TextReaderTest, quotedHeader)

{
Options opts;
opts.add("header", "\"X\"\"Y\" \"Z\" ");
opts.add("header", "\"X\",\"Y\",\"Z\"");
opts.add("skip", 1);
testme(opts);
}

{
Options opts;
opts.add("header", "\"X\"\"Y\" \" ");
opts.add("header", "\"X\", \"Y\" , \"Z\" ");
opts.add("skip", 1);
testme(opts);
}

{
Options opts;
opts.add("header", "\"X\",\"Y\" \" ");
opts.add("skip", 1);
EXPECT_THROW(testme(opts), pdal_error);
}

{
Options opts;
opts.add("header", " \"X\"\"Y\" \" ");
opts.add("header", " \"X\",,\"Y\",\"Z\"");
opts.add("skip", 1);
EXPECT_THROW(testme(opts), pdal_error);
}

{
Options opts;
opts.add("separator", ' ');
testme(opts, "text/quoted2.txt");
}
}

0 comments on commit 78c6515

Please sign in to comment.