attrs.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. //
  2. // attrs.cc        : Attribute Functions
  3. // authors         : John Heidemann and Fabio Silva
  4. //
  5. // Copyright (C) 2000-2002 by the University of Southern California
  6. // $Id: attrs.cc,v 1.7 2005/09/13 04:53:49 tomh Exp $
  7. //
  8. // This program is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU General Public License,
  10. // version 2, as published by the Free Software Foundation.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License along
  18. // with this program; if not, write to the Free Software Foundation, Inc.,
  19. // 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  20. //
  21. // Linking this file statically or dynamically with other modules is making
  22. // a combined work based on this file.  Thus, the terms and conditions of
  23. // the GNU General Public License cover the whole combination.
  24. //
  25. // In addition, as a special exception, the copyright holders of this file
  26. // give you permission to combine this file with free software programs or
  27. // libraries that are released under the GNU LGPL and with code included in
  28. // the standard release of ns-2 under the Apache 2.0 license or under
  29. // otherwise-compatible licenses with advertising requirements (or modified
  30. // versions of such code, with unchanged license).  You may copy and
  31. // distribute such a system following the terms of the GNU GPL for this
  32. // file and the licenses of the other code concerned, provided that you
  33. // include the source code of that other code when and as the GNU GPL
  34. // requires distribution of source code.
  35. //
  36. // Note that people who make modified versions of this file are not
  37. // obligated to grant this special exception for their modified versions;
  38. // it is their choice whether to do so.  The GNU General Public License
  39. // gives permission to release a modified version without this exception;
  40. // this exception also makes it possible to release a modified version
  41. // which carries forward this exception.
  42. //
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include "attrs.hh"
  46. class PackedAttribute {
  47. public:
  48.   int32_t key_;
  49.   int8_t type_;
  50.   int8_t op_;
  51.   int16_t len_;
  52.   int32_t val_;
  53. };
  54. NRAttrVec * CopyAttrs(NRAttrVec *src_attrs)
  55. {
  56.   NRAttrVec::iterator itr;
  57.   NRAttrVec *dst_attrs;
  58.   NRAttribute *src;
  59.   dst_attrs = new NRAttrVec;
  60.   for (itr = src_attrs->begin(); itr != src_attrs->end(); ++itr){
  61.     src = *itr;
  62.     switch (src->getType()){
  63.     case NRAttribute::INT32_TYPE:
  64.       dst_attrs->push_back(new NRSimpleAttribute<int>(src->getKey(),
  65. NRAttribute::INT32_TYPE,
  66.         src->getOp(),
  67.        ((NRSimpleAttribute<int> *)src)->getVal()));
  68.       break;
  69.     case NRAttribute::FLOAT32_TYPE:
  70.       dst_attrs->push_back(new NRSimpleAttribute<float>(src->getKey(),
  71. NRAttribute::FLOAT32_TYPE,
  72. src->getOp(),
  73. ((NRSimpleAttribute<float> *)src)->getVal()));
  74.       break;
  75.     case NRAttribute::FLOAT64_TYPE:
  76.       dst_attrs->push_back(new NRSimpleAttribute<double>(src->getKey(),
  77.  NRAttribute::FLOAT64_TYPE,
  78.  src->getOp(),
  79.  ((NRSimpleAttribute<double> *)src)->getVal()));
  80.       break;
  81.     case NRAttribute::STRING_TYPE:
  82.       dst_attrs->push_back(new NRSimpleAttribute<char *>(src->getKey(),
  83. NRAttribute::STRING_TYPE,
  84. src->getOp(),
  85. ((NRSimpleAttribute<char *> *)src)->getVal()));
  86.       break;
  87.     case NRAttribute::BLOB_TYPE:
  88.       dst_attrs->push_back(new NRSimpleAttribute<void *>(src->getKey(),
  89.       NRAttribute::BLOB_TYPE,
  90.       src->getOp(),
  91.       ((NRSimpleAttribute<void *> *)src)->getVal(),
  92.       src->getLen()));
  93.       break;
  94.     default:
  95.       DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in CopyAttrs() !n");
  96.       break;
  97.     }
  98.   }
  99.   return dst_attrs;
  100. }
  101. void AddAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
  102. {
  103.   NRAttrVec *copied_attrs;
  104.   NRAttrVec::iterator itr;
  105.   NRAttribute *src;
  106.   if (attr_vec1 == NULL)
  107.     attr_vec1 = new NRAttrVec;
  108.   // Check if there's something to do
  109.   if (attr_vec2 == NULL)
  110.     return;
  111.   // Duplicate source attributes so they can be added to the dst set
  112.   copied_attrs = CopyAttrs(attr_vec2);
  113.   // Add all attributes in the copied set into the dst set
  114.   for (itr = copied_attrs->begin(); itr != copied_attrs->end(); ++itr){
  115.     src = *itr;
  116.     attr_vec1->push_back(src);
  117.   }
  118.   // Delete the copied_attr vector without deleting its attributes
  119.   delete copied_attrs;
  120. }
  121. void ClearAttrs(NRAttrVec *attr_vec)
  122. {
  123.   NRAttrVec::iterator itr;
  124.   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
  125.     delete *itr;
  126.   }
  127.   attr_vec->clear();
  128. }
  129. void PrintAttrs(NRAttrVec *attr_vec)
  130. {
  131.   NRAttrVec::iterator itr;
  132.   NRAttribute *aux;
  133.   int counter = 0;
  134.   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
  135.     aux = *itr;
  136.     DiffPrint(DEBUG_ALWAYS, "Attribute #%dn", counter);
  137.     counter++;
  138.     DiffPrint(DEBUG_ALWAYS, "-------------n");
  139.     DiffPrint(DEBUG_ALWAYS, "Type = %dn", aux->getType());
  140.     DiffPrint(DEBUG_ALWAYS, "Key  = %dn", aux->getKey());
  141.     DiffPrint(DEBUG_ALWAYS, "Op   = %dn", aux->getOp());
  142.     DiffPrint(DEBUG_ALWAYS, "Len  = %dn", aux->getLen());
  143.     switch(aux->getType()){
  144.     case NRAttribute::INT32_TYPE:
  145.       DiffPrint(DEBUG_ALWAYS, "Val  = %dn",
  146. ((NRSimpleAttribute<int> *)aux)->getVal());
  147.       break;
  148.     case NRAttribute::FLOAT32_TYPE:
  149.       DiffPrint(DEBUG_ALWAYS, "Val  = %fn",
  150. ((NRSimpleAttribute<float> *)aux)->getVal());
  151.       break;
  152.     case NRAttribute::FLOAT64_TYPE:
  153.       DiffPrint(DEBUG_ALWAYS, "Val  = %fn",
  154. ((NRSimpleAttribute<double> *)aux)->getVal());
  155.       break;
  156.     case NRAttribute::STRING_TYPE:
  157.       DiffPrint(DEBUG_ALWAYS, "Val  = %sn",
  158. ((NRSimpleAttribute<char *> *)aux)->getVal());
  159.       break;
  160.     case NRAttribute::BLOB_TYPE:
  161.       DiffPrint(DEBUG_ALWAYS, "Val  = %sn",
  162. ((NRSimpleAttribute<void *> *)aux)->getVal());
  163.       break;
  164.     default:
  165.       DiffPrint(DEBUG_ALWAYS, "Val  = Unknownn");
  166.       break;
  167.     }
  168.     DiffPrint(DEBUG_ALWAYS, "n");
  169.   }
  170. }
  171. DiffPacket AllocateBuffer(NRAttrVec *attr_vec)
  172. {
  173.   DiffPacket pkt;
  174.   int len;
  175.   len = CalculateSize(attr_vec);
  176.   len = len + sizeof(struct hdr_diff);
  177.   pkt = new int [1 + (len / sizeof(int))];
  178.   if (pkt == NULL){
  179.     DiffPrint(DEBUG_ALWAYS, "Cannot allocate memory for packet !n");
  180.     exit(-1);
  181.   }
  182.   return pkt;
  183. }
  184. int CalculateSize(NRAttrVec *attr_vec)
  185. {
  186.   NRAttrVec::iterator itr;
  187.   NRAttribute *temp;
  188.   int pad, attr_len;
  189.   int total_len = 0;
  190.   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
  191.     temp = *itr;
  192.     attr_len = temp->getLen();
  193.     // We have to pad to avoid bus errors
  194.     pad = 0;
  195.     if (attr_len % sizeof(int)){
  196.       pad = sizeof(int) - (attr_len % sizeof(int));
  197.     }
  198.     total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
  199.   }
  200.   return total_len;
  201. }
  202. int PackAttrs(NRAttrVec *attr_vec, char *start_pos)
  203. {
  204.   PackedAttribute *current;
  205.   NRAttrVec::iterator itr;
  206.   NRAttribute *temp;
  207.   int32_t t;
  208.   char *pos;
  209.   int pad, attr_len;
  210.   int total_len = 0;
  211.   current = (PackedAttribute *) start_pos;
  212.   for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){
  213.     temp = *itr;
  214.     current->key_ = htonl(temp->getKey());
  215.     current->type_ = temp->getType();
  216.     current->op_ = temp->getOp();
  217.     attr_len = temp->getLen();
  218.     current->len_ = htons(attr_len);
  219.     if (attr_len > 0){
  220.       switch (current->type_){
  221.       case NRAttribute::INT32_TYPE:
  222. t = htonl(((NRSimpleAttribute<int> *)temp)->getVal());
  223. memcpy(&current->val_, &t, sizeof(int32_t));
  224. break;
  225.       default:
  226. memcpy(&current->val_, temp->getGenericVal(), attr_len);
  227. break;
  228.       }
  229.     }
  230.     // We have to pad in order to avoid bus errors
  231.     pad = 0;
  232.     if (attr_len % sizeof(int)){
  233.       pad = sizeof(int) - (attr_len % sizeof(int));
  234.     }
  235.     total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
  236.     pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
  237.     current = (PackedAttribute *) pos;
  238.   }
  239.   return total_len;
  240. }
  241. NRAttrVec * UnpackAttrs(DiffPacket pkt, int num_attr)
  242. {
  243.   PackedAttribute *current;
  244.   NRAttrVec *attr_vec;
  245.   int attr_len;
  246.   char *pos;
  247.   int pad;
  248.   attr_vec = new NRAttrVec;
  249.   pos = (char *) &pkt[0];
  250.   current = (PackedAttribute *) (pos + sizeof(struct hdr_diff));
  251.   for (int i = 0; i < num_attr; i++){
  252.     switch (current->type_){
  253.     case NRAttribute::INT32_TYPE:
  254.       attr_vec->push_back(new NRSimpleAttribute<int>(ntohl(current->key_),
  255. NRAttribute::INT32_TYPE,
  256. current->op_,
  257. ntohl(*(int *)&current->val_)));
  258.       break;
  259.     case NRAttribute::FLOAT32_TYPE:
  260.       attr_vec->push_back(new NRSimpleAttribute<float>(ntohl(current->key_),
  261. NRAttribute::FLOAT32_TYPE,
  262.         current->op_,
  263.         *(float *)&current->val_));
  264.       break;
  265.     case NRAttribute::FLOAT64_TYPE:
  266.       attr_vec->push_back(new NRSimpleAttribute<double>(ntohl(current->key_),
  267.      NRAttribute::FLOAT64_TYPE,
  268.      current->op_,
  269.      *(double *)&current->val_));
  270.       break;
  271.     case NRAttribute::STRING_TYPE:
  272.       attr_vec->push_back(new NRSimpleAttribute<char *>(ntohl(current->key_),
  273.     NRAttribute::STRING_TYPE,
  274.     current->op_,
  275.     (char *)&current->val_));
  276.       break;
  277.     case NRAttribute::BLOB_TYPE:
  278.       attr_vec->push_back(new NRSimpleAttribute<void *>(ntohl(current->key_),
  279.   NRAttribute::BLOB_TYPE,
  280.           current->op_,
  281.   (void *)&current->val_,
  282.                   ntohs(current->len_)));
  283.       break;
  284.     default:
  285.       DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in UnpackAttrs() !n");
  286.       break;
  287.     }
  288.     attr_len = ntohs(current->len_);
  289.     pad = 0;
  290.     if (attr_len % sizeof(int)){
  291.       // We have to calculate how much 'padding' to skip in order to
  292.       // avoid bus errors
  293.       pad = sizeof(int) - (attr_len % sizeof(int));
  294.     }
  295.     pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad;
  296.     current = (PackedAttribute *) pos;
  297.   }
  298.   return attr_vec;
  299. }
  300. bool PerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
  301. {
  302.   if (attr_vec1->size() != attr_vec2->size())
  303.     return false;
  304.   if (OneWayPerfectMatch(attr_vec1, attr_vec2))
  305.     if (OneWayPerfectMatch(attr_vec2, attr_vec1))
  306.       return true;
  307.   return false;
  308. }
  309. bool OneWayPerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
  310. {
  311.   NRAttrVec::iterator itr1, itr2;
  312.   NRAttribute *a;
  313.   NRAttribute *b;
  314.   for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){
  315.     // For each attribute in vec1, we look in vec2 for the same attr
  316.     a = *itr1;
  317.     itr2 = attr_vec2->begin();
  318.     b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
  319.     while (b){
  320.       // They should have the same operator and be "EQUAL"
  321.       if (a->getOp() == b->getOp())
  322. if (a->isEQ(b))
  323.   break;
  324.       // Keys match but value/operator don't. Let's
  325.       // Try to find another attribute with the same key
  326.       itr2++;
  327.       b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
  328.     }
  329.     // Check if attribute found
  330.     if (b == NULL)
  331.       return false;
  332.   }
  333.   // All attributes match !
  334.   return true;
  335. }
  336. bool MatchAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
  337. {
  338.   if (OneWayMatch(attr_vec1, attr_vec2))
  339.     if (OneWayMatch(attr_vec2, attr_vec1))
  340.       return true;
  341.   return false;
  342. }
  343. bool OneWayMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2)
  344. {
  345.   NRAttrVec::iterator itr1, itr2;
  346.   NRAttribute *a;
  347.   NRAttribute *b;
  348.   bool found_attr;
  349.   for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){
  350.     // For each attribute in vec1 that has an operator different
  351.     // than "IS", we need to find a "matchable" one in vec2
  352.     a = *itr1;
  353.     if (a->getOp() == NRAttribute::IS)
  354.       continue;
  355.     itr2 = attr_vec2->begin();
  356.     for (;;){
  357.       b = a->find_matching_key_from(attr_vec2, itr2, &itr2);
  358.       // Found ?
  359.       if (!b)
  360. return false;
  361.       // If Op is not "IS" we need keep looking
  362.       if (b->getOp() != NRAttribute::IS){
  363. itr2++;
  364. continue;
  365.       }
  366.       // If a's Op is "EQ_ANY" that's enough   
  367.       if (a->getOp() == NRAttribute::EQ_ANY){
  368. found_attr = true;
  369. break;
  370.       }
  371.       found_attr = false;
  372.       switch (a->getOp()){
  373.  case NRAttribute::EQ:
  374.    if (b->isEQ(a))
  375.      found_attr = true;
  376.    break;
  377.       case NRAttribute::GT:
  378. if (b->isGT(a))
  379.   found_attr = true;
  380. break;
  381.       case NRAttribute::GE:
  382. if (b->isGE(a))
  383.   found_attr = true;
  384. break;
  385.       case NRAttribute::LT:
  386. if (b->isLT(a))
  387.   found_attr = true;
  388. break;
  389.       case NRAttribute::LE:
  390. if (b->isLE(a))
  391.   found_attr = true;
  392. break;
  393.       case NRAttribute::NE:
  394. if (b->isNE(a))
  395.   found_attr = true;
  396. break;
  397.       default:
  398. DiffPrint(DEBUG_ALWAYS, "Unknown operator found in OneWayMacth !n");
  399. break;
  400.       }
  401.       if (found_attr)
  402. break;
  403.       itr2++;
  404.     }
  405.   }
  406.   // All attributes found !
  407.   return true;
  408. }