attrs.cc

Go to the documentation of this file.
00001 //
00002 // attrs.cc        : Attribute Functions
00003 // authors         : John Heidemann and Fabio Silva
00004 //
00005 // Copyright (C) 2000-2002 by the University of Southern California
00006 // $Id: attrs.cc,v 1.7 2005/09/13 04:53:49 tomh Exp $
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License,
00010 // version 2, as published by the Free Software Foundation.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License along
00018 // with this program; if not, write to the Free Software Foundation, Inc.,
00019 // 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00020 //
00021 // Linking this file statically or dynamically with other modules is making
00022 // a combined work based on this file.  Thus, the terms and conditions of
00023 // the GNU General Public License cover the whole combination.
00024 //
00025 // In addition, as a special exception, the copyright holders of this file
00026 // give you permission to combine this file with free software programs or
00027 // libraries that are released under the GNU LGPL and with code included in
00028 // the standard release of ns-2 under the Apache 2.0 license or under
00029 // otherwise-compatible licenses with advertising requirements (or modified
00030 // versions of such code, with unchanged license).  You may copy and
00031 // distribute such a system following the terms of the GNU GPL for this
00032 // file and the licenses of the other code concerned, provided that you
00033 // include the source code of that other code when and as the GNU GPL
00034 // requires distribution of source code.
00035 //
00036 // Note that people who make modified versions of this file are not
00037 // obligated to grant this special exception for their modified versions;
00038 // it is their choice whether to do so.  The GNU General Public License
00039 // gives permission to release a modified version without this exception;
00040 // this exception also makes it possible to release a modified version
00041 // which carries forward this exception.
00042 //
00043 
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046 
00047 #include "attrs.hh"
00048 
00049 class PackedAttribute {
00050 public:
00051   int32_t key_;
00052   int8_t type_;
00053   int8_t op_;
00054   int16_t len_;
00055   int32_t val_;
00056 };
00057 
00058 NRAttrVec * CopyAttrs(NRAttrVec *src_attrs)
00059 {
00060   NRAttrVec::iterator itr;
00061   NRAttrVec *dst_attrs;
00062   NRAttribute *src;
00063 
00064   dst_attrs = new NRAttrVec;
00065 
00066   for (itr = src_attrs->begin(); itr != src_attrs->end(); ++itr){
00067     src = *itr;
00068     switch (src->getType()){
00069     case NRAttribute::INT32_TYPE:
00070       dst_attrs->push_back(new NRSimpleAttribute<int>(src->getKey(),
00071                         NRAttribute::INT32_TYPE,
00072                             src->getOp(),
00073                            ((NRSimpleAttribute<int> *)src)->getVal()));
00074       break;
00075 
00076     case NRAttribute::FLOAT32_TYPE:
00077       dst_attrs->push_back(new NRSimpleAttribute<float>(src->getKey(),
00078                         NRAttribute::FLOAT32_TYPE,
00079                         src->getOp(),
00080                         ((NRSimpleAttribute<float> *)src)->getVal()));
00081       break;
00082 
00083     case NRAttribute::FLOAT64_TYPE:
00084       dst_attrs->push_back(new NRSimpleAttribute<double>(src->getKey(),
00085                          NRAttribute::FLOAT64_TYPE,
00086                          src->getOp(),
00087                          ((NRSimpleAttribute<double> *)src)->getVal()));
00088       break;
00089 
00090     case NRAttribute::STRING_TYPE:
00091       dst_attrs->push_back(new NRSimpleAttribute<char *>(src->getKey(),
00092                         NRAttribute::STRING_TYPE,
00093                         src->getOp(),
00094                         ((NRSimpleAttribute<char *> *)src)->getVal()));
00095       break;
00096 
00097     case NRAttribute::BLOB_TYPE:
00098       dst_attrs->push_back(new NRSimpleAttribute<void *>(src->getKey(),
00099                           NRAttribute::BLOB_TYPE,
00100                           src->getOp(),
00101                           ((NRSimpleAttribute<void *> *)src)->getVal(),
00102                           src->getLen()));
00103       break;
00104 
00105     default:
00106 
00107       DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in CopyAttrs() !\n");
00108       break;
00109     }
00110   }
00111   return dst_attrs;
00112 }
00113 
00114 void AddAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
00115 {
00116   NRAttrVec *copied_attrs;
00117   NRAttrVec::iterator itr;
00118   NRAttribute *src;
00119 
00120   if (attr_vec1 == NULL)
00121     attr_vec1 = new NRAttrVec;
00122 
00123   // Check if there's something to do
00124   if (attr_vec2 == NULL)
00125     return;
00126 
00127   // Duplicate source attributes so they can be added to the dst set
00128   copied_attrs = CopyAttrs(attr_vec2);
00129 
00130   // Add all attributes in the copied set into the dst set
00131   for (itr = copied_attrs->begin(); itr != copied_attrs->end(); ++itr){
00132     src = *itr;
00133 
00134     attr_vec1->push_back(src);
00135   }
00136 
00137   // Delete the copied_attr vector without deleting its attributes
00138   delete copied_attrs;
00139 }
00140 
00141 void ClearAttrs(NRAttrVec *attr_vec)
00142 {
00143   NRAttrVec::iterator itr;
00144 
00145   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
00146     delete *itr;
00147   }
00148 
00149   attr_vec->clear();
00150 }
00151 
00152 void PrintAttrs(NRAttrVec *attr_vec)
00153 {
00154   NRAttrVec::iterator itr;
00155   NRAttribute *aux;
00156   int counter = 0;
00157 
00158   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
00159     aux = *itr;
00160     DiffPrint(DEBUG_ALWAYS, "Attribute #%d\n", counter);
00161     counter++;
00162     DiffPrint(DEBUG_ALWAYS, "-------------\n");
00163     DiffPrint(DEBUG_ALWAYS, "Type = %d\n", aux->getType());
00164     DiffPrint(DEBUG_ALWAYS, "Key  = %d\n", aux->getKey());
00165     DiffPrint(DEBUG_ALWAYS, "Op   = %d\n", aux->getOp());
00166     DiffPrint(DEBUG_ALWAYS, "Len  = %d\n", aux->getLen());
00167     switch(aux->getType()){
00168     case NRAttribute::INT32_TYPE:
00169       DiffPrint(DEBUG_ALWAYS, "Val  = %d\n",
00170         ((NRSimpleAttribute<int> *)aux)->getVal());
00171       break;
00172     case NRAttribute::FLOAT32_TYPE:
00173       DiffPrint(DEBUG_ALWAYS, "Val  = %f\n",
00174         ((NRSimpleAttribute<float> *)aux)->getVal());
00175       break;
00176     case NRAttribute::FLOAT64_TYPE:
00177       DiffPrint(DEBUG_ALWAYS, "Val  = %f\n",
00178         ((NRSimpleAttribute<double> *)aux)->getVal());
00179       break;
00180     case NRAttribute::STRING_TYPE:
00181       DiffPrint(DEBUG_ALWAYS, "Val  = %s\n",
00182         ((NRSimpleAttribute<char *> *)aux)->getVal());
00183       break;
00184     case NRAttribute::BLOB_TYPE:
00185       DiffPrint(DEBUG_ALWAYS, "Val  = %s\n",
00186         ((NRSimpleAttribute<void *> *)aux)->getVal());
00187       break;
00188     default:
00189       DiffPrint(DEBUG_ALWAYS, "Val  = Unknown\n");
00190       break;
00191     }
00192     DiffPrint(DEBUG_ALWAYS, "\n");
00193   }
00194 }
00195 
00196 DiffPacket AllocateBuffer(NRAttrVec *attr_vec)
00197 {
00198   DiffPacket pkt;
00199   int len;
00200 
00201   len = CalculateSize(attr_vec);
00202   len = len + sizeof(struct hdr_diff);
00203   pkt = new int [1 + (len / sizeof(int))];
00204 
00205   if (pkt == NULL){
00206     DiffPrint(DEBUG_ALWAYS, "Cannot allocate memory for packet !\n");
00207     exit(-1);
00208   }
00209 
00210   return pkt;
00211 }
00212 
00213 int CalculateSize(NRAttrVec *attr_vec)
00214 {
00215   NRAttrVec::iterator itr;
00216   NRAttribute *temp;
00217   int pad, attr_len;
00218   int total_len = 0;
00219 
00220   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
00221     temp = *itr;
00222     attr_len = temp->getLen();
00223 
00224     // We have to pad to avoid bus errors
00225     pad = 0;
00226     if (attr_len % sizeof(int)){
00227       pad = sizeof(int) - (attr_len % sizeof(int));
00228     }
00229     total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
00230   }
00231   return total_len;
00232 }
00233 
00234 int PackAttrs(NRAttrVec *attr_vec, char *start_pos)
00235 {
00236   PackedAttribute *current;
00237   NRAttrVec::iterator itr;
00238   NRAttribute *temp;
00239   int32_t t;
00240   char *pos;
00241   int pad, attr_len;
00242   int total_len = 0;
00243 
00244   current = (PackedAttribute *) start_pos;
00245 
00246   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
00247     temp = *itr;
00248     current->key_ = htonl(temp->getKey());
00249     current->type_ = temp->getType();
00250     current->op_ = temp->getOp();
00251     attr_len = temp->getLen();
00252     current->len_ = htons(attr_len);
00253     if (attr_len > 0){
00254       switch (current->type_){
00255       case NRAttribute::INT32_TYPE:
00256 
00257     t = htonl(((NRSimpleAttribute<int> *)temp)->getVal());
00258     memcpy(&current->val_, &t, sizeof(int32_t));
00259 
00260     break;
00261 
00262       default:
00263 
00264     memcpy(&current->val_, temp->getGenericVal(), attr_len);
00265 
00266     break;
00267       }
00268     }
00269 
00270     // We have to pad in order to avoid bus errors
00271     pad = 0;
00272     if (attr_len % sizeof(int)){
00273       pad = sizeof(int) - (attr_len % sizeof(int));
00274     }
00275     total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
00276     pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
00277     current = (PackedAttribute *) pos;
00278   }
00279   return total_len;
00280 }
00281 
00282 NRAttrVec * UnpackAttrs(DiffPacket pkt, int num_attr)
00283 {
00284   PackedAttribute *current;
00285   NRAttrVec *attr_vec;
00286   int attr_len;
00287   char *pos;
00288   int pad;
00289 
00290   attr_vec = new NRAttrVec;
00291 
00292   pos = (char *) &pkt[0];
00293   current = (PackedAttribute *) (pos + sizeof(struct hdr_diff));
00294 
00295   for (int i = 0; i < num_attr; i++){
00296     switch (current->type_){
00297     case NRAttribute::INT32_TYPE:
00298       attr_vec->push_back(new NRSimpleAttribute<int>(ntohl(current->key_),
00299                         NRAttribute::INT32_TYPE,
00300                         current->op_,
00301                         ntohl(*(int *)&current->val_)));
00302       break;
00303 
00304     case NRAttribute::FLOAT32_TYPE:
00305       attr_vec->push_back(new NRSimpleAttribute<float>(ntohl(current->key_),
00306                         NRAttribute::FLOAT32_TYPE,
00307                             current->op_,
00308                             *(float *)&current->val_));
00309       break;
00310 
00311     case NRAttribute::FLOAT64_TYPE:
00312       attr_vec->push_back(new NRSimpleAttribute<double>(ntohl(current->key_),
00313                          NRAttribute::FLOAT64_TYPE,
00314                          current->op_,
00315                          *(double *)&current->val_));
00316       break;
00317 
00318     case NRAttribute::STRING_TYPE:
00319       attr_vec->push_back(new NRSimpleAttribute<char *>(ntohl(current->key_),
00320                         NRAttribute::STRING_TYPE,
00321                         current->op_,
00322                         (char *)&current->val_));
00323       break;
00324 
00325     case NRAttribute::BLOB_TYPE:
00326       attr_vec->push_back(new NRSimpleAttribute<void *>(ntohl(current->key_),
00327                       NRAttribute::BLOB_TYPE,
00328                           current->op_,
00329                       (void *)&current->val_,
00330                               ntohs(current->len_)));
00331       break;
00332 
00333     default:
00334 
00335       DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in UnpackAttrs() !\n");
00336       break;
00337     }
00338 
00339     attr_len = ntohs(current->len_);
00340 
00341     pad = 0;
00342     if (attr_len % sizeof(int)){
00343       // We have to calculate how much 'padding' to skip in order to
00344       // avoid bus errors
00345       pad = sizeof(int) - (attr_len % sizeof(int));
00346     }
00347     pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
00348     current = (PackedAttribute *) pos;
00349   }
00350 
00351   return attr_vec;
00352 }
00353 
00354 bool PerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
00355 {
00356   if (attr_vec1->size() != attr_vec2->size())
00357     return false;
00358 
00359   if (OneWayPerfectMatch(attr_vec1, attr_vec2))
00360     if (OneWayPerfectMatch(attr_vec2, attr_vec1))
00361       return true;
00362 
00363   return false;
00364 }
00365 
00366 bool OneWayPerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
00367 {
00368   NRAttrVec::iterator itr1, itr2;
00369   NRAttribute *a;
00370   NRAttribute *b;
00371 
00372   for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){
00373 
00374     // For each attribute in vec1, we look in vec2 for the same attr
00375     a = *itr1;
00376     itr2 = attr_vec2->begin();
00377     b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
00378 
00379     while (b){
00380       // They should have the same operator and be "EQUAL"
00381       if (a->getOp() == b->getOp())
00382     if (a->isEQ(b))
00383       break;
00384 
00385       // Keys match but value/operator don't. Let's
00386       // Try to find another attribute with the same key
00387       itr2++;
00388       b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
00389     }
00390 
00391     // Check if attribute found
00392     if (b == NULL)
00393       return false;
00394   }
00395 
00396   // All attributes match !
00397   return true;
00398 }
00399 
00400 bool MatchAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
00401 {
00402   if (OneWayMatch(attr_vec1, attr_vec2))
00403     if (OneWayMatch(attr_vec2, attr_vec1))
00404       return true;
00405 
00406   return false;
00407 }
00408 
00409 bool OneWayMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
00410 {
00411   NRAttrVec::iterator itr1, itr2;
00412   NRAttribute *a;
00413   NRAttribute *b;
00414   bool found_attr;
00415 
00416   for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){
00417 
00418     // For each attribute in vec1 that has an operator different
00419     // than "IS", we need to find a "matchable" one in vec2
00420     a = *itr1;
00421     if (a->getOp() == NRAttribute::IS)
00422       continue;
00423 
00424     itr2 = attr_vec2->begin();
00425     for (;;){
00426       b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
00427 
00428       // Found ?
00429       if (!b)
00430     return false;
00431 
00432       // If Op is not "IS" we need keep looking
00433       if (b->getOp() != NRAttribute::IS){
00434     itr2++;
00435     continue;
00436       }
00437 
00438       // If a's Op is "EQ_ANY" that's enough   
00439       if (a->getOp() == NRAttribute::EQ_ANY){
00440     found_attr = true;
00441     break;
00442       }
00443 
00444       found_attr = false;
00445 
00446       switch (a->getOp()){
00447 
00448      case NRAttribute::EQ:
00449 
00450        if (b->isEQ(a))
00451          found_attr = true;
00452 
00453        break;
00454 
00455       case NRAttribute::GT:
00456 
00457     if (b->isGT(a))
00458       found_attr = true;
00459 
00460     break;
00461 
00462       case NRAttribute::GE:
00463 
00464     if (b->isGE(a))
00465       found_attr = true;
00466 
00467     break;
00468 
00469       case NRAttribute::LT:
00470 
00471     if (b->isLT(a))
00472       found_attr = true;
00473 
00474     break;
00475 
00476       case NRAttribute::LE:
00477 
00478     if (b->isLE(a))
00479       found_attr = true;
00480 
00481     break;
00482 
00483       case NRAttribute::NE:
00484 
00485     if (b->isNE(a))
00486       found_attr = true;
00487 
00488     break;
00489 
00490       default:
00491 
00492     DiffPrint(DEBUG_ALWAYS, "Unknown operator found in OneWayMacth !\n");
00493     break;
00494       }
00495 
00496       if (found_attr)
00497     break;
00498 
00499       itr2++;
00500     }
00501   }
00502 
00503   // All attributes found !
00504   return true;
00505 }
00506 

Generated on Tue Mar 6 16:47:43 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6