mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add ability to grow/shrink a vector using slicing, also adds Insert/Remove methods for VectorVal
This commit is contained in:
parent
23f9fb0ae9
commit
502ad9abc3
5 changed files with 61 additions and 9 deletions
20
src/Expr.cc
20
src/Expr.cc
|
@ -3201,24 +3201,26 @@ void IndexExpr::Assign(Frame* f, Val* v, Opcode op)
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
{
|
{
|
||||||
const ListVal *lv = v2->AsListVal();
|
const ListVal *lv = v2->AsListVal();
|
||||||
|
VectorVal* v1_vect = v1->AsVectorVal();
|
||||||
|
|
||||||
if ( lv->Length() > 1 )
|
if ( lv->Length() > 1 )
|
||||||
{
|
{
|
||||||
int len = v1->AsVectorVal()->Size();
|
int len = v1_vect->Size();
|
||||||
bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len);
|
bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len);
|
||||||
bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len);
|
bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len);
|
||||||
int slice_length = last - first;
|
|
||||||
|
|
||||||
const VectorVal *v_vect = v->AsVectorVal();
|
// Remove the elements from the vector within the slice
|
||||||
if ( slice_length != v_vect->Size())
|
|
||||||
RuntimeError("vector being assigned to slice does not match size of slice");
|
|
||||||
else if ( slice_length >= 0 )
|
|
||||||
{
|
|
||||||
for ( int idx = first; idx < last; idx++ )
|
for ( int idx = first; idx < last; idx++ )
|
||||||
v1->AsVectorVal()->Assign(idx, v_vect->Lookup(idx - first)->Ref(), op);
|
v1_vect->Remove(first);
|
||||||
|
|
||||||
|
// Insert the new elements starting at the first position
|
||||||
|
VectorVal* v_vect = v->AsVectorVal();
|
||||||
|
for ( int idx = 0; idx < v_vect->Size(); idx++, first++ )
|
||||||
|
{
|
||||||
|
v1_vect->Insert(first, v_vect->Lookup(idx)->Ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !v1->AsVectorVal()->Assign(v2, v, op))
|
else if ( !v1_vect->Assign(v2, v, op) )
|
||||||
{
|
{
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
{
|
||||||
|
|
38
src/Val.cc
38
src/Val.cc
|
@ -3407,6 +3407,44 @@ bool VectorVal::AssignRepeat(unsigned int index, unsigned int how_many,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VectorVal::Insert(unsigned int index, Val* element)
|
||||||
|
{
|
||||||
|
if ( element &&
|
||||||
|
! same_type(element->Type(), vector_type->YieldType(), 0) )
|
||||||
|
{
|
||||||
|
Unref(element);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Val*>::iterator it;
|
||||||
|
if ( index < val.vector_val->size() )
|
||||||
|
it = std::next(val.vector_val->begin(), index);
|
||||||
|
else
|
||||||
|
it = val.vector_val->end();
|
||||||
|
|
||||||
|
// Note: we do *not* Ref() the element, if any, at this point.
|
||||||
|
// AssignExpr::Eval() already does this; other callers must remember
|
||||||
|
// to do it similarly.
|
||||||
|
val.vector_val->insert(it, element);
|
||||||
|
|
||||||
|
Modified();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VectorVal::Remove(unsigned int index)
|
||||||
|
{
|
||||||
|
if ( index >= val.vector_val->size() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Val* val_at_index = (*val.vector_val)[index];
|
||||||
|
auto it = std::next(val.vector_val->begin(), index);
|
||||||
|
val.vector_val->erase(it);
|
||||||
|
Unref(val_at_index);
|
||||||
|
|
||||||
|
Modified();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int VectorVal::AddTo(Val* val, int /* is_first_init */) const
|
int VectorVal::AddTo(Val* val, int /* is_first_init */) const
|
||||||
{
|
{
|
||||||
if ( val->Type()->Tag() != TYPE_VECTOR )
|
if ( val->Type()->Tag() != TYPE_VECTOR )
|
||||||
|
|
|
@ -1194,6 +1194,12 @@ public:
|
||||||
// Won't shrink size.
|
// Won't shrink size.
|
||||||
unsigned int ResizeAtLeast(unsigned int new_num_elements);
|
unsigned int ResizeAtLeast(unsigned int new_num_elements);
|
||||||
|
|
||||||
|
// Insert an element at a specific position into the underlying vector.
|
||||||
|
bool Insert(unsigned int index, Val* element);
|
||||||
|
|
||||||
|
// Removes an element or a range of elements from a specific position.
|
||||||
|
bool Remove(unsigned int start_index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Val;
|
friend class Val;
|
||||||
VectorVal() { }
|
VectorVal() { }
|
||||||
|
|
|
@ -65,3 +65,5 @@ slicing (PASS)
|
||||||
slicing (PASS)
|
slicing (PASS)
|
||||||
slicing assignment (PASS)
|
slicing assignment (PASS)
|
||||||
slicing assignment (PASS)
|
slicing assignment (PASS)
|
||||||
|
slicing assignment grow (PASS)
|
||||||
|
slicing assignment shrink (PASS)
|
||||||
|
|
|
@ -179,4 +179,8 @@ event zeek_init()
|
||||||
test_case( "slicing assignment", all_set(v17 == vector(6, 2, 3, 4, 5)) );
|
test_case( "slicing assignment", all_set(v17 == vector(6, 2, 3, 4, 5)) );
|
||||||
v17[2:4] = vector(7, 8);
|
v17[2:4] = vector(7, 8);
|
||||||
test_case( "slicing assignment", all_set(v17 == vector(6, 2, 7, 8, 5)) );
|
test_case( "slicing assignment", all_set(v17 == vector(6, 2, 7, 8, 5)) );
|
||||||
|
v17[2:4] = vector(9, 10, 11);
|
||||||
|
test_case( "slicing assignment grow", all_set(v17 == vector(6, 2, 9, 10, 11, 5)) );
|
||||||
|
v17[2:5] = vector(9);
|
||||||
|
test_case( "slicing assignment shrink", all_set(v17 == vector(6, 2, 9, 5)) );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue