mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 13:08:20 +00:00
Ascii reader error changes - fix small bugs
The changes are now a bit more succinct with less code changes required. Behavior is tested a little bit more thoroughly and a memory problem when reading incomplete lines was fixed. ReadHeader also always directly returns if header reading failed. Error messages now are back to what they were before the change, if the new behavior is not used. I also tweaked the documentation text a bit.
This commit is contained in:
parent
5078159080
commit
b6e6302b40
11 changed files with 187 additions and 60 deletions
|
@ -61,7 +61,7 @@ void Ascii::DoClose()
|
|||
|
||||
bool Ascii::DoInit(const ReaderInfo& info, int num_fields, const Field* const* fields)
|
||||
{
|
||||
is_failed = false;
|
||||
suppress_warnings = false;
|
||||
|
||||
separator.assign( (const char*) BifConst::InputAscii::separator->Bytes(),
|
||||
BifConst::InputAscii::separator->Len());
|
||||
|
@ -109,43 +109,48 @@ bool Ascii::DoInit(const ReaderInfo& info, int num_fields, const Field* const* f
|
|||
formatter::Ascii::SeparatorInfo sep_info(separator, set_separator, unset_field, empty_field);
|
||||
formatter = unique_ptr<threading::formatter::Formatter>(new formatter::Ascii(this, sep_info));
|
||||
|
||||
DoUpdate();
|
||||
|
||||
return true;
|
||||
return DoUpdate();
|
||||
}
|
||||
|
||||
void Ascii::FailWarn(bool is_error, const char *msg)
|
||||
void Ascii::FailWarn(bool is_error, const char *msg, bool suppress_future)
|
||||
{
|
||||
if ( is_error )
|
||||
Error(msg);
|
||||
else
|
||||
Warning(msg);
|
||||
{
|
||||
// suppress error message when we are already in error mode.
|
||||
// There is no reason to repeat it every second.
|
||||
if ( ! suppress_warnings )
|
||||
Warning(msg);
|
||||
|
||||
if ( suppress_future )
|
||||
suppress_warnings = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ascii::OpenFile()
|
||||
{
|
||||
if ( file.is_open() && ! is_failed )
|
||||
if ( file.is_open() )
|
||||
return true;
|
||||
|
||||
file.open(Info().source);
|
||||
|
||||
if ( ! file.is_open() )
|
||||
{
|
||||
if ( ! is_failed )
|
||||
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s", Info().source));
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem;
|
||||
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s", Info().source), true);
|
||||
|
||||
return ! fail_on_file_problem;
|
||||
}
|
||||
|
||||
if ( ReadHeader(false) == false )
|
||||
{
|
||||
if ( ! is_failed )
|
||||
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s; headers are incorrect", Info().source));
|
||||
FailWarn(fail_on_file_problem, Fmt("Init: cannot open %s; problem reading file header", Info().source), true);
|
||||
|
||||
file.close();
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem;
|
||||
return ! fail_on_file_problem;
|
||||
}
|
||||
|
||||
is_failed = false;
|
||||
suppress_warnings = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -158,7 +163,11 @@ bool Ascii::ReadHeader(bool useCached)
|
|||
if ( ! useCached )
|
||||
{
|
||||
if ( ! GetLine(line) )
|
||||
{
|
||||
FailWarn(fail_on_file_problem, Fmt("Could not read input data file %s; first line could not be read",
|
||||
Info().source), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
headerline = line;
|
||||
}
|
||||
|
@ -198,12 +207,10 @@ bool Ascii::ReadHeader(bool useCached)
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( ! is_failed )
|
||||
FailWarn(fail_on_file_problem, Fmt("Did not find requested field %s in input data file %s.",
|
||||
field->name, Info().source));
|
||||
FailWarn(fail_on_file_problem, Fmt("Did not find requested field %s in input data file %s.",
|
||||
field->name, Info().source), true);
|
||||
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem;
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldMapping f(field->name, field->type, field->subtype, ifields[field->name]);
|
||||
|
@ -213,12 +220,10 @@ bool Ascii::ReadHeader(bool useCached)
|
|||
map<string, uint32_t>::iterator fit2 = ifields.find(field->secondary_name);
|
||||
if ( fit2 == ifields.end() )
|
||||
{
|
||||
if ( ! is_failed )
|
||||
FailWarn(fail_on_file_problem, Fmt("Could not find requested port type field %s in input data file.",
|
||||
field->secondary_name));
|
||||
FailWarn(fail_on_file_problem, Fmt("Could not find requested port type field %s in input data file.",
|
||||
field->secondary_name), true);
|
||||
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem;
|
||||
return false;
|
||||
}
|
||||
|
||||
f.secondary_position = ifields[field->secondary_name];
|
||||
|
@ -258,7 +263,7 @@ bool Ascii::GetLine(string& str)
|
|||
bool Ascii::DoUpdate()
|
||||
{
|
||||
if ( ! OpenFile() )
|
||||
return !fail_on_file_problem;
|
||||
return ! fail_on_file_problem;
|
||||
|
||||
switch ( Info().mode ) {
|
||||
case MODE_REREAD:
|
||||
|
@ -267,11 +272,10 @@ bool Ascii::DoUpdate()
|
|||
struct stat sb;
|
||||
if ( stat(Info().source, &sb) == -1 )
|
||||
{
|
||||
if ( ! is_failed )
|
||||
FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", Info().source));
|
||||
FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", Info().source), true);
|
||||
|
||||
file.close();
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem;
|
||||
return ! fail_on_file_problem;
|
||||
}
|
||||
|
||||
if ( sb.st_mtime <= mtime ) // no change
|
||||
|
@ -293,10 +297,9 @@ bool Ascii::DoUpdate()
|
|||
if ( Info().mode == MODE_STREAM )
|
||||
{
|
||||
file.clear(); // remove end of file evil bits
|
||||
if ( !ReadHeader(true) )
|
||||
if ( ! ReadHeader(true) )
|
||||
{
|
||||
is_failed = true;
|
||||
return !fail_on_file_problem; // header reading failed
|
||||
return ! fail_on_file_problem; // header reading failed
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -360,15 +363,15 @@ bool Ascii::DoUpdate()
|
|||
if ( (*fit).position > pos || (*fit).secondary_position > pos )
|
||||
{
|
||||
FailWarn(fail_on_invalid_lines, Fmt("Not enough fields in line %s. Found %d fields, want positions %d and %d",
|
||||
line.c_str(), pos, (*fit).position, (*fit).secondary_position));
|
||||
|
||||
for ( int i = 0; i < fpos; i++ )
|
||||
delete fields[i];
|
||||
|
||||
delete [] fields;
|
||||
line.c_str(), pos, (*fit).position, (*fit).secondary_position));
|
||||
|
||||
if ( fail_on_invalid_lines )
|
||||
{
|
||||
for ( int i = 0; i < fpos; i++ )
|
||||
delete fields[i];
|
||||
|
||||
delete [] fields;
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -432,7 +435,7 @@ bool Ascii::DoUpdate()
|
|||
bool Ascii::DoHeartbeat(double network_time, double current_time)
|
||||
{
|
||||
if ( ! OpenFile() )
|
||||
return !fail_on_file_problem;
|
||||
return ! fail_on_file_problem;
|
||||
|
||||
switch ( Info().mode )
|
||||
{
|
||||
|
|
|
@ -56,8 +56,10 @@ private:
|
|||
bool ReadHeader(bool useCached);
|
||||
bool GetLine(string& str);
|
||||
bool OpenFile();
|
||||
void FailWarn(bool is_error, const char *msg);
|
||||
|
||||
// Call Warning or Error, depending on the is_error boolean.
|
||||
// In case of a warning, setting suppress_future to true will suppress all future warnings
|
||||
// (by setting suppress_warnings to true, until suppress_warnings is set back to false)
|
||||
void FailWarn(bool is_error, const char *msg, bool suppress_future = false);
|
||||
|
||||
ifstream file;
|
||||
time_t mtime;
|
||||
|
@ -77,8 +79,8 @@ private:
|
|||
bool fail_on_file_problem;
|
||||
|
||||
// this is an internal indicator in case the read is currently in a failed state
|
||||
// it's used by the options for continuing instead of failing and killing the reader.
|
||||
bool is_failed;
|
||||
// it's used to suppress duplicate error messages.
|
||||
bool suppress_warnings;
|
||||
|
||||
std::unique_ptr<threading::formatter::Formatter> formatter;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue