Наследование: java.lang.Object
Пример #1
0
 internal virtual CoderResult Get(int len)
 {
     lock (this)
     {
         if (len <= 0)
         {
             throw new IllegalArgumentException("Non-positive length");
         }
         Integer k = new Integer(len);
         WeakReference <CoderResult> w;
         CoderResult e = null;
         if (Cache == null)
         {
             Cache = new Dictionary <Integer, WeakReference <CoderResult> >();
         }
         else if ((w = Cache[k]) != null)
         {
             e = w.get();
         }
         if (e == null)
         {
             e        = Create(len);
             Cache[k] = new WeakReference <CoderResult>(e);
         }
         return(e);
     }
 }
Пример #2
0
        /// <summary>
        /// Flushes this decoder.
        ///
        /// <para> Some decoders maintain internal state and may need to write some
        /// final characters to the output buffer once the overall input sequence has
        /// been read.
        ///
        /// </para>
        /// <para> Any additional output is written to the output buffer beginning at
        /// its current position.  At most <seealso cref="Buffer#remaining out.remaining()"/>
        /// characters will be written.  The buffer's position will be advanced
        /// appropriately, but its mark and limit will not be modified.
        ///
        /// </para>
        /// <para> If this method completes successfully then it returns {@link
        /// CoderResult#UNDERFLOW}.  If there is insufficient room in the output
        /// buffer then it returns <seealso cref="CoderResult#OVERFLOW"/>.  If this happens
        /// then this method must be invoked again, with an output buffer that has
        /// more room, in order to complete the current <a href="#steps">decoding
        /// operation</a>.
        ///
        /// </para>
        /// <para> If this decoder has already been flushed then invoking this method
        /// has no effect.
        ///
        /// </para>
        /// <para> This method invokes the <seealso cref="#implFlush implFlush"/> method to
        /// perform the actual flushing operation.  </para>
        /// </summary>
        /// <param name="out">
        ///         The output character buffer
        /// </param>
        /// <returns>  A coder-result object, either <seealso cref="CoderResult#UNDERFLOW"/> or
        ///          <seealso cref="CoderResult#OVERFLOW"/>
        /// </returns>
        /// <exception cref="IllegalStateException">
        ///          If the previous step of the current decoding operation was an
        ///          invocation neither of the <seealso cref="#flush flush"/> method nor of
        ///          the three-argument {@link
        ///          #decode(ByteBuffer,CharBuffer,boolean) decode} method
        ///          with a value of <tt>true</tt> for the <tt>endOfInput</tt>
        ///          parameter </exception>
        public CoderResult Flush(CharBuffer @out)
        {
            if (State == ST_END)
            {
                CoderResult cr = ImplFlush(@out);
                if (cr.Underflow)
                {
                    State = ST_FLUSHED;
                }
                return(cr);
            }

            if (State != ST_FLUSHED)
            {
                ThrowIllegalStateException(State, ST_FLUSHED);
            }

            return(CoderResult.UNDERFLOW);            // Already flushed
        }
Пример #3
0
        /// <summary>
        /// Tells whether or not the given byte array is a legal replacement value
        /// for this encoder.
        ///
        /// <para> A replacement is legal if, and only if, it is a legal sequence of
        /// bytes in this encoder's charset; that is, it must be possible to decode
        /// the replacement into one or more sixteen-bit Unicode characters.
        ///
        /// </para>
        /// <para> The default implementation of this method is not very efficient; it
        /// should generally be overridden to improve performance.  </para>
        /// </summary>
        /// <param name="repl">  The byte array to be tested
        /// </param>
        /// <returns>  <tt>true</tt> if, and only if, the given byte array
        ///          is a legal replacement value for this encoder </returns>
        public virtual bool IsLegalReplacement(sbyte[] repl)
        {
            WeakReference <CharsetDecoder> wr = CachedDecoder;
            CharsetDecoder dec = null;

            if ((wr == null) || ((dec = wr.get()) == null))
            {
                dec = Charset().NewDecoder();
                dec.OnMalformedInput(CodingErrorAction.REPORT);
                dec.OnUnmappableCharacter(CodingErrorAction.REPORT);
                CachedDecoder = new WeakReference <CharsetDecoder>(dec);
            }
            else
            {
                dec.Reset();
            }
            ByteBuffer  bb = ByteBuffer.Wrap(repl);
            CharBuffer  cb = CharBuffer.Allocate((int)(bb.Remaining() * dec.MaxCharsPerByte()));
            CoderResult cr = dec.Decode(bb, cb, true);

            return(!cr.Error);
        }
Пример #4
0
        /// <summary>
        /// Convenience method that decodes the remaining content of a single input
        /// byte buffer into a newly-allocated character buffer.
        ///
        /// <para> This method implements an entire <a href="#steps">decoding
        /// operation</a>; that is, it resets this decoder, then it decodes the
        /// bytes in the given byte buffer, and finally it flushes this
        /// decoder.  This method should therefore not be invoked if a decoding
        /// operation is already in progress.  </para>
        /// </summary>
        /// <param name="in">
        ///         The input byte buffer
        /// </param>
        /// <returns> A newly-allocated character buffer containing the result of the
        ///         decoding operation.  The buffer's position will be zero and its
        ///         limit will follow the last character written.
        /// </returns>
        /// <exception cref="IllegalStateException">
        ///          If a decoding operation is already in progress
        /// </exception>
        /// <exception cref="MalformedInputException">
        ///          If the byte sequence starting at the input buffer's current
        ///          position is not legal for this charset and the current malformed-input action
        ///          is <seealso cref="CodingErrorAction#REPORT"/>
        /// </exception>
        /// <exception cref="UnmappableCharacterException">
        ///          If the byte sequence starting at the input buffer's current
        ///          position cannot be mapped to an equivalent character sequence and
        ///          the current unmappable-character action is {@link
        ///          CodingErrorAction#REPORT} </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public final java.nio.CharBuffer decode(java.nio.ByteBuffer in) throws CharacterCodingException
        public CharBuffer Decode(ByteBuffer @in)
        {
            int        n    = (int)(@in.Remaining() * AverageCharsPerByte());
            CharBuffer @out = CharBuffer.Allocate(n);

            if ((n == 0) && (@in.Remaining() == 0))
            {
                return(@out);
            }
            Reset();
            for (;;)
            {
                CoderResult cr = @in.HasRemaining() ? Decode(@in, @out, true) : CoderResult.UNDERFLOW;
                if (cr.Underflow)
                {
                    cr = Flush(@out);
                }

                if (cr.Underflow)
                {
                    break;
                }
                if (cr.Overflow)
                {
                    n = 2 * n + 1;                     // Ensure progress; n might be 0!
                    CharBuffer o = CharBuffer.Allocate(n);
                    @out.Flip();
                    o.Put(@out);
                    @out = o;
                    continue;
                }
                cr.ThrowException();
            }
            @out.Flip();
            return(@out);
        }
Пример #5
0
        /// <summary>
        /// Decodes as many bytes as possible from the given input buffer,
        /// writing the results to the given output buffer.
        ///
        /// <para> The buffers are read from, and written to, starting at their current
        /// positions.  At most <seealso cref="Buffer#remaining in.remaining()"/> bytes
        /// will be read and at most <seealso cref="Buffer#remaining out.remaining()"/>
        /// characters will be written.  The buffers' positions will be advanced to
        /// reflect the bytes read and the characters written, but their marks and
        /// limits will not be modified.
        ///
        /// </para>
        /// <para> In addition to reading bytes from the input buffer and writing
        /// characters to the output buffer, this method returns a <seealso cref="CoderResult"/>
        /// object to describe its reason for termination:
        ///
        /// <ul>
        ///
        /// </para>
        ///   <li><para> <seealso cref="CoderResult#UNDERFLOW"/> indicates that as much of the
        ///   input buffer as possible has been decoded.  If there is no further
        ///   input then the invoker can proceed to the next step of the
        ///   <a href="#steps">decoding operation</a>.  Otherwise this method
        ///   should be invoked again with further input.  </para></li>
        ///
        ///   <li><para> <seealso cref="CoderResult#OVERFLOW"/> indicates that there is
        ///   insufficient space in the output buffer to decode any more bytes.
        ///   This method should be invoked again with an output buffer that has
        ///   more <seealso cref="Buffer#remaining remaining"/> characters. This is
        ///   typically done by draining any decoded characters from the output
        ///   buffer.  </para></li>
        ///
        ///   <li><para> A {@link CoderResult#malformedForLength
        ///   malformed-input} result indicates that a malformed-input
        ///   error has been detected.  The malformed bytes begin at the input
        ///   buffer's (possibly incremented) position; the number of malformed
        ///   bytes may be determined by invoking the result object's {@link
        ///   CoderResult#length() length} method.  This case applies only if the
        ///   <seealso cref="#onMalformedInput malformed action"/> of this decoder
        ///   is <seealso cref="CodingErrorAction#REPORT"/>; otherwise the malformed input
        ///   will be ignored or replaced, as requested.  </para></li>
        ///
        ///   <li><para> An {@link CoderResult#unmappableForLength
        ///   unmappable-character} result indicates that an
        ///   unmappable-character error has been detected.  The bytes that
        ///   decode the unmappable character begin at the input buffer's (possibly
        ///   incremented) position; the number of such bytes may be determined
        ///   by invoking the result object's <seealso cref="CoderResult#length() length"/>
        ///   method.  This case applies only if the {@link #onUnmappableCharacter
        ///   unmappable action} of this decoder is {@link
        ///   CodingErrorAction#REPORT}; otherwise the unmappable character will be
        ///   ignored or replaced, as requested.  </para></li>
        ///
        /// </ul>
        ///
        /// In any case, if this method is to be reinvoked in the same decoding
        /// operation then care should be taken to preserve any bytes remaining
        /// in the input buffer so that they are available to the next invocation.
        ///
        /// <para> The <tt>endOfInput</tt> parameter advises this method as to whether
        /// the invoker can provide further input beyond that contained in the given
        /// input buffer.  If there is a possibility of providing additional input
        /// then the invoker should pass <tt>false</tt> for this parameter; if there
        /// is no possibility of providing further input then the invoker should
        /// pass <tt>true</tt>.  It is not erroneous, and in fact it is quite
        /// common, to pass <tt>false</tt> in one invocation and later discover that
        /// no further input was actually available.  It is critical, however, that
        /// the final invocation of this method in a sequence of invocations always
        /// pass <tt>true</tt> so that any remaining undecoded input will be treated
        /// as being malformed.
        ///
        /// </para>
        /// <para> This method works by invoking the <seealso cref="#decodeLoop decodeLoop"/>
        /// method, interpreting its results, handling error conditions, and
        /// reinvoking it as necessary.  </para>
        ///
        /// </summary>
        /// <param name="in">
        ///         The input byte buffer
        /// </param>
        /// <param name="out">
        ///         The output character buffer
        /// </param>
        /// <param name="endOfInput">
        ///         <tt>true</tt> if, and only if, the invoker can provide no
        ///         additional input bytes beyond those in the given buffer
        /// </param>
        /// <returns>  A coder-result object describing the reason for termination
        /// </returns>
        /// <exception cref="IllegalStateException">
        ///          If a decoding operation is already in progress and the previous
        ///          step was an invocation neither of the <seealso cref="#reset reset"/>
        ///          method, nor of this method with a value of <tt>false</tt> for
        ///          the <tt>endOfInput</tt> parameter, nor of this method with a
        ///          value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
        ///          but a return value indicating an incomplete decoding operation
        /// </exception>
        /// <exception cref="CoderMalfunctionError">
        ///          If an invocation of the decodeLoop method threw
        ///          an unexpected exception </exception>
        public CoderResult Decode(ByteBuffer @in, CharBuffer @out, bool endOfInput)
        {
            int newState = endOfInput ? ST_END : ST_CODING;

            if ((State != ST_RESET) && (State != ST_CODING) && !(endOfInput && (State == ST_END)))
            {
                ThrowIllegalStateException(State, newState);
            }
            State = newState;

            for (;;)
            {
                CoderResult cr;
                try
                {
                    cr = DecodeLoop(@in, @out);
                }
                catch (BufferUnderflowException x)
                {
                    throw new CoderMalfunctionError(x);
                }
                catch (BufferOverflowException x)
                {
                    throw new CoderMalfunctionError(x);
                }

                if (cr.Overflow)
                {
                    return(cr);
                }

                if (cr.Underflow)
                {
                    if (endOfInput && @in.HasRemaining())
                    {
                        cr = CoderResult.MalformedForLength(@in.Remaining());
                        // Fall through to malformed-input case
                    }
                    else
                    {
                        return(cr);
                    }
                }

                CodingErrorAction action = null;
                if (cr.Malformed)
                {
                    action = MalformedInputAction_Renamed;
                }
                else if (cr.Unmappable)
                {
                    action = UnmappableCharacterAction_Renamed;
                }
                else
                {
                    Debug.Assert(false, cr.ToString());
                }

                if (action == CodingErrorAction.REPORT)
                {
                    return(cr);
                }

                if (action == CodingErrorAction.REPLACE)
                {
                    if (@out.Remaining() < Replacement_Renamed.Length())
                    {
                        return(CoderResult.OVERFLOW);
                    }
                    @out.Put(Replacement_Renamed);
                }

                if ((action == CodingErrorAction.IGNORE) || (action == CodingErrorAction.REPLACE))
                {
                    // Skip erroneous input either way
                    @in.Position(@in.Position() + cr.Length());
                    continue;
                }

                Debug.Assert(false);
            }
        }