diff options
Diffstat (limited to 'ASNMP/asnmp/octet.cpp')
-rw-r--r-- | ASNMP/asnmp/octet.cpp | 594 |
1 files changed, 594 insertions, 0 deletions
diff --git a/ASNMP/asnmp/octet.cpp b/ASNMP/asnmp/octet.cpp new file mode 100644 index 00000000000..c76f5df3b97 --- /dev/null +++ b/ASNMP/asnmp/octet.cpp @@ -0,0 +1,594 @@ +/* -*-C++-*- */ +// ============================================================================ +// +// = LIBRARY +// asnmp +// +// = FILENAME +// octet.cpp +// +// = DESCRIPTION +// Implements the SMI Octet datatype (RFC 1155) +// This class is fully contained and does not rely on or any other +// SNMP libraries. Ported to ACE by Michael MacFaden mrm@cisco.com +// +// = AUTHOR +// Peter E Mellquist +// +// ============================================================================ +/*=================================================================== + Copyright (c) 1996 + Hewlett-Packard Company + + ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. + Permission to use, copy, modify, distribute and/or sell this software + and/or its documentation is hereby granted without fee. User agrees + to display the above copyright notice and this license notice in all + copies of the software and any documentation of the software. User + agrees to assume all liability for the use of the software; Hewlett-Packard + makes no representations about the suitability of this software for any + purpose. It is provided "AS-IS without warranty of any kind,either express + or implied. User hereby grants a royalty-free license to any and all + derivatives based upon this software code base. +=====================================================================*/ + +#include "ace/OS.h" +#include "asnmp/octet.h" // include definition for octet class + +//============[ syntax type ]========================================= +SmiUINT32 OctetStr::get_syntax() +{ + return sNMP_SYNTAX_OCTETS; +} + +inline +void init_octet_smi(SmiVALUE& smi) +{ + smi.syntax = sNMP_SYNTAX_OCTETS; + smi.value.string.ptr = 0; + smi.value.string.len = 0; +} + +inline +void reset_octet_smi(SmiVALUE& smi) +{ + delete [] smi.value.string.ptr; + smi.value.string.ptr = NULL; + smi.value.string.len = 0; +} + +inline +int copy_octet_smi(SmiVALUE& smi, int size, const char *src, int& valid_flag) +{ + valid_flag = FALSE; + ACE_NEW_RETURN(smi.value.string.ptr, SmiBYTE[size], 1); + ACE_OS::memcpy( smi.value.string.ptr, src, (size_t) size); + smi.value.string.len = size; + valid_flag = TRUE; + return 0; +} + +//============[ default constructor ]========================= +OctetStr::OctetStr( const char * string, long size): + output_buffer(NULL), validity(FALSE) +{ + + size_t z; + init_octet_smi(smival); + + // check for null string + if ( !string || !(z = ACE_OS::strlen( string))) + return; + + if (size == -1) + size = z; + + if (size > z) + size = z; + + copy_octet_smi(smival, size, string, validity); +} + + +//============[ set the data on an already constructed Octet ]============ +// TODO: should return status since it can fail in so many places +void OctetStr::set_data( const SmiBYTE* string, long size) +{ + size_t z; + // check for null string + if ( !string || !(z = ACE_OS::strlen( (char *)string))) + return; + + if (size == -1) + size = z; + + if (size > z) + return; + + // free up already used space + if ( smival.value.string.ptr ) { + reset_octet_smi(smival); + } + smival.value.string.len = 0; + + // check for zero len + if ( !string || !size) { + validity = TRUE; + return; + } + + copy_octet_smi(smival, size, (const char *)string, validity); +} + +//============[ constructor using another octet object ]============== +OctetStr::OctetStr ( const OctetStr &octet): + output_buffer(NULL), validity(TRUE) +{ + init_octet_smi(smival); + // check for zero len case + if ( octet.smival.value.string.len == 0) { + return; + } + + // must be a valid object + if ( octet.validity == FALSE) { + validity = FALSE; + return; + } + + // get the mem needed + copy_octet_smi(smival, octet.smival.value.string.len, + (const char *)octet.smival.value.string.ptr, validity); +} + +//=============[ destructor ]========================================= +OctetStr::~OctetStr() +{ + reset_octet_smi(smival); + delete [] output_buffer; +} + + +//=============[ assignment to a string operator overloaded ]========= +OctetStr& OctetStr::operator=( const char *string) +{ + // get the string size + size_t nz; + + // free up previous memory if needed + if ( smival.value.string.ptr ) { + reset_octet_smi(smival); + } + + // if empty then we are done + if (!string || !(nz = ACE_OS::strlen( string))) { + validity = TRUE; + return *this; + } + + // get memory needed + copy_octet_smi(smival, nz, string, validity); + return *this; +} + +//=============[ assignment to another oid object overloaded ]======== +OctetStr& OctetStr::operator=( const OctetStr &octet) +{ + // protect against assignment from self + if ( this == &octet ) + return *this; + + // don't assign from invalid objs + if (!octet.validity) { + return *this; + } + + // free up previous memory if needed + if ( smival.value.string.len ) { + reset_octet_smi(smival); + } + + if (!octet.smival.value.string.len) { + validity = TRUE; + return *this; + } + + // get some memory + copy_octet_smi(smival, octet.smival.value.string.len, + (const char*) octet.smival.value.string.ptr, validity); + return *this; // return self reference +} + +//==============[ equivlence operator overloaded ]==================== +int operator==( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0) + return TRUE; + else + return FALSE; +} + +//==============[ not equivlence operator overloaded ]================ +int operator!=( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)!=0) + return TRUE; + else + return FALSE; +} + +//==============[ less than < overloaded ]============================ +int operator<( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) + return TRUE; + else + return FALSE; +} + +//==============[ less than <= overloaded ]=========================== +int operator<=( const OctetStr &lhs, const OctetStr &rhs) +{ + if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)<0) || + ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)) + return TRUE; + else + return FALSE; +} + +//===============[ greater than > overloaded ]======================== +int operator>( const OctetStr &lhs, const OctetStr &rhs) +{ + if( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) + return TRUE; + else + return FALSE; +} + +//===============[ greater than >= overloaded ]======================= +int operator>=( const OctetStr &lhs, const OctetStr &rhs) +{ + if(( lhs.left_comparison( rhs.smival.value.string.len, rhs)>0) || + ( lhs.left_comparison( rhs.smival.value.string.len, rhs)==0)) + return TRUE; + else + return FALSE; +} + +//===============[ equivlence operator overloaded ]=================== +int operator==( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if( lhs.left_comparison( to.smival.value.string.len,to)==0) + return TRUE; + else + return FALSE; +} + +//===============[ not equivlence operator overloaded ]=============== +int operator!=( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)!=0) + return TRUE; + else + return FALSE; +} + +//===============[ less than < operator overloaded ]================== +int operator<( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)<0) + return TRUE; + else + return FALSE; +} + +//===============[ less than <= operator overloaded ]================= +int operator<=( const OctetStr &lhs,char *rhs) +{ + OctetStr to( rhs); + if (( lhs.left_comparison( to.smival.value.string.len,to)<0) || + ( lhs.left_comparison( to.smival.value.string.len,to)==0)) + return TRUE; + else + return FALSE; +} + +//===============[ greater than > operator overloaded ]=============== +int operator>( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if ( lhs.left_comparison( to.smival.value.string.len,to)>0) + return TRUE; + else + return FALSE; +} + +//===============[ greater than >= operator overloaded ]============== +int operator>=( const OctetStr &lhs,const char *rhs) +{ + OctetStr to( rhs); + if (( lhs.left_comparison( to.smival.value.string.len,to)>0) || + ( lhs.left_comparison( to.smival.value.string.len,to)==0)) + return TRUE; + else + return FALSE; +} + +//===============[ append operator, appends a string ]================ +OctetStr& OctetStr::operator+=( const char *a) +{ + SmiBYTE *tmp; // temp pointer + size_t slen,nlen; + + // get len of string + if ( !a || ((slen = ACE_OS::strlen( a)) == 0)) + return *this; + + // total len of octet + nlen = slen + (size_t) smival.value.string.len; + ACE_NEW_RETURN(tmp, SmiBYTE [ nlen], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); + ACE_OS::memcpy( tmp + smival.value.string.len, a, (size_t) slen); + // delete the original + if ( smival.value.string.ptr ) + reset_octet_smi(smival); + smival.value.string.ptr = tmp; + smival.value.string.len = nlen; + return *this; +} + +//================[ append one OctetStr to another ]================== +OctetStr& OctetStr::operator+=( const OctetStr& octetstr) +{ + SmiBYTE *tmp; // temp pointer + size_t slen,nlen; + + if (!octetstr.validity || + !(slen = (size_t)octetstr.length())) + return *this; + + // total len of octet + nlen = slen + (size_t) smival.value.string.len; + // get mem needed + ACE_NEW_RETURN(tmp, SmiBYTE[ nlen], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); + ACE_OS::memcpy( tmp + smival.value.string.len, octetstr.data(), + (size_t) slen); + if ( smival.value.string.ptr ) + reset_octet_smi(smival); + smival.value.string.ptr = tmp; + smival.value.string.len = nlen; + return *this; +} + +//================[ appends an int ]================================== +OctetStr& OctetStr::operator+=( const char c) +{ + SmiBYTE *tmp; + // get the memory needed plus one extra byte + ACE_NEW_RETURN(tmp, SmiBYTE[ smival.value.string.len + 1], *this); + ACE_OS::memcpy ( tmp, smival.value.string.ptr, + (size_t) smival.value.string.len); // len of original + tmp[ smival.value.string.len ] = c; // assign in byte + if ( smival.value.string.ptr ) // delete the original + reset_octet_smi(smival); + + smival.value.string.ptr = tmp; // point to one + smival.value.string.len++; // up the len + return *this; +} + + +//================[ compare n elements of an Octet ]================== +int OctetStr::left_comparison( const long n, const OctetStr &o) const +{ + long z, w; + + // both are empty, they are equal + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len == 0)) + return 0; // equal + + // self is empty and param has something + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len >0) && + (n>0)) + return -1; + + // self has something and param has nothing + if (( smival.value.string.len > 0) && + ( o.smival.value.string.len ==0) && + (n>0)) + return 1; + + // special case + if (( smival.value.string.len == 0) && + ( o.smival.value.string.len > 0) && + ( n == 0)) + return 0; + + // pick the Min of n, this and the param len + // this is the maximum # to iterate a search + w = smival.value.string.len < o.smival.value.string.len + ? smival.value.string.len : o.smival.value.string.len; + if (n<w) w=n; + + z = 0; + while( z < w) { + if ( smival.value.string.ptr[z] < o.smival.value.string.ptr[z]) + return -1; // less than + if ( smival.value.string.ptr[z] > o.smival.value.string.ptr[z]) + return 1; // greater than + z++; + } + + if (( z == 0) && + ( smival.value.string.len == 0) && + ( o.smival.value.string.len > 0)) + return -1; + + if (( z == 0) && + ( o.smival.value.string.len == 0) && + ( smival.value.string.len > 0)) + return 1; + + return 0; +} + +//================[ return the length of the oid ]======================= +size_t OctetStr::length() const +{ + return (size_t) smival.value.string.len; +} + +//================[ operator[]: access as if array ]================== +SmiBYTE& OctetStr::operator[]( int position) +{ + return smival.value.string.ptr[position]; +} + +//===============[ reuturns pointer to internal data ]=============== +SmiBYTE * OctetStr::data() const +{ + return smival.value.string.ptr; +} + +//================[ returns validity ]================================ +int OctetStr::valid() const +{ + return validity; +} + +//================[ clone() ]========================================= +SnmpSyntax * OctetStr::clone() const +{ + OctetStr *tmp = new OctetStr(*this); + return ( SnmpSyntax *) tmp; +} + +//================[ ASCII format return ]============================= +char * OctetStr::to_string() +{ + for ( long i=0; i < smival.value.string.len; i++) { + if (( smival.value.string.ptr[i] != '\r')&& + ( smival.value.string.ptr[i] != '\n')&& + (isprint((int) (smival.value.string.ptr[i]))==0)) + return(to_string_hex()); + } + + if ( output_buffer != NULL) + delete [] output_buffer; + + ACE_NEW_RETURN(output_buffer, char[smival.value.string.len + 1], ""); + if (smival.value.string.len) + ACE_OS::memcpy(output_buffer, smival.value.string.ptr, + (int) smival.value.string.len); + output_buffer[smival.value.string.len] = '\0'; + return output_buffer; +} + + +//================[ general Value = operator ]======================== +SnmpSyntax& OctetStr::operator=( SnmpSyntax &val) +{ + // protect against assignment from self + if ( this == &val ) + return *this; + + // blow away the old value + validity=FALSE; + if (smival.value.string.ptr) { + reset_octet_smi(smival); + } + smival.value.string.len = 0; + if (val.valid()){ + switch (val.get_syntax()) { + case sNMP_SYNTAX_OCTETS: + case sNMP_SYNTAX_IPADDR: + set_data( ((OctetStr &)val).smival.value.string.ptr, + ((OctetStr &)val).smival.value.string.len); + break; + } + } + return *this; +} + +//================[ format the output into hex ]======================== +char *OctetStr::to_string_hex() +{ + int cnt; + char char_buf[80]; // holds ASCII representation of data + char *buf_ptr; // pointer into ASCII listing + char *line_ptr; // pointer into Hex listing + int storageNeeded; // how much space do we need ? + int local_len = (int) smival.value.string.len; + SmiBYTE *bytes = smival.value.string.ptr; + + + storageNeeded = (int) ((smival.value.string.len/16)+1) * 72 + 1; + + if ( output_buffer != NULL) + delete [] output_buffer; + + ACE_NEW_RETURN(output_buffer, char[storageNeeded], ""); + + line_ptr = output_buffer; + + /*----------------------------------------*/ + /* processing loop for entire data buffer */ + /*----------------------------------------*/ + while (local_len > 0) { + cnt = 16; /* print 16 bytes per line */ + buf_ptr = char_buf; + sprintf(line_ptr, " "); + line_ptr += 2; /* indent */ + + /*-----------------------*/ + /* process a single line */ + /*-----------------------*/ + while (cnt-- > 0 && local_len-- > 0) { + sprintf(line_ptr, "%2.2X ", *bytes); + + line_ptr +=3; /* the display of a byte always 3 chars long */ + if (isprint(*bytes)) + sprintf(buf_ptr, "%c", *bytes); + else + sprintf(buf_ptr, "."); + bytes++; + buf_ptr++; + } + cnt++; + + /*----------------------------------------------------------*/ + /* this is to make sure that the ASCII displays line up for */ + /* incomplete lines of hex */ + /*----------------------------------------------------------*/ + while (cnt-- > 0) { + sprintf(line_ptr," "); + line_ptr += 3; + } + + /*------------------------------------------*/ + /* append the ASCII display to the Hex line */ + /*------------------------------------------*/ + +// TODO: verify ACE_OS:: on NT works like this or not +#if defined(__unix) + char *fmt = " %s\n"; +#endif // __unix + +#if defined(_WIN32) + char *fmt = " %s\r\n"; +#endif // _WIN32 + + ACE_OS::sprintf(line_ptr, fmt, char_buf); + line_ptr += 3 + strlen(char_buf); + } + + return output_buffer; +} |