// Fallback the current byte by sticking it into the remaining char buffer. // This can only be called by our encodings (other have to use the public fallback methods), so // we can use our DecoderNLS here too (except we don't). // Returns true if we are successful, false if we can't fallback the character (no buffer space) // So the caller needs to throw buffer space if the method returns false. // Right now this has both bytes and bytes[], since we might have extra bytes, hence the // array, and we might need the index, hence the byte* // Don't touch ref chars unless we succeed internal bool InternalFallback(byte[] bytes, byte *pBytes, ref char *chars) { Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize"); // See if there's a fallback character and we have an output buffer then copy our string. if (_fallbackBuffer.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length))) { // Copy the chars to our output char ch; char *charTemp = chars; bool bHighSurrogate = false; while ((ch = _fallbackBuffer.GetNextChar()) != 0) { // Make sure no mixed up surrogates if (Char.IsSurrogate(ch)) { if (Char.IsHighSurrogate(ch)) { // High Surrogate if (bHighSurrogate) { throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); } bHighSurrogate = true; } else { // Low surrogate if (bHighSurrogate == false) { throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); } bHighSurrogate = false; } } if (charTemp >= charEnd) { // No buffer space return(false); } *(charTemp++) = ch; } // Need to make sure that bHighSurrogate isn't true if (bHighSurrogate) { throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex); } // Now we aren't going to be false, so its OK to update chars chars = charTemp; } return(true); }
int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref DecoderFallbackBuffer buffer) { #endif if (bytes == null) { throw new ArgumentNullException("bytes"); } if (chars == null) { throw new ArgumentNullException("chars"); } if (byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException("byteIndex", _("ArgRange_Array")); } if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) { throw new ArgumentOutOfRangeException("byteCount", _("ArgRange_Array")); } if (charIndex < 0 || charIndex > chars.Length) { throw new ArgumentOutOfRangeException("charIndex", _("ArgRange_Array")); } if ((chars.Length - charIndex) < byteCount) { throw new ArgumentException(_("Arg_InsufficientSpace")); } int count = byteCount; while (count-- > 0) { char c = (char)bytes [byteIndex++]; if (c < '\x80') { chars [charIndex++] = c; } else { #if NET_2_0 if (buffer == null) { buffer = DecoderFallback.CreateFallbackBuffer(); } buffer.Fallback(bytes, byteIndex); while (buffer.Remaining > 0) { chars [charIndex++] = buffer.GetNextChar(); } #else chars [charIndex++] = '?'; #endif } } return(byteCount); }
private int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref DecoderFallbackBuffer buffer) { if (bytes == null) { throw new ArgumentNullException("bytes"); } if (chars == null) { throw new ArgumentNullException("chars"); } if (byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException("byteIndex", Encoding._("ArgRange_Array")); } if (byteCount < 0 || byteCount > bytes.Length - byteIndex) { throw new ArgumentOutOfRangeException("byteCount", Encoding._("ArgRange_Array")); } if (charIndex < 0 || charIndex > chars.Length) { throw new ArgumentOutOfRangeException("charIndex", Encoding._("ArgRange_Array")); } if (chars.Length - charIndex < byteCount) { throw new ArgumentException(Encoding._("Arg_InsufficientSpace")); } int num = byteCount; while (num-- > 0) { char c = (char)bytes[byteIndex++]; if (c < '\u0080') { chars[charIndex++] = c; } else { if (buffer == null) { buffer = base.DecoderFallback.CreateFallbackBuffer(); } buffer.Fallback(bytes, byteIndex); while (buffer.Remaining > 0) { chars[charIndex++] = buffer.GetNextChar(); } } } return(byteCount); }
// for GetChars() static unsafe void Fallback (object provider, ref DecoderFallbackBuffer buffer, ref byte [] bufferArg, byte* bytes, long byteIndex, uint size, char* chars, ref int charIndex) { if (buffer == null) { DecoderFallback fb = provider as DecoderFallback; if (fb != null) buffer = fb.CreateFallbackBuffer (); else buffer = ((Decoder) provider).FallbackBuffer; } if (bufferArg == null) bufferArg = new byte [1]; for (int i = 0; i < size; i++) { bufferArg [0] = bytes [byteIndex + i]; buffer.Fallback (bufferArg, 0); while (buffer.Remaining > 0) chars [charIndex++] = buffer.GetNextChar (); buffer.Reset (); } }
int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref DecoderFallbackBuffer buffer) { if (bytes == null) throw new ArgumentNullException ("bytes"); if (chars == null) throw new ArgumentNullException ("chars"); if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array")); if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array")); if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array")); if ((chars.Length - charIndex) < byteCount) throw new ArgumentException (_("Arg_InsufficientSpace")); int count = byteCount; while (count-- > 0) { char c = (char) bytes [byteIndex++]; if (c < '\x80') chars [charIndex++] = c; else { if (buffer == null) buffer = DecoderFallback.CreateFallbackBuffer (); buffer.Fallback (bytes, byteIndex); while (buffer.Remaining > 0) chars [charIndex++] = buffer.GetNextChar (); } } return byteCount; }
// This function is called when we want to flush the decoder state // (i.e. in case of invalid UTF-8 characters or interrupted sequences) internal unsafe static DecoderStatus InternalGetCharsFlush ( char* chars, int charCount, DecoderFallbackBuffer fallbackBuffer, DecoderStatus s, int bytesProcessed, ref int charsProcessed, ref uint leftBytes, ref uint leftBits, ref uint procBytes) { // if there is nothing to flush, then exit silently if(procBytes == 0) return DecoderStatus.Ok; // now we build a 'bytesUnknown' array with the // stored bytes in 'procBytes'. int extra = 0; for (uint t = procBytes; t != 0; extra++) t = t >> 8; byte [] bytesUnknown = new byte [extra]; for (int i = extra; i > 0; i--) bytesUnknown [i - 1] = (byte) ((procBytes >> (8 * (extra - i))) & 0xff); // partial reset: this condition avoids infinite loops if (s == DecoderStatus.InvalidSequence) leftBytes = 0; // call the fallback and cross fingers fallbackBuffer.Fallback (bytesUnknown, bytesProcessed - extra); if (chars != null) { while (fallbackBuffer.Remaining > 0) { if (charsProcessed >= charCount) return DecoderStatus.InsufficientSpace; chars [charsProcessed++] = fallbackBuffer.GetNextChar (); } } else charsProcessed += fallbackBuffer.Remaining; fallbackBuffer.Reset (); // recovery was succesful, flush decoder state leftBits = leftBytes = procBytes = 0; return DecoderStatus.Ok; }
int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref DecoderFallbackBuffer buffer) { if (bytes == null) throw new ArgumentNullException ("bytes"); if (chars == null) throw new ArgumentNullException ("chars"); if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array")); if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array")); if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array")); if ((chars.Length - charIndex) < byteCount) throw new ArgumentException (_("Arg_InsufficientSpace")); int count = byteCount; while (count-- > 0) { char c = (char) bytes [byteIndex++]; if (c < '\x80') chars [charIndex++] = c; else { if (buffer == null) buffer = DecoderFallback.CreateFallbackBuffer (); var thisByte = new byte[] { bytes [byteIndex-1] }; buffer.Fallback (thisByte, 0); while (buffer.Remaining > 0) { if (charIndex < chars.Length) { chars [charIndex++] = buffer.GetNextChar (); continue; } throw new ArgumentException ( "The output char buffer is too small to contain the " + "decoded characters."); } } } return byteCount; }
int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref DecoderFallbackBuffer buffer) { if (bytes == null) { throw new ArgumentNullException("bytes"); } if (chars == null) { throw new ArgumentNullException("chars"); } if (byteIndex < 0 || byteIndex > bytes.Length) { throw new ArgumentOutOfRangeException("byteIndex", _("ArgRange_Array")); } if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) { throw new ArgumentOutOfRangeException("byteCount", _("ArgRange_Array")); } if (charIndex < 0 || charIndex > chars.Length) { throw new ArgumentOutOfRangeException("charIndex", _("ArgRange_Array")); } if ((chars.Length - charIndex) < byteCount) { throw new ArgumentException(_("Arg_InsufficientSpace")); } int count = byteCount; while (count-- > 0) { char c = (char)bytes [byteIndex++]; if (c < '\x80') { chars [charIndex++] = c; } else { if (buffer == null) { buffer = DecoderFallback.CreateFallbackBuffer(); } var thisByte = new byte[] { bytes [byteIndex - 1] }; buffer.Fallback(thisByte, 0); while (buffer.Remaining > 0) { if (charIndex < chars.Length) { chars [charIndex++] = buffer.GetNextChar(); continue; } throw new ArgumentException( "The output char buffer is too small to contain the " + "decoded characters."); } } } return(byteCount); }