mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
functions for indexing slices and strings
This commit is contained in:
parent
8f2637decb
commit
b792feccab
2 changed files with 63 additions and 48 deletions
107
src/Expr.cc
107
src/Expr.cc
|
@ -2936,24 +2936,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
if ( lv->Length() == 1 )
|
if ( lv->Length() == 1 )
|
||||||
v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned());
|
v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned());
|
||||||
else
|
else
|
||||||
{
|
return index_slice(vect, lv);
|
||||||
size_t len = vect->Size();
|
|
||||||
auto result = make_intrusive<VectorVal>(vect->GetType<VectorType>());
|
|
||||||
|
|
||||||
bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len);
|
|
||||||
bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len);
|
|
||||||
bro_int_t sub_length = last - first;
|
|
||||||
|
|
||||||
if ( sub_length >= 0 )
|
|
||||||
{
|
|
||||||
result->Resize(sub_length);
|
|
||||||
|
|
||||||
for ( bro_int_t idx = first; idx < last; idx++ )
|
|
||||||
result->Assign(idx - first, vect->ValAt(idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2962,36 +2945,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
{
|
return index_string(v1->AsString(), v2->AsListVal());
|
||||||
const ListVal* lv = v2->AsListVal();
|
|
||||||
const String* s = v1->AsString();
|
|
||||||
int len = s->Len();
|
|
||||||
String* substring = nullptr;
|
|
||||||
|
|
||||||
if ( lv->Length() == 1 )
|
|
||||||
{
|
|
||||||
bro_int_t idx = lv->Idx(0)->AsInt();
|
|
||||||
|
|
||||||
if ( idx < 0 )
|
|
||||||
idx += len;
|
|
||||||
|
|
||||||
// Out-of-range index will return null pointer.
|
|
||||||
substring = s->GetSubstring(idx, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bro_int_t first = get_slice_index(lv->Idx(0)->AsInt(), len);
|
|
||||||
bro_int_t last = get_slice_index(lv->Idx(1)->AsInt(), len);
|
|
||||||
bro_int_t substring_len = last - first;
|
|
||||||
|
|
||||||
if ( substring_len < 0 )
|
|
||||||
substring = nullptr;
|
|
||||||
else
|
|
||||||
substring = s->GetSubstring(first, substring_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return make_intrusive<StringVal>(substring ? substring : new String(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RuntimeError("type cannot be indexed");
|
RuntimeError("type cannot be indexed");
|
||||||
|
@ -3005,6 +2959,63 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringValPtr index_string(const String* s, const ListVal* lv)
|
||||||
|
{
|
||||||
|
int len = s->Len();
|
||||||
|
String* substring = nullptr;
|
||||||
|
|
||||||
|
if ( lv->Length() == 1 )
|
||||||
|
{
|
||||||
|
bro_int_t idx = lv->Idx(0)->AsInt();
|
||||||
|
|
||||||
|
if ( idx < 0 )
|
||||||
|
idx += len;
|
||||||
|
|
||||||
|
// Out-of-range index will return null pointer.
|
||||||
|
substring = s->GetSubstring(idx, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bro_int_t first = get_slice_index(lv->Idx(0)->AsInt(), len);
|
||||||
|
bro_int_t last = get_slice_index(lv->Idx(1)->AsInt(), len);
|
||||||
|
bro_int_t substring_len = last - first;
|
||||||
|
|
||||||
|
if ( substring_len < 0 )
|
||||||
|
substring = nullptr;
|
||||||
|
else
|
||||||
|
substring = s->GetSubstring(first, substring_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_intrusive<StringVal>(substring ? substring : new String(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorValPtr index_slice(VectorVal* vect, const ListVal* lv)
|
||||||
|
{
|
||||||
|
auto first = lv->Idx(0)->CoerceToInt();
|
||||||
|
auto last = lv->Idx(1)->CoerceToInt();
|
||||||
|
return index_slice(vect, first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorValPtr index_slice(VectorVal* vect, int _first, int _last)
|
||||||
|
{
|
||||||
|
size_t len = vect->Size();
|
||||||
|
auto result = make_intrusive<VectorVal>(vect->GetType<VectorType>());
|
||||||
|
|
||||||
|
bro_int_t first = get_slice_index(_first, len);
|
||||||
|
bro_int_t last = get_slice_index(_last, len);
|
||||||
|
bro_int_t sub_length = last - first;
|
||||||
|
|
||||||
|
if ( sub_length >= 0 )
|
||||||
|
{
|
||||||
|
result->Resize(sub_length);
|
||||||
|
|
||||||
|
for ( bro_int_t idx = first; idx < last; idx++ )
|
||||||
|
result->Assign(idx - first, vect->ValAt(idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void IndexExpr::Assign(Frame* f, ValPtr v)
|
void IndexExpr::Assign(Frame* f, ValPtr v)
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
|
|
|
@ -941,6 +941,10 @@ protected:
|
||||||
bool is_slice;
|
bool is_slice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern VectorValPtr index_slice(VectorVal* vect, const ListVal* lv);
|
||||||
|
extern VectorValPtr index_slice(VectorVal* vect, int first, int last);
|
||||||
|
extern StringValPtr index_string(const String* s, const ListVal* lv);
|
||||||
|
|
||||||
class IndexExprWhen final : public IndexExpr {
|
class IndexExprWhen final : public IndexExpr {
|
||||||
public:
|
public:
|
||||||
static inline std::vector<ValPtr> results = {};
|
static inline std::vector<ValPtr> results = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue