00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include "Attr.h"
00025 #include "Expr.h"
00026 #include "Serializer.h"
00027
00028 const char* attr_name(attr_tag t)
00029 {
00030 static const char* attr_names[int(NUM_ATTRS)] = {
00031 "&optional", "&default", "&redef",
00032 "&rotate_interval", "&rotate_size",
00033 "&add_func", "&delete_func", "&expire_func",
00034 "&read_expire", "&write_expire", "&create_expire",
00035 "&persistent", "&postprocessor", "&encrypt",
00036 "&match",
00037 };
00038
00039 return attr_names[int(t)];
00040 }
00041
00042 Attr::Attr(attr_tag t, Expr* e)
00043 {
00044 tag = t;
00045 expr = e;
00046 SetLocationInfo(&start_location, &end_location);
00047 }
00048
00049 Attr::~Attr()
00050 {
00051 Unref(expr);
00052 }
00053
00054 void Attr::Describe(ODesc* d) const
00055 {
00056 AddTag(d);
00057
00058 if ( expr )
00059 {
00060 if ( ! d->IsBinary() )
00061 d->Add("=");
00062
00063 expr->Describe(d);
00064 }
00065 }
00066
00067 void Attr::AddTag(ODesc* d) const
00068 {
00069 if ( d->IsBinary() )
00070 d->Add(bro_int_t(Tag()));
00071 else
00072 d->Add(attr_name(Tag()));
00073 }
00074
00075 Attributes::Attributes(attr_list* a, BroType* t)
00076 {
00077 attrs = new attr_list(a->length());
00078 type = t->Ref();
00079
00080 SetLocationInfo(&start_location, &end_location);
00081
00082
00083
00084
00085
00086 loop_over_list(*a, i)
00087 AddAttr((*a)[i]);
00088
00089 delete a;
00090 }
00091
00092 Attributes::~Attributes()
00093 {
00094 loop_over_list(*attrs, i)
00095 Unref((*attrs)[i]);
00096
00097 delete attrs;
00098
00099 Unref(type);
00100 }
00101
00102 void Attributes::AddAttr(Attr* attr)
00103 {
00104 if ( ! attrs )
00105 attrs = new attr_list;
00106
00107 if ( ! attr->RedundantAttrOkay() )
00108
00109 RemoveAttr(attr->Tag());
00110
00111 attrs->append(attr);
00112 Ref(attr);
00113
00114
00115
00116 CheckAttr(attr);
00117
00118
00119
00120 if ( (attr->Tag() == ATTR_ADD_FUNC || attr->Tag() == ATTR_DEL_FUNC) &&
00121 ! FindAttr(ATTR_REDEF) )
00122 attrs->append(new Attr(ATTR_REDEF));
00123
00124
00125 if ( attr->Tag() == ATTR_DEFAULT && ! FindAttr(ATTR_OPTIONAL) )
00126 attrs->append(new Attr(ATTR_OPTIONAL));
00127 }
00128
00129 void Attributes::AddAttrs(Attributes* a)
00130 {
00131 attr_list* as = a->Attrs();
00132 loop_over_list(*as, i)
00133 AddAttr((*as)[i]);
00134
00135 Unref(a);
00136 }
00137
00138 Attr* Attributes::FindAttr(attr_tag t) const
00139 {
00140 if ( ! attrs )
00141 return 0;
00142
00143 loop_over_list(*attrs, i)
00144 {
00145 Attr* a = (*attrs)[i];
00146 if ( a->Tag() == t )
00147 return a;
00148 }
00149
00150 return 0;
00151 }
00152
00153 void Attributes::RemoveAttr(attr_tag t)
00154 {
00155 for ( int i = 0; i < attrs->length(); i++ )
00156 if ( (*attrs)[i]->Tag() == t )
00157 attrs->remove_nth(i--);
00158 }
00159
00160 void Attributes::Describe(ODesc* d) const
00161 {
00162 if ( ! attrs )
00163 {
00164 d->AddCount(0);
00165 return;
00166 }
00167
00168 d->AddCount(attrs->length());
00169
00170 loop_over_list(*attrs, i)
00171 {
00172 if ( (d->IsReadable() || d->IsPortable()) && i > 0 )
00173 d->Add(", ");
00174
00175 (*attrs)[i]->Describe(d);
00176 }
00177 }
00178
00179 void Attributes::CheckAttr(Attr* a)
00180 {
00181 switch ( a->Tag() ) {
00182 case ATTR_OPTIONAL:
00183 case ATTR_REDEF:
00184 break;
00185
00186 case ATTR_ADD_FUNC:
00187 case ATTR_DEL_FUNC:
00188 {
00189 int is_add = a->Tag() == ATTR_ADD_FUNC;
00190
00191 BroType* at = a->AttrExpr()->Type();
00192 if ( at->Tag() != TYPE_FUNC )
00193 {
00194 a->AttrExpr()->Error(
00195 is_add ?
00196 "&add_func must be a function" :
00197 "&delete_func must be a function");
00198 break;
00199 }
00200
00201 FuncType* aft = at->AsFuncType();
00202 if ( ! same_type(aft->YieldType(), type) )
00203 {
00204 a->AttrExpr()->Error(
00205 is_add ?
00206 "&add_func function must yield same type as variable" :
00207 "&delete_func function must yield same type as variable");
00208 break;
00209 }
00210 }
00211 break;
00212
00213 case ATTR_DEFAULT:
00214 {
00215 BroType* atype = a->AttrExpr()->Type();
00216
00217 if ( type->Tag() != TYPE_TABLE || type->IsSet() )
00218 {
00219 if ( ! same_type(atype, type) )
00220 a->AttrExpr()->Error("&default value has inconsistent type", type);
00221 break;
00222 }
00223
00224 TableType* tt = type->AsTableType();
00225
00226 if ( ! same_type(atype, tt->YieldType()) )
00227 {
00228
00229 if ( atype->Tag() == TYPE_FUNC )
00230 {
00231 FuncType* f = atype->AsFuncType();
00232 if ( ! f->CheckArgs(tt->IndexTypes()) ||
00233 ! same_type(f->YieldType(), tt->YieldType()) )
00234 Error("&default function type clash");
00235 }
00236 else
00237 Error("&default value has inconsistent type");
00238 }
00239 }
00240 break;
00241
00242 case ATTR_ROTATE_INTERVAL:
00243 if ( type->Tag() != TYPE_FILE )
00244 Error("&rotate_interval only applicable to files");
00245 break;
00246
00247 case ATTR_ROTATE_SIZE:
00248 if ( type->Tag() != TYPE_FILE )
00249 Error("&rotate_size only applicable to files");
00250 break;
00251
00252 case ATTR_POSTPROCESSOR:
00253 if ( type->Tag() != TYPE_FILE )
00254 Error("&postprocessor only applicable to files");
00255 break;
00256
00257 case ATTR_ENCRYPT:
00258 if ( type->Tag() != TYPE_FILE )
00259 Error("&encrypt only applicable to files");
00260 break;
00261
00262 case ATTR_EXPIRE_READ:
00263 case ATTR_EXPIRE_WRITE:
00264 case ATTR_EXPIRE_CREATE:
00265 if ( type->Tag() != TYPE_TABLE )
00266 {
00267 Error("expiration only applicable to tables");
00268 break;
00269 }
00270
00271 #if 0
00272
00273 if ( ! IsGlobal() )
00274 Error("expiration not supported for local variables");
00275 #endif
00276 break;
00277
00278 case ATTR_EXPIRE_FUNC:
00279 {
00280 if ( type->Tag() != TYPE_TABLE )
00281 {
00282 Error("expiration only applicable to tables");
00283 break;
00284 }
00285
00286 const Expr* expire_func = a->AttrExpr();
00287 const FuncType* e_ft = expire_func->Type()->AsFuncType();
00288
00289 if ( ((const BroType*) e_ft)->YieldType()->Tag() != TYPE_INTERVAL )
00290 {
00291 Error("&expire_func must yield a value of type interval");
00292 break;
00293 }
00294
00295 if ( e_ft->Args()->NumFields() != 2 )
00296 {
00297 Error("&expire_func function must take exactly two arguments");
00298 break;
00299 }
00300 }
00301 break;
00302
00303 case ATTR_PERSISTENT:
00304 case ATTR_SYNCHRONIZED:
00305
00306 break;
00307
00308 case ATTR_MATCH:
00309
00310
00311 break;
00312
00313 default:
00314 BadTag("Attributes::CheckAttr");
00315 }
00316 }
00317
00318 bool Attributes::Serialize(SerialInfo* info) const
00319 {
00320 return SerialObj::Serialize(info);
00321 }
00322
00323 Attributes* Attributes::Unserialize(UnserialInfo* info)
00324 {
00325 return (Attributes*) SerialObj::Unserialize(info, SER_ATTRIBUTES);
00326 }
00327
00328 IMPLEMENT_SERIAL(Attributes, SER_ATTRIBUTES);
00329
00330 bool Attributes::DoSerialize(SerialInfo* info) const
00331 {
00332 DO_SERIALIZE(SER_ATTRIBUTES, BroObj);
00333
00334 info->s->WriteOpenTag("Attributes");
00335 assert(type);
00336 if ( ! (type->Serialize(info) && SERIALIZE(attrs->length())) )
00337 return false;
00338
00339 loop_over_list((*attrs), i)
00340 {
00341 Attr* a = (*attrs)[i];
00342 SERIALIZE_OPTIONAL(a->AttrExpr())
00343 if ( ! SERIALIZE(char(a->Tag())) )
00344 return false;
00345 }
00346
00347 info->s->WriteCloseTag("Attributes");
00348 return true;
00349 }
00350
00351 bool Attributes::DoUnserialize(UnserialInfo* info)
00352 {
00353 DO_UNSERIALIZE(BroObj);
00354
00355 type = BroType::Unserialize(info);
00356 if ( ! type )
00357 return false;
00358
00359 int len;
00360 if ( ! UNSERIALIZE(&len) )
00361 return false;
00362
00363 attrs = new attr_list(len);
00364 while ( len-- )
00365 {
00366 Expr* e;
00367 UNSERIALIZE_OPTIONAL(e, Expr::Unserialize(info))
00368
00369 char tag;
00370 if ( ! UNSERIALIZE(&tag) )
00371 {
00372 delete e;
00373 return false;
00374 }
00375
00376 attrs->append(new Attr((attr_tag)tag, e));
00377 }
00378
00379 return true;
00380 }
00381