Commit 9594464d authored by Zack Galbreath's avatar Zack Galbreath Committed by Code Review
Browse files

Merge topic 'DelimitedTextReaderAcceptStringInput' into master

ade77513 ENH: DelimitedTextReader supports string input.
parents b911e889 ade77513
......@@ -4,5 +4,6 @@ vtk_add_test_cxx(NO_VALID
TestNewickTreeWriter.cxx
TestMultiNewickTreeReader.cxx
TestTulipReaderProperties.cxx
TestDelimitedTextReader2.cxx
)
vtk_test_cxx_executable(${vtk-module}CxxTests)
/*=========================================================================
Program: Visualization Toolkit
Module: TestDelimitedTextReader.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include <vtkDelimitedTextReader.h>
#include <vtkTable.h>
#include <vtkTestUtilities.h>
// This test mainly tests the capability of the DelimitedTextReader accepting
// both a file and a text string as the input
int TestDelimitedTextReader2(int argc, char *argv[])
{
//------------ test the reader with an input file-----------------
char* filename = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/authors.csv");
vtkDelimitedTextReader *reader = vtkDelimitedTextReader::New();
reader->SetFileName(filename);
reader->SetHaveHeaders(1);
reader->SetDetectNumericColumns(1);
reader->Update();
vtkTable* table = reader->GetOutput();
table->Dump();
cout << "Printing reader info..." << endl;
reader->Print(cout);
if (table->GetNumberOfRows() != 6)
{
cout << "ERROR: Wrong number of rows: " << table->GetNumberOfRows()<<endl;
return 1;
}
if (table->GetNumberOfColumns() != 6)
{
cout << "ERROR: Wrong number of columns: " << table->GetNumberOfColumns()<<endl;
return 1;
}
reader->Delete();
//------------ test the reader with an input string-----------------
char inputString[] = ",awesomeness,fitness,region\r\nAbby,1,2,china\r\nBob,5,0.2,US\r\nCatie,3,0.3,UK\r\nDavid,2,100,UK\r\nGrace,4,20,US\r\nIlknur,6,5,Turkey\r\n";
vtkDelimitedTextReader *reader2 = vtkDelimitedTextReader::New();
reader2->SetHaveHeaders(1);
reader2->SetReadFromInputString(1);
reader2->SetInputString(inputString);
reader2->SetDetectNumericColumns(1);
reader2->Update();
vtkTable* table2 = reader2->GetOutput();
table2->Dump();
cout << "Printing reader2 info..." << endl;
reader2->Print(cout);
if (table2->GetNumberOfRows() != 6)
{
cout << "ERROR: Wrong number of rows: " << table2->GetNumberOfRows()<<endl;
return 1;
}
if (table2->GetNumberOfColumns() != 4)
{
cout << "ERROR: Wrong number of columns: " << table2->GetNumberOfColumns()<<endl;
return 1;
}
reader2->Delete();
return 0;
}
......@@ -36,6 +36,7 @@
#include "vtkTextCodecFactory.h"
#include <vtksys/ios/sstream>
#include <vtksys/ios/iostream>
#include <algorithm>
#include <iterator>
#include <stdexcept>
......@@ -387,6 +388,9 @@ vtkDelimitedTextReader::vtkDelimitedTextReader() :
this->SetNumberOfInputPorts(0);
this->SetNumberOfOutputPorts(1);
this->ReadFromInputString = 0;
this->InputString = NULL;
this->InputStringLength = 0;
this->MergeConsecutiveDelimiters = false;
this->PedigreeIdArrayName = NULL;
this->SetPedigreeIdArrayName("id");
......@@ -409,6 +413,7 @@ vtkDelimitedTextReader::~vtkDelimitedTextReader()
this->SetPedigreeIdArrayName(0);
this->SetUnicodeCharacterSet(0);
this->SetFileName(0);
this->SetInputString(NULL);
this->SetFieldDelimiterCharacters(0);
}
......@@ -417,6 +422,16 @@ void vtkDelimitedTextReader::PrintSelf(ostream& os, vtkIndent indent)
this->Superclass::PrintSelf(os, indent);
os << indent << "FileName: "
<< (this->FileName ? this->FileName : "(none)") << endl;
os << indent << "ReadFromInputString: "
<< (this->ReadFromInputString ? "On\n" : "Off\n");
if ( this->InputString )
{
os << indent << "Input String: " << this->InputString << "\n";
}
else
{
os << indent << "Input String: (None)\n";
}
os << indent << "UnicodeCharacterSet: "
<< (this->UnicodeCharacterSet ? this->UnicodeCharacterSet : "(none)") << endl;
os << indent << "MaxRecords: " << this->MaxRecords
......@@ -456,6 +471,48 @@ void vtkDelimitedTextReader::PrintSelf(ostream& os, vtkIndent indent)
<< (this->OutputPedigreeIds? "true" : "false") << endl;
}
void vtkDelimitedTextReader::SetInputString(const char *in)
{
int len = 0;
if (in != NULL)
{
len = static_cast<int>(strlen(in));
}
this->SetInputString(in, len);
}
void vtkDelimitedTextReader::SetInputString(const char *in, int len)
{
if (this->InputString && in && strncmp(in, this->InputString, len) == 0)
{
return;
}
if (this->InputString)
{
delete [] this->InputString;
}
if (in && len>0)
{
// Add a NULL terminator so that GetInputString
// callers (from wrapped languages) get a valid
// C string in *ALL* cases...
//
this->InputString = new char[len+1];
memcpy(this->InputString,in,len);
this->InputString[len] = 0;
this->InputStringLength = len;
}
else
{
this->InputString = NULL;
this->InputStringLength = 0;
}
this->Modified();
}
void vtkDelimitedTextReader::SetUnicodeRecordDelimiters(const vtkUnicodeString& delimiters)
{
this->UnicodeRecordDelimiters = delimiters;
......@@ -546,26 +603,34 @@ int vtkDelimitedTextReader::RequestData(
return 1;
}
// If the filename hasn't been specified, we're done ...
if(!this->FileName)
{
return 1;
}
if (!this->PedigreeIdArrayName)
throw std::runtime_error("You must specify a pedigree id array name");
// Get the total size of the input file in bytes
ifstream file_stream(this->FileName, ios::binary);
if(!file_stream.good())
istream* input_stream_pt = NULL;
ifstream file_stream;
std::istringstream string_stream;
if(!this->ReadFromInputString)
{
throw std::runtime_error(
"Unable to open input file " + std::string(this->FileName));
}
// Get the total size of the input file in bytes
file_stream.open(this->FileName, ios::binary);
if(!file_stream.good())
{
throw std::runtime_error(
"Unable to open input file " + std::string(this->FileName));
}
file_stream.seekg(0, ios::end);
//const vtkIdType total_bytes = file_stream.tellg();
file_stream.seekg(0, ios::beg);
file_stream.seekg(0, ios::end);
//const vtkIdType total_bytes = file_stream.tellg();
file_stream.seekg(0, ios::beg);
input_stream_pt = dynamic_cast<istream*>(&file_stream);
}
else
{
string_stream.str(this->InputString);
input_stream_pt = dynamic_cast<istream*>(&string_stream);
}
vtkStdString character_set;
vtkTextCodec* transCodec = NULL;
......@@ -588,7 +653,7 @@ int vtkDelimitedTextReader::RequestData(
this->UnicodeStringDelimiters =
vtkUnicodeString::from_utf8(tstring);
this->UnicodeOutputArrays = false;
transCodec = vtkTextCodecFactory::CodecToHandle(file_stream);
transCodec = vtkTextCodecFactory::CodecToHandle(*input_stream_pt);
}
if (NULL == transCodec)
......@@ -612,7 +677,7 @@ int vtkDelimitedTextReader::RequestData(
vtkTextCodec::OutputIterator& outIter = iterator;
transCodec->ToUnicode(file_stream, outIter);
transCodec->ToUnicode(*input_stream_pt, outIter);
iterator.ReachedEndOfInput();
transCodec->Delete();
......
......@@ -79,6 +79,25 @@ public:
vtkGetStringMacro(FileName);
vtkSetStringMacro(FileName);
// Description:
// Specify the InputString for use when reading from a character array.
// Optionally include the length for binary strings. Note that a copy
// of the string is made and stored. If this causes exceedingly large
// memory consumption, consider using InputArray instead.
void SetInputString(const char *in);
vtkGetStringMacro(InputString);
void SetInputString(const char *in, int len);
vtkGetMacro(InputStringLength, int);
void SetInputString(const vtkStdString& input)
{ this->SetInputString(input.c_str(), static_cast<int>(input.length())); }
// Description:
// Enable reading from an InputString or InputArray instead of the default,
// a file.
vtkSetMacro(ReadFromInputString,int);
vtkGetMacro(ReadFromInputString,int);
vtkBooleanMacro(ReadFromInputString,int);
// Description:
// Specifies the character set used in the input file. Valid character set
// names will be drawn from the list maintained by the Internet Assigned Name
......@@ -245,6 +264,9 @@ protected:
vtkInformationVector*);
char* FileName;
int ReadFromInputString;
char *InputString;
int InputStringLength;
char* UnicodeCharacterSet;
vtkIdType MaxRecords;
vtkUnicodeString UnicodeRecordDelimiters;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment