Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

854 lines
19 KiB

// 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;
}