mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-10-01 03:57:43 +03:00
chimera: hybrid of Hyperscan and PCRE
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Intel Corporation
|
||||
* Copyright (c) 2016-2018, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -57,20 +57,22 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
EngineContext::EngineContext(const hs_database_t *db) {
|
||||
EngineHSContext::EngineHSContext(const hs_database_t *db) {
|
||||
hs_alloc_scratch(db, &scratch);
|
||||
assert(scratch);
|
||||
}
|
||||
|
||||
EngineContext::~EngineContext() {
|
||||
EngineHSContext::~EngineHSContext() {
|
||||
hs_free_scratch(scratch);
|
||||
}
|
||||
|
||||
EngineHSStream::~EngineHSStream() { }
|
||||
|
||||
namespace /* anonymous */ {
|
||||
|
||||
/** Scan context structure passed to the onMatch callback function. */
|
||||
struct ScanContext {
|
||||
ScanContext(unsigned id_in, ResultEntry &result_in,
|
||||
struct ScanHSContext {
|
||||
ScanHSContext(unsigned id_in, ResultEntry &result_in,
|
||||
const EngineStream *stream_in)
|
||||
: id(id_in), result(result_in), stream(stream_in) {}
|
||||
unsigned id;
|
||||
@@ -87,7 +89,7 @@ struct ScanContext {
|
||||
static
|
||||
int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
|
||||
void *ctx) {
|
||||
ScanContext *sc = static_cast<ScanContext *>(ctx);
|
||||
ScanHSContext *sc = static_cast<ScanHSContext *>(ctx);
|
||||
assert(sc);
|
||||
sc->result.matches++;
|
||||
|
||||
@@ -101,7 +103,7 @@ int onMatch(unsigned int, unsigned long long, unsigned long long, unsigned int,
|
||||
static
|
||||
int onMatchEcho(unsigned int id, unsigned long long, unsigned long long to,
|
||||
unsigned int, void *ctx) {
|
||||
ScanContext *sc = static_cast<ScanContext *>(ctx);
|
||||
ScanHSContext *sc = static_cast<ScanHSContext *>(ctx);
|
||||
assert(sc);
|
||||
sc->result.matches++;
|
||||
|
||||
@@ -114,7 +116,7 @@ int onMatchEcho(unsigned int id, unsigned long long, unsigned long long to,
|
||||
return 0;
|
||||
}
|
||||
|
||||
EngineHyperscan::EngineHyperscan(hs_database_t *db_in, CompileStats cs)
|
||||
EngineHyperscan::EngineHyperscan(hs_database_t *db_in, CompileHSStats cs)
|
||||
: db(db_in), compile_stats(std::move(cs)) {
|
||||
assert(db);
|
||||
}
|
||||
@@ -124,14 +126,15 @@ EngineHyperscan::~EngineHyperscan() {
|
||||
}
|
||||
|
||||
unique_ptr<EngineContext> EngineHyperscan::makeContext() const {
|
||||
return ue2::make_unique<EngineContext>(db);
|
||||
return ue2::make_unique<EngineHSContext>(db);
|
||||
}
|
||||
|
||||
void EngineHyperscan::scan(const char *data, unsigned int len, unsigned int id,
|
||||
ResultEntry &result, EngineContext &ctx) const {
|
||||
ResultEntry &result, EngineContext &ectx) const {
|
||||
assert(data);
|
||||
|
||||
ScanContext sc(id, result, nullptr);
|
||||
EngineHSContext &ctx = static_cast<EngineHSContext &>(ectx);
|
||||
ScanHSContext sc(id, result, nullptr);
|
||||
auto callback = echo_matches ? onMatchEcho : onMatch;
|
||||
hs_error_t rv = hs_scan(db, data, len, 0, ctx.scratch, callback, &sc);
|
||||
|
||||
@@ -144,11 +147,12 @@ void EngineHyperscan::scan(const char *data, unsigned int len, unsigned int id,
|
||||
void EngineHyperscan::scan_vectored(const char *const *data,
|
||||
const unsigned int *len, unsigned int count,
|
||||
unsigned streamId, ResultEntry &result,
|
||||
EngineContext &ctx) const {
|
||||
EngineContext &ectx) const {
|
||||
assert(data);
|
||||
assert(len);
|
||||
|
||||
ScanContext sc(streamId, result, nullptr);
|
||||
EngineHSContext &ctx = static_cast<EngineHSContext &>(ectx);
|
||||
ScanHSContext sc(streamId, result, nullptr);
|
||||
auto callback = echo_matches ? onMatchEcho : onMatch;
|
||||
hs_error_t rv =
|
||||
hs_scan_vector(db, data, len, count, 0, ctx.scratch, callback, &sc);
|
||||
@@ -159,9 +163,10 @@ void EngineHyperscan::scan_vectored(const char *const *data,
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<EngineStream> EngineHyperscan::streamOpen(EngineContext &ctx,
|
||||
unique_ptr<EngineStream> EngineHyperscan::streamOpen(EngineContext &ectx,
|
||||
unsigned streamId) const {
|
||||
auto stream = ue2::make_unique<EngineStream>();
|
||||
EngineHSContext &ctx = static_cast<EngineHSContext &>(ectx);
|
||||
auto stream = ue2::make_unique<EngineHSStream>();
|
||||
stream->ctx = &ctx;
|
||||
|
||||
hs_open_stream(db, 0, &stream->id);
|
||||
@@ -170,17 +175,18 @@ unique_ptr<EngineStream> EngineHyperscan::streamOpen(EngineContext &ctx,
|
||||
return nullptr;
|
||||
}
|
||||
stream->sn = streamId;
|
||||
return stream;
|
||||
return move(stream);
|
||||
}
|
||||
|
||||
void EngineHyperscan::streamClose(unique_ptr<EngineStream> stream,
|
||||
ResultEntry &result) const {
|
||||
assert(stream);
|
||||
|
||||
auto &s = static_cast<EngineStream &>(*stream);
|
||||
EngineContext &ctx = *s.ctx;
|
||||
auto &s = static_cast<EngineHSStream &>(*stream);
|
||||
EngineContext &ectx = *s.ctx;
|
||||
EngineHSContext &ctx = static_cast<EngineHSContext &>(ectx);
|
||||
|
||||
ScanContext sc(0, result, &s);
|
||||
ScanHSContext sc(0, result, &s);
|
||||
auto callback = echo_matches ? onMatchEcho : onMatch;
|
||||
|
||||
assert(s.id);
|
||||
@@ -193,10 +199,10 @@ void EngineHyperscan::streamScan(EngineStream &stream, const char *data,
|
||||
ResultEntry &result) const {
|
||||
assert(data);
|
||||
|
||||
auto &s = static_cast<EngineStream &>(stream);
|
||||
EngineContext &ctx = *s.ctx;
|
||||
auto &s = static_cast<EngineHSStream &>(stream);
|
||||
EngineHSContext &ctx = *s.ctx;
|
||||
|
||||
ScanContext sc(id, result, &s);
|
||||
ScanHSContext sc(id, result, &s);
|
||||
auto callback = echo_matches ? onMatchEcho : onMatch;
|
||||
hs_error_t rv =
|
||||
hs_scan_stream(s.id, data, len, 0, ctx.scratch, callback, &sc);
|
||||
@@ -210,11 +216,12 @@ void EngineHyperscan::streamScan(EngineStream &stream, const char *data,
|
||||
void EngineHyperscan::streamCompressExpand(EngineStream &stream,
|
||||
vector<char> &temp) const {
|
||||
size_t used = 0;
|
||||
hs_error_t err = hs_compress_stream(stream.id, temp.data(), temp.size(),
|
||||
auto &s = static_cast<EngineHSStream &>(stream);
|
||||
hs_error_t err = hs_compress_stream(s.id, temp.data(), temp.size(),
|
||||
&used);
|
||||
if (err == HS_INSUFFICIENT_SPACE) {
|
||||
temp.resize(used);
|
||||
err = hs_compress_stream(stream.id, temp.data(), temp.size(), &used);
|
||||
err = hs_compress_stream(s.id, temp.data(), temp.size(), &used);
|
||||
}
|
||||
|
||||
if (err != HS_SUCCESS) {
|
||||
@@ -223,10 +230,10 @@ void EngineHyperscan::streamCompressExpand(EngineStream &stream,
|
||||
}
|
||||
|
||||
if (printCompressSize) {
|
||||
printf("stream %u: compressed to %zu\n", stream.sn, used);
|
||||
printf("stream %u: compressed to %zu\n", s.sn, used);
|
||||
}
|
||||
|
||||
err = hs_reset_and_expand_stream(stream.id, temp.data(), temp.size(),
|
||||
err = hs_reset_and_expand_stream(s.id, temp.data(), temp.size(),
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
if (err != HS_SUCCESS) {
|
||||
@@ -469,7 +476,7 @@ buildEngineHyperscan(const ExpressionMap &expressions, ScanMode scan_mode,
|
||||
hs_free_scratch(scratch);
|
||||
|
||||
// Collect summary information.
|
||||
CompileStats cs;
|
||||
CompileHSStats cs;
|
||||
cs.sigs_name = sigs_name;
|
||||
if (!sigs_name.empty()) {
|
||||
const auto pos = name.find_last_of('/');
|
||||
|
Reference in New Issue
Block a user