mirror of
https://github.com/zeek/zeek.git
synced 2025-10-01 22:28:20 +00:00
168 lines
5.1 KiB
C++
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
|