001    /*
002     * Copyright 2007-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2015 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.asn1;
022    
023    
024    
025    import com.unboundid.util.NotMutable;
026    import com.unboundid.util.ThreadSafety;
027    import com.unboundid.util.ThreadSafetyLevel;
028    
029    import static com.unboundid.asn1.ASN1Constants.*;
030    import static com.unboundid.asn1.ASN1Messages.*;
031    import static com.unboundid.util.Debug.*;
032    import static com.unboundid.util.StaticUtils.*;
033    
034    
035    
036    /**
037     * This class provides an ASN.1 null element, which does not hold a value.  Null
038     * elements are generally used as placeholders that can be substituted for other
039     * types of elements.
040     */
041    @NotMutable()
042    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
043    public final class ASN1Null
044           extends ASN1Element
045    {
046      /**
047       * A pre-allocated ASN.1 null element with the universal null BER type.
048       */
049      public static final ASN1Null UNIVERSAL_NULL_ELEMENT = new ASN1Null();
050    
051    
052    
053      /**
054       * The serial version UID for this serializable class.
055       */
056      private static final long serialVersionUID = -3264450066845549348L;
057    
058    
059    
060      /**
061       * Creates a new ASN.1 null element with the default BER type.
062       */
063      public ASN1Null()
064      {
065        super(UNIVERSAL_NULL_TYPE);
066      }
067    
068    
069    
070      /**
071       * Creates a new ASN.1 null element with the specified BER type.
072       *
073       * @param  type  The BER type to use for this ASN.1 null element.
074       */
075      public ASN1Null(final byte type)
076      {
077        super(type);
078      }
079    
080    
081    
082      /**
083       * Decodes the contents of the provided byte array as a null element.
084       *
085       * @param  elementBytes  The byte array to decode as an ASN.1 null element.
086       *
087       * @return  The decoded ASN.1 null element.
088       *
089       * @throws  ASN1Exception  If the provided array cannot be decoded as a null
090       *                         element.
091       */
092      public static ASN1Null decodeAsNull(final byte[] elementBytes)
093             throws ASN1Exception
094      {
095        try
096        {
097          int valueStartPos = 2;
098          int length = (elementBytes[1] & 0x7F);
099          if (length != elementBytes[1])
100          {
101            final int numLengthBytes = length;
102    
103            length = 0;
104            for (int i=0; i < numLengthBytes; i++)
105            {
106              length <<= 8;
107              length |= (elementBytes[valueStartPos++] & 0xFF);
108            }
109          }
110    
111          if ((elementBytes.length - valueStartPos) != length)
112          {
113            throw new ASN1Exception(ERR_ELEMENT_LENGTH_MISMATCH.get(length,
114                                         (elementBytes.length - valueStartPos)));
115          }
116    
117          if (length != 0)
118          {
119            throw new ASN1Exception(ERR_NULL_HAS_VALUE.get());
120          }
121    
122          return new ASN1Null(elementBytes[0]);
123        }
124        catch (final ASN1Exception ae)
125        {
126          debugException(ae);
127          throw ae;
128        }
129        catch (final Exception e)
130        {
131          debugException(e);
132          throw new ASN1Exception(ERR_ELEMENT_DECODE_EXCEPTION.get(e), e);
133        }
134      }
135    
136    
137    
138      /**
139       * Decodes the provided ASN.1 element as a null element.
140       *
141       * @param  element  The ASN.1 element to be decoded.
142       *
143       * @return  The decoded ASN.1 null element.
144       *
145       * @throws  ASN1Exception  If the provided element cannot be decoded as a null
146       *                         element.
147       */
148      public static ASN1Null decodeAsNull(final ASN1Element element)
149             throws ASN1Exception
150      {
151        if (element.getValue().length != 0)
152        {
153          throw new ASN1Exception(ERR_NULL_HAS_VALUE.get());
154        }
155    
156        return new ASN1Null(element.getType());
157      }
158    
159    
160    
161      /**
162       * Appends a string representation of this ASN.1 element to the provided
163       * buffer.
164       *
165       * @param  buffer  The buffer to which to append the information.
166       */
167      @Override()
168      public void toString(final StringBuilder buffer)
169      {
170        buffer.append("ASN1Null(type=");
171        toHex(getType(), buffer);
172        buffer.append(')');
173      }
174    }