oid.cpp
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:20k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*_############################################################################
  2.   _## 
  3.   _##  oid.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.22
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2007 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Wed May  2 23:22:30 CEST 2007 
  27.   _##  
  28.   _##########################################################################*/
  29. /*===================================================================
  30.   Copyright (c) 1999
  31.   Hewlett-Packard Company
  32.   ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  33.   Permission to use, copy, modify, distribute and/or sell this software
  34.   and/or its documentation is hereby granted without fee. User agrees
  35.   to display the above copyright notice and this license notice in all
  36.   copies of the software and any documentation of the software. User
  37.   agrees to assume all liability for the use of the software; Hewlett-Packard
  38.   makes no representations about the suitability of this software for any
  39.   purpose. It is provided "AS-IS" without warranty of any kind,either express
  40.   or implied. User hereby grants a royalty-free license to any and all
  41.   derivatives based upon this software code base.
  42.   O I D. C P P
  43.   OID CLASS IMPLEMENTATION
  44.   DESIGN + AUTHOR:         Peter E. Mellquist
  45.   DESCRIPTION:
  46.   This module contains the implementation of the oid class. This
  47.   includes all protected and public member functions. The oid class
  48.   may be compiled stand alone without the use of any other library.
  49.   LANGUAGE:                ANSI C++
  50. =====================================================================*/
  51. char oid_cpp_version[]="#(@) SNMP++ $Id: oid.cpp 281 2007-03-22 21:58:34Z katz $";
  52. //---------[ external C libaries used ]--------------------------------
  53. #include <stdio.h>                // standard io
  54. #if !(defined (CPU) && CPU == PPC603)
  55. #include <memory.h>               // memcpy's
  56. #endif
  57. #include <string.h>               // strlen, etc..
  58. #include <stdlib.h>               // standard library
  59. #include <ctype.h>                // isdigit
  60. #include <stdlib.h>               // malloc, free
  61. #include "snmp_pp/oid.h"                  // include def for oid class
  62. #ifdef SNMP_PP_NAMESPACE
  63. namespace Snmp_pp {
  64. #endif
  65. #define  SNMPBUFFSIZE 11          // size of scratch buffer
  66. #define  SNMPCHARSIZE 11          // an individual oid instance as a string
  67. /* Borlands isdigit has a bug */
  68. #ifdef __BCPLUSPLUS__
  69. #define my_isdigit(c) ((c) >= '0' && (c) <= '9')
  70. #else
  71. #define my_isdigit isdigit
  72. #endif
  73. //=============[Oid::Oid(void)]============================================
  74. // constructor using no arguments
  75. // initialize octet ptr and string
  76. // ptr to null
  77. Oid::Oid() : iv_str(0), iv_part_str(0), m_changed(true)
  78. {
  79.   smival.syntax = sNMP_SYNTAX_OID;
  80.   smival.value.oid.len = 0;
  81.   smival.value.oid.ptr = 0;
  82. }
  83. //=============[Oid::Oid(const char *dotted_string ]=====================
  84. // constructor using a dotted string
  85. //
  86. // do a string to oid using the string passed in
  87. Oid::Oid(const char *oid_string, const bool is_dotted_oid_string)
  88.   : iv_str(0), iv_part_str(0), m_changed(true)
  89. {
  90.   smival.syntax = sNMP_SYNTAX_OID;
  91.   smival.value.oid.len = 0;
  92.   smival.value.oid.ptr = 0;
  93.   if (is_dotted_oid_string)
  94.     StrToOid(oid_string, &smival.value.oid);
  95.   else
  96.     set_data(oid_string, oid_string ? strlen(oid_string) : 0);
  97. }
  98. //=============[Oid::Oid(const Oid &oid) ]================================
  99. // constructor using another oid object
  100. //
  101. // do an oid copy using the oid object passed in
  102. Oid::Oid(const Oid &oid)
  103.   : iv_str(0), iv_part_str(0), m_changed(true)
  104. {
  105.   smival.syntax = sNMP_SYNTAX_OID;
  106.   smival.value.oid.len = 0;
  107.   smival.value.oid.ptr = 0;
  108.   // allocate some memory for the oid
  109.   // in this case the size to allocate is the same size as the source oid
  110.   if (oid.smival.value.oid.len)
  111.   {
  112.     smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid.smival.value.oid.len];
  113.     if (smival.value.oid.ptr)
  114.       OidCopy((SmiLPOID)&(oid.smival.value.oid), (SmiLPOID)&smival.value.oid);
  115.   }
  116. }
  117. //=============[Oid::Oid(const unsigned long *raw_oid, int oid_len) ]====
  118. // constructor using raw numeric form
  119. //
  120. // copy the integer values into the private member
  121. Oid::Oid(const unsigned long *raw_oid, int oid_len)
  122.   : iv_str(0), iv_part_str(0), m_changed(true)
  123. {
  124.   smival.syntax = sNMP_SYNTAX_OID;
  125.   smival.value.oid.len = 0;
  126.   smival.value.oid.ptr = 0;
  127.   if (raw_oid && (oid_len > 0))
  128.   {
  129.     smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid_len];
  130.     if (smival.value.oid.ptr)
  131.     {
  132.       smival.value.oid.len = oid_len;
  133.       for (int i=0; i < oid_len; i++)
  134.         smival.value.oid.ptr[i] = raw_oid[i];
  135.     }
  136.   }
  137. }
  138. #if 0
  139. // Constructor from standard C string array.
  140. Oid::Oid(const char *str, const unsigned int str_len)
  141.   : iv_str(0), iv_part_str(0), m_changed(true)
  142. {
  143.   smival.syntax = sNMP_SYNTAX_OID;
  144.   smival.value.oid.len = 0;
  145.   smival.value.oid.ptr = 0;
  146.   set_data(str, str_len);
  147. }
  148. #endif
  149. //=============[Oid::~Oid]==============================================
  150. Oid::~Oid()
  151. {
  152.   delete_oid_ptr();
  153.   if (iv_str)      delete [] iv_str;        // free up the output string
  154.   if (iv_part_str) delete [] iv_part_str;   // free up the output string
  155. }
  156. //=============[Oid::operator = const char * dotted_string ]==============
  157. // assignment to a string operator overloaded
  158. //
  159. // free the existing oid
  160. // create the new oid from the string
  161. // return this object
  162. Oid& Oid::operator=(const char *dotted_oid_string)
  163. {
  164.   delete_oid_ptr();
  165.   // assign the new value
  166.   StrToOid(dotted_oid_string, &smival.value.oid);
  167.   return *this;
  168. }
  169. //=============[Oid:: operator = const Oid &oid ]==========================
  170. // assignment to another oid object overloaded
  171. //
  172. // free the existing oid
  173. // create a new one from the object passed in
  174. Oid& Oid::operator=(const Oid &oid)
  175. {
  176.   if (this == &oid) return *this;  // protect against assignment from self
  177.   delete_oid_ptr();
  178.   // check for zero len on source
  179.   if (oid.smival.value.oid.len == 0)
  180.     return *this;
  181.   // allocate some memory for the oid
  182.   smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid.smival.value.oid.len];
  183.   if (smival.value.oid.ptr)
  184.     OidCopy((SmiLPOID)&(oid.smival.value.oid), (SmiLPOID)&smival.value.oid);
  185.   return *this;
  186. }
  187. //==============[Oid:: operator += const char *a ]=========================
  188. // append operator, appends a string
  189. //
  190. // allocate some space for a max oid string
  191. // extract current string into space
  192. // concat new string
  193. // free up existing oid
  194. // make a new oid from string
  195. // delete allocated space
  196. Oid& Oid::operator+=(const char *a)
  197. {
  198.   unsigned int n;
  199.   if (!a) return *this;
  200.   if (*a == '.') ++a;
  201.   n = (smival.value.oid.len * SNMPCHARSIZE) + (smival.value.oid.len)
  202.        + 1 + SAFE_UINT_CAST(strlen(a));
  203.   char *ptr = new char[n];
  204.   if (ptr)
  205.   {
  206.     /// @todo optimze this function (avoid conversion to string)
  207.     OidToStr(&smival.value.oid, n, ptr);
  208.     if (ptr[0])
  209.       STRCAT(ptr,".");
  210.     STRCAT(ptr,a);
  211.     delete_oid_ptr();
  212.     StrToOid(ptr, &smival.value.oid);
  213.     delete [] ptr;
  214.   }
  215.   return *this;
  216. }
  217. //=============[ int operator == oid,oid ]=================================
  218. // equivlence operator overloaded
  219. int operator==(const Oid &lhs, const Oid &rhs)
  220. {
  221.   // ensure same len, then use nCompare
  222.   if (rhs.len() != lhs.len()) return 0;
  223.   return (lhs.nCompare(rhs.len(), rhs) == 0);
  224. }
  225. //==============[ operator<(Oid &x,Oid &y) ]=============================
  226. // less than < overloaded
  227. int operator<(const Oid &lhs, const Oid &rhs)
  228. {
  229.   int result;
  230.   // call nCompare with the current
  231.   // Oidx, Oidy and len of Oidx
  232.   if((result = lhs.nCompare(rhs.len(), rhs))<0)  return 1;
  233.   if (result > 0)    return 0;
  234.   // if here, equivalent substrings, call the shorter one <
  235.   return (lhs.len() < rhs.len());
  236. }
  237. //==============[ operator==(Oid &x,char *) ]=============================
  238. // equivlence operator overloaded
  239. int operator==(const Oid &x, const char *dotted_oid_string)
  240. {
  241.   Oid to(dotted_oid_string);   // create a temp oid object
  242.   return (x == to);   // compare using existing operator
  243. }
  244. //==============[ operator!=(Oid &x,char*) ]=============================
  245. // not equivlence operator overloaded
  246. int operator!=(const Oid &x, const char *dotted_oid_string)
  247. {
  248.   Oid to(dotted_oid_string);  // create a temp oid object
  249.   return (x != to);  // compare using existing operator
  250. }
  251. //==============[ operator<(Oid &x,char*) ]=============================
  252. // less than < operator overloaded
  253. int operator<(const Oid &x, const char *dotted_oid_string)
  254. {
  255.   Oid to(dotted_oid_string);  // create a temp oid object
  256.   return (x < to);  // compare using existing operator
  257. }
  258. //==============[ operator<=(Oid &x,char *) ]=============================
  259. // less than <= operator overloaded
  260. int operator<=(const Oid &x,char *dotted_oid_string)
  261. {
  262.   Oid to(dotted_oid_string);  // create a temp oid object
  263.   return (x <= to);  // compare using existing operator
  264. }
  265. //==============[ operator>(Oid &x,char* ]=============================
  266. // greater than > operator overloaded
  267. int operator>(const Oid &x,const char *dotted_oid_string)
  268. {
  269.   Oid to(dotted_oid_string);  // create a temp oid object
  270.   return (x > to);   // compare using existing operator
  271. }
  272. //==============[ operator>=(Oid &x,char*) ]=============================
  273. // greater than >= operator overloaded
  274. int operator>=(const Oid &x,const char *dotted_oid_string)
  275. {
  276.   Oid to(dotted_oid_string);  // create a temp oid object
  277.   return (x >= to);   // compare using existing operator
  278. }
  279. //===============[Oid::set_data ]==---=====================================
  280. // copy data from raw form...
  281. void Oid::set_data(const unsigned long *raw_oid,
  282.                    const unsigned int oid_len)
  283. {
  284.   if (smival.value.oid.len < oid_len)
  285.   {
  286.     delete_oid_ptr();
  287.     smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[oid_len];
  288.     if (!smival.value.oid.ptr) return;
  289.   }
  290.   MEMCPY((SmiLPBYTE) smival.value.oid.ptr,
  291.          (SmiLPBYTE) raw_oid,
  292.          (size_t) (oid_len*sizeof(SmiUINT32)));
  293.   smival.value.oid.len = oid_len;
  294.   m_changed = true;
  295. }
  296. // Set the data from raw form.
  297. void Oid::set_data(const char *str, const unsigned int str_len)
  298. {
  299.   if (smival.value.oid.len < str_len)
  300.   {
  301.     delete_oid_ptr();
  302.     smival.value.oid.ptr = (SmiLPUINT32) new unsigned long[str_len];
  303.     if (!smival.value.oid.ptr) return;
  304.   }
  305.   if ((!str) || (str_len == 0))
  306.     return;
  307.   for (unsigned int i=0; i<str_len; i++)
  308.     smival.value.oid.ptr[i] = str[i];
  309.   smival.value.oid.len = str_len;
  310.   m_changed = true;
  311. }
  312. //===============[Oid::trim(unsigned int) ]============================
  313. // trim off the n leftmost values of an oid
  314. // Note!, does not adjust actual space for
  315. // speed
  316. void Oid::trim(const unsigned long n)
  317. {
  318.   // verify that n is legal
  319.   if ((n <= smival.value.oid.len) && (n > 0))
  320.   {
  321.     smival.value.oid.len -= n;
  322.     if (smival.value.oid.len == 0)
  323.       delete_oid_ptr();
  324.     m_changed = true;
  325.   }
  326. }
  327. //===============[Oid::operator += const unsigned int) ]====================
  328. // append operator, appends an int
  329. //
  330. Oid& Oid::operator+=(const unsigned long i)
  331. {
  332.   Oid other(&i, 1);
  333.   (*this) += other;
  334.   return *this;
  335. }
  336. //===============[Oid::operator += const Oid) ]========================
  337. // append operator, appends an Oid
  338. //
  339. // allocate some space for a max oid string
  340. // extract current string into space
  341. // concat new string
  342. // free up existing oid
  343. // make a new oid from string
  344. // delete allocated space
  345. Oid& Oid::operator+=(const Oid &o)
  346. {
  347.   SmiLPUINT32 new_oid;
  348.   if (o.smival.value.oid.len == 0)
  349.     return *this;
  350.   new_oid = (SmiLPUINT32) new unsigned long[smival.value.oid.len + o.smival.value.oid.len];
  351.   if (new_oid == 0)
  352.   {
  353.     delete_oid_ptr();
  354.     return *this;
  355.   }
  356.   if (smival.value.oid.ptr)
  357.   {
  358.     MEMCPY((SmiLPBYTE) new_oid,
  359.            (SmiLPBYTE) smival.value.oid.ptr,
  360.            (size_t) (smival.value.oid.len*sizeof(SmiUINT32)));
  361.     delete [] smival.value.oid.ptr;
  362.   }
  363.   // out with the old, in with the new...
  364.   smival.value.oid.ptr = new_oid;
  365.   MEMCPY((SmiLPBYTE) &new_oid[smival.value.oid.len],
  366.          (SmiLPBYTE) o.smival.value.oid.ptr,
  367.          (size_t) (o.smival.value.oid.len*sizeof(SmiUINT32)));
  368.   smival.value.oid.len += o.smival.value.oid.len;
  369.   m_changed = true;
  370.   return *this;
  371. }
  372. //==============[Oid::get_printable(unsigned int start, n) ]=============
  373. // return a dotted string starting at start,
  374. // going n positions to the left
  375. // NOTE, start is 1 based (the first id is at position #1)
  376. const char *Oid::get_printable(const unsigned long start,
  377.                                const unsigned long n,
  378.                                char *&buffer) const
  379. {
  380.   if (!m_changed && (buffer == iv_str))  return buffer;
  381.   unsigned long nz;
  382.   unsigned long my_start = start - 1;
  383.   unsigned long my_end   = my_start + n;
  384.   nz = (smival.value.oid.len * (SNMPCHARSIZE + 1)) + 1;
  385.   if (buffer) delete [] buffer;  // delete the previous output string
  386.   buffer = new char[nz];  // allocate some space for the output string
  387.   if (buffer == 0)
  388.     return 0;
  389.   buffer[0] = 0;  // init the string
  390.   // cannot ask for more than there is..
  391.   if ((start == 0) || (my_end > smival.value.oid.len))
  392.     return buffer;
  393.   char *cur_ptr = buffer;
  394.   bool first = true;
  395.   // loop through and build up a string
  396.   for (unsigned long index = my_start; index < my_end; ++index)
  397.   {
  398.     // if not at begin, pad with a dot
  399.     if (first)
  400.       first = false;
  401.     else
  402.       *cur_ptr++ = '.';
  403.     // convert data element to a string
  404.     cur_ptr += sprintf(cur_ptr, "%lu", smival.value.oid.ptr[index]);
  405.   }
  406.   if (buffer == iv_str)
  407.   {
  408.     Oid *nc_this = PP_CONST_CAST(Oid*, this);
  409.     nc_this->m_changed = false;
  410.   }
  411.   return buffer;
  412. }
  413. //=============[Oid::StrToOid(char *string, SmiLPOID dst) ]==============
  414. // convert a string to an oid
  415. int Oid::StrToOid(const char *str, SmiLPOID dstOid) const
  416. {
  417.   unsigned int index = 0;
  418.   // make a temp buffer to copy the data into first
  419.   SmiLPUINT32 temp;
  420.   unsigned int nz;
  421.   if (str && *str)
  422.   {
  423.     nz = SAFE_UINT_CAST(strlen(str));
  424.   }
  425.   else
  426.   {
  427.     dstOid->len = 0;
  428.     dstOid->ptr = 0;
  429.     return -1;
  430.   }
  431.   temp = (SmiLPUINT32) new unsigned long[nz];
  432.   if (temp == 0) return -1;   // return if can't get the mem
  433.   while ((*str) && (index < nz))
  434.   {
  435.     // skip over the dot
  436.     if (*str == '.') ++str;
  437.     // convert digits
  438.     if (my_isdigit(*str))
  439.     {
  440.       unsigned long number = 0;
  441.       // grab a digit token and convert it to a long int
  442.       while (my_isdigit(*str))
  443.         number = (number * 10) + *(str++) - '0';
  444.       // stuff the value into the array and bump the counter
  445.       temp[index++] = number;
  446.       // there must be a dot or end of string now
  447.       if ((*str) && (*str != '.'))
  448.       {
  449.         delete [] temp;
  450.         return -1;
  451.       }
  452.     }
  453.     // check for other chars
  454.     if ((*str) && (*str != '.'))
  455.     {
  456.       // found String -> converting it into an oid
  457.       if (*str != '$')
  458.       {
  459.         delete [] temp;
  460.         return -1;
  461.       }
  462.       // skip $
  463.       ++str;
  464.       // copy until second $
  465.       while ((*str) && (*str != '$'))
  466.       {
  467.         temp[index] = (unsigned char)*str;
  468.         ++str;
  469.         ++index;
  470.       }
  471.       if (*str != '$')
  472.       {
  473.         delete [] temp;
  474.         return -1;
  475.       }
  476.       // skip over the $
  477.       ++str;
  478.       // there must be a dot or end of string now
  479.       if ((*str) && (*str != '.'))
  480.       {
  481.         delete [] temp;
  482.         return -1;
  483.       }
  484.     }
  485.   }
  486.   // get some space for the real oid
  487.   dstOid->ptr = (SmiLPUINT32) new unsigned long[index];
  488.   // return if can't get the mem needed
  489.   if(dstOid->ptr == 0)
  490.   {
  491.     delete [] temp;
  492.     return -1;
  493.   }
  494.   // copy in the temp data
  495.   MEMCPY((SmiLPBYTE) dstOid->ptr,
  496.          (SmiLPBYTE) temp,
  497.          (size_t) (index*sizeof(SmiUINT32)));
  498.   // set the len of the oid
  499.   dstOid->len = index;
  500.   // free up temp data
  501.   delete [] temp;
  502.   return (int) index;
  503. }
  504. //===============[Oid::OidCopy(source, destination) ]====================
  505. // Copy an oid
  506. int Oid::OidCopy(SmiLPOID srcOid, SmiLPOID dstOid) const
  507. {
  508.   // check source len ! zero
  509.   if (srcOid->len == 0) return -1;
  510.   // copy source to destination
  511.   MEMCPY((SmiLPBYTE) dstOid->ptr,
  512.          (SmiLPBYTE) srcOid->ptr,
  513.          (size_t) (srcOid->len*sizeof(SmiUINT32)));
  514.   //set the new len
  515.   dstOid->len = srcOid->len;
  516.   return (int) srcOid->len;
  517. }
  518. //===============[Oid::nCompare(n, Oid) ]=================================
  519. // compare the n leftmost values of two oids (left-to_right )
  520. //
  521. // self == Oid then return 0, they are equal
  522. // self < Oid then return -1, <
  523. // self > Oid then return 1,  >
  524. int Oid::nCompare(const unsigned long n,
  525.                   const Oid &o) const
  526. {
  527.   unsigned long length = n;
  528.   bool reduced_len = false;
  529.   // If both oids are too short, decrease len
  530.   while ((smival.value.oid.len < length) && (o.smival.value.oid.len < length))
  531.     length--;
  532.   if (length == 0) return 0; // equal
  533.     
  534.   // only compare for the minimal length
  535.   if (length > smival.value.oid.len)
  536.   {
  537.     length = smival.value.oid.len;
  538.     reduced_len = true;
  539.   }
  540.   if (length > o.smival.value.oid.len)
  541.   {
  542.     length = o.smival.value.oid.len;
  543.     reduced_len = true;
  544.   }
  545.   unsigned long z = 0;
  546.   while (z < length)
  547.   {
  548.     if (smival.value.oid.ptr[z] < o.smival.value.oid.ptr[z])
  549.       return -1;                              // less than
  550.     if (smival.value.oid.ptr[z] > o.smival.value.oid.ptr[z])
  551.       return 1;                               // greater than
  552.     ++z;
  553.   }
  554.   // if we truncated the len then these may not be equal
  555.   if (reduced_len)
  556.   {
  557.     if (smival.value.oid.len < o.smival.value.oid.len) return -1;
  558.     if (smival.value.oid.len > o.smival.value.oid.len) return 1;
  559.   }
  560.   return 0;                                 // equal
  561. }
  562. //================[Oid::OidToStr ]=========================================
  563. // convert an oid to a string
  564. int Oid::OidToStr(const SmiOID *srcOid,
  565.                   SmiUINT32 size,
  566.                   char *str) const
  567. {
  568.   unsigned totLen = 0;
  569.   char szNumber[SNMPBUFFSIZE];
  570.   int cur_len;
  571.   str[0] = 0;   // init the string
  572.   // verify there is something to copy
  573.   if (srcOid->len == 0)
  574.     return -1;
  575.   // loop through and build up a string
  576.   for (unsigned long index = 0; index < srcOid->len; ++index)
  577.   {
  578.     // convert data element to a string
  579.     cur_len = sprintf(szNumber, "%lu", srcOid->ptr[index]);
  580.     // verify len is not over
  581.     if (totLen + cur_len + 1 >= size)
  582.       return -2;
  583.     // if not at begin, pad with a dot
  584.     if (totLen)
  585.       str[totLen++] = '.';
  586.     // copy the string token into the main string
  587.     STRCPY(str + totLen, szNumber);
  588.     // adjust the total len
  589.     totLen += cur_len;
  590.   }
  591.   return totLen+1;
  592. }
  593. //================[ general Value = operator ]========================
  594. SnmpSyntax& Oid::operator=(const SnmpSyntax &val)
  595. {
  596.   if (this == &val) return *this; // protect against assignment from self
  597.   delete_oid_ptr();
  598.   // assign new value
  599.   if (val.valid())
  600.   {
  601.     switch (val.get_syntax())
  602.     {
  603.       case sNMP_SYNTAX_OID:
  604.         set_data(((Oid &)val).smival.value.oid.ptr,
  605.                   (unsigned int)((Oid &)val).smival.value.oid.len);
  606.         break;
  607.     }
  608.   }
  609.   return *this;
  610. }
  611. int Oid::get_asn1_length() const
  612. {
  613.   int length = 1; // for first 2 subids
  614.   for (unsigned int i = 2; i < smival.value.oid.len; ++i)
  615.   {
  616.     unsigned long v = smival.value.oid.ptr[i];
  617.     if      (v <       0x80) //  7 bits long subid 
  618.       length += 1;
  619.     else if (v <     0x4000) // 14 bits long subid
  620.       length += 2;
  621.     else if (v <   0x200000) // 21 bits long subid
  622.       length += 3;
  623.     else if (v < 0x10000000) // 28 bits long subid
  624.       length += 4;
  625.     else                     // 32 bits long subid
  626.       length += 5;
  627.   }
  628.   if (length < 128)
  629.     return length + 2;
  630.   else if (length < 256)
  631.     return length + 3;
  632.   return length + 4;
  633. }
  634. #ifdef SNMP_PP_NAMESPACE
  635. }; // end of namespace Snmp_pp
  636. #endif