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); }
public override unsafe int GetChars(byte *bytes, int byteCount, char *chars, int charCount, DecoderNLS decoder) { // Just need to ASSERT, this is called by something else internal that checked parameters already Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetChars]bytes is null"); Debug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetChars]byteCount is negative"); Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetChars]chars is null"); Debug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetChars]charCount is negative"); CheckMemorySection(); // See if we have best fit bool bUseBestFit = false; // Do it fast way if using ? replacement or best fit fallbacks byte *byteEnd = bytes + byteCount; byte *byteStart = bytes; char *charStart = chars; // Only need decoder fallback buffer if not using default replacement fallback or best fit fallback. DecoderReplacementFallback fallback = null; if (decoder == null) { fallback = DecoderFallback as DecoderReplacementFallback; bUseBestFit = DecoderFallback is InternalDecoderBestFitFallback; } else { fallback = decoder.Fallback as DecoderReplacementFallback; bUseBestFit = decoder.Fallback is InternalDecoderBestFitFallback; Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start"); } if (bUseBestFit || (fallback != null && fallback.MaxCharCount == 1)) { // Try it the fast way char replacementChar; if (fallback == null) { replacementChar = '?'; // Best fit always has ? for fallback for SBCS } else { replacementChar = fallback.DefaultString[0]; } // Need byteCount chars, otherwise too small buffer if (charCount < byteCount) { // Need at least 1 output byte, throw if must throw ThrowCharsOverflow(decoder, charCount < 1); // Not throwing, use what we can byteEnd = bytes + charCount; } // Quick loop, just do '?' replacement because we don't have fallbacks for decodings. while (bytes < byteEnd) { char c; if (bUseBestFit) { if (arrayBytesBestFit == null) { ReadBestFitTable(); } c = arrayBytesBestFit[*bytes]; } else { c = _mapBytesToUnicode[*bytes]; } bytes++; if (c == UNKNOWN_CHAR) { // This is an invalid byte in the ASCII encoding. *chars = replacementChar; } else { *chars = c; } chars++; } // bytes & chars used are the same if (decoder != null) { decoder.m_bytesUsed = (int)(bytes - byteStart); } return((int)(chars - charStart)); } // Slower way's going to need a fallback buffer DecoderFallbackBuffer fallbackBuffer = null; byte[] byteBuffer = new byte[1]; char * charEnd = chars + charCount; DecoderFallbackBufferHelper fallbackHelper = new DecoderFallbackBufferHelper(null); // Not quite so fast loop while (bytes < byteEnd) { // Faster if don't use *bytes++; char c = _mapBytesToUnicode[*bytes]; bytes++; // See if it was unknown if (c == UNKNOWN_CHAR) { // Make sure we have a fallback buffer if (fallbackBuffer == null) { if (decoder == null) { fallbackBuffer = DecoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = decoder.FallbackBuffer; } fallbackHelper = new DecoderFallbackBufferHelper(fallbackBuffer); fallbackHelper.InternalInitialize(byteEnd - byteCount, charEnd); } // Use fallback buffer Debug.Assert(bytes > byteStart, "[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (unknown byte)"); byteBuffer[0] = *(bytes - 1); // Fallback adds fallback to chars, but doesn't increment chars unless the whole thing fits. if (!fallbackHelper.InternalFallback(byteBuffer, bytes, ref chars)) { // May or may not throw, but we didn't get this byte bytes--; // unused byte fallbackHelper.InternalReset(); // Didn't fall this back ThrowCharsOverflow(decoder, bytes == byteStart); // throw? break; // don't throw, but stop loop } } else { // Make sure we have buffer space if (chars >= charEnd) { Debug.Assert(bytes > byteStart, "[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (known byte)"); bytes--; // unused byte ThrowCharsOverflow(decoder, bytes == byteStart); // throw? break; // don't throw, but stop loop } *(chars) = c; chars++; } } // Might have had decoder fallback stuff. if (decoder != null) { decoder.m_bytesUsed = (int)(bytes - byteStart); } // Expect Empty fallback buffer for GetChars Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetChars]Expected Empty fallback buffer at end"); return((int)(chars - charStart)); }
// This is internal and called by something else, public override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS decoder) { // Just assert, we're called internally so these should be safe, checked already Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetCharCount]bytes is null"); Debug.Assert(count >= 0, "[SBCSCodePageEncoding.GetCharCount]byteCount is negative"); CheckMemorySection(); // See if we have best fit bool bUseBestFit = false; // Only need decoder fallback buffer if not using default replacement fallback or best fit fallback. DecoderReplacementFallback fallback = null; if (decoder == null) { fallback = DecoderFallback as DecoderReplacementFallback; bUseBestFit = DecoderFallback is InternalDecoderBestFitFallback; } else { fallback = decoder.Fallback as DecoderReplacementFallback; bUseBestFit = decoder.Fallback is InternalDecoderBestFitFallback; Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start"); } if (bUseBestFit || (fallback != null && fallback.MaxCharCount == 1)) { // Just return length, SBCS stay the same length because they don't map to surrogate // pairs and we don't have a decoder fallback. return(count); } // Might need one of these later DecoderFallbackBuffer fallbackBuffer = null; DecoderFallbackBufferHelper fallbackHelper = new DecoderFallbackBufferHelper(fallbackBuffer); // Have to do it the hard way. // Assume charCount will be == count int charCount = count; byte[] byteBuffer = new byte[1]; // Do it our fast way byte *byteEnd = bytes + count; // Quick loop while (bytes < byteEnd) { // Faster if don't use *bytes++; char c; c = _mapBytesToUnicode[*bytes]; bytes++; // If unknown we have to do fallback count if (c == UNKNOWN_CHAR) { // Must have a fallback buffer if (fallbackBuffer == null) { // Need to adjust count so we get real start if (decoder == null) { fallbackBuffer = DecoderFallback.CreateFallbackBuffer(); } else { fallbackBuffer = decoder.FallbackBuffer; } fallbackHelper = new DecoderFallbackBufferHelper(fallbackBuffer); fallbackHelper.InternalInitialize(byteEnd - count, null); } // Use fallback buffer byteBuffer[0] = *(bytes - 1); charCount--; // We'd already reserved one for *(bytes-1) charCount += fallbackHelper.InternalFallback(byteBuffer, bytes); } } // Fallback buffer must be empty Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetCharCount]Expected Empty fallback buffer at end"); // Converted sequence is same length as input return(charCount); }
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); }