move Value and Field from the logging namespace to the threading namespace, because other modules using threading will need them.

This commit is contained in:
Bernhard Amann 2012-02-03 14:12:29 -08:00
parent 70fe7876a1
commit a0487ecb30
15 changed files with 512 additions and 472 deletions

View file

@ -0,0 +1,319 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "SerializationTypes.h"
#include "../RemoteSerializer.h"
using namespace threading;
bool Field::Read(SerializationFormat* fmt)
{
int t;
int st;
bool success = (fmt->Read(&name, "name") && fmt->Read(&t, "type") && fmt->Read(&st, "subtype") );
type = (TypeTag) t;
subtype = (TypeTag) st;
return success;
}
bool Field::Write(SerializationFormat* fmt) const
{
return (fmt->Write(name, "name") && fmt->Write((int)type, "type") && fmt->Write((int)subtype, "subtype"));
}
Value::~Value()
{
if ( (type == TYPE_ENUM || type == TYPE_STRING || type == TYPE_FILE || type == TYPE_FUNC)
&& present )
delete val.string_val;
if ( type == TYPE_TABLE && present )
{
for ( int i = 0; i < val.set_val.size; i++ )
delete val.set_val.vals[i];
delete [] val.set_val.vals;
}
if ( type == TYPE_VECTOR && present )
{
for ( int i = 0; i < val.vector_val.size; i++ )
delete val.vector_val.vals[i];
delete [] val.vector_val.vals;
}
}
bool Value::IsCompatibleType(BroType* t, bool atomic_only)
{
if ( ! t )
return false;
switch ( t->Tag() ) {
case TYPE_BOOL:
case TYPE_INT:
case TYPE_COUNT:
case TYPE_COUNTER:
case TYPE_PORT:
case TYPE_SUBNET:
case TYPE_ADDR:
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
case TYPE_ENUM:
case TYPE_STRING:
case TYPE_FILE:
case TYPE_FUNC:
return true;
case TYPE_RECORD:
return ! atomic_only;
case TYPE_TABLE:
{
if ( atomic_only )
return false;
if ( ! t->IsSet() )
return false;
return IsCompatibleType(t->AsSetType()->Indices()->PureType(), true);
}
case TYPE_VECTOR:
{
if ( atomic_only )
return false;
return IsCompatibleType(t->AsVectorType()->YieldType(), true);
}
default:
return false;
}
return false;
}
bool Value::Read(SerializationFormat* fmt)
{
int ty;
if ( ! (fmt->Read(&ty, "type") && fmt->Read(&present, "present")) )
return false;
type = (TypeTag)(ty);
if ( ! present )
return true;
switch ( type ) {
case TYPE_BOOL:
case TYPE_INT:
return fmt->Read(&val.int_val, "int");
case TYPE_COUNT:
case TYPE_COUNTER:
case TYPE_PORT:
return fmt->Read(&val.uint_val, "uint");
case TYPE_SUBNET:
{
uint32 net[4];
if ( ! (fmt->Read(&net[0], "net0") &&
fmt->Read(&net[1], "net1") &&
fmt->Read(&net[2], "net2") &&
fmt->Read(&net[3], "net3") &&
fmt->Read(&val.subnet_val.width, "width")) )
return false;
#ifdef BROv6
val.subnet_val.net[0] = net[0];
val.subnet_val.net[1] = net[1];
val.subnet_val.net[2] = net[2];
val.subnet_val.net[3] = net[3];
#else
val.subnet_val.net = net[0];
#endif
return true;
}
case TYPE_ADDR:
{
uint32 addr[4];
if ( ! (fmt->Read(&addr[0], "addr0") &&
fmt->Read(&addr[1], "addr1") &&
fmt->Read(&addr[2], "addr2") &&
fmt->Read(&addr[3], "addr3")) )
return false;
val.addr_val[0] = addr[0];
#ifdef BROv6
val.addr_val[1] = addr[1];
val.addr_val[2] = addr[2];
val.addr_val[3] = addr[3];
#endif
return true;
}
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
return fmt->Read(&val.double_val, "double");
case TYPE_ENUM:
case TYPE_STRING:
case TYPE_FILE:
case TYPE_FUNC:
{
val.string_val = new string;
return fmt->Read(val.string_val, "string");
}
case TYPE_TABLE:
{
if ( ! fmt->Read(&val.set_val.size, "set_size") )
return false;
val.set_val.vals = new Value* [val.set_val.size];
for ( int i = 0; i < val.set_val.size; ++i )
{
val.set_val.vals[i] = new Value;
if ( ! val.set_val.vals[i]->Read(fmt) )
return false;
}
return true;
}
case TYPE_VECTOR:
{
if ( ! fmt->Read(&val.vector_val.size, "vector_size") )
return false;
val.vector_val.vals = new Value* [val.vector_val.size];
for ( int i = 0; i < val.vector_val.size; ++i )
{
val.vector_val.vals[i] = new Value;
if ( ! val.vector_val.vals[i]->Read(fmt) )
return false;
}
return true;
}
default:
reporter->InternalError("unsupported type %s in Value::Write", type_name(type));
}
return false;
}
bool Value::Write(SerializationFormat* fmt) const
{
if ( ! (fmt->Write((int)type, "type") &&
fmt->Write(present, "present")) )
return false;
if ( ! present )
return true;
switch ( type ) {
case TYPE_BOOL:
case TYPE_INT:
return fmt->Write(val.int_val, "int");
case TYPE_COUNT:
case TYPE_COUNTER:
case TYPE_PORT:
return fmt->Write(val.uint_val, "uint");
case TYPE_SUBNET:
{
uint32 net[4];
#ifdef BROv6
net[0] = val.subnet_val.net[0];
net[1] = val.subnet_val.net[1];
net[2] = val.subnet_val.net[2];
net[3] = val.subnet_val.net[3];
#else
net[0] = val.subnet_val.net;
net[1] = net[2] = net[3] = 0;
#endif
return fmt->Write(net[0], "net0") &&
fmt->Write(net[1], "net1") &&
fmt->Write(net[2], "net2") &&
fmt->Write(net[3], "net3") &&
fmt->Write(val.subnet_val.width, "width");
}
case TYPE_ADDR:
{
uint32 addr[4];
addr[0] = val.addr_val[0];
#ifdef BROv6
addr[1] = val.addr_val[1];
addr[2] = val.addr_val[2];
addr[3] = val.addr_val[3];
#else
addr[1] = addr[2] = addr[3] = 0;
#endif
return fmt->Write(addr[0], "addr0") &&
fmt->Write(addr[1], "addr1") &&
fmt->Write(addr[2], "addr2") &&
fmt->Write(addr[3], "addr3");
}
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
return fmt->Write(val.double_val, "double");
case TYPE_ENUM:
case TYPE_STRING:
case TYPE_FILE:
case TYPE_FUNC:
return fmt->Write(*val.string_val, "string");
case TYPE_TABLE:
{
if ( ! fmt->Write(val.set_val.size, "set_size") )
return false;
for ( int i = 0; i < val.set_val.size; ++i )
{
if ( ! val.set_val.vals[i]->Write(fmt) )
return false;
}
return true;
}
case TYPE_VECTOR:
{
if ( ! fmt->Write(val.vector_val.size, "vector_size") )
return false;
for ( int i = 0; i < val.vector_val.size; ++i )
{
if ( ! val.vector_val.vals[i]->Write(fmt) )
return false;
}
return true;
}
default:
reporter->InternalError("unsupported type %s in Value::REad", type_name(type));
}
return false;
}

View file

@ -0,0 +1,126 @@
#ifndef THREADING_SERIALIZATIONTYPES_H
#define THREADING_SERIALIZATIONTZPES_H
#include "../RemoteSerializer.h"
using namespace std;
namespace threading {
/**
* Definition of a log file, i.e., one column of a log stream.
*/
struct Field {
string name; //! Name of the field.
TypeTag type; //! Type of the field.
TypeTag subtype; //! Inner type for sets.
/**
* Constructor.
*/
Field() { subtype = TYPE_VOID; }
/**
* Copy constructor.
*/
Field(const Field& other)
: name(other.name), type(other.type), subtype(other.subtype) { }
/**
* Unserializes a field.
*
* @param fmt The serialization format to use. The format handles
* low-level I/O.
*
* @return False if an error occured.
*/
bool Read(SerializationFormat* fmt);
/**
* Serializes a field.
*
* @param fmt The serialization format to use. The format handles
* low-level I/O.
*
* @return False if an error occured.
*/
bool Write(SerializationFormat* fmt) const;
};
/**
* Definition of a log value, i.e., a entry logged by a stream.
*
* This struct essentialy represents a serialization of a Val instance (for
* those Vals supported).
*/
struct Value {
TypeTag type; //! The type of the value.
bool present; //! False for optional record fields that are not set.
struct set_t { bro_int_t size; Value** vals; };
typedef set_t vec_t;
/**
* This union is a subset of BroValUnion, including only the types we
* can log directly. See IsCompatibleType().
*/
union _val {
bro_int_t int_val;
bro_uint_t uint_val;
uint32 addr_val[NUM_ADDR_WORDS];
subnet_type subnet_val;
double double_val;
string* string_val;
set_t set_val;
vec_t vector_val;
} val;
/**
* Constructor.
*
* arg_type: The type of the value.
*
* arg_present: False if the value represents an optional record field
* that is not set.
*/
Value(TypeTag arg_type = TYPE_ERROR, bool arg_present = true)
: type(arg_type), present(arg_present) {}
/**
* Destructor.
*/
~Value();
/**
* Unserializes a value.
*
* @param fmt The serialization format to use. The format handles low-level I/O.
*
* @return False if an error occured.
*/
bool Read(SerializationFormat* fmt);
/**
* Serializes a value.
*
* @param fmt The serialization format to use. The format handles
* low-level I/O.
*
* @return False if an error occured.
*/
bool Write(SerializationFormat* fmt) const;
/**
* Returns true if the type can be represented by a Value. If
* `atomic_only` is true, will not permit composite types.
*/
static bool IsCompatibleType(BroType* t, bool atomic_only=false);
private:
Value(const Value& other) { } // Disabled.
};
}
#endif /* THREADING_SERIALIZATIONTZPES_H */