mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Switch ListVal to store IntrusivePtrs
* Deprecates ListVal::Index() methods and replaces with ListVal::Idx() * Replaces ListVal::Vals() method with one that returns std::vector<IntrusivePtr<Val>> rather than val_list
This commit is contained in:
parent
b422f68b88
commit
5f57ceb70a
19 changed files with 111 additions and 100 deletions
|
@ -238,7 +238,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
||||||
for ( auto& kv : hashkeys )
|
for ( auto& kv : hashkeys )
|
||||||
{
|
{
|
||||||
auto idx = kv.second;
|
auto idx = kv.second;
|
||||||
Val* key = lv->Index(idx);
|
Val* key = lv->Idx(idx).get();
|
||||||
|
|
||||||
if ( ! (kp1 = SingleValHash(type_check, kp1, key->Type(), key,
|
if ( ! (kp1 = SingleValHash(type_check, kp1, key->Type(), key,
|
||||||
false)) )
|
false)) )
|
||||||
|
@ -292,7 +292,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
||||||
kp1 = reinterpret_cast<char*>(kp+1);
|
kp1 = reinterpret_cast<char*>(kp+1);
|
||||||
for ( int i = 0; i < lv->Length(); ++i )
|
for ( int i = 0; i < lv->Length(); ++i )
|
||||||
{
|
{
|
||||||
Val* v = lv->Index(i);
|
Val* v = lv->Idx(i).get();
|
||||||
if ( ! (kp1 = SingleValHash(type_check, kp1, v->Type(), v,
|
if ( ! (kp1 = SingleValHash(type_check, kp1, v->Type(), v,
|
||||||
false)) )
|
false)) )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -371,14 +371,15 @@ HashKey* CompositeHash::ComputeHash(const Val* v, bool type_check) const
|
||||||
if ( type_check && v->Type()->Tag() != TYPE_LIST )
|
if ( type_check && v->Type()->Tag() != TYPE_LIST )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const val_list* vl = v->AsListVal()->Vals();
|
auto lv = v->AsListVal();
|
||||||
if ( type_check && vl->length() != tl->length() )
|
|
||||||
|
if ( type_check && lv->Length() != tl->length() )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
char* kp = k;
|
char* kp = k;
|
||||||
loop_over_list(*tl, i)
|
loop_over_list(*tl, i)
|
||||||
{
|
{
|
||||||
kp = SingleValHash(type_check, kp, (*tl)[i], (*vl)[i], false);
|
kp = SingleValHash(type_check, kp, (*tl)[i], lv->Idx(i).get(), false);
|
||||||
if ( ! kp )
|
if ( ! kp )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -390,11 +391,12 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) cons
|
||||||
{
|
{
|
||||||
if ( v->Type()->Tag() == TYPE_LIST )
|
if ( v->Type()->Tag() == TYPE_LIST )
|
||||||
{
|
{
|
||||||
const val_list* vl = v->AsListVal()->Vals();
|
auto lv = v->AsListVal();
|
||||||
if ( type_check && vl->length() != 1 )
|
|
||||||
|
if ( type_check && lv->Length() != 1 )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
v = (*vl)[0];
|
v = lv->Idx(0).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( type_check && v->Type()->InternalType() != singleton_tag )
|
if ( type_check && v->Type()->InternalType() != singleton_tag )
|
||||||
|
@ -536,7 +538,7 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
|
||||||
ListVal* lv = tv->ConvertToList();
|
ListVal* lv = tv->ConvertToList();
|
||||||
for ( int i = 0; i < tv->Size(); ++i )
|
for ( int i = 0; i < tv->Size(); ++i )
|
||||||
{
|
{
|
||||||
Val* key = lv->Index(i);
|
Val* key = lv->Idx(i).get();
|
||||||
sz = SingleTypeKeySize(key->Type(), key, type_check, sz, false,
|
sz = SingleTypeKeySize(key->Type(), key, type_check, sz, false,
|
||||||
calc_static_size);
|
calc_static_size);
|
||||||
if ( ! sz )
|
if ( ! sz )
|
||||||
|
@ -594,7 +596,7 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
|
||||||
ListVal* lv = const_cast<ListVal*>(v->AsListVal());
|
ListVal* lv = const_cast<ListVal*>(v->AsListVal());
|
||||||
for ( int i = 0; i < lv->Length(); ++i )
|
for ( int i = 0; i < lv->Length(); ++i )
|
||||||
{
|
{
|
||||||
sz = SingleTypeKeySize(lv->Index(i)->Type(), lv->Index(i),
|
sz = SingleTypeKeySize(lv->Idx(i)->Type(), lv->Idx(i).get(),
|
||||||
type_check, sz, false, calc_static_size);
|
type_check, sz, false, calc_static_size);
|
||||||
if ( ! sz) return 0;
|
if ( ! sz) return 0;
|
||||||
}
|
}
|
||||||
|
@ -631,21 +633,22 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v,
|
||||||
int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_static_size) const
|
int CompositeHash::ComputeKeySize(const Val* v, bool type_check, bool calc_static_size) const
|
||||||
{
|
{
|
||||||
const type_list* tl = type->Types();
|
const type_list* tl = type->Types();
|
||||||
const val_list* vl = nullptr;
|
|
||||||
if ( v )
|
if ( v )
|
||||||
{
|
{
|
||||||
if ( type_check && v->Type()->Tag() != TYPE_LIST )
|
if ( type_check && v->Type()->Tag() != TYPE_LIST )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vl = v->AsListVal()->Vals();
|
auto lv = v->AsListVal();
|
||||||
if ( type_check && vl->length() != tl->length() )
|
|
||||||
|
if ( type_check && lv->Length() != tl->length() )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sz = 0;
|
int sz = 0;
|
||||||
loop_over_list(*tl, i)
|
loop_over_list(*tl, i)
|
||||||
{
|
{
|
||||||
sz = SingleTypeKeySize((*tl)[i], v ? v->AsListVal()->Index(i) : nullptr,
|
sz = SingleTypeKeySize((*tl)[i], v ? v->AsListVal()->Idx(i).get() : nullptr,
|
||||||
type_check, sz, false, calc_static_size);
|
type_check, sz, false, calc_static_size);
|
||||||
if ( ! sz )
|
if ( ! sz )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -888,19 +888,19 @@ IntrusivePtr<ListVal> DNS_Mgr::AddrListDelta(ListVal* al1, ListVal* al2)
|
||||||
|
|
||||||
for ( int i = 0; i < al1->Length(); ++i )
|
for ( int i = 0; i < al1->Length(); ++i )
|
||||||
{
|
{
|
||||||
const IPAddr& al1_i = al1->Index(i)->AsAddr();
|
const IPAddr& al1_i = al1->Idx(i)->AsAddr();
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for ( j = 0; j < al2->Length(); ++j )
|
for ( j = 0; j < al2->Length(); ++j )
|
||||||
{
|
{
|
||||||
const IPAddr& al2_j = al2->Index(j)->AsAddr();
|
const IPAddr& al2_j = al2->Idx(j)->AsAddr();
|
||||||
if ( al1_i == al2_j )
|
if ( al1_i == al2_j )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( j >= al2->Length() )
|
if ( j >= al2->Length() )
|
||||||
// Didn't find it.
|
// Didn't find it.
|
||||||
delta->Append({NewRef{}, al1->Index(i)});
|
delta->Append(al1->Idx(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return delta;
|
return delta;
|
||||||
|
@ -910,7 +910,7 @@ void DNS_Mgr::DumpAddrList(FILE* f, ListVal* al)
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < al->Length(); ++i )
|
for ( int i = 0; i < al->Length(); ++i )
|
||||||
{
|
{
|
||||||
const IPAddr& al_i = al->Index(i)->AsAddr();
|
const IPAddr& al_i = al->Idx(i)->AsAddr();
|
||||||
fprintf(f, "%s%s", i > 0 ? "," : "", al_i.AsString().c_str());
|
fprintf(f, "%s%s", i > 0 ? "," : "", al_i.AsString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
src/Expr.cc
24
src/Expr.cc
|
@ -311,7 +311,7 @@ ConstExpr::ConstExpr(IntrusivePtr<Val> arg_val)
|
||||||
: Expr(EXPR_CONST), val(std::move(arg_val))
|
: Expr(EXPR_CONST), val(std::move(arg_val))
|
||||||
{
|
{
|
||||||
if ( val->Type()->Tag() == TYPE_LIST && val->AsListVal()->Length() == 1 )
|
if ( val->Type()->Tag() == TYPE_LIST && val->AsListVal()->Length() == 1 )
|
||||||
val = {NewRef{}, val->AsListVal()->Index(0)};
|
val = val->AsListVal()->Idx(0);
|
||||||
|
|
||||||
SetType({NewRef{}, val->Type()});
|
SetType({NewRef{}, val->Type()});
|
||||||
}
|
}
|
||||||
|
@ -2587,7 +2587,7 @@ IntrusivePtr<Val> IndexExpr::Eval(Frame* f) const
|
||||||
if ( ! v2 )
|
if ( ! v2 )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Val* indv = v2->AsListVal()->Index(0);
|
Val* indv = v2->AsListVal()->Idx(0).get();
|
||||||
|
|
||||||
if ( is_vector(indv) )
|
if ( is_vector(indv) )
|
||||||
{
|
{
|
||||||
|
@ -2662,8 +2662,8 @@ IntrusivePtr<Val> IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
size_t len = vect->Size();
|
size_t len = vect->Size();
|
||||||
auto result = make_intrusive<VectorVal>(vect->Type()->AsVectorType());
|
auto result = make_intrusive<VectorVal>(vect->Type()->AsVectorType());
|
||||||
|
|
||||||
bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len);
|
bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len);
|
||||||
bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len);
|
bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len);
|
||||||
bro_int_t sub_length = last - first;
|
bro_int_t sub_length = last - first;
|
||||||
|
|
||||||
if ( sub_length >= 0 )
|
if ( sub_length >= 0 )
|
||||||
|
@ -2695,7 +2695,7 @@ IntrusivePtr<Val> IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
|
|
||||||
if ( lv->Length() == 1 )
|
if ( lv->Length() == 1 )
|
||||||
{
|
{
|
||||||
bro_int_t idx = lv->Index(0)->AsInt();
|
bro_int_t idx = lv->Idx(0)->AsInt();
|
||||||
|
|
||||||
if ( idx < 0 )
|
if ( idx < 0 )
|
||||||
idx += len;
|
idx += len;
|
||||||
|
@ -2705,8 +2705,8 @@ IntrusivePtr<Val> IndexExpr::Fold(Val* v1, Val* v2) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bro_int_t first = get_slice_index(lv->Index(0)->AsInt(), len);
|
bro_int_t first = get_slice_index(lv->Idx(0)->AsInt(), len);
|
||||||
bro_int_t last = get_slice_index(lv->Index(1)->AsInt(), len);
|
bro_int_t last = get_slice_index(lv->Idx(1)->AsInt(), len);
|
||||||
bro_int_t substring_len = last - first;
|
bro_int_t substring_len = last - first;
|
||||||
|
|
||||||
if ( substring_len < 0 )
|
if ( substring_len < 0 )
|
||||||
|
@ -2759,8 +2759,8 @@ void IndexExpr::Assign(Frame* f, IntrusivePtr<Val> v)
|
||||||
if ( lv->Length() > 1 )
|
if ( lv->Length() > 1 )
|
||||||
{
|
{
|
||||||
auto len = v1_vect->Size();
|
auto len = v1_vect->Size();
|
||||||
bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len);
|
bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len);
|
||||||
bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len);
|
bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len);
|
||||||
|
|
||||||
// Remove the elements from the vector within the slice
|
// Remove the elements from the vector within the slice
|
||||||
for ( auto idx = first; idx < last; idx++ )
|
for ( auto idx = first; idx < last; idx++ )
|
||||||
|
@ -3053,7 +3053,7 @@ IntrusivePtr<Val> RecordConstructorExpr::Fold(Val* v) const
|
||||||
auto rv = make_intrusive<RecordVal>(rt);
|
auto rv = make_intrusive<RecordVal>(rt);
|
||||||
|
|
||||||
for ( int i = 0; i < lv->Length(); ++i )
|
for ( int i = 0; i < lv->Length(); ++i )
|
||||||
rv->Assign(i, lv->Index(i)->Ref());
|
rv->Assign(i, lv->Idx(i));
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -4764,11 +4764,11 @@ void ListExpr::Assign(Frame* f, IntrusivePtr<Val> v)
|
||||||
{
|
{
|
||||||
ListVal* lv = v->AsListVal();
|
ListVal* lv = v->AsListVal();
|
||||||
|
|
||||||
if ( exprs.length() != lv->Vals()->length() )
|
if ( exprs.length() != lv->Length() )
|
||||||
RuntimeError("mismatch in list lengths");
|
RuntimeError("mismatch in list lengths");
|
||||||
|
|
||||||
loop_over_list(exprs, i)
|
loop_over_list(exprs, i)
|
||||||
exprs[i]->Assign(f, {NewRef{}, (*lv->Vals())[i]});
|
exprs[i]->Assign(f, lv->Idx(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
TraversalCode ListExpr::Traverse(TraversalCallback* cb) const
|
TraversalCode ListExpr::Traverse(TraversalCallback* cb) const
|
||||||
|
|
|
@ -45,7 +45,7 @@ void* PrefixTable::Insert(const Val* value, void* data)
|
||||||
// [elem] -> elem
|
// [elem] -> elem
|
||||||
if ( value->Type()->Tag() == TYPE_LIST &&
|
if ( value->Type()->Tag() == TYPE_LIST &&
|
||||||
value->AsListVal()->Length() == 1 )
|
value->AsListVal()->Length() == 1 )
|
||||||
value = value->AsListVal()->Index(0);
|
value = value->AsListVal()->Idx(0).get();
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
|
@ -105,7 +105,7 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const
|
||||||
// [elem] -> elem
|
// [elem] -> elem
|
||||||
if ( value->Type()->Tag() == TYPE_LIST &&
|
if ( value->Type()->Tag() == TYPE_LIST &&
|
||||||
value->AsListVal()->Length() == 1 )
|
value->AsListVal()->Length() == 1 )
|
||||||
value = value->AsListVal()->Index(0);
|
value = value->AsListVal()->Idx(0).get();
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
|
@ -144,7 +144,7 @@ void* PrefixTable::Remove(const Val* value)
|
||||||
// [elem] -> elem
|
// [elem] -> elem
|
||||||
if ( value->Type()->Tag() == TYPE_LIST &&
|
if ( value->Type()->Tag() == TYPE_LIST &&
|
||||||
value->AsListVal()->Length() == 1 )
|
value->AsListVal()->Length() == 1 )
|
||||||
value = value->AsListVal()->Index(0);
|
value = value->AsListVal()->Idx(0).get();
|
||||||
|
|
||||||
switch ( value->Type()->Tag() ) {
|
switch ( value->Type()->Tag() ) {
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR:
|
||||||
|
|
|
@ -79,7 +79,7 @@ void Reporter::InitOptions()
|
||||||
while ( (v = wl_table->NextEntry(k, c)) )
|
while ( (v = wl_table->NextEntry(k, c)) )
|
||||||
{
|
{
|
||||||
auto index = wl_val->RecoverIndex(k);
|
auto index = wl_val->RecoverIndex(k);
|
||||||
std::string key = index->Index(0)->AsString()->CheckString();
|
std::string key = index->Idx(0)->AsString()->CheckString();
|
||||||
weird_sampling_whitelist.emplace(move(key));
|
weird_sampling_whitelist.emplace(move(key));
|
||||||
delete k;
|
delete k;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1362,9 +1362,9 @@ void id_to_maskedvallist(const char* id, maskedvalue_list* append_to,
|
||||||
if ( v->Type()->Tag() == TYPE_TABLE )
|
if ( v->Type()->Tag() == TYPE_TABLE )
|
||||||
{
|
{
|
||||||
ListVal* lv = v->AsTableVal()->ConvertToPureList();
|
ListVal* lv = v->AsTableVal()->ConvertToPureList();
|
||||||
val_list* vals = lv->Vals();
|
|
||||||
for ( const auto& val : *vals )
|
for ( const auto& val : lv->Vals() )
|
||||||
if ( ! val_to_maskedval(val, append_to, prefix_vector) )
|
if ( ! val_to_maskedval(val.get(), append_to, prefix_vector) )
|
||||||
{
|
{
|
||||||
Unref(lv);
|
Unref(lv);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ bool NetSessions::IsLikelyServerPort(uint32_t port, TransportProto proto) const
|
||||||
{
|
{
|
||||||
ListVal* lv = likely_server_ports->ConvertToPureList();
|
ListVal* lv = likely_server_ports->ConvertToPureList();
|
||||||
for ( int i = 0; i < lv->Length(); i++ )
|
for ( int i = 0; i < lv->Length(); i++ )
|
||||||
port_cache.insert(lv->Index(i)->InternalUnsigned());
|
port_cache.insert(lv->Idx(i)->InternalUnsigned());
|
||||||
have_cache = true;
|
have_cache = true;
|
||||||
Unref(lv);
|
Unref(lv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||||
f->SetElement(value_var.get(), current_tev->Value()->Ref());
|
f->SetElement(value_var.get(), current_tev->Value()->Ref());
|
||||||
|
|
||||||
for ( int i = 0; i < ind_lv->Length(); i++ )
|
for ( int i = 0; i < ind_lv->Length(); i++ )
|
||||||
f->SetElement((*loop_vars)[i], ind_lv->Index(i)->Ref());
|
f->SetElement((*loop_vars)[i], ind_lv->Idx(i)->Ref());
|
||||||
|
|
||||||
flow = FLOW_NEXT;
|
flow = FLOW_NEXT;
|
||||||
|
|
||||||
|
|
82
src/Val.cc
82
src/Val.cc
|
@ -538,7 +538,7 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val*
|
||||||
{
|
{
|
||||||
auto lv = tval->RecoverIndex(k);
|
auto lv = tval->RecoverIndex(k);
|
||||||
delete k;
|
delete k;
|
||||||
Val* entry_key = lv->Length() == 1 ? lv->Index(0) : lv.get();
|
Val* entry_key = lv->Length() == 1 ? lv->Idx(0).get() : lv.get();
|
||||||
|
|
||||||
if ( tval->Type()->IsSet() )
|
if ( tval->Type()->IsSet() )
|
||||||
BuildJSON(writer, entry_key, only_loggable, re);
|
BuildJSON(writer, entry_key, only_loggable, re);
|
||||||
|
@ -608,7 +608,7 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val*
|
||||||
auto* lval = val->AsListVal();
|
auto* lval = val->AsListVal();
|
||||||
size_t size = lval->Length();
|
size_t size = lval->Length();
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
BuildJSON(writer, lval->Index(i), only_loggable, re);
|
BuildJSON(writer, lval->Idx(i).get(), only_loggable, re);
|
||||||
|
|
||||||
writer.EndArray();
|
writer.EndArray();
|
||||||
break;
|
break;
|
||||||
|
@ -1189,14 +1189,12 @@ ListVal::ListVal(TypeTag t)
|
||||||
|
|
||||||
ListVal::~ListVal()
|
ListVal::~ListVal()
|
||||||
{
|
{
|
||||||
for ( const auto& val : vals )
|
|
||||||
Unref(val);
|
|
||||||
Unref(type);
|
Unref(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntrusivePtr<Val> ListVal::SizeVal() const
|
IntrusivePtr<Val> ListVal::SizeVal() const
|
||||||
{
|
{
|
||||||
return val_mgr->Count(vals.length());
|
return val_mgr->Count(vals.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
RE_Matcher* ListVal::BuildRE() const
|
RE_Matcher* ListVal::BuildRE() const
|
||||||
|
@ -1223,7 +1221,7 @@ void ListVal::Append(IntrusivePtr<Val> v)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vt = v->Type();
|
auto vt = v->Type();
|
||||||
vals.push_back(v.release());
|
vals.emplace_back(std::move(v));
|
||||||
type->AsTypeList()->Append({NewRef{}, vt});
|
type->AsTypeList()->Append({NewRef{}, vt});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1242,7 @@ IntrusivePtr<TableVal> ListVal::ToSetVal() const
|
||||||
auto t = make_intrusive<TableVal>(std::move(s));
|
auto t = make_intrusive<TableVal>(std::move(s));
|
||||||
|
|
||||||
for ( const auto& val : vals )
|
for ( const auto& val : vals )
|
||||||
t->Assign(val, nullptr);
|
t->Assign(val.get(), nullptr);
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1260,13 +1258,13 @@ void ListVal::Describe(ODesc* d) const
|
||||||
{
|
{
|
||||||
type->Describe(d);
|
type->Describe(d);
|
||||||
d->SP();
|
d->SP();
|
||||||
d->Add(vals.length());
|
d->Add(static_cast<uint64_t>(vals.size()));
|
||||||
d->SP();
|
d->SP();
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_over_list(vals, i)
|
for ( auto i = 0u; i < vals.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( i > 0 )
|
if ( i > 0u )
|
||||||
{
|
{
|
||||||
if ( d->IsReadable() || d->IsPortable() )
|
if ( d->IsReadable() || d->IsPortable() )
|
||||||
{
|
{
|
||||||
|
@ -1282,7 +1280,7 @@ void ListVal::Describe(ODesc* d) const
|
||||||
IntrusivePtr<Val> ListVal::DoClone(CloneState* state)
|
IntrusivePtr<Val> ListVal::DoClone(CloneState* state)
|
||||||
{
|
{
|
||||||
auto lv = make_intrusive<ListVal>(tag);
|
auto lv = make_intrusive<ListVal>(tag);
|
||||||
lv->vals.resize(vals.length());
|
lv->vals.reserve(vals.size());
|
||||||
state->NewClone(this, lv);
|
state->NewClone(this, lv);
|
||||||
|
|
||||||
for ( const auto& val : vals )
|
for ( const auto& val : vals )
|
||||||
|
@ -1297,8 +1295,8 @@ unsigned int ListVal::MemoryAllocation() const
|
||||||
for ( const auto& val : vals )
|
for ( const auto& val : vals )
|
||||||
size += val->MemoryAllocation();
|
size += val->MemoryAllocation();
|
||||||
|
|
||||||
return size + padded_sizeof(*this) + vals.MemoryAllocation() - padded_sizeof(vals)
|
size += pad_size(vals.capacity() * sizeof(decltype(vals)::value_type));
|
||||||
+ type->MemoryAllocation();
|
return size + padded_sizeof(*this) + type->MemoryAllocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
TableEntryVal* TableEntryVal::Clone(Val::CloneState* state)
|
TableEntryVal* TableEntryVal::Clone(Val::CloneState* state)
|
||||||
|
@ -1772,7 +1770,7 @@ bool TableVal::ExpandAndInit(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val)
|
||||||
reporter->InternalError("bad singleton list index");
|
reporter->InternalError("bad singleton list index");
|
||||||
|
|
||||||
for ( int i = 0; i < iv->Length(); ++i )
|
for ( int i = 0; i < iv->Length(); ++i )
|
||||||
if ( ! ExpandAndInit({NewRef{}, iv->Index(i)}, new_val) )
|
if ( ! ExpandAndInit(iv->Idx(i), new_val) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1780,22 +1778,25 @@ bool TableVal::ExpandAndInit(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val)
|
||||||
|
|
||||||
else
|
else
|
||||||
{ // Compound table.
|
{ // Compound table.
|
||||||
val_list* vl = iv->Vals();
|
int i;
|
||||||
loop_over_list(*vl, i)
|
|
||||||
|
for ( i = 0; i < iv->Length(); ++i )
|
||||||
{
|
{
|
||||||
|
const auto& v = iv->Idx(i);
|
||||||
// ### if CompositeHash::ComputeHash did flattening
|
// ### if CompositeHash::ComputeHash did flattening
|
||||||
// of 1-element lists (like ComputeSingletonHash does),
|
// of 1-element lists (like ComputeSingletonHash does),
|
||||||
// then we could optimize here.
|
// then we could optimize here.
|
||||||
BroType* t = (*vl)[i]->Type();
|
BroType* t = v->Type();
|
||||||
|
|
||||||
if ( t->IsSet() || t->Tag() == TYPE_LIST )
|
if ( t->IsSet() || t->Tag() == TYPE_LIST )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( i >= vl->length() )
|
if ( i >= iv->Length() )
|
||||||
// Nothing to expand.
|
// Nothing to expand.
|
||||||
return CheckAndAssign(index.get(), std::move(new_val));
|
return CheckAndAssign(index.get(), std::move(new_val));
|
||||||
else
|
else
|
||||||
return ExpandCompoundAndInit(vl, i, std::move(new_val));
|
return ExpandCompoundAndInit(iv, i, std::move(new_val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1855,11 +1856,11 @@ IntrusivePtr<Val> TableVal::Default(Val* index)
|
||||||
|
|
||||||
if ( index->Type()->Tag() == TYPE_LIST )
|
if ( index->Type()->Tag() == TYPE_LIST )
|
||||||
{
|
{
|
||||||
const val_list* vl0 = index->AsListVal()->Vals();
|
auto lv = index->AsListVal();
|
||||||
vl.reserve(vl0->length());
|
vl.reserve(lv->Length());
|
||||||
|
|
||||||
for ( const auto& v : *vl0 )
|
for ( const auto& v : lv->Vals() )
|
||||||
vl.emplace_back(NewRef{}, v);
|
vl.emplace_back(v);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vl.emplace_back(NewRef{}, index);
|
vl.emplace_back(NewRef{}, index);
|
||||||
|
@ -2026,10 +2027,10 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
|
||||||
}
|
}
|
||||||
|
|
||||||
const Func* f = thefunc->AsFunc();
|
const Func* f = thefunc->AsFunc();
|
||||||
const auto& index_list = *index->AsListVal()->Vals();
|
auto lv = index->AsListVal();
|
||||||
|
|
||||||
zeek::Args vl;
|
zeek::Args vl;
|
||||||
vl.reserve(2 + index_list.length() + table_type->IsTable());
|
vl.reserve(2 + lv->Length() + table_type->IsTable());
|
||||||
vl.emplace_back(NewRef{}, this);
|
vl.emplace_back(NewRef{}, this);
|
||||||
|
|
||||||
switch ( tpe )
|
switch ( tpe )
|
||||||
|
@ -2047,8 +2048,8 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
|
||||||
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED));
|
vl.emplace_back(BifType::Enum::TableChange->GetVal(BifEnum::TableChange::TABLE_ELEMENT_EXPIRED));
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( const auto& v : *index->AsListVal()->Vals() )
|
for ( const auto& v : lv->Vals() )
|
||||||
vl.emplace_back(NewRef{}, v);
|
vl.emplace_back(v);
|
||||||
|
|
||||||
if ( table_type->IsTable() )
|
if ( table_type->IsTable() )
|
||||||
vl.emplace_back(NewRef{}, old_value);
|
vl.emplace_back(NewRef{}, old_value);
|
||||||
|
@ -2129,7 +2130,7 @@ ListVal* TableVal::ConvertToList(TypeTag t) const
|
||||||
if ( index->Length() != 1 )
|
if ( index->Length() != 1 )
|
||||||
InternalWarning("bad index in TableVal::ConvertToList");
|
InternalWarning("bad index in TableVal::ConvertToList");
|
||||||
|
|
||||||
l->Append({NewRef{}, index->Index(0)});
|
l->Append(index->Idx(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete k;
|
delete k;
|
||||||
|
@ -2241,23 +2242,26 @@ void TableVal::Describe(ODesc* d) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TableVal::ExpandCompoundAndInit(val_list* vl, int k, IntrusivePtr<Val> new_val)
|
bool TableVal::ExpandCompoundAndInit(ListVal* lv, int k, IntrusivePtr<Val> new_val)
|
||||||
{
|
{
|
||||||
Val* ind_k_v = (*vl)[k];
|
Val* ind_k_v = lv->Idx(k).get();
|
||||||
auto ind_k = ind_k_v->Type()->IsSet() ?
|
auto ind_k = ind_k_v->Type()->IsSet() ?
|
||||||
IntrusivePtr<ListVal>{AdoptRef{}, ind_k_v->AsTableVal()->ConvertToList()} :
|
IntrusivePtr<ListVal>{AdoptRef{}, ind_k_v->AsTableVal()->ConvertToList()} :
|
||||||
IntrusivePtr<ListVal>{NewRef{}, ind_k_v->AsListVal()};
|
IntrusivePtr<ListVal>{NewRef{}, ind_k_v->AsListVal()};
|
||||||
|
|
||||||
for ( int i = 0; i < ind_k->Length(); ++i )
|
for ( int i = 0; i < ind_k->Length(); ++i )
|
||||||
{
|
{
|
||||||
Val* ind_k_i = ind_k->Index(i);
|
const auto& ind_k_i = ind_k->Idx(i);
|
||||||
auto expd = make_intrusive<ListVal>(TYPE_ANY);
|
auto expd = make_intrusive<ListVal>(TYPE_ANY);
|
||||||
loop_over_list(*vl, j)
|
|
||||||
|
for ( auto j = 0; j < lv->Length(); ++j )
|
||||||
{
|
{
|
||||||
|
const auto& v = lv->Idx(j);
|
||||||
|
|
||||||
if ( j == k )
|
if ( j == k )
|
||||||
expd->Append({NewRef{}, ind_k_i});
|
expd->Append(ind_k_i);
|
||||||
else
|
else
|
||||||
expd->Append({NewRef{}, (*vl)[j]});
|
expd->Append(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! ExpandAndInit(std::move(expd), new_val) )
|
if ( ! ExpandAndInit(std::move(expd), new_val) )
|
||||||
|
@ -2474,12 +2478,12 @@ double TableVal::CallExpireFunc(IntrusivePtr<ListVal> idx)
|
||||||
|
|
||||||
if ( ! any_idiom )
|
if ( ! any_idiom )
|
||||||
{
|
{
|
||||||
const auto& index_list = *idx->AsListVal()->Vals();
|
auto lv = idx->AsListVal();
|
||||||
vl.reserve(1 + index_list.length());
|
vl.reserve(1 + lv->Length());
|
||||||
vl.emplace_back(NewRef{}, this);
|
vl.emplace_back(NewRef{}, this);
|
||||||
|
|
||||||
for ( const auto& v : index_list )
|
for ( const auto& v : lv->Vals() )
|
||||||
vl.emplace_back(NewRef{}, v);
|
vl.emplace_back(v);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2489,7 +2493,7 @@ double TableVal::CallExpireFunc(IntrusivePtr<ListVal> idx)
|
||||||
ListVal* idx_list = idx->AsListVal();
|
ListVal* idx_list = idx->AsListVal();
|
||||||
// Flatten if only one element
|
// Flatten if only one element
|
||||||
if ( idx_list->Length() == 1 )
|
if ( idx_list->Length() == 1 )
|
||||||
vl.emplace_back(NewRef{}, idx_list->Index(0));
|
vl.emplace_back(idx_list->Idx(0));
|
||||||
else
|
else
|
||||||
vl.emplace_back(std::move(idx));
|
vl.emplace_back(std::move(idx));
|
||||||
}
|
}
|
||||||
|
|
22
src/Val.h
22
src/Val.h
|
@ -627,9 +627,14 @@ public:
|
||||||
|
|
||||||
IntrusivePtr<Val> SizeVal() const override;
|
IntrusivePtr<Val> SizeVal() const override;
|
||||||
|
|
||||||
int Length() const { return vals.length(); }
|
int Length() const { return vals.size(); }
|
||||||
Val* Index(const int n) { return vals[n]; }
|
|
||||||
const Val* Index(const int n) const { return vals[n]; }
|
const IntrusivePtr<Val>& Idx(size_t i) const { return vals[i]; }
|
||||||
|
|
||||||
|
[[deprecated("Remove in v4.1. Use Idx() instead")]]
|
||||||
|
Val* Index(const int n) { return vals[n].get(); }
|
||||||
|
[[deprecated("Remove in v4.1. Use Idx() instead")]]
|
||||||
|
const Val* Index(const int n) const { return vals[n].get(); }
|
||||||
|
|
||||||
// Returns an RE_Matcher() that will match any string that
|
// Returns an RE_Matcher() that will match any string that
|
||||||
// includes embedded within it one of the patterns listed
|
// includes embedded within it one of the patterns listed
|
||||||
|
@ -656,8 +661,7 @@ public:
|
||||||
[[deprecated("Remove in v4.1. Use ToSetVal() instead.")]]
|
[[deprecated("Remove in v4.1. Use ToSetVal() instead.")]]
|
||||||
TableVal* ConvertToSet() const;
|
TableVal* ConvertToSet() const;
|
||||||
|
|
||||||
const val_list* Vals() const { return &vals; }
|
const std::vector<IntrusivePtr<Val>>& Vals() const { return vals; }
|
||||||
val_list* Vals() { return &vals; }
|
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
|
@ -666,7 +670,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
IntrusivePtr<Val> DoClone(CloneState* state) override;
|
IntrusivePtr<Val> DoClone(CloneState* state) override;
|
||||||
|
|
||||||
val_list vals;
|
std::vector<IntrusivePtr<Val>> vals;
|
||||||
TypeTag tag;
|
TypeTag tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -867,7 +871,7 @@ protected:
|
||||||
void RebuildTable(ParseTimeTableState ptts);
|
void RebuildTable(ParseTimeTableState ptts);
|
||||||
|
|
||||||
void CheckExpireAttr(attr_tag at);
|
void CheckExpireAttr(attr_tag at);
|
||||||
bool ExpandCompoundAndInit(val_list* vl, int k, IntrusivePtr<Val> new_val);
|
bool ExpandCompoundAndInit(ListVal* lv, int k, IntrusivePtr<Val> new_val);
|
||||||
bool CheckAndAssign(Val* index, IntrusivePtr<Val> new_val);
|
bool CheckAndAssign(Val* index, IntrusivePtr<Val> new_val);
|
||||||
|
|
||||||
// Calculates default value for index. Returns 0 if none.
|
// Calculates default value for index. Returns 0 if none.
|
||||||
|
@ -1014,7 +1018,7 @@ public:
|
||||||
template<typename E>
|
template<typename E>
|
||||||
bool Assign(Val* index, E&& element)
|
bool Assign(Val* index, E&& element)
|
||||||
{
|
{
|
||||||
return Assign(index->AsListVal()->Index(0)->CoerceToUnsigned(),
|
return Assign(index->AsListVal()->Idx(0)->CoerceToUnsigned(),
|
||||||
std::forward<E>(element));
|
std::forward<E>(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,7 +1036,7 @@ public:
|
||||||
Val* Lookup(unsigned int index) const;
|
Val* Lookup(unsigned int index) const;
|
||||||
Val* Lookup(Val* index)
|
Val* Lookup(Val* index)
|
||||||
{
|
{
|
||||||
bro_uint_t i = index->AsListVal()->Index(0)->CoerceToUnsigned();
|
bro_uint_t i = index->AsListVal()->Idx(0)->CoerceToUnsigned();
|
||||||
return Lookup(static_cast<unsigned int>(i));
|
return Lookup(static_cast<unsigned int>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ void Manager::InitPostScript()
|
||||||
auto port_list = table_val->ConvertToPureList();
|
auto port_list = table_val->ConvertToPureList();
|
||||||
|
|
||||||
for ( auto i = 0; i < port_list->Length(); ++i )
|
for ( auto i = 0; i < port_list->Length(); ++i )
|
||||||
vxlan_ports.emplace_back(port_list->Index(i)->AsPortVal()->Port());
|
vxlan_ports.emplace_back(port_list->Idx(i)->AsPortVal()->Port());
|
||||||
|
|
||||||
Unref(port_list);
|
Unref(port_list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -912,7 +912,7 @@ broker::expected<broker::data> bro_broker::val_to_data(const Val* v)
|
||||||
|
|
||||||
for ( auto k = 0; k < vl->Length(); ++k )
|
for ( auto k = 0; k < vl->Length(); ++k )
|
||||||
{
|
{
|
||||||
auto key_part = val_to_data((*vl->Vals())[k]);
|
auto key_part = val_to_data(vl->Idx(k).get());
|
||||||
|
|
||||||
if ( ! key_part )
|
if ( ! key_part )
|
||||||
return broker::ec::invalid_data;
|
return broker::ec::invalid_data;
|
||||||
|
|
|
@ -39,7 +39,7 @@ std::set<std::string> val_to_topic_set(Val* val)
|
||||||
while ( tbl->NextEntry(k, c) )
|
while ( tbl->NextEntry(k, c) )
|
||||||
{
|
{
|
||||||
auto index = val->AsTableVal()->RecoverIndex(k);
|
auto index = val->AsTableVal()->RecoverIndex(k);
|
||||||
rval.emplace(index->Index(0)->AsString()->CheckString());
|
rval.emplace(index->Idx(0)->AsString()->CheckString());
|
||||||
delete k;
|
delete k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,8 +249,8 @@ X509_STORE* file_analysis::X509::GetRootStore(TableVal* root_certs)
|
||||||
// Build the validation store
|
// Build the validation store
|
||||||
for ( int i = 0; i < idxs->Length(); ++i )
|
for ( int i = 0; i < idxs->Length(); ++i )
|
||||||
{
|
{
|
||||||
Val* key = idxs->Index(i);
|
const auto& key = idxs->Idx(i);
|
||||||
StringVal *sv = root_certs->Lookup(key)->AsStringVal();
|
StringVal *sv = root_certs->Lookup(key.get())->AsStringVal();
|
||||||
assert(sv);
|
assert(sv);
|
||||||
const uint8_t* data = sv->Bytes();
|
const uint8_t* data = sv->Bytes();
|
||||||
::X509* x = d2i_X509(NULL, &data, sv->Len());
|
::X509* x = d2i_X509(NULL, &data, sv->Len());
|
||||||
|
|
|
@ -284,7 +284,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
|
||||||
while ( (v = info->config->AsTable()->NextEntry(k, c)) )
|
while ( (v = info->config->AsTable()->NextEntry(k, c)) )
|
||||||
{
|
{
|
||||||
auto index = info->config->RecoverIndex(k);
|
auto index = info->config->RecoverIndex(k);
|
||||||
string key = index->Index(0)->AsString()->CheckString();
|
string key = index->Idx(0)->AsString()->CheckString();
|
||||||
string value = v->Value()->AsString()->CheckString();
|
string value = v->Value()->AsString()->CheckString();
|
||||||
rinfo.config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
rinfo.config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
||||||
delete k;
|
delete k;
|
||||||
|
@ -1919,7 +1919,7 @@ RecordVal* Manager::ListValToRecordVal(ListVal* list, RecordType *request_type,
|
||||||
fieldVal = ListValToRecordVal(list, request_type->FieldType(i)->AsRecordType(), position);
|
fieldVal = ListValToRecordVal(list, request_type->FieldType(i)->AsRecordType(), position);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fieldVal = list->Index(*position);
|
fieldVal = list->Idx(*position).get();
|
||||||
(*position)++;
|
(*position)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -870,7 +870,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
|
||||||
while ( (v = filter->config->AsTable()->NextEntry(k, c)) )
|
while ( (v = filter->config->AsTable()->NextEntry(k, c)) )
|
||||||
{
|
{
|
||||||
auto index = filter->config->RecoverIndex(k);
|
auto index = filter->config->RecoverIndex(k);
|
||||||
string key = index->Index(0)->AsString()->CheckString();
|
string key = index->Idx(0)->AsString()->CheckString();
|
||||||
string value = v->Value()->AsString()->CheckString();
|
string value = v->Value()->AsString()->CheckString();
|
||||||
info->config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
info->config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
||||||
delete k;
|
delete k;
|
||||||
|
@ -1022,7 +1022,7 @@ threading::Value* Manager::ValToLogVal(Val* val, BroType* ty)
|
||||||
lval->val.set_val.vals = new threading::Value* [lval->val.set_val.size];
|
lval->val.set_val.vals = new threading::Value* [lval->val.set_val.size];
|
||||||
|
|
||||||
for ( int i = 0; i < lval->val.set_val.size; i++ )
|
for ( int i = 0; i < lval->val.set_val.size; i++ )
|
||||||
lval->val.set_val.vals[i] = ValToLogVal(set->Index(i));
|
lval->val.set_val.vals[i] = ValToLogVal(set->Idx(i).get());
|
||||||
|
|
||||||
Unref(set);
|
Unref(set);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -180,7 +180,7 @@ function Reporter::set_weird_sampling_whitelist%(weird_sampling_whitelist: strin
|
||||||
while ( (v = wl_table->NextEntry(k, c)) )
|
while ( (v = wl_table->NextEntry(k, c)) )
|
||||||
{
|
{
|
||||||
auto index = wl_val->RecoverIndex(k);
|
auto index = wl_val->RecoverIndex(k);
|
||||||
string key = index->Index(0)->AsString()->CheckString();
|
string key = index->Idx(0)->AsString()->CheckString();
|
||||||
whitelist_set.emplace(move(key));
|
whitelist_set.emplace(move(key));
|
||||||
delete k;
|
delete k;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1026,7 +1026,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
|
||||||
{
|
{
|
||||||
auto key = cluster_table_val->RecoverIndex(k);
|
auto key = cluster_table_val->RecoverIndex(k);
|
||||||
delete k;
|
delete k;
|
||||||
auto name = key->Index(0)->AsStringVal()->ToStdString();
|
auto name = key->Idx(0)->AsStringVal()->ToStdString();
|
||||||
auto rv = v->Value()->AsRecordVal();
|
auto rv = v->Value()->AsRecordVal();
|
||||||
|
|
||||||
Supervisor::ClusterEndpoint ep;
|
Supervisor::ClusterEndpoint ep;
|
||||||
|
|
|
@ -405,8 +405,8 @@ static bool prepare_environment(TableVal* tbl, bool set)
|
||||||
|
|
||||||
for ( int i = 0; i < idxs->Length(); ++i )
|
for ( int i = 0; i < idxs->Length(); ++i )
|
||||||
{
|
{
|
||||||
Val* key = idxs->Index(i);
|
const auto& key = idxs->Idx(i);
|
||||||
auto val = tbl->Lookup(key, false);
|
auto val = tbl->Lookup(key.get(), false);
|
||||||
|
|
||||||
if ( key->Type()->Tag() != TYPE_STRING ||
|
if ( key->Type()->Tag() != TYPE_STRING ||
|
||||||
val->Type()->Tag() != TYPE_STRING )
|
val->Type()->Tag() != TYPE_STRING )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue