|
|
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
/*---------------------------------------------------------
Filename: value.cpp Written By: B.Rajeev ----------------------------------------------------------*/
#include "precomp.h"
#include <typeinfo.h>
#include "common.h"
#include "address.h"
#include "value.h"
#define MAX_FIELDS 100
#define FIELD_SEPARATOR '.'
BOOL SnmpNull :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = TRUE; }
return bResult; }
// Copy constructor
SnmpInteger::SnmpInteger ( IN const SnmpInteger &value ) { val = value.GetValue(); }
BOOL SnmpInteger :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpInteger &)value); }
return bResult; }
LONG SnmpInteger::GetValue () const { return val; }
void SnmpInteger::SetValue ( IN const LONG value ) { val = value; }
SnmpValue *SnmpInteger::Copy () const { return new SnmpInteger(val); }
// Copy constructor
SnmpGauge::SnmpGauge ( IN const SnmpGauge &value ) { val = value.GetValue(); }
BOOL SnmpGauge :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpGauge &)value); }
return bResult; }
ULONG SnmpGauge::GetValue () const { return val; }
void SnmpGauge::SetValue ( IN const ULONG value ) { val = value; }
SnmpValue *SnmpGauge::Copy () const { return new SnmpGauge(val); }
// Copy constructor
SnmpCounter::SnmpCounter ( IN const SnmpCounter &value ) { val = value.GetValue(); }
BOOL SnmpCounter :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpCounter &)value); }
return bResult; }
ULONG SnmpCounter::GetValue () const { return val; }
void SnmpCounter::SetValue ( IN const ULONG value ) { val = value; }
SnmpValue *SnmpCounter::Copy () const { return new SnmpCounter(val); }
// Copy constructor
SnmpTimeTicks::SnmpTimeTicks ( IN const SnmpTimeTicks &value ) { val = value.GetValue(); }
BOOL SnmpTimeTicks :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpTimeTicks &)value); }
return bResult; }
ULONG SnmpTimeTicks::GetValue () const { return val; }
void SnmpTimeTicks::SetValue ( IN const ULONG value ) { val = value; }
SnmpValue *SnmpTimeTicks::Copy () const { return new SnmpTimeTicks(val); }
void SnmpOctetString::OverWrite(IN const UCHAR *value) { if ( value && length ) { memcpy(val, value, sizeof(UCHAR)*length); } }
void SnmpOctetString::Initialize(IN const UCHAR *value, IN const ULONG valueLength) { is_valid = FALSE;
if ( (value == NULL) && (valueLength != 0) ) return;
length = valueLength; val = Replicate(value, valueLength); is_valid = TRUE; }
void SnmpOctetString::UnReplicate(UCHAR *value) { if ( is_valid == TRUE ) delete[] val; }
SnmpOctetString::SnmpOctetString ( IN const UCHAR *value , IN const ULONG valueLength ) : is_valid ( FALSE ) { Initialize(value, valueLength); }
SnmpOctetString::SnmpOctetString ( IN const SnmpOctetString &value ) : is_valid ( FALSE ) { Initialize(value.GetValue(), value.GetValueLength()); }
SnmpOctetString::~SnmpOctetString () { UnReplicate(val); }
ULONG SnmpOctetString::GetValueLength () const { return length; }
UCHAR *SnmpOctetString::GetValue () const { return val; }
SnmpValue *SnmpOctetString::Copy () const { return new SnmpOctetString(val, length); } UCHAR *SnmpOctetString::Replicate(IN const UCHAR *value, IN const ULONG valueLength) { if ( value ) { UCHAR *temp = new UCHAR[valueLength];
memcpy(temp, value, sizeof(UCHAR)*valueLength);
return temp; } else { return NULL ; } }
void SnmpOctetString::SetValue ( IN const UCHAR *value , IN const ULONG valueLength ) { if (length != valueLength) { UnReplicate(val); Initialize(value, valueLength); } else OverWrite(value); }
BOOL SnmpOctetString :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpOctetString &)value); }
return bResult; }
BOOL SnmpOctetString::Equivalent(IN const SnmpOctetString &snmp_octet_string) const { if ( is_valid && snmp_octet_string() ) { if ( length != snmp_octet_string.GetValueLength() ) return FALSE;
UCHAR *octet_values = snmp_octet_string.GetValue();
for( UINT i=0; i < length; i++) { if ( val[i] != octet_values[i] ) return FALSE; }
return TRUE; } else return FALSE; }
void SnmpObjectIdentifier::OverWrite(IN const ULONG *value) { if ( value ) { memcpy(val, value, sizeof(ULONG)*length); } }
void SnmpObjectIdentifier::Initialize(IN const ULONG *value, IN const ULONG valueLength) { if ( ( (value == NULL) && (valueLength != 0) ) || ( valueLength == 0 ) ) { length = 0 ; val = NULL ; return; }
length = valueLength;
if ( length <= DEFAULT_OBJECTIDENTIFIER_LENGTH ) { val = m_value ; memcpy(val , value, sizeof(ULONG)*length); is_valid = TRUE;
} else { val = new ULONG[length]; memcpy(val , value, sizeof(ULONG)*length); is_valid = TRUE; } }
void SnmpObjectIdentifier::UnReplicate(ULONG *value) { if ( ( is_valid == TRUE ) & ( length > DEFAULT_OBJECTIDENTIFIER_LENGTH ) ) { delete[] val; } }
SnmpObjectIdentifier::SnmpObjectIdentifier ( IN const ULONG *value , IN const ULONG valueLength ) : val ( NULL ) , length ( 0 ) , is_valid ( TRUE ) { Initialize(value, valueLength); }
SnmpObjectIdentifier::SnmpObjectIdentifier ( IN const SnmpObjectIdentifier &value ) : val ( NULL ) , length ( 0 ) , is_valid ( TRUE ) { Initialize(value.GetValue(), value.GetValueLength()); }
SnmpObjectIdentifier::~SnmpObjectIdentifier () { UnReplicate(val); }
ULONG SnmpObjectIdentifier::GetValueLength () const { return length; }
ULONG *SnmpObjectIdentifier::GetValue () const { return val; }
SnmpValue *SnmpObjectIdentifier::Copy () const { return new SnmpObjectIdentifier(val, length); }
ULONG *SnmpObjectIdentifier::Replicate(IN const ULONG *value, IN const ULONG valueLength) const { if ( value ) { ULONG *temp = new ULONG[valueLength]; memcpy(temp, value, sizeof(ULONG)*valueLength); return temp; } else { return NULL ; } }
ULONG *SnmpObjectIdentifier::Replicate(IN const ULONG *first_value, IN const ULONG first_length, IN const ULONG *second_value, IN const ULONG second_length) const { if ( first_value && second_value ) { ULONG new_length = first_length + second_length; ULONG *temp = new ULONG[new_length]; int first_value_size = sizeof(ULONG)*first_length;
memcpy(temp, first_value, first_value_size); memcpy(temp + first_length, second_value, sizeof(ULONG)*second_length); return temp; } else if ( first_value ) { ULONG *temp = new ULONG [ first_length]; memcpy(temp, first_value, sizeof(ULONG)*first_length); return temp; } else if ( second_value ) { ULONG *temp = new ULONG [ second_length]; memcpy(temp, second_value, sizeof(ULONG)*second_length); return temp;
} else { return NULL ; } }
SnmpObjectIdentifier::Comparison SnmpObjectIdentifier::Compare(IN const SnmpObjectIdentifier &first, IN const SnmpObjectIdentifier &second) const { ULONG *first_string = first.GetValue(); ULONG *second_string = second.GetValue(); int first_length = first.GetValueLength(); int second_length = second.GetValueLength(); int min_length = MIN(first_length,second_length);
for(int i=0; i < min_length; i++) { if ( first_string[i] < second_string[i] ) return LESS_THAN; else if ( first_string[i] > second_string[i] ) return GREATER_THAN; else continue; }
if ( first_length < second_length ) return LESS_THAN; else if ( first_length > second_length ) return GREATER_THAN; else return EQUAL_TO; }
void SnmpObjectIdentifier::SetValue ( IN const ULONG *value , IN const ULONG valueLength ) { if (valueLength) { if ( length != valueLength) { UnReplicate(val); Initialize(value, valueLength); } else { OverWrite(value); } } else { UnReplicate(val); val = NULL ; length = 0 ; } }
// A null terminated dot-separated string representing the
// object identifer value is passed and the private fields
// and length are set from it
SnmpObjectIdentifier::SnmpObjectIdentifier(IN const char *value) { is_valid = FALSE;
UINT str_len = strlen(value); if ( str_len <= 0 ) return;
ULONG temp_field[MAX_FIELDS];
// create an input stream from the string
istrstream input_stream((char *)value);
// consecutive fields must be separated by a
// FIELD_SEPARATOR
char separator;
input_stream >> temp_field[0];
if ( input_stream.bad() || input_stream.fail() ) return;
// while the stream still has something,
// read (FIELD_SEPARATOR, ULONG) pairs from the input stream
// and set the temp_fields
// check if the read was bad or failed after the event
for( int i = 1 ; (i < MAX_FIELDS) && (!input_stream.eof()); i++) { input_stream >> separator;
if ( input_stream.bad() || input_stream.fail() ) return;
if ( separator != FIELD_SEPARATOR ) return;
input_stream >> temp_field[i]; if ( input_stream.bad() || input_stream.fail() ) return; }
is_valid = TRUE;
// set the length
length = i; val = NULL ;
// create memory for the fields and copy temp_fields into it
Initialize(temp_field, length); }
BOOL SnmpObjectIdentifier::Equivalent(IN const SnmpObjectIdentifier &value, IN ULONG max_length) const { if ( (!is_valid) || (!value()) ) return FALSE;
if ( (length < max_length) || (value.GetValueLength() < max_length) ) return FALSE;
ULONG *value_string = value.GetValue();
for( UINT i=0; i < max_length; i++ ) if ( val[i] != value_string[i] ) return FALSE;
return TRUE; }
BOOL SnmpObjectIdentifier::Equivalent(IN const SnmpObjectIdentifier &value) const { if ( (!is_valid) || (!value()) ) return FALSE;
ULONG *value_string = value.GetValue();
for( UINT i=length; i ; i-- ) { if ( val[i-1] != value_string[i-1] ) return FALSE; }
return TRUE; }
BOOL SnmpObjectIdentifier :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpObjectIdentifier &)value); }
return bResult; }
SnmpObjectIdentifier SnmpObjectIdentifier::operator+ ( IN const SnmpObjectIdentifier &value ) const { ULONG *temp_plus_array = Replicate(val, length, value.GetValue(), value.GetValueLength());
SnmpObjectIdentifier local_identifier(temp_plus_array, length+value.GetValueLength()); delete[] temp_plus_array;
return SnmpObjectIdentifier(local_identifier); }
// Determines the fields (starting from left), common to the
// two object identifiers and returns a new object identifier
// with only these fields. If nothing is shared, NULL is returned
SnmpObjectIdentifier *SnmpObjectIdentifier::Cut( SnmpObjectIdentifier &value ) const { // determine the smaller of the two lengths
int min_length = MIN(length, value.GetValueLength()); ULONG *other_field = value.GetValue();
// compare the fields
for(int index=0; index < min_length; index++) if ( val[index] != other_field[index] ) break;
// if nothing in common - return NULL
if ( index == 0 ) return NULL;
// they must have the fields in the range [0..(index-1)] common
// therefore, a common length of "index"
return new SnmpObjectIdentifier(other_field, index); }
ULONG &SnmpObjectIdentifier::operator [] ( IN const ULONG index ) const { if ( index < length ) return val[index];
// should never reach here if the user checks the
// index value before
return val[0]; }
//returns an allocated char* representation of the OID.
//The return value must be freed by the caller i.e. delete []
char *SnmpObjectIdentifier::GetAllocatedString() const { char * retVal = NULL ;
if (length) { retVal = new char [ length * 18 ] ; ostrstream s ( retVal , length * 18 ) ; s << val[0]; UINT i = 1; char dot = '.';
while (i < length) { s << dot << val[i++] ; } s << ends ; }
return retVal; }
SnmpIpAddress::SnmpIpAddress ( IN const char *value ) { // create a stream to read the fields from
istrstream address_stream((char *)value);
// store the values [0..255] separated by FIELD_SEPARATORs
// in the value string
UCHAR field[SNMP_IP_ADDR_LEN];
// contains the maximum value for a UCHAR. used
// for comparison with the field values read
const UCHAR max_uchar = -1;
// consecutive fields must be separated by a
// FIELD_SEPARATOR
char separator;
// a field is first read into this for comparison
// with max_uchar
ULONG temp_field;
is_valid = FALSE;
// read the first three (UCHAR,FIELD_SEPARATOR) pairs
// check if the stream is good before each read
for(int i=0; i < (SNMP_IP_ADDR_LEN-1); i++) { if ( !address_stream.good() ) return;
address_stream >> temp_field; if ( temp_field > max_uchar ) return;
field[i] = (UCHAR)temp_field;
if ( !address_stream.good() ) return;
address_stream >> separator; if ( separator != FIELD_SEPARATOR ) return; }
if ( !address_stream.good() ) return;
address_stream >> temp_field; if (temp_field > max_uchar) return;
field[SNMP_IP_ADDR_LEN-1] = (UCHAR)temp_field;
// make sure that there are is nothing more left in the
// stream
if ( !address_stream.eof() ) return;
ULONG byteA = field [ 0 ] ; ULONG byteB = field [ 1 ] ; ULONG byteC = field [ 2 ] ; ULONG byteD = field [ 3 ] ;
val = ( byteA << 24 ) + ( byteB << 16 ) + ( byteC << 8 ) + byteD ;
is_valid = TRUE; }
// Copy constructor
SnmpIpAddress::SnmpIpAddress ( IN const SnmpIpAddress &value ) { if ( value() ) { val = value.GetValue(); is_valid = TRUE; } else is_valid = FALSE; }
BOOL SnmpIpAddress :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpIpAddress &)value); }
return bResult; }
ULONG SnmpIpAddress::GetValue () const { return val; }
void SnmpIpAddress::SetValue ( IN const ULONG value ) { val = value; is_valid = TRUE; }
SnmpValue *SnmpIpAddress::Copy () const { return new SnmpIpAddress(val); }
// Copy constructor
SnmpUInteger32::SnmpUInteger32 ( IN const SnmpUInteger32 &value ) { val = value.GetValue(); }
ULONG SnmpUInteger32::GetValue () const { return val; }
void SnmpUInteger32::SetValue ( IN const ULONG value ) { val = value; }
SnmpValue *SnmpUInteger32::Copy () const { return new SnmpUInteger32(val); }
BOOL SnmpUInteger32 :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpUInteger32 &)value); }
return bResult; }
// Copy constructor
SnmpCounter64::SnmpCounter64( IN const SnmpCounter64 &value ) { lval = value.GetLowValue(); hval = value.GetHighValue(); }
ULONG SnmpCounter64::GetLowValue () const { return lval; }
ULONG SnmpCounter64::GetHighValue () const { return hval; }
void SnmpCounter64::SetValue ( IN const ULONG lvalue , IN const ULONG hvalue ) { lval = lvalue; hval = hvalue ; }
SnmpValue *SnmpCounter64::Copy () const { return new SnmpCounter64(lval,hval); }
BOOL SnmpCounter64 :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpCounter64 &)value); }
return bResult; }
BOOL SnmpNoSuchInstance :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = TRUE; }
return bResult; }
BOOL SnmpNoSuchObject :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = TRUE; }
return bResult; }
BOOL SnmpEndOfMibView :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = TRUE; }
return bResult; }
BOOL SnmpOpaque :: Equivalent (IN const SnmpValue &value) const { BOOL bResult = FALSE;
if (typeid(*this) == typeid(value)) { bResult = Equivalent((const SnmpOpaque &)value); }
return bResult; }
|