Ejemplo n.º 1
0
        /*
         * This is a facade method for the encoding operation.
         * <p />
         * This method encodes the remaining character sequence of the given
         * character buffer into a new byte buffer. This method performs a complete
         * encoding operation, resets at first, then encodes, and flushes at last.
         * <p />
         * This method should not be invoked if another encode operation is ongoing.
         *
         * @param in
         *            the input buffer.
         * @return a new <code>ByteBuffer</code> containing the bytes produced by
         *         this encoding operation. The buffer's limit will be the position
         *         of the last byte in the buffer, and the position will be zero.
         * @throws IllegalStateException
         *             if another encoding operation is ongoing.
         * @throws MalformedInputException
         *             if an illegal input character sequence for this charset is
         *             encountered, and the action for malformed error is
         *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}
         * @throws UnmappableCharacterException
         *             if a legal but unmappable input character sequence for this
         *             charset is encountered, and the action for unmappable
         *             character error is
         *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.
         *             Unmappable means the Unicode character sequence at the input
         *             buffer's current position cannot be mapped to a equivalent
         *             byte sequence.
         * @throws CharacterCodingException
         *             if other exception happened during the encode operation.
         */
        public ByteBuffer encode(CharBuffer inJ) //throws CharacterCodingException
        {
            if (inJ.remaining() == 0)
            {
                return(ByteBuffer.allocate(0));
            }
            reset();
            int         length = (int)(inJ.remaining() * averBytes);
            ByteBuffer  output = ByteBuffer.allocate(length);
            CoderResult result = null;

            while (true)
            {
                result = encode(inJ, output, false);
                if (result == CoderResult.UNDERFLOW)
                {
                    break;
                }
                else if (result == CoderResult.OVERFLOW)
                {
                    output = allocateMore(output);
                    continue;
                }
                checkCoderResult(result);
            }
            result = encode(inJ, output, true);
            checkCoderResult(result);

            while (true)
            {
                result = flush(output);
                if (result == CoderResult.UNDERFLOW)
                {
                    output.flip();
                    break;
                }
                else if (result == CoderResult.OVERFLOW)
                {
                    output = allocateMore(output);
                    continue;
                }
                checkCoderResult(result);
                output.flip();
                if (result.isMalformed())
                {
                    throw new MalformedInputException(result.length());
                }
                else if (result.isUnmappable())
                {
                    throw new UnmappableCharacterException(result.length());
                }
                break;
            }
            status   = READY;
            finished = true;
            return(output);
        }
Ejemplo n.º 2
0
 /*
  * checks the result whether it needs to throw CharacterCodingException.
  */
 private void checkCoderResult(CoderResult result)// throws CharacterCodingException
 {
     if (malformAction == CodingErrorAction.REPORT && result.isMalformed())
     {
         throw new MalformedInputException(result.length());
     }
     else if (unmapAction == CodingErrorAction.REPORT && result.isUnmappable())
     {
         throw new UnmappableCharacterException(result.length());
     }
 }
 //throws CharacterCodingException
 /*
  * checks the result whether it needs to throw CharacterCodingException.
  */
 private void checkCoderResult(CoderResult result)
 {
     if (result.isMalformed() && malformAction == CodingErrorAction.REPORT) {
         throw new MalformedInputException(result.length());
     } else if (result.isUnmappable()
             && unmapAction == CodingErrorAction.REPORT) {
         throw new UnmappableCharacterException(result.length());
     }
 }
Ejemplo n.º 4
0
        /*
         * Decodes bytes starting at the current position of the given input buffer,
         * and writes the equivalent character sequence into the given output buffer
         * from its current position.
         * <p>
         * The buffers' position will be changed with the reading and writing
         * operation, but their limits and marks will be kept intact.
         * <p>
         * A <code>CoderResult</code> instance will be returned according to
         * following rules:
         * <ul>
         * <li>{@link CoderResult#OVERFLOW CoderResult.OVERFLOW} indicates that
         * even though not all of the input has been processed, the buffer the
         * output is being written to has reached its capacity. In the event of this
         * code being returned this method should be called once more with an
         * <code>out</code> argument that has not already been filled.</li>
         * <li>{@link CoderResult#UNDERFLOW CoderResult.UNDERFLOW} indicates that
         * as many bytes as possible in the input buffer have been decoded. If there
         * is no further input and no remaining bytes in the input buffer then this
         * operation may be regarded as complete. Otherwise, this method should be
         * called once more with additional input.</li>
         * <li>A {@link CoderResult#malformedForLength(int) malformed input} result
         * indicates that some malformed input error has been encountered, and the
         * erroneous bytes start at the input buffer's position and their number can
         * be got by result's {@link CoderResult#length() length}. This kind of
         * result can be returned only if the malformed action is
         * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. </li>
         * <li>A {@link CoderResult#unmappableForLength(int) unmappable character}
         * result indicates that some unmappable character error has been
         * encountered, and the erroneous bytes start at the input buffer's position
         * and their number can be got by result's
         * {@link CoderResult#length() length}. This kind of result can be returned
         * only if the unmappable character action is
         * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. </li>
         * </ul>
         * <p>
         * The <code>endOfInput</code> parameter indicates that the invoker cannot
         * provide further input. This parameter is true if and only if the bytes in
         * current input buffer are all inputs for this decoding operation. Note
         * that it is common and won't cause an error if the invoker sets false and
         * then can't provide more input, while it may cause an error if the invoker
         * always sets true in several consecutive invocations. This would make the
         * remaining input to be treated as malformed input.
         * <p>
         * This method invokes the
         * {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop} method to
         * implement the basic decode logic for a specific charset.
         *
         * @param in
         *            the input buffer.
         * @param out
         *            the output buffer.
         * @param endOfInput
         *            true if all the input characters have been provided.
         * @return a <code>CoderResult</code> instance which indicates the reason
         *         of termination.
         * @throws IllegalStateException
         *             if decoding has started or no more input is needed in this
         *             decoding progress.
         * @throws CoderMalfunctionError
         *             if the {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop}
         *             method threw an <code>BufferUnderflowException</code> or
         *             <code>BufferOverflowException</code>.
         */
        public CoderResult decode(ByteBuffer inJ, CharBuffer outJ,
                                  bool endOfInput)
        {
            /*
             * status check
             */
            if ((status == FLUSH) || (!endOfInput && status == END))
            {
                throw new java.lang.IllegalStateException();
            }

            CoderResult result = null;

            // begin to decode
            while (true)
            {
                CodingErrorAction action = null;
                try {
                    result = decodeLoop(inJ, outJ);
                } catch (BufferOverflowException ex) {
                    // unexpected exception
                    throw new CoderMalfunctionError(ex);
                } catch (BufferUnderflowException ex) {
                    // unexpected exception
                    throw new CoderMalfunctionError(ex);
                }

                /*
                 * result handling
                 */
                if (result.isUnderflow())
                {
                    int remaining = inJ.remaining(); // WHY inJ.remaining() == 1?
                    status = endOfInput ? END : ONGOING;
                    if (endOfInput && remaining > 0)
                    {
                        result = CoderResult.malformedForLength(remaining);
                    }
                    else
                    {
                        return(result);
                    }
                }
                if (result.isOverflow())
                {
                    return(result);
                }
                // set coding error handle action
                action = malformAction;
                if (result.isUnmappable())
                {
                    action = unmapAction;
                }
                // If the action is IGNORE or REPLACE, we should continue decoding.
                if (action == CodingErrorAction.REPLACE)
                {
                    if (outJ.remaining() < replace.length())
                    {
                        return(CoderResult.OVERFLOW);
                    }
                    outJ.put(replace);
                }
                else
                {
                    if (action != CodingErrorAction.IGNORE)
                    {
                        return(result);
                    }
                }
                inJ.position(inJ.position() + result.length());
            }
        }