001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2016 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    
026    import static com.unboundid.asn1.ASN1Messages.*;
027    
028    
029    
030    /**
031     * This class provides a data structure which is used in the course of reading
032     * an ASN.1 sequence from an ASN.1 stream reader.  It provides access to the
033     * BER type and the total number of bytes in the encoded representations of all
034     * of the embedded values, and provides a method to determine when the end of
035     * the sequence has been reached.
036     */
037    public final class ASN1StreamReaderSequence
038    {
039      // The ASN.1 stream reader associated with this object.
040      private final ASN1StreamReader reader;
041    
042      // The BER type for this ASN.1 sequence.
043      private final byte type;
044    
045      // The number of bytes contained in the encoded representations of all of the
046      // embedded values.
047      private final int length;
048    
049      // The value for the total number of bytes read from the associated reader at
050      // which the end of the sequence should be encountered.
051      private final long endBytesRead;
052    
053    
054    
055      /**
056       * Creates a new instance of this class with the provided information.
057       *
058       * @param  reader  The ASN.1 stream reader with which this object will be
059       *                 associated.
060       * @param  type    The BER type for this ASN.1 sequence.
061       * @param  length  The number of bytes contained in the encoded
062       *                 representations of all the embedded values.
063       */
064      ASN1StreamReaderSequence(final ASN1StreamReader reader, final byte type,
065                               final int length)
066      {
067        this.reader = reader;
068        this.type   = type;
069        this.length = length;
070    
071        endBytesRead = reader.getTotalBytesRead() + length;
072      }
073    
074    
075    
076      /**
077       * Retrieves the BER type for this ASN.1 sequence.
078       *
079       * @return  The BER type for this ASN.1 sequence.
080       */
081      public byte getType()
082      {
083        return type;
084      }
085    
086    
087    
088      /**
089       * Retrieves the number of bytes contained in the encoded representations of
090       * all the embedded values.
091       *
092       * @return  The number of bytes contained in the encoded representations of
093       *          all the embedded values.
094       */
095      public int getLength()
096      {
097        return length;
098      }
099    
100    
101    
102      /**
103       * Indicates whether there are more elements in this sequence to be read from
104       * the associated ASN.1 stream reader.
105       *
106       * @return  {@code true} if there are more elements in this sequence to be
107       *          read from the associated ASN.1 stream reader or false if the end
108       *          of the sequence has been reached.
109       *
110       * @throws  ASN1Exception  If the associated ASN.1 stream reader has already
111       *                         read beyond the end of the sequence.
112       */
113      public boolean hasMoreElements()
114             throws ASN1Exception
115      {
116        final long currentBytesRead = reader.getTotalBytesRead();
117        if (currentBytesRead == endBytesRead)
118        {
119          return false;
120        }
121        else if (currentBytesRead < endBytesRead)
122        {
123          return true;
124        }
125    
126        throw new ASN1Exception(ERR_STREAM_READER_SEQUENCE_READ_PAST_END.get(
127             length, endBytesRead, currentBytesRead));
128      }
129    }