private bool CanEncode(CharBuffer cb) { if (State == ST_FLUSHED) { Reset(); } else if (State != ST_RESET) { ThrowIllegalStateException(State, ST_CODING); } CodingErrorAction ma = MalformedInputAction(); CodingErrorAction ua = UnmappableCharacterAction(); try { OnMalformedInput(CodingErrorAction.REPORT); OnUnmappableCharacter(CodingErrorAction.REPORT); Encode(cb); } catch (CharacterCodingException) { return(false); } finally { OnMalformedInput(ma); OnUnmappableCharacter(ua); Reset(); } return(true); }
/// <summary> /// Changes this decoder's action for unmappable-character errors. /// /// <para> This method invokes the {@link #implOnUnmappableCharacter /// implOnUnmappableCharacter} method, passing the new action. </para> /// </summary> /// <param name="newAction"> The new action; must not be <tt>null</tt> /// </param> /// <returns> This decoder /// </returns> /// <exception cref="IllegalArgumentException"> /// If the precondition on the parameter does not hold </exception> public CharsetDecoder OnUnmappableCharacter(CodingErrorAction newAction) { if (newAction == null) { throw new IllegalArgumentException("Null action"); } UnmappableCharacterAction_Renamed = newAction; ImplOnUnmappableCharacter(newAction); return(this); }
/// <summary> /// Changes this decoder's action for malformed-input errors. /// /// <para> This method invokes the {@link #implOnMalformedInput /// implOnMalformedInput} method, passing the new action. </para> /// </summary> /// <param name="newAction"> The new action; must not be <tt>null</tt> /// </param> /// <returns> This decoder /// </returns> /// <exception cref="IllegalArgumentException"> /// If the precondition on the parameter does not hold </exception> public CharsetDecoder OnMalformedInput(CodingErrorAction newAction) { if (newAction == null) { throw new IllegalArgumentException("Null action"); } MalformedInputAction_Renamed = newAction; ImplOnMalformedInput(newAction); return(this); }
/// <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); } }
/// <summary> /// Reports a change to this decoder's unmappable-character action. /// /// <para> The default implementation of this method does nothing. This method /// should be overridden by decoders that require notification of changes to /// the unmappable-character action. </para> /// </summary> /// <param name="newAction"> The new action </param> protected internal virtual void ImplOnUnmappableCharacter(CodingErrorAction newAction) { }
/// <summary> /// Reports a change to this decoder's malformed-input action. /// /// <para> The default implementation of this method does nothing. This method /// should be overridden by decoders that require notification of changes to /// the malformed-input action. </para> /// </summary> /// <param name="newAction"> The new action </param> protected internal virtual void ImplOnMalformedInput(CodingErrorAction newAction) { }