public static int ToChars(byte[] buffer, int offset, int count, char[] chars, int charOffset) { try { return(UTF8Encoding.GetChars(buffer, offset, count, chars, charOffset)); } catch (DecoderFallbackException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(buffer, offset, count, exception)); } }
public static byte[] ToBytes(string value) { try { return(UTF8Encoding.GetBytes(value)); } catch (DecoderFallbackException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(value, exception)); } }
public static string ToStringUnicode(byte[] buffer, int offset, int count) { try { return(UnicodeEncoding.GetString(buffer, offset, count)); } catch (DecoderFallbackException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(buffer, offset, count, exception)); } }
public bool TryReadChars(char[] chars, int offset, int count, out int actual) { DiagnosticUtility.DebugAssert(offset + count <= chars.Length, string.Format("offset '{0}' + count '{1}' MUST BE <= chars.Length '{2}'", offset, count, chars.Length)); if (_type == ValueHandleType.Unicode) { return(TryReadUnicodeChars(chars, offset, count, out actual)); } if (_type != ValueHandleType.UTF8) { actual = 0; return(false); } int charOffset = offset; int charCount = count; byte[] bytes = _bufferReader.Buffer; int byteOffset = _offset; int byteCount = _length; bool insufficientSpaceInCharsArray = false; var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); while (true) { while (charCount > 0 && byteCount > 0) { // fast path for codepoints U+0000 - U+007F byte b = bytes[byteOffset]; if (b >= 0x80) { break; } chars[charOffset] = (char)b; byteOffset++; byteCount--; charOffset++; charCount--; } if (charCount == 0 || byteCount == 0 || insufficientSpaceInCharsArray) { break; } int actualByteCount; int actualCharCount; try { // If we're asking for more than are possibly available, or more than are truly available then we can return the entire thing if (charCount >= encoding.GetMaxCharCount(byteCount) || charCount >= encoding.GetCharCount(bytes, byteOffset, byteCount)) { actualCharCount = encoding.GetChars(bytes, byteOffset, byteCount, chars, charOffset); actualByteCount = byteCount; } else { Decoder decoder = encoding.GetDecoder(); // Since x bytes can never generate more than x characters this is a safe estimate as to what will fit actualByteCount = Math.Min(charCount, byteCount); // We use a decoder so we don't error if we fall across a character boundary actualCharCount = decoder.GetChars(bytes, byteOffset, actualByteCount, chars, charOffset); // We might have gotten zero characters though if < 4 bytes were requested because // codepoints from U+0000 - U+FFFF can be up to 3 bytes in UTF-8, and represented as ONE char // codepoints from U+10000 - U+10FFFF (last Unicode codepoint representable in UTF-8) are represented by up to 4 bytes in UTF-8 // and represented as TWO chars (high+low surrogate) // (e.g. 1 char requested, 1 char in the buffer represented in 3 bytes) while (actualCharCount == 0) { // Note the by the time we arrive here, if actualByteCount == 3, the next decoder.GetChars() call will read the 4th byte // if we don't bail out since the while loop will advance actualByteCount only after reading the byte. if (actualByteCount >= 3 && charCount < 2) { // If we reach here, it means that we're: // - trying to decode more than 3 bytes and, // - there is only one char left of charCount where we're stuffing decoded characters. // In this case, we need to back off since decoding > 3 bytes in UTF-8 means that we will get 2 16-bit chars // (a high surrogate and a low surrogate) - the Decoder will attempt to provide both at once // and an ArgumentException will be thrown complaining that there's not enough space in the output char array. // actualByteCount = 0 when the while loop is broken out of; decoder goes out of scope so its state no longer matters insufficientSpaceInCharsArray = true; break; } else { DiagnosticUtility.DebugAssert(byteOffset + actualByteCount < bytes.Length, string.Format("byteOffset {0} + actualByteCount {1} MUST BE < bytes.Length {2}", byteOffset, actualByteCount, bytes.Length)); // Request a few more bytes to get at least one character actualCharCount = decoder.GetChars(bytes, byteOffset + actualByteCount, 1, chars, charOffset); actualByteCount++; } } // Now that we actually retrieved some characters, figure out how many bytes it actually was actualByteCount = encoding.GetByteCount(chars, charOffset, actualCharCount); } } catch (FormatException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(bytes, byteOffset, byteCount, exception)); } // Advance byteOffset += actualByteCount; byteCount -= actualByteCount; charOffset += actualCharCount; charCount -= actualCharCount; } _offset = byteOffset; _length = byteCount; actual = (count - charCount); return(true); }
public bool TryReadChars(char[] chars, int offset, int count, out int actual) { if (_type == ValueHandleType.Unicode) { return(TryReadUnicodeChars(chars, offset, count, out actual)); } if (_type != ValueHandleType.UTF8) { actual = 0; return(false); } int charOffset = offset; int charCount = count; byte[] bytes = _bufferReader.Buffer; int byteOffset = _offset; int byteCount = _length; while (true) { while (charCount > 0 && byteCount > 0) { byte b = bytes[byteOffset]; if (b >= 0x80) { break; } chars[charOffset] = (char)b; byteOffset++; byteCount--; charOffset++; charCount--; } if (charCount == 0 || byteCount == 0) { break; } int actualByteCount; int actualCharCount; UTF8Encoding encoding = new UTF8Encoding(false, true); try { // If we're asking for more than are possibly available, or more than are truly available then we can return the entire thing if (charCount >= encoding.GetMaxCharCount(byteCount) || charCount >= encoding.GetCharCount(bytes, byteOffset, byteCount)) { actualCharCount = encoding.GetChars(bytes, byteOffset, byteCount, chars, charOffset); actualByteCount = byteCount; } else { Decoder decoder = encoding.GetDecoder(); // Since x bytes can never generate more than x characters this is a safe estimate as to what will fit actualByteCount = Math.Min(charCount, byteCount); // We use a decoder so we don't error if we fall across a character boundary actualCharCount = decoder.GetChars(bytes, byteOffset, actualByteCount, chars, charOffset); // We might've gotten zero characters though if < 3 chars were requested // (e.g. 1 char requested, 1 char in the buffer represented in 3 bytes) while (actualCharCount == 0) { // Request a few more bytes to get at least one character actualCharCount = decoder.GetChars(bytes, byteOffset + actualByteCount, 1, chars, charOffset); actualByteCount++; } // Now that we actually retrieved some characters, figure out how many bytes it actually was actualByteCount = encoding.GetByteCount(chars, charOffset, actualCharCount); } } catch (FormatException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(bytes, byteOffset, byteCount, exception)); } // Advance byteOffset += actualByteCount; byteCount -= actualByteCount; charOffset += actualCharCount; charCount -= actualCharCount; } _offset = byteOffset; _length = byteCount; actual = (count - charCount); return(true); }
public bool TryReadChars(char[] chars, int offset, int count, out int actual) { if (this.type == ValueHandleType.Unicode) { return(this.TryReadUnicodeChars(chars, offset, count, out actual)); } if (this.type != ValueHandleType.UTF8) { actual = 0; return(false); } int index = offset; int num2 = count; byte[] bytes = this.bufferReader.Buffer; int num3 = this.offset; int length = this.length; Label_006C: while ((num2 > 0) && (length > 0)) { byte num5 = bytes[num3]; if (num5 >= 0x80) { break; } chars[index] = (char)num5; num3++; length--; index++; num2--; } if ((num2 != 0) && (length != 0)) { int num6; int num7; UTF8Encoding encoding = new UTF8Encoding(false, true); try { if ((num2 >= encoding.GetMaxCharCount(length)) || (num2 >= encoding.GetCharCount(bytes, num3, length))) { num7 = encoding.GetChars(bytes, num3, length, chars, index); num6 = length; } else { System.Text.Decoder decoder = encoding.GetDecoder(); num6 = Math.Min(num2, length); num7 = decoder.GetChars(bytes, num3, num6, chars, index); while (num7 == 0) { num7 = decoder.GetChars(bytes, num3 + num6, 1, chars, index); num6++; } num6 = encoding.GetByteCount(chars, index, num7); } } catch (FormatException exception) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(bytes, num3, length, exception)); } num3 += num6; length -= num6; index += num7; num2 -= num7; goto Label_006C; } this.offset = num3; this.length = length; actual = count - num2; return(true); }