/*
 * Copyright (C) 1997-2003 by Objective Systems, Inc.
 *
 * This software is furnished under a license and may be used and copied
 * only in accordance with the terms of such license and with the
 * inclusion of the above copyright notice. This software or any other
 * copies thereof may not be provided or otherwise made available to any
 * other person. No title to and ownership of the software is hereby
 * transferred.
 *
 * The information in this software is subject to change without notice
 * and should not be construed as a commitment by Objective Systems, Inc.
 *
 * PROPRIETARY NOTICE
 *
 * This software is an unpublished work subject to a confidentiality agreement
 * and is protected by copyright and trade secret law.  Unauthorized copying,
 * redistribution or other use of this work is prohibited.
 *
 * The above notice of copyright on this source code product does not indicate
 * any actual or intended publication of such source code.
 *
 *****************************************************************************/

#ifndef _ASN1CBITSTR_H_
#define _ASN1CBITSTR_H_

#include "asn1CppTypes.h"
/**
 * @file ASN1CBitStr.h 
 * Bit string control class definitions.
 */
/**
 * @addtogroup asn1ctrl 
 * @{
 */
//////////////////////////////////////////////////////////////////////
//
// ASN1CBitStr
// 
// Bit string implementation. This class provides all functionalty
// necessary for bit strings. 
//
// Author Artem Bolgar.
// version 1.52   21 Feb, 2003
//
#ifndef _NO_UTILS_CLASSES

/**
 * ASN.1 bit string control class. 
 * The ASN1CBitStr class is derived from the ASN1CType base class. It is used
 * as the base class for generated control classes for the ASN.1 BIT STRING
 * type. This class provides utility methods for operating on the bit string
 * referenced by the generated class. This class can also be used inline to
 * operate on bits within generated BIT STRING elements in a SEQUENCE, SET, or
 * CHOICE construct.
 */
class EXTERNRT ASN1CBitStr : public ASN1CType {
 private:
   ASN1UINT    _numbits; // placeholder
   ASN1OCTET*  _units;   // placeholder
 protected:
   ASN1OCTET** mpUnits;
   ASN1UINT    mMaxNumBits;
   ASN1UINT*   mpNumBits; 
   int         mUnitsUsed;
   int         mUnitsAllocated;
   ASN1BOOL    mDynAlloc;
 private:
   ASN1OCTET* allocateMemory(int sz);

   ASN1OCTET* reallocateMemory(ASN1OCTET* old, int oldBufSz, int newBufSz);

   void freeMemory(ASN1OCTET* mem);
   /*
   * Set the field mUnitsUsed with the logical size in units of the bit
   * set.  WARNING:This function assumes that the number of units actually
   * in use is less than or equal to the current value of mUnitsUsed!
   */
   void recalculateUnitsUsed();

   /*
   * Ensures that the bit string can hold enough units.
   * param	unitsRequired the minimum acceptable number of units.
   */
   int checkCapacity(int unitsRequired);

   
   /* 
   * Returns the unit of this bitset at index j as if this bit string had an
   * infinite amount of storage.
   */
   ASN1OCTET getBits(int j);

   void privateInit (ASN1UINT nbits);
   void privateInit (ASN1OCTET* bitStr, 
      ASN1UINT& octsNumbits, ASN1UINT maxNumbits_);
   void privateInit (ASN1TDynBitStr& bitStr);
 protected:
   /*
   * Creates an empty bit string. The string should be additionaly initialized 
   * by call to 'init' method.
   */
   ASN1CBitStr (ASN1MessageBufferIF& msgBuf);

   /*
   * Default protected ctor. mpContext should be set and the string should be 
   * additionaly initialized by call to 'init' method.
   */
   ASN1CBitStr();

   /*
    * This constructor creates an empty bit string.
    *
    * @param ctxt - Reference to reference-counted context object.
    */
   ASN1CBitStr (ASN1Context& ctxt);

   /*
    * This constructor initializes the internal bit string to the 
    * given value.
    *
    * @param pBits - Pointer to binary bit string data.
    * @param numbits - Reference to counter to hold number of bits.
    * @param maxNumbits - Maximum size (in bits) of this bit string.
    */
   ASN1CBitStr (ASN1OCTET* pBits, ASN1UINT& numbits, ASN1UINT maxNumbits);

   /*
    * This constructor initializes the internal bit string to the 
    * given value.
    *
    * @param bitstr - Reference to a bit string variable.
    */
   ASN1CBitStr (ASN1TDynBitStr& bitStr);

   void init (ASN1OCTET* pBits, ASN1UINT& numbits, ASN1UINT maxNumbits);
   void init (ASN1TDynBitStr& bitStr);

 public:
   /**
    * This constructor creates an empty bit string. If the \c nbits argument is
    * zero, the bit string is set to be dynamic; otherwise, the capacity is set
    * to \c nbits.
    *
    * @param msgbuf       - ASN.1 message buffer or stream object.
    * @param nbits        - Number of bits this bit string can contain (zero if
    *                       unbounded.
    */
   ASN1CBitStr (ASN1MessageBufferIF& msgbuf, ASN1UINT nbits);
             
   /**
    * This constructor creates a bit string from an array of bits. The
    * constructor does not copy the bit string data, it just references the
    * given data variables. All operations on the bit string cause the
    * referenced items to be updated directly.
    *
    * @param msgbuf       - ASN.1 message buffer or stream object.
    * @param bitStr       - Pointer to static byte array
    * @param numbits      - Reference to length of bit string (in bits)
    * @param maxNumbits_  - sets maximum length in bits
    */
   ASN1CBitStr (ASN1MessageBufferIF& msgbuf, ASN1OCTET* bitStr, 
                ASN1UINT& numbits, ASN1UINT maxNumbits_); 

   /*
   * Creates bits string from ASN1TDynBitStr. Ctor does not copy bytes,
   * just assign array (data member of ASN1TDynBitStr) to units.
   * This string will be extendable.
   */
   ASN1CBitStr(ASN1MessageBufferIF& msgBuf, ASN1TDynBitStr& bitStr);

   /*
   * Creates empty bit string. If nbits == 0 then bit string is dynamic; 
   * else capacity will be fixed to nbits.
   */
   ASN1CBitStr(ASN1Context& ctxt, ASN1UINT nbits);
             
   /*
   * Creates bits string from array of bits. Ctor does not copy bytes,
   * just assign passed array to units.
   * Param bitStr - pointer to static byte array
   * Param numbits - reference to length of bit string (in bits);
   * Param maxNumbits_  - sets maximum length in bits
   */
   ASN1CBitStr(ASN1Context& ctxt, ASN1OCTET* bitStr, 
      ASN1UINT& octsNumbits, ASN1UINT maxNumbits_); 

   /*
   * Creates bits string from ASN1TDynBitStr. Ctor does not copy bytes,
   * just assign array (data member of ASN1TDynBitStr) to units.
   * This string will be extendable.
   */
   ASN1CBitStr(ASN1Context& ctxt, ASN1TDynBitStr& bitStr);

   /*
   * Copy constructor.
   */
   ASN1CBitStr(const ASN1CBitStr& bitStr);

   /*
   * Copy constructor, but allows to specify 'extendable' parameter
   */
   ASN1CBitStr(const ASN1CBitStr& bitStr, ASN1BOOL extendable);


   ~ASN1CBitStr();
  /**
   * This version of the set method sets the given bit in the target string.
   *
   * @param bitIndex     Relative index of the bit to set in the string. The
   *                       bit idex 0 refers to the MS bit (bit 8) in the first
   *                       octet. The index values then progress from the left
   *                       to right (MS to LS).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets the bit at the specified index to 1.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if 'bitIndex' is out of bounds, or
   *          other error codes (see asn1type.h).
   */
   int set(ASN1UINT bitIndex);

  /**
   * This version of teh set method sets the bits from the specified fromIndex
   * (inclusive) to the specified toIndex (exclusive) to one.
   *
   * @param fromIndex    Relative start index (inclusive) of bits in the
   *                       string. The bit index 0 refers to the MS bit (bit 8)
   *                       in the first octet. The index values then progress
   *                       from the left to right (MS to LS).
   * @param toIndex      Relative end index (exclusive) of bits in the string.
   *                       The bit index 0 refers to the MS bit (bit 8) in the
   *                       first octet. The index values then progress from the
   *                       left to right (MS to LS).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets the bits from the specified fromIndex(inclusive) to the
   * specified toIndex(exclusive) to 1.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if one of indexes is out of bounds, or
   *          ASN_E_RANGERR - if fromIndex > toIndex, or
   *          other error codes (see asn1type.h).
   */
   int set(ASN1UINT fromIndex, ASN1UINT toIndex);

   /**
    * Changes the bit at the specified index to the specified value.
    *
    * @param bitIndex     Relative index of bit to set in string. Bit index 0
    *                       refers to the MS bit (bit 8) in the first octet.
    *                       The index values then progress from left to right
    *                       (MS to LS bits).
    * @param value        Boolean value to which the bit is to be set.
    * @return             Completion status of operation: ASN_OK - if succeed
    *                       - 0 (ASN_OK) = success
    *                       - negative return value is error.
   */          
   /*Returns (details): ASN_E_OUTOFBND - if 'bitIndex' is out of bounds, or
   *          other error codes (see asn1type.h).
   */
   inline int change(ASN1UINT bitIndex, ASN1BOOL value) {
      if(value)
         return set(bitIndex);
      else
         return clear(bitIndex);
   }

  /** 
   * This version of the clear method sets the given bit in the target string
   * to zero.
   *
   * @param bitIndex     Relative index of bit in string. Bit index 0 refers to
   *                       the MS bit (bit 8) in the first octet. The index
   *                       values then progress from left to right (MS to LS
   *                       bits).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets the bit specified by the index to 0.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if 'bitIndex' is out of bounds, or
   *          other error codes (see asn1type.h).
   */
   int clear(ASN1UINT bitIndex);

  /**
   * This version of the clear method sets the bits from the specified
   * fromIndex (inclusive) to the specified toIndex (exclusive) to zero.
   *
   * @param fromIndex    Relative start index (inclusive) of bits in string.
   *                       Bit index 0 refers to the MS bit (bit 8) in the
   *                       first octet. The index values then progress from
   *                       left to right (MS to LS bits).
   * @param toIndex      Relative end index (exclusive) of bits in string. Bit
   *                       index 0 refers to the MS bit (bit 8) in the first
   *                       octet. The index values then progress from left to
   *                       right (MS to LS bits).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets the bits from the specified fromIndex(inclusive) to the
   * specified toIndex(exclusive) to 0.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if one of indexes is out of bounds, or
   *          ASN_E_RANGERR - if fromIndex > toIndex, or
   *          other error codes (see asn1type.h).
   */
   int clear(ASN1UINT fromIndex, ASN1UINT toIndex);

  /**
   * This version of the clear method sets all bits in the bit string to zero.
   *
   * @param             - none
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets all of the bits in this bit string to 0.
   */
   void clear();

  /**
   * This version of the invert method inverts the given bit in the target
   * string.
   *
   * If the bit in the bit string is a zero, it will be set to 1; if the bit is
   * a one, it will be set to 0.
   *
   * @param bitIndex     Relative index of bit in string. Bit index 0 refers to
   *                       the MS bit (bit 8) in the first octet. The index
   *                       values then progress from left to right (MS to LS
   *                       bits).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Sets the bit at the specified index to to the complement of its
   * current value.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if 'bitIndex' is out of bounds, or
   *          other error codes (see asn1type.h).
   */
   int invert(ASN1UINT bitIndex);

   /**
    * This version inverts the bits from the specified fromIndex (inclusive) to
    * the specified toIndex (exclusive).
    *
    * If the bit in the bit string is a zero, it will be set to 1; if the bit
    * is a one, it will be set to 0.
    *
    * @param fromIndex    Relative start index (inclusive) of bits in string.
    *                       Bit index 0 refers to the MS bit (bit 8) in the
    *                       first octet. The index values then progress from
    *                       left to right (MS to LS bits).
    * @param toIndex      Relative end index (exclusive) of bits in string. Bit
    *                       index 0 refers to the MS bit (bit 8) in the first
    *                       octet. The index values then progress from left to
    *                       right (MS to LS bits).
    * @return             Completion status of operation:
    *                       - 0 (ASN_OK) = success,
    *                       - negative return value is error.
   */
   /*
   * Sets each bit from the specified fromIndex(inclusive) to the
   * specified toIndex(exclusive) to the complement of its current
   * value.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_OUTOFBND - if one of indexes is out of bounds, or
   *          ASN_E_RANGERR - if fromIndex > toIndex, or
   *          other error codes (see asn1type.h).
   */
   int invert(ASN1UINT fromIndex, ASN1UINT toIndex);

  /**
   * This method returns the value of the bit with the specified index.
   *
   * @param bitIndex     Relative index of bit in string. Bit index 0 refers to
   *                       the MS bit (bit 8) in the first octet. The index
   *                       values then progress from left to right (MS to LS
   *                       bits).
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Returns the value of the bit with the specified index.
   */
   ASN1BOOL get(ASN1UINT bitIndex);

  /**
   * This method is the same as ASN1CBitStr::get.
   *
   * @see get           (ASN1UINT bitIndex)
   */
   /*
   * Returns TRUE if the value of the bit with the specified index is set to 1.
   */
   inline ASN1BOOL isSet(ASN1UINT bitIndex) { return get(bitIndex); }

  /**
   * This method returns TRUE if this bit string contains no bits that are set
   * to 1.
   *
   * @param             - none
   * @return             TRUE, if the bit string contains no bits that are set
   *                       to 1.
   */
   /*
   * Returns true if this bit string contains no bits that are set
   * to 1.
   */
   inline ASN1BOOL isEmpty() { return (mUnitsUsed == 0); }

  /**
   * This method returns the number of bytes of space actually in use by this
   * bit string to represent bit values.
   *
   * @param             - none
   * @return             Number of bytes of space actually in use by this bit
   *                       string to represent bit values.
   */
   /*
   * Returns the number of bytes of space actually in use by this 
   * bit string to represent bit values. 
   */
   int size() const;

  /**
   * This method Calculates the "logical size" of the bith string.
   *
   * The "logical size" is caluculated by noting the index of the highest set
   * bit in the bit string plus one. Zero will be returned if the bit string
   * contains no set bits. The highest bit in the bit string is the LS bit in
   * the last octet set to 1.
   *
   * @param             - none
   * @return             Returns the "logical size" of this bit string.
   */
   /*
   * Returns the "logical size" of this bit string: the index of
   * the highest set bit in the bit string plus one. Returns zero
   * if the bit string contains no set bits.
   */
   ASN1UINT length() const;

  /**
   * This method calculates the cardinality of the target bit string.
   *
   * Cardinality of the bit string is the number of bits set to 1.
   *
   * @param             - none
   * @return             The number of bytes of space actually in use by this
   *                       bit string to represent the bit values.
   */
   /*
   * Returns the number of bits set to 1 in this
   * bit string.
   */
   int cardinality() const;

  /**
   * This method copies the bit string to the given buffer.
   *
   * @param pBuf         Pointer to the destination buffer where bytes will be
   *                       copied.
   * @param bufSz        Size of the destination buffer. If the size of 
   *                       the buffer is not large enough to receive the 
   *                       entire bit string, a negative status value 
   *                       (ASN_E_BUFOVFLOW) will be returned.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Copies bit string to buffer (pBuf).
   */
   int getBytes(ASN1OCTET* pBuf, int bufSz);

  /**
   * This version of the get method copies the bit string composed of bits from
   * this bit string from the specified fromIndex (inclusive) to the specified
   * toIndex (exclusive) into the given buffer.
   *
   * @param fromIndex    Relative start index (inclusive) of bits in string.
   *                       Bit index 0 refers to the MS bit (bit 8) in the
   *                       first octet. The index values then progress from
   *                       left to right (MS to LS bits).
   * @param toIndex      Relative end index (exclusive) of bits in string. Bit
   *                       index 0 refers to the MS bit (bit 8) in the first
   *                       octet. The index values then progress from left to
   *                       right (MS to LS bits).
   * @param pBuf         Pointer to destination buffer where bytes will be
   *                       copied.
   * @param bufSz        Size of the destination buffer. If the size of 
   *                       the buffer is not large enough to receive the 
   *                       entire bit string, a negative status value 
   *                       (ASN_E_BUFOVFLOW) will be returned.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - ASN_E_OUTOFBND index value is out of bounds
   *                       - ASN_E_RANGERR fromIndex > toIndex
   *                       - other error codes (see asn1type.h).
   */
   int get(ASN1UINT fromIndex, ASN1UINT toIndex, ASN1OCTET* pBuf, int bufSz);

  /**
   * This method provides the logical AND of the target bit string with the
   * argument bit string.
   *
   * @param pOctstr      A pointer to octets of another bit string for
   *                       performing logical operation.
   * @param octsNumbits  A number of bits in arguent bit string.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Performs a logical AND of this target bit set with the 
   * argument bit set.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_INVLEN - if 'octsNumbits' is negative, or
   *          ASN_E_INVPARAM - if pOctstr is the same bit string as this or null, or
   *          other error codes (see asn1type.h).
   */
   int doAnd(const ASN1OCTET* pOctstr, ASN1UINT octsNumbits);
   
  /**
   * This method performs a logical AND of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference t another bit string represented by
   *                       ASN1TDynBitStr type for performing logical
   *                       operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doAnd(const ASN1TDynBitStr& bitStr) {
      return doAnd(bitStr.data, bitStr.numbits);
   }
 
  /**  
   * This method performs a logical AND of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference to another bit string represented by
   *                       ASN1CBitStr type for performing logical operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doAnd(const ASN1CBitStr& bitStr) {
      return doAnd(*bitStr.mpUnits, bitStr.length());
   }


  /**
   * This method preforms a logical OR of the target bit string with the
   * argument bit string.
   *
   * @param pOctstr      A pointer to octets of another bit string for
   *                       performing logical operation.
   * @param octsNumbits  A number of bits in arguent bit string.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Performs a logical OR of this target bit set with the 
   * argument bit set.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_INVLEN - if 'octsNumbits' is negative, or
   *          ASN_E_INVPARAM - if pOctstr is the same bit string as this or null, or
   *          other error codes (see asn1type.h).
   */
   int doOr(const ASN1OCTET* pOctstr, ASN1UINT octsNumbits);
   
  /** 
   * This method performs a logical OR of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference t another bit string represented by
   *                       ASN1TDynBitStr type for performing logical
   *                       operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doOr(const ASN1TDynBitStr& bitStr) {
      return doOr(bitStr.data, bitStr.numbits);
   }
   
  /**  
   * This method performs a logical OR of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference to another bit string represented by
   *                       ASN1CBitStr type for performing logical operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doOr(const ASN1CBitStr& bitStr) {
      return doOr(*bitStr.mpUnits, bitStr.length());
   }

   /**
    * This method provides the logical XOR of the target bit string with the
    * argument bit string.
    *
    * @param pOctstr      A pointer to octets of another bit string for
    *                       performing logical operation.
    * @param octsNumbits  A number of bits in arguent bit string.
    * @return             Completion status of operation:
    *                       - 0 (ASN_OK) = success,
    *                       - negative return value is error.
   */
   /*
   * Performs a logical XOR of this target bit set with the 
   * argument bit set.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_INVLEN - if 'octsNumbits' is negative, or
   *          ASN_E_INVPARAM - if pOctstr is null, or
   *          other error codes (see asn1type.h).
   */
   int doXor(const ASN1OCTET* pOctstr, ASN1UINT octsNumbits);
 
  /** 
   * This method performs a logical XOR of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference t another bit string represented by
   *                       ASN1TDynBitStr type for performing logical
   *                       operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */  
   inline int doXor(const ASN1TDynBitStr& bitStr) {
      return doXor(bitStr.data, bitStr.numbits);
   }

  /**  
   * This method performs a logical OR of the target bit string with the
   * argument bit string.
   *
   * @param bitStr       A reference to another bit string represented by
   *                       ASN1CBitStr type for performing logical operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doXor(const ASN1CBitStr& bitStr) {
      return doXor(*bitStr.mpUnits, bitStr.length());
   }

  /**
   * This method performs a logical ANDNOT of the target bit string with the
   * argument bit string.
   *
   * Logical ANDNOT clars all of the bits in this bit string whose
   * corresponding bit is set in the specified bit string.
   *
   * @param pOctstr      A pointer to octets of another bit string for
   *                       performing logical operation.
   * @param octsNumbits  A number of bits in arguent bit string.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Clears all of the bits in this bit string whose corresponding
   * bit is set in the specified bit string.
   *
   * Returns: ASN_OK - if succeed, or 
   *          ASN_E_INVLEN - if 'octsNumbits' is negative, or
   *          ASN_E_INVPARAM - if pOctstr is null, or
   *          other error codes (see asn1type.h).
   */
   int doAndNot(const ASN1OCTET* pOctstr, ASN1UINT octsNumbits);
   
  /**
   * This method performs a logical ANDNOT of the target bit string with the
   * argument bit string.
   *
   * Logical ANDNOT clears all of the bits in this bit string whose
   * corresponding bit is set in the specified bit string.
   *
   * @param bitStr       A reference t another bit string represented by
   *                       ASN1TDynBitStr type for performing logical
   *                       operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   inline int doAndNot(const ASN1TDynBitStr& bitStr) {
      return doAndNot(bitStr.data, bitStr.numbits);
   }

  /**
   * This method performs a logical ANDNOT of the target bit string with the
   * argument bit string.
   *
   * Logical ANDNOT clears all of the bits in this bit string whose
   * corresponding bit is set in the specified bit string.
   *
   * @param bitStr       A reference to another bit string represented by
   *                       ASN1CBitStr type for performing logical operation.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */   
   inline int doAndNot(const ASN1CBitStr& bitStr) {
      return doAndNot(*bitStr.mpUnits, bitStr.length());
   }

  /**
   * This method shifts all bits to the left by the number of specified in the
   * shift operand.
   *
   * If the bit string can dynamically grow, then the length of the bit string
   * will be decreased by shift bits. Otherwise, bits that are shifted into the
   * bitstring are filled with zeros from the right. Most left bits are lost.
   *
   * @param shift        Number of bits to be shifted.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Shifts all bits to the left by 'shift' bits.
   */
   int shiftLeft(ASN1UINT shift);

  /**
   * This method shifts all bits to the right by the number of specified in the
   * shift operand.
   *
   * If the bit string can dynamically grow, then the length of the bit string
   * will be decreased by shift bits. Otherwise, bits that are shifted into the
   * bitstring are filled with zeros from the left. Most right bits are lost.
   *
   * @param shift        Number of bits to be shifted.
   * @return             Completion status of operation:
   *                       - 0 (ASN_OK) = success,
   *                       - negative return value is error.
   */
   /*
   * Shifts all bits to the right by 'shift' bits.
   */
   int shiftRight(ASN1UINT shift);

  /**
   * This method returns the number of unused bits in the last octet.
   *
   * @param             - none
   * @return             Number of bits in teh last octet. It equals to
   *                       length() % 8.
   */
   /* 
   * Returns number of unused bits in last unit. 
   */
   int unusedBitsInLastUnit();

  /**
   * This method returns a filled ANSDITDynBitStr variable.
   *
   * Memory is not allocated when calling this method; only a pointer is
   * assigned. Thus, the ASN1TDynBitStr variable is only valid while this
   * ASN1CBitStr is in scope.
   *
   * @param             - none
   * @return             Filled ASN1TDynBitStr.
   */
   /*
   * Returns filled ASN1TDynBitStr. Memory for data is not
   * reallocated, thus, this ASN1TDynBitStr will be eligible while
   * this ASN1CBitStr is in scope.
   */
   operator ASN1TDynBitStr();
   
  /**
   * This method returns a pointer to the filled ANSDITDynBitStr variable.
   *
   * Memory for the ASN1DynBitStr variable is alloced using memory memAlloc and
   * bits are copied into it.
   *
   * @param             - none
   * @return             Pointer to a filled ASN1TDynBitStr.
   */
   /*
   * Returns pointer to filled ASN1TDynBitStr. In this method,
   * memory is allocated, and bits are copied to it.
   */
   operator ASN1TDynBitStr*();
} ;
#else
typedef class _ASN1CBitStr : public ASN1CType {
 public:
   _ASN1CBitStr (ASN1MessageBufferIF& msgBuf, ASN1UINT nbits) :
      ASN1CType (msgBuf) {}
   _ASN1CBitStr (ASN1MessageBufferIF& msgBuf, ASN1OCTET* bitStr, 
      ASN1UINT& octsNumbits, ASN1UINT maxNumbits_) :
      ASN1CType (msgBuf) {}
   _ASN1CBitStr (ASN1MessageBufferIF& msgBuf, ASN1TDynBitStr& bitStr) :
      ASN1CType (msgBuf) {}
} ASN1CBitStr;
#endif // _NO_UTILS_CLASSES
#endif // _ASN1CBITSTR_H_
/** 
 * @}asn1cb 
 */
