internal override unsafe int GetChars(byte *bytes, int byteCount, char *chars, int charCount, DecoderNLS baseDecoder) { Debug.Assert(chars != null, "[UTF32Encoding.GetChars]chars!=null"); Debug.Assert(bytes != null, "[UTF32Encoding.GetChars]bytes!=null"); Debug.Assert(byteCount >= 0, "[UTF32Encoding.GetChars]byteCount >=0"); Debug.Assert(charCount >= 0, "[UTF32Encoding.GetChars]charCount >=0"); UTF32Decoder decoder = (UTF32Decoder)baseDecoder; // None so far! char *charStart = chars; char *charEnd = chars + charCount; byte *byteStart = bytes; byte *byteEnd = bytes + byteCount; // See if there's anything in our decoder (but don't clear it yet) int readCount = 0; uint iChar = 0; // For fallback we may need a fallback buffer DecoderFallbackBuffer fallbackBuffer = null; char *charsForFallback; // See if there's anything in our decoder if (decoder != null) { readCount = decoder.readByteCount; iChar = (uint)decoder.iChar; fallbackBuffer = baseDecoder.FallbackBuffer; // Shouldn't have anything in fallback buffer for GetChars // (don't have to check m_throwOnOverflow for chars) Debug.Assert(fallbackBuffer.Remaining == 0, "[UTF32Encoding.GetChars]Expected empty fallback buffer at start"); } else { fallbackBuffer = this.decoderFallback.CreateFallbackBuffer(); } // Set our internal fallback interesting things. fallbackBuffer.InternalInitialize(bytes, chars + charCount); // Loop through our input, 4 characters at a time! while (bytes < byteEnd) { // Get our next character if (bigEndian) { // Scoot left and add it to the bottom iChar <<= 8; iChar += *(bytes++); } else { // Scoot right and add it to the top iChar >>= 8; iChar += (uint)(*(bytes++)) << 24; } readCount++; // See if we have all the bytes yet if (readCount < 4) { continue; } // Have the bytes readCount = 0; // See if its valid to encode if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF)) { // Need to fall back these 4 bytes byte[] fallbackBytes; if (bigEndian) { fallbackBytes = new byte[] { unchecked ((byte)(iChar >> 24)), unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar)) }; } else { fallbackBytes = new byte[] { unchecked ((byte)(iChar)), unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 24)) }; } // Chars won't be updated unless this works. charsForFallback = chars; bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback); chars = charsForFallback; if (!fallbackResult) { // Couldn't fallback, throw or wait til next time // We either read enough bytes for bytes-=4 to work, or we're // going to throw in ThrowCharsOverflow because chars == charStart Debug.Assert(bytes >= byteStart + 4 || chars == charStart, "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (bad surrogate)"); bytes -= 4; // get back to where we were iChar = 0; // Remembering nothing fallbackBuffer.InternalReset(); ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output break; // Stop here, didn't throw } // Ignore the illegal character iChar = 0; continue; } // Ok, we have something we can add to our output if (iChar >= 0x10000) { // Surrogates take 2 if (chars >= charEnd - 1) { // Throwing or stopping // We either read enough bytes for bytes-=4 to work, or we're // going to throw in ThrowCharsOverflow because chars == charStart Debug.Assert(bytes >= byteStart + 4 || chars == charStart, "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (surrogate)"); bytes -= 4; // get back to where we were iChar = 0; // Remembering nothing ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output break; // Stop here, didn't throw } *(chars++) = GetHighSurrogate(iChar); iChar = GetLowSurrogate(iChar); } // Bounds check for normal character else if (chars >= charEnd) { // Throwing or stopping // We either read enough bytes for bytes-=4 to work, or we're // going to throw in ThrowCharsOverflow because chars == charStart Debug.Assert(bytes >= byteStart + 4 || chars == charStart, "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (normal char)"); bytes -= 4; // get back to where we were iChar = 0; // Remembering nothing ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output break; // Stop here, didn't throw } // Add the rest of the surrogate or our normal character *(chars++) = (char)iChar; // iChar is back to 0 iChar = 0; } // See if we have something left over that has to be decoded if (readCount > 0 && (decoder == null || decoder.MustFlush)) { // Oops, there's something left over with no place to go. byte[] fallbackBytes = new byte[readCount]; int tempCount = readCount; if (bigEndian) { while (tempCount > 0) { fallbackBytes[--tempCount] = unchecked ((byte)iChar); iChar >>= 8; } } else { while (tempCount > 0) { fallbackBytes[--tempCount] = unchecked ((byte)(iChar >> 24)); iChar <<= 8; } } charsForFallback = chars; bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback); chars = charsForFallback; if (!fallbackResult) { // Couldn't fallback. fallbackBuffer.InternalReset(); ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output // Stop here, didn't throw, backed up, so still nothing in buffer } else { // Don't clear our decoder unless we could fall it back. // If we caught the if above, then we're a convert() and will catch this next time. readCount = 0; iChar = 0; } } // Remember any left over stuff, clearing buffer as well for MustFlush if (decoder != null) { decoder.iChar = (int)iChar; decoder.readByteCount = readCount; decoder.m_bytesUsed = (int)(bytes - byteStart); } // Shouldn't have anything in fallback buffer for GetChars // (don't have to check m_throwOnOverflow for chars) Debug.Assert(fallbackBuffer.Remaining == 0, "[UTF32Encoding.GetChars]Expected empty fallback buffer at end"); // Return our count return((int)(chars - charStart)); }
internal override unsafe int GetChars(byte *bytes, int byteCount, char *chars, int charCount, DecoderNLS baseDecoder) { UTF32Decoder decoder = (UTF32Decoder)baseDecoder; char * chPtr = chars; char * chPtr2 = chars + charCount; byte * numPtr = bytes; byte * numPtr2 = bytes + byteCount; int readByteCount = 0; uint iChar = 0; DecoderFallbackBuffer fallbackBuffer = null; if (decoder != null) { readByteCount = decoder.readByteCount; iChar = (uint)decoder.iChar; fallbackBuffer = baseDecoder.FallbackBuffer; } else { fallbackBuffer = base.decoderFallback.CreateFallbackBuffer(); } fallbackBuffer.InternalInitialize(bytes, chars + charCount); while (bytes < numPtr2) { if (this.bigEndian) { iChar = iChar << 8; bytes++; iChar += bytes[0]; } else { iChar = iChar >> 8; bytes++; iChar += (uint)(bytes[0] << 0x18); } readByteCount++; if (readByteCount >= 4) { readByteCount = 0; if ((iChar > 0x10ffff) || ((iChar >= 0xd800) && (iChar <= 0xdfff))) { byte[] buffer2; if (this.bigEndian) { buffer2 = new byte[] { (byte)(iChar >> 0x18), (byte)(iChar >> 0x10), (byte)(iChar >> 8), (byte)iChar }; } else { buffer2 = new byte[] { (byte)iChar, (byte)(iChar >> 8), (byte)(iChar >> 0x10), (byte)(iChar >> 0x18) }; } if (!fallbackBuffer.InternalFallback(buffer2, bytes, ref chars)) { bytes -= 4; iChar = 0; fallbackBuffer.InternalReset(); base.ThrowCharsOverflow(decoder, chars == chPtr); break; } iChar = 0; } else { if (iChar >= 0x10000) { if (chars >= (chPtr2 - 1)) { bytes -= 4; iChar = 0; base.ThrowCharsOverflow(decoder, chars == chPtr); break; } chars++; chars[0] = this.GetHighSurrogate(iChar); iChar = this.GetLowSurrogate(iChar); } else if (chars >= chPtr2) { bytes -= 4; iChar = 0; base.ThrowCharsOverflow(decoder, chars == chPtr); break; } chars++; chars[0] = (char)iChar; iChar = 0; } } } if ((readByteCount > 0) && ((decoder == null) || decoder.MustFlush)) { byte[] buffer3 = new byte[readByteCount]; int num3 = readByteCount; if (!this.bigEndian) { while (num3 > 0) { buffer3[--num3] = (byte)(iChar >> 0x18); iChar = iChar << 8; } } else { while (num3 > 0) { buffer3[--num3] = (byte)iChar; iChar = iChar >> 8; } } if (!fallbackBuffer.InternalFallback(buffer3, bytes, ref chars)) { fallbackBuffer.InternalReset(); base.ThrowCharsOverflow(decoder, chars == chPtr); } else { readByteCount = 0; iChar = 0; } } if (decoder != null) { decoder.iChar = (int)iChar; decoder.readByteCount = readByteCount; decoder.m_bytesUsed = (int)((long)((bytes - numPtr) / 1)); } return((int)((long)((chars - chPtr) / 2))); }
internal override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS baseDecoder) { Debug.Assert(bytes != null, "[UTF32Encoding.GetCharCount]bytes!=null"); Debug.Assert(count >= 0, "[UTF32Encoding.GetCharCount]count >=0"); UTF32Decoder decoder = (UTF32Decoder)baseDecoder; // None so far! int charCount = 0; byte *end = bytes + count; byte *byteStart = bytes; // Set up decoder int readCount = 0; uint iChar = 0; // For fallback we may need a fallback buffer DecoderFallbackBuffer fallbackBuffer = null; // See if there's anything in our decoder if (decoder != null) { readCount = decoder.readByteCount; iChar = (uint)decoder.iChar; fallbackBuffer = decoder.FallbackBuffer; // Shouldn't have anything in fallback buffer for GetCharCount // (don't have to check m_throwOnOverflow for chars or count) Debug.Assert(fallbackBuffer.Remaining == 0, "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at start"); } else { fallbackBuffer = this.decoderFallback.CreateFallbackBuffer(); } // Set our internal fallback interesting things. fallbackBuffer.InternalInitialize(byteStart, null); // Loop through our input, 4 characters at a time! while (bytes < end && charCount >= 0) { // Get our next character if (bigEndian) { // Scoot left and add it to the bottom iChar <<= 8; iChar += *(bytes++); } else { // Scoot right and add it to the top iChar >>= 8; iChar += (uint)(*(bytes++)) << 24; } readCount++; // See if we have all the bytes yet if (readCount < 4) { continue; } // Have the bytes readCount = 0; // See if its valid to encode if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF)) { // Need to fall back these 4 bytes byte[] fallbackBytes; if (bigEndian) { fallbackBytes = new byte[] { unchecked ((byte)(iChar >> 24)), unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar)) }; } else { fallbackBytes = new byte[] { unchecked ((byte)(iChar)), unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 24)) }; } charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes); // Ignore the illegal character iChar = 0; continue; } // Ok, we have something we can add to our output if (iChar >= 0x10000) { // Surrogates take 2 charCount++; } // Add the rest of the surrogate or our normal character charCount++; // iChar is back to 0 iChar = 0; } // See if we have something left over that has to be decoded if (readCount > 0 && (decoder == null || decoder.MustFlush)) { // Oops, there's something left over with no place to go. byte[] fallbackBytes = new byte[readCount]; if (bigEndian) { while (readCount > 0) { fallbackBytes[--readCount] = unchecked ((byte)iChar); iChar >>= 8; } } else { while (readCount > 0) { fallbackBytes[--readCount] = unchecked ((byte)(iChar >> 24)); iChar <<= 8; } } charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes); } // Check for overflows. if (charCount < 0) { throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow")); } // Shouldn't have anything in fallback buffer for GetCharCount // (don't have to check m_throwOnOverflow for chars or count) Debug.Assert(fallbackBuffer.Remaining == 0, "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at end"); // Return our count return(charCount); }
internal override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS baseDecoder) { UTF32Decoder decoder = (UTF32Decoder)baseDecoder; int num = 0; byte * numPtr = bytes + count; byte * byteStart = bytes; int readByteCount = 0; uint iChar = 0; DecoderFallbackBuffer fallbackBuffer = null; if (decoder != null) { readByteCount = decoder.readByteCount; iChar = (uint)decoder.iChar; fallbackBuffer = decoder.FallbackBuffer; } else { fallbackBuffer = base.decoderFallback.CreateFallbackBuffer(); } fallbackBuffer.InternalInitialize(byteStart, null); while ((bytes < numPtr) && (num >= 0)) { if (this.bigEndian) { iChar = iChar << 8; bytes++; iChar += bytes[0]; } else { iChar = iChar >> 8; bytes++; iChar += (uint)(bytes[0] << 0x18); } readByteCount++; if (readByteCount >= 4) { readByteCount = 0; if ((iChar > 0x10ffff) || ((iChar >= 0xd800) && (iChar <= 0xdfff))) { byte[] buffer2; if (this.bigEndian) { buffer2 = new byte[] { (byte)(iChar >> 0x18), (byte)(iChar >> 0x10), (byte)(iChar >> 8), (byte)iChar }; } else { buffer2 = new byte[] { (byte)iChar, (byte)(iChar >> 8), (byte)(iChar >> 0x10), (byte)(iChar >> 0x18) }; } num += fallbackBuffer.InternalFallback(buffer2, bytes); iChar = 0; } else { if (iChar >= 0x10000) { num++; } num++; iChar = 0; } } } if ((readByteCount > 0) && ((decoder == null) || decoder.MustFlush)) { byte[] buffer3 = new byte[readByteCount]; if (!this.bigEndian) { while (readByteCount > 0) { buffer3[--readByteCount] = (byte)(iChar >> 0x18); iChar = iChar << 8; } } else { while (readByteCount > 0) { buffer3[--readByteCount] = (byte)iChar; iChar = iChar >> 8; } } num += fallbackBuffer.InternalFallback(buffer3, bytes); } if (num < 0) { throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow")); } return(num); }