コード例 #1
0
        /// <summary>
        /// Continue scanning input starting from offset_ to find the element end.
        /// If the end of the element which started at offset 0 is found, this returns
        /// true and getOffset() is the length of the element.  Otherwise, this returns
        /// false which means you should read more into input and call again.
        /// </summary>
        ///
        /// <param name="input">You have to pass in input each time because the buffer could be reallocated.</param>
        /// <returns>true if found the element end, false if not.</returns>
        public bool findElementEnd(ByteBuffer input)
        {
            if (gotElementEnd_)
            {
                // Someone is calling when we already got the end.
                return(true);
            }

            TlvDecoder decoder = new TlvDecoder(input);

            while (true)
            {
                if (offset_ >= input.limit())
                {
                    // All the cases assume we have some input. Return and wait for more.
                    return(false);
                }

                if (state_ == TlvStructureDecoder.READ_TYPE)
                {
                    int firstOctet = (int)input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet < 253)
                    {
                        // The value is simple, so we can skip straight to reading the length.
                        state_ = TlvStructureDecoder.READ_LENGTH;
                    }
                    else
                    {
                        // Set up to skip the type bytes.
                        if (firstOctet == 253)
                        {
                            nBytesToRead_ = 2;
                        }
                        else if (firstOctet == 254)
                        {
                            nBytesToRead_ = 4;
                        }
                        else
                        {
                            // value == 255.
                            nBytesToRead_ = 8;
                        }

                        state_ = TlvStructureDecoder.READ_TYPE_BYTES;
                    }
                }
                else if (state_ == TlvStructureDecoder.READ_TYPE_BYTES)
                {
                    int nRemainingBytes = input.limit() - offset_;
                    if (nRemainingBytes < nBytesToRead_)
                    {
                        // Need more.
                        offset_       += nRemainingBytes;
                        nBytesToRead_ -= nRemainingBytes;
                        return(false);
                    }

                    // Got the type bytes. Move on to read the length.
                    offset_ += nBytesToRead_;
                    state_   = TlvStructureDecoder.READ_LENGTH;
                }
                else if (state_ == TlvStructureDecoder.READ_LENGTH)
                {
                    int firstOctet_0 = (int)input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet_0 < 253)
                    {
                        // The value is simple, so we can skip straight to reading
                        //  the value bytes.
                        nBytesToRead_ = firstOctet_0;
                        if (nBytesToRead_ == 0)
                        {
                            // No value bytes to read. We're finished.
                            gotElementEnd_ = true;
                            return(true);
                        }

                        state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                    }
                    else
                    {
                        // We need to read the bytes in the extended encoding of
                        //  the length.
                        if (firstOctet_0 == 253)
                        {
                            nBytesToRead_ = 2;
                        }
                        else if (firstOctet_0 == 254)
                        {
                            nBytesToRead_ = 4;
                        }
                        else
                        {
                            // value == 255.
                            nBytesToRead_ = 8;
                        }

                        // We need to use firstOctet in the next state.
                        firstOctet_ = firstOctet_0;
                        state_      = TlvStructureDecoder.READ_LENGTH_BYTES;
                    }
                }
                else if (state_ == TlvStructureDecoder.READ_LENGTH_BYTES)
                {
                    int nRemainingBytes_1 = input.limit() - offset_;
                    if (!useHeaderBuffer_ && nRemainingBytes_1 >= nBytesToRead_)
                    {
                        // We don't have to use the headerBuffer. Set nBytesToRead.
                        decoder.seek(offset_);

                        nBytesToRead_ = decoder.readExtendedVarNumber(firstOctet_);
                        // Update offset_ to the decoder's offset after reading.
                        offset_ = decoder.getOffset();
                    }
                    else
                    {
                        useHeaderBuffer_ = true;

                        int nNeededBytes = nBytesToRead_ - headerBuffer_.position();
                        if (nNeededBytes > nRemainingBytes_1)
                        {
                            // We can't get all of the header bytes from this input.
                            // Save in headerBuffer.
                            if (headerBuffer_.position() + nRemainingBytes_1 > headerBuffer_
                                .limit())
                            {
                                // We don't expect this to happen.
                                throw new Exception(
                                          "Cannot store more header bytes than the size of headerBuffer");
                            }
                            ByteBuffer remainingInput = input.duplicate();
                            remainingInput.position(offset_);
                            headerBuffer_.put(remainingInput);
                            offset_ += nRemainingBytes_1;

                            return(false);
                        }

                        // Copy the remaining bytes into headerBuffer, read the
                        //   length and set nBytesToRead.
                        if (headerBuffer_.position() + nNeededBytes > headerBuffer_
                            .limit())
                        {
                            // We don't expect this to happen.
                            throw new Exception(
                                      "Cannot store more header bytes than the size of headerBuffer");
                        }
                        ByteBuffer remainingLengthBytes = input.duplicate();
                        remainingLengthBytes.position(offset_);
                        remainingLengthBytes.limit(offset_ + nNeededBytes);
                        headerBuffer_.put(remainingLengthBytes);
                        offset_ += nNeededBytes;

                        // Use a local decoder just for the headerBuffer.
                        headerBuffer_.flip();
                        TlvDecoder bufferDecoder = new TlvDecoder(headerBuffer_);
                        // Replace nBytesToRead with the length of the value.
                        nBytesToRead_ = bufferDecoder
                                        .readExtendedVarNumber(firstOctet_);
                    }

                    if (nBytesToRead_ == 0)
                    {
                        // No value bytes to read. We're finished.
                        gotElementEnd_ = true;
                        return(true);
                    }

                    // Get ready to read the value bytes.
                    state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                }
                else if (state_ == TlvStructureDecoder.READ_VALUE_BYTES)
                {
                    int nRemainingBytes_2 = input.limit() - offset_;
                    if (nRemainingBytes_2 < nBytesToRead_)
                    {
                        // Need more.
                        offset_       += nRemainingBytes_2;
                        nBytesToRead_ -= nRemainingBytes_2;
                        return(false);
                    }

                    // Got the bytes. We're finished.
                    offset_       += nBytesToRead_;
                    gotElementEnd_ = true;
                    return(true);
                }
                else
                {
                    // We don't expect this to happen.
                    throw new Exception("findElementEnd: unrecognized state");
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Continue scanning input starting from offset_ to find the element end.
        /// If the end of the element which started at offset 0 is found, this returns
        /// true and getOffset() is the length of the element.  Otherwise, this returns
        /// false which means you should read more into input and call again.
        /// </summary>
        ///
        /// <param name="input">You have to pass in input each time because the buffer could be reallocated.</param>
        /// <returns>true if found the element end, false if not.</returns>
        public bool findElementEnd(ByteBuffer input)
        {
            if (gotElementEnd_)
                // Someone is calling when we already got the end.
                return true;

            TlvDecoder decoder = new TlvDecoder(input);

            while (true) {
                if (offset_ >= input.limit())
                    // All the cases assume we have some input. Return and wait for more.
                    return false;

                if (state_ == TlvStructureDecoder.READ_TYPE) {
                    int firstOctet = (int) input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet < 253)
                        // The value is simple, so we can skip straight to reading the length.
                        state_ = TlvStructureDecoder.READ_LENGTH;
                    else {
                        // Set up to skip the type bytes.
                        if (firstOctet == 253)
                            nBytesToRead_ = 2;
                        else if (firstOctet == 254)
                            nBytesToRead_ = 4;
                        else
                            // value == 255.
                            nBytesToRead_ = 8;

                        state_ = TlvStructureDecoder.READ_TYPE_BYTES;
                    }
                } else if (state_ == TlvStructureDecoder.READ_TYPE_BYTES) {
                    int nRemainingBytes = input.limit() - offset_;
                    if (nRemainingBytes < nBytesToRead_) {
                        // Need more.
                        offset_ += nRemainingBytes;
                        nBytesToRead_ -= nRemainingBytes;
                        return false;
                    }

                    // Got the type bytes. Move on to read the length.
                    offset_ += nBytesToRead_;
                    state_ = TlvStructureDecoder.READ_LENGTH;
                } else if (state_ == TlvStructureDecoder.READ_LENGTH) {
                    int firstOctet_0 = (int) input.get(offset_) & 0xff;
                    offset_ += 1;
                    if (firstOctet_0 < 253) {
                        // The value is simple, so we can skip straight to reading
                        //  the value bytes.
                        nBytesToRead_ = firstOctet_0;
                        if (nBytesToRead_ == 0) {
                            // No value bytes to read. We're finished.
                            gotElementEnd_ = true;
                            return true;
                        }

                        state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                    } else {
                        // We need to read the bytes in the extended encoding of
                        //  the length.
                        if (firstOctet_0 == 253)
                            nBytesToRead_ = 2;
                        else if (firstOctet_0 == 254)
                            nBytesToRead_ = 4;
                        else
                            // value == 255.
                            nBytesToRead_ = 8;

                        // We need to use firstOctet in the next state.
                        firstOctet_ = firstOctet_0;
                        state_ = TlvStructureDecoder.READ_LENGTH_BYTES;
                    }
                } else if (state_ == TlvStructureDecoder.READ_LENGTH_BYTES) {
                    int nRemainingBytes_1 = input.limit() - offset_;
                    if (!useHeaderBuffer_ && nRemainingBytes_1 >= nBytesToRead_) {
                        // We don't have to use the headerBuffer. Set nBytesToRead.
                        decoder.seek(offset_);

                        nBytesToRead_ = decoder.readExtendedVarNumber(firstOctet_);
                        // Update offset_ to the decoder's offset after reading.
                        offset_ = decoder.getOffset();
                    } else {
                        useHeaderBuffer_ = true;

                        int nNeededBytes = nBytesToRead_ - headerBuffer_.position();
                        if (nNeededBytes > nRemainingBytes_1) {
                            // We can't get all of the header bytes from this input.
                            // Save in headerBuffer.
                            if (headerBuffer_.position() + nRemainingBytes_1 > headerBuffer_
                                    .limit())
                                // We don't expect this to happen.
                                throw new Exception(
                                        "Cannot store more header bytes than the size of headerBuffer");
                            ByteBuffer remainingInput = input.duplicate();
                            remainingInput.position(offset_);
                            headerBuffer_.put(remainingInput);
                            offset_ += nRemainingBytes_1;

                            return false;
                        }

                        // Copy the remaining bytes into headerBuffer, read the
                        //   length and set nBytesToRead.
                        if (headerBuffer_.position() + nNeededBytes > headerBuffer_
                                .limit())
                            // We don't expect this to happen.
                            throw new Exception(
                                    "Cannot store more header bytes than the size of headerBuffer");
                        ByteBuffer remainingLengthBytes = input.duplicate();
                        remainingLengthBytes.position(offset_);
                        remainingLengthBytes.limit(offset_ + nNeededBytes);
                        headerBuffer_.put(remainingLengthBytes);
                        offset_ += nNeededBytes;

                        // Use a local decoder just for the headerBuffer.
                        headerBuffer_.flip();
                        TlvDecoder bufferDecoder = new TlvDecoder(headerBuffer_);
                        // Replace nBytesToRead with the length of the value.
                        nBytesToRead_ = bufferDecoder
                                .readExtendedVarNumber(firstOctet_);
                    }

                    if (nBytesToRead_ == 0) {
                        // No value bytes to read. We're finished.
                        gotElementEnd_ = true;
                        return true;
                    }

                    // Get ready to read the value bytes.
                    state_ = TlvStructureDecoder.READ_VALUE_BYTES;
                } else if (state_ == TlvStructureDecoder.READ_VALUE_BYTES) {
                    int nRemainingBytes_2 = input.limit() - offset_;
                    if (nRemainingBytes_2 < nBytesToRead_) {
                        // Need more.
                        offset_ += nRemainingBytes_2;
                        nBytesToRead_ -= nRemainingBytes_2;
                        return false;
                    }

                    // Got the bytes. We're finished.
                    offset_ += nBytesToRead_;
                    gotElementEnd_ = true;
                    return true;
                } else
                    // We don't expect this to happen.
                    throw new Exception("findElementEnd: unrecognized state");
            }
        }