zeek/tools/binpac/src/pac_record.h

168 lines
5.1 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#ifndef pac_record_h
#define pac_record_h
#include "pac_common.h"
#include "pac_field.h"
#include "pac_id.h"
#include "pac_type.h"
class RecordType : public Type {
public:
RecordType(RecordFieldList* fields);
~RecordType() override;
bool DefineValueVar() const override;
string DataTypeStr() const override;
void Prepare(Env* env, int flags) override;
void GenPubDecls(Output* out, Env* env) override;
void GenPrivDecls(Output* out, Env* env) override;
void GenInitCode(Output* out, Env* env) override;
void GenCleanUpCode(Output* out, Env* env) override;
int StaticSize(Env* env) const override;
void SetBoundaryChecked() override;
const ID* parsing_dataptr_var() const;
bool IsPointerType() const override {
ASSERT(0);
return false;
}
protected:
void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) override;
void GenDynamicSize(Output* out, Env* env, const DataPtr& data) override;
Type* DoClone() const override { return nullptr; }
void DoMarkIncrementalInput() override;
bool DoTraverse(DataDepVisitor* visitor) override;
bool ByteOrderSensitive() const override;
private:
Field* parsing_dataptr_var_field_;
RecordFieldList* record_fields_;
};
// A data field of a record type. A RecordField corresponds to a
// segment of input data, and therefore RecordField's are ordered---each
// of them has a known previous and next field.
class RecordField : public Field {
public:
RecordField(FieldType tof, ID* id, Type* type);
~RecordField() override;
RecordType* record_type() const { return record_type_; }
void set_record_type(RecordType* ty) { record_type_ = ty; }
virtual void GenParseCode(Output* out, Env* env) = 0;
RecordField* prev() const { return prev_; }
RecordField* next() const { return next_; }
void set_prev(RecordField* f) { prev_ = f; }
void set_next(RecordField* f) { next_ = f; }
int static_offset() const { return static_offset_; }
void set_static_offset(int offset) { static_offset_ = offset; }
int parsing_state_seq() const { return parsing_state_seq_; }
void set_parsing_state_seq(int x) { parsing_state_seq_ = x; }
virtual int StaticSize(Env* env, int offset) const = 0;
const char* FieldSize(Output* out, Env* env);
const char* FieldOffset(Output* out, Env* env);
virtual bool BoundaryChecked() const { return boundary_checked_; }
virtual void SetBoundaryChecked() { boundary_checked_ = true; }
virtual bool RequiresByteOrder() const = 0;
friend class RecordType;
protected:
RecordType* record_type_;
RecordField* prev_;
RecordField* next_;
bool boundary_checked_;
int static_offset_;
int parsing_state_seq_;
DataPtr* begin_of_field_dataptr;
DataPtr* end_of_field_dataptr;
char* field_size_expr;
char* field_offset_expr;
ID* end_of_field_dataptr_var;
const DataPtr& getFieldBegin(Output* out_cc, Env* env);
const DataPtr& getFieldEnd(Output* out_cc, Env* env);
virtual void GenFieldEnd(Output* out, Env* env, const DataPtr& begin) = 0;
bool AttemptBoundaryCheck(Output* out_cc, Env* env);
virtual bool GenBoundaryCheck(Output* out_cc, Env* env) = 0;
};
class RecordDataField : public RecordField, public Evaluatable {
public:
RecordDataField(ID* arg_id, Type* arg_type);
~RecordDataField() override;
// Instantiates abstract class Field
void Prepare(Env* env) override;
void GenParseCode(Output* out, Env* env) override;
// Instantiates abstract class Evaluatable
void GenEval(Output* out, Env* env) override;
int StaticSize(Env* env, int) const override { return type()->StaticSize(env); }
void SetBoundaryChecked() override;
bool RequiresByteOrder() const override { return type()->RequiresByteOrder(); }
bool RequiresAnalyzerContext() const override;
protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin) override;
bool GenBoundaryCheck(Output* out_cc, Env* env) override;
bool DoTraverse(DataDepVisitor* visitor) override;
};
enum PaddingType : uint8_t { PAD_BY_LENGTH, PAD_TO_OFFSET, PAD_TO_NEXT_WORD };
class RecordPaddingField : public RecordField {
public:
RecordPaddingField(ID* id, PaddingType ptype, Expr* expr);
~RecordPaddingField() override;
void Prepare(Env* env) override;
void GenPubDecls(Output* out, Env* env) override { /* nothing */ }
void GenPrivDecls(Output* out, Env* env) override { /* nothing */ }
void GenInitCode(Output* out, Env* env) override { /* nothing */ }
void GenCleanUpCode(Output* out, Env* env) override { /* nothing */ }
void GenParseCode(Output* out, Env* env) override;
int StaticSize(Env* env, int offset) const override;
bool RequiresByteOrder() const override { return false; }
protected:
void GenFieldEnd(Output* out, Env* env, const DataPtr& begin) override;
bool GenBoundaryCheck(Output* out_cc, Env* env) override;
bool DoTraverse(DataDepVisitor* visitor) override;
private:
PaddingType ptype_;
Expr* expr_;
int wordsize_;
};
#endif // pac_record_h