mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
many helper functions
This commit is contained in:
parent
3654060246
commit
d7a3b85fcd
6 changed files with 245 additions and 31 deletions
|
@ -100,31 +100,62 @@ InputReader* InputMgr::CreateReader(EnumVal* reader, RecordVal* description)
|
|||
|
||||
void InputMgr::Error(InputReader* reader, const char* msg)
|
||||
{
|
||||
reporter->Error(fmt("error with input reader for %s: %s",
|
||||
reader->Source().c_str(), msg));
|
||||
reporter->Error("error with input reader for %s: %s", reader->Source().c_str(), msg);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
void InputMgr::SendEvent(string name) {
|
||||
//EventHandler* handler = event_registry->Lookup(eventName.c_str());
|
||||
|
||||
//if ( handler == 0 ) {
|
||||
// reporter->Error("Event %s not found", eventName.c_str());
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//val_list* vl = new val_list;
|
||||
//vl->append(new Val(12, TYPE_COUNT));
|
||||
|
||||
//mgr.Dispatch(new Event(handler, vl));
|
||||
void InputMgr::SendEvent(const string& name, const int num_vals, const LogVal* const *vals)
|
||||
{
|
||||
EventHandler* handler = event_registry->Lookup(name.c_str());
|
||||
if ( handler == 0 ) {
|
||||
reporter->Error("Event %s not found", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
val_list* vl = new val_list;
|
||||
for ( int i = 0; i < num_vals; i++) {
|
||||
vl->append(LogValToVal(vals[i]));
|
||||
}
|
||||
|
||||
mgr.Dispatch(new Event(handler, vl));
|
||||
}
|
||||
|
||||
*/
|
||||
Val* InputMgr::LogValToVal(const LogVal* val) {
|
||||
switch ( val->type ) {
|
||||
case TYPE_BOOL:
|
||||
case TYPE_INT:
|
||||
return new Val(val->val.int_val, val->type);
|
||||
break;
|
||||
|
||||
case TYPE_COUNT:
|
||||
case TYPE_COUNTER:
|
||||
return new Val(val->val.uint_val, val->type);
|
||||
break;
|
||||
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
return new Val(val->val.double_val, val->type);
|
||||
break;
|
||||
|
||||
case TYPE_STRING:
|
||||
{
|
||||
BroString *s = new BroString(*(val->val.string_val));
|
||||
return new StringVal(s);
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_PORT:
|
||||
return new PortVal(val->val.uint_val);
|
||||
break;
|
||||
|
||||
default:
|
||||
reporter->InternalError("unsupported type for input_read");
|
||||
}
|
||||
|
||||
|
||||
reporter->InternalError("Impossible error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
class InputReader;
|
||||
|
||||
|
||||
class InputMgr {
|
||||
public:
|
||||
InputMgr();
|
||||
|
@ -29,6 +28,9 @@ protected:
|
|||
private:
|
||||
// required functionality
|
||||
// InputValsToRecord to convert received inputvals back to bro records / tables / whatever
|
||||
Val* LogValToVal(const LogVal* val);
|
||||
|
||||
void SendEvent(const string& name, const int num_vals, const LogVal* const *vals);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -33,3 +33,34 @@ bool InputReader::Init(string arg_source, int arg_num_fields,
|
|||
void InputReader::Finish() {
|
||||
DoFinish();
|
||||
}
|
||||
|
||||
bool InputReader::Update() {
|
||||
return DoUpdate();
|
||||
}
|
||||
|
||||
// stolen from logwriter
|
||||
const char* InputReader::Fmt(const char* format, ...)
|
||||
{
|
||||
if ( ! buf )
|
||||
buf = (char*) malloc(buf_len);
|
||||
|
||||
va_list al;
|
||||
va_start(al, format);
|
||||
int n = safe_vsnprintf(buf, buf_len, format, al);
|
||||
va_end(al);
|
||||
|
||||
if ( (unsigned int) n >= buf_len )
|
||||
{ // Not enough room, grow the buffer.
|
||||
buf_len = n + 32;
|
||||
buf = (char*) realloc(buf, buf_len);
|
||||
|
||||
// Is it portable to restart?
|
||||
va_start(al, format);
|
||||
n = safe_vsnprintf(buf, buf_len, format, al);
|
||||
va_end(al);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,18 +19,26 @@ public:
|
|||
|
||||
void Finish();
|
||||
|
||||
bool Update();
|
||||
|
||||
protected:
|
||||
// Methods that have to be overwritten by the individual readers
|
||||
virtual bool DoInit(string arg_source, int num_fields, const LogField* const * fields) = 0;
|
||||
|
||||
virtual void DoFinish() = 0;
|
||||
|
||||
// update file contents to logmgr
|
||||
virtual bool DoUpdate() = 0;
|
||||
|
||||
// Reports an error to the user.
|
||||
void Error(const char *msg);
|
||||
|
||||
// The following methods return the information as passed to Init().
|
||||
const string Source() const { return source; }
|
||||
|
||||
// A thread-safe version of fmt(). (stolen from logwriter)
|
||||
const char* Fmt(const char* format, ...);
|
||||
|
||||
private:
|
||||
friend class InputMgr;
|
||||
|
||||
|
@ -44,6 +52,10 @@ private:
|
|||
bool disabled;
|
||||
|
||||
bool Disabled() { return disabled; }
|
||||
|
||||
// For implementing Fmt().
|
||||
char* buf;
|
||||
unsigned int buf_len;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "InputReaderAscii.h"
|
||||
#include "DebugLogger.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
FieldMapping::FieldMapping(const string& arg_name, const TypeTag& arg_type, int arg_position)
|
||||
: name(arg_name), type(arg_type)
|
||||
{
|
||||
position = arg_position;
|
||||
}
|
||||
|
||||
FieldMapping::FieldMapping(const FieldMapping& arg)
|
||||
: name(arg.name), type(arg.type)
|
||||
{
|
||||
position = arg.position;
|
||||
}
|
||||
|
||||
InputReaderAscii::InputReaderAscii()
|
||||
{
|
||||
//DBG_LOG(DBG_LOGGING, "input reader initialized");
|
||||
|
@ -18,31 +31,134 @@ void InputReaderAscii::DoFinish()
|
|||
{
|
||||
}
|
||||
|
||||
bool InputReaderAscii::DoInit(string path, int num_fields,
|
||||
const LogField* const * fields)
|
||||
bool InputReaderAscii::DoInit(string path, int num_fields, const LogField* const * fields)
|
||||
{
|
||||
fname = path;
|
||||
|
||||
file = new ifstream(path.c_str());
|
||||
if ( !file->is_open() ) {
|
||||
Error(Fmt("cannot open %s", path.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to read the header line...
|
||||
string line;
|
||||
if ( !getline(*file, line) )
|
||||
if ( !getline(*file, line) ) {
|
||||
Error("could not read first line");
|
||||
return false;
|
||||
}
|
||||
|
||||
// split on tabs...
|
||||
istringstream ss(line);
|
||||
while ( ss ) {
|
||||
istringstream splitstream(line);
|
||||
unsigned int currTab = 0;
|
||||
int wantFields = 0;
|
||||
while ( splitstream ) {
|
||||
string s;
|
||||
if ( !getline(ss, s, '\t'))
|
||||
if ( !getline(splitstream, s, '\t'))
|
||||
break;
|
||||
|
||||
// current found heading in s... compare if we want it
|
||||
for ( int i = 0; i < num_fields; i++ ) {
|
||||
const LogField* field = fields[i];
|
||||
if ( field->name == s ) {
|
||||
// cool, found field. note position
|
||||
FieldMapping f(field->name, field->type, i);
|
||||
columnMap.push_back(f);
|
||||
wantFields++;
|
||||
break; // done with searching
|
||||
}
|
||||
}
|
||||
|
||||
// look if we did push something...
|
||||
if ( columnMap.size() == currTab ) {
|
||||
// no, we didn't. note that...
|
||||
FieldMapping empty;
|
||||
columnMap.push_back(empty);
|
||||
}
|
||||
|
||||
// done
|
||||
currTab++;
|
||||
}
|
||||
|
||||
if ( wantFields != num_fields ) {
|
||||
// we did not find all fields?
|
||||
// :(
|
||||
Error("wantFields != num_fields");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
this->num_fields = num_fields;
|
||||
|
||||
// well, that seems to have worked...
|
||||
return true;
|
||||
}
|
||||
|
||||
// read the entire file and send appropriate thingies back to InputMgr
|
||||
bool InputReaderAscii::DoUpdate() {
|
||||
// TODO: all the stuff we need for a second reading.
|
||||
// *cough*
|
||||
//
|
||||
|
||||
|
||||
string line;
|
||||
while ( getline(*file, line ) ) {
|
||||
// split on tabs
|
||||
|
||||
istringstream splitstream(line);
|
||||
string s;
|
||||
|
||||
LogVal fields[num_fields];
|
||||
|
||||
unsigned int currTab = 0;
|
||||
unsigned int currField = 0;
|
||||
while ( splitstream ) {
|
||||
if ( !getline(splitstream, s, '\t') )
|
||||
break;
|
||||
|
||||
|
||||
if ( currTab >= columnMap.size() ) {
|
||||
Error("Tabs in heading do not match tabs in data?");
|
||||
//disabled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldMapping currMapping = columnMap[currTab];
|
||||
currTab++;
|
||||
|
||||
if ( currMapping.IsEmpty() ) {
|
||||
// well, that was easy
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( currField >= num_fields ) {
|
||||
Error("internal error - fieldnum greater as possible");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogVal val(currMapping.type, true);
|
||||
|
||||
switch ( currMapping.type ) {
|
||||
case TYPE_STRING:
|
||||
val.val.string_val = new string(s);
|
||||
|
||||
default:
|
||||
Error(Fmt("unsupported field format %d for %s", currMapping.type,
|
||||
currMapping.name.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
currField++;
|
||||
}
|
||||
|
||||
if ( currField != num_fields ) {
|
||||
Error("curr_field != num_fields in DoUpdate");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ok, now we have built our line. send it back to... whomever.
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef INPUTREADERASCII_H
|
||||
#define INPUTREADERASCII_H
|
||||
|
@ -5,6 +6,19 @@
|
|||
#include "InputReader.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Description for input field mapping
|
||||
struct FieldMapping {
|
||||
string name;
|
||||
TypeTag type;
|
||||
int position;
|
||||
|
||||
FieldMapping(const string& arg_name, const TypeTag& arg_type, int arg_position);
|
||||
FieldMapping(const FieldMapping& arg);
|
||||
FieldMapping() { position = -1; }
|
||||
bool IsEmpty() { return position == -1; }
|
||||
};
|
||||
|
||||
|
||||
class InputReaderAscii : public InputReader {
|
||||
|
@ -20,10 +34,18 @@ protected:
|
|||
const LogField* const * fields);
|
||||
virtual void DoFinish();
|
||||
|
||||
virtual bool DoUpdate();
|
||||
|
||||
private:
|
||||
|
||||
ifstream* file;
|
||||
string fname;
|
||||
|
||||
unsigned int num_fields;
|
||||
|
||||
// map columns in the file to columns to send back to the manager
|
||||
vector<FieldMapping> columnMap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue