示例#1
0
        public void TestMaxCharCount()
        {
            UTF8Encoding UTF8enc = new UTF8Encoding();

#if NET_2_0
            // hmm, where is this extra 1 coming from?
            Assert.AreEqual(51, UTF8enc.GetMaxCharCount(50), "UTF #1");
#else
            Assert.AreEqual(50, UTF8enc.GetMaxCharCount(50), "UTF #1");
#endif
        }
示例#2
0
        public HessianReader(Stream input, bool leaveOpen)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (!input.CanRead)
            {
                throw new ArgumentException("Argument_StreamNotReadable");
            }
            Contract.EndContractBlock();
            Encoding encoding = new UTF8Encoding(false, true);

            m_stream       = input;
            m_decoder      = encoding.GetDecoder();
            m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
            int minBufferSize = encoding.GetMaxByteCount(1);  // max bytes per one char

            if (minBufferSize < 16)
            {
                minBufferSize = 16;
            }
            m_buffer = new byte[minBufferSize];
            // m_charBuffer and m_charBytes will be left null.

            // For Encodings that always use 2 bytes per char (or more),
            // special case them here to make Read() & Peek() faster.
            m_2BytesPerChar = encoding is UnicodeEncoding;
            // check if BinaryReader is based on MemoryStream, and keep this for it's life
            // we cannot use "as" operator, since derived classes are not allowed
            m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
            m_leaveOpen      = leaveOpen;
        }
    public bool NegTest1()
    {
        bool retVal = true;

        TestLibrary.TestFramework.BeginScenario("NegTest1: ArgumentOutOfRangeException is not thrown when byteCount is less than zero.");

        try
        {
            UTF8Encoding utf8         = new UTF8Encoding();
            int          byteCount    = -1;
            int          maxCharCount = utf8.GetMaxCharCount(byteCount);

            TestLibrary.TestFramework.LogError("101.1", "ArgumentOutOfRangeException is not thrown when byteCount is less than zero.");
            retVal = false;
        }
        catch (ArgumentOutOfRangeException) { }
        catch (Exception e)
        {
            TestLibrary.TestFramework.LogError("101.2", "Unexpected exception: " + e);
            TestLibrary.TestFramework.LogInformation(e.StackTrace);
            retVal = false;
        }

        return(retVal);
    }
    public bool NegTest1()
    {
        bool retVal = true;

        TestLibrary.TestFramework.BeginScenario("NegTest1: ArgumentOutOfRangeException is not thrown when byteCount is less than zero.");

        try
        {
            UTF8Encoding utf8 = new UTF8Encoding();
            int byteCount = -1;
            int maxCharCount = utf8.GetMaxCharCount(byteCount);

            TestLibrary.TestFramework.LogError("101.1", "ArgumentOutOfRangeException is not thrown when byteCount is less than zero.");
            retVal = false;
        }
        catch (ArgumentOutOfRangeException) { }
        catch (Exception e)
        {
            TestLibrary.TestFramework.LogError("101.2", "Unexpected exception: " + e);
            TestLibrary.TestFramework.LogInformation(e.StackTrace);
            retVal = false;
        }

        return retVal;
    }
            public string stringFromNative(IntPtr nativePtr)
            {
                if (nativePtr == IntPtr.Zero)
                {
                    return(string.Empty);
                }
                int i;

                for (i = 0; Marshal.ReadByte(nativePtr, i) != 0; i++)
                {
                }
                if (i == 0)
                {
                    return(string.Empty);
                }
                if (i > encodedBuffer.Length)
                {
                    encodedBuffer = new byte[roundUpPowerTwo(i)];
                }
                Marshal.Copy(nativePtr, encodedBuffer, 0, i);
                int maxCharCount = encoding.GetMaxCharCount(i);

                if (maxCharCount > decodedBuffer.Length)
                {
                    int charCount = encoding.GetCharCount(encodedBuffer, 0, i);
                    if (charCount > decodedBuffer.Length)
                    {
                        decodedBuffer = new char[roundUpPowerTwo(charCount)];
                    }
                }
                int chars = encoding.GetChars(encodedBuffer, 0, i, decodedBuffer, 0);

                return(new string(decodedBuffer, 0, chars));
            }
示例#6
0
        public void TestMaxCharCount()
        {
            UTF8Encoding UTF8enc        = new UTF8Encoding();
            Encoding     UTF8encWithBOM = new UTF8Encoding(true);

            Assert.AreEqual(51, UTF8enc.GetMaxCharCount(50), "UTF #1");
            Assert.AreEqual(UTF8enc.GetMaxByteCount(50), UTF8encWithBOM.GetMaxByteCount(50), "UTF #2");
        }
 public void NegTest1()
 {
     UTF8Encoding utf8 = new UTF8Encoding();
     int byteCount = -1;
     Assert.Throws<ArgumentOutOfRangeException>(() =>
     {
         int maxCharCount = utf8.GetMaxCharCount(byteCount);
     });
 }
示例#8
0
        public void NegTest1()
        {
            UTF8Encoding utf8      = new UTF8Encoding();
            int          byteCount = -1;

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                int maxCharCount = utf8.GetMaxCharCount(byteCount);
            });
        }
示例#9
0
        private static ByteStringContext.InternalScope UnlikelyGetLowerUnicode(ByteStringContext byteStringContext, byte *str, int size, out Slice loweredKey)
        {
            var maxCharCount = Encoding.GetMaxCharCount(size);
            var bufferSize   = maxCharCount * sizeof(char);

            using (byteStringContext.Allocate(bufferSize, out var ptr))
            {
                var chars     = (char *)ptr.Ptr;
                var charCount = Encoding.GetChars(str, size, chars, maxCharCount);

                for (int i = 0; i < charCount; i++)
                {
                    chars[i] = char.ToLowerInvariant(chars[i]);
                }

                var release = byteStringContext.From(chars, charCount, ByteStringType.Immutable, out var result);
                loweredKey = new Slice(result);
                return(release);
            }
        }
示例#10
0
    public static void Main()
    {
        UTF8Encoding utf8         = new UTF8Encoding();
        int          byteCount    = 8;
        int          maxCharCount = utf8.GetMaxCharCount(byteCount);

        Console.WriteLine(
            "Maximum of {0} characters needed to decode {1} bytes.",
            maxCharCount,
            byteCount
            );
    }
示例#11
0
    public BinaryReader(byte[] buffer)
    {
        var encoding = new UTF8Encoding();

        m_decoder      = encoding.GetDecoder();
        m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
        int minBufferSize = encoding.GetMaxByteCount(1);

        if (minBufferSize < 16)
        {
            minBufferSize = 16;
        }
        mBuffer = new byte[minBufferSize];
        Buffer  = buffer;
    }
    public bool PosTest1()
    {
        bool retVal = true;

        // Add your scenario description here
        TestLibrary.TestFramework.BeginScenario("PosTest1: Verify method GetMaxCharCount");

        try
        {
            UTF8Encoding utf8         = new UTF8Encoding();
            int          byteCount    = 8;
            int          maxCharCount = utf8.GetMaxCharCount(byteCount);
        }
        catch (Exception e)
        {
            TestLibrary.TestFramework.LogError("001", "Unexpected exception: " + e);
            TestLibrary.TestFramework.LogInformation(e.StackTrace);
            retVal = false;
        }

        return(retVal);
    }
    public bool PosTest1()
    {
        bool retVal = true;

        // Add your scenario description here
        TestLibrary.TestFramework.BeginScenario("PosTest1: Verify method GetMaxCharCount");

        try
        {
            UTF8Encoding utf8 = new UTF8Encoding();
            int byteCount = 8;
            int maxCharCount = utf8.GetMaxCharCount(byteCount);

        }
        catch (Exception e)
        {
            TestLibrary.TestFramework.LogError("001", "Unexpected exception: " + e);
            TestLibrary.TestFramework.LogInformation(e.StackTrace);
            retVal = false;
        }

        return retVal;
    }
示例#14
0
        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);
        }
 public void PosTest1()
 {
     UTF8Encoding utf8 = new UTF8Encoding();
     int byteCount = 8;
     int maxCharCount = utf8.GetMaxCharCount(byteCount);
 }
示例#16
0
 public static int GetMaxCharCount(int byteCount)
 => Encoder.GetMaxCharCount(byteCount);
示例#17
0
        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);
        }
示例#18
0
 public void PosTest1()
 {
     UTF8Encoding utf8         = new UTF8Encoding();
     int          byteCount    = 8;
     int          maxCharCount = utf8.GetMaxCharCount(byteCount);
 }
        public async Task <bool> UpdateServer(Server server)
        {
            var serverPath = new DirectoryInfo(server.Path);

            if (!serverPath.Exists)
            {
                serverPath.Create();
            }

            using (var scope = _serviceScopeFactory.CreateScope())
                using (var db = scope.ServiceProvider.GetRequiredService <MonitorDBContext>())
                {
                    var scopedServices = scope.ServiceProvider;

                    StringBuilder outputStringBuilder = new StringBuilder();

                    // Params stuff
                    List <string[]> parameterBuilder = new List <string[]>
                    {
                        new string[] { "+login", "anonymous" },                 // TODO: Allow user logins
                        new string[] { "+force_install_dir", $"\"{serverPath.FullName}\"" }
                    };

                    // F*****g dynamic shit param builder what the f**k
                    List <string> updateText = new List <string>
                    {
                        server.Game.SteamID?.ToString(CultureInfo.InvariantCulture)
                    };
                    if (!String.IsNullOrEmpty(server.Branch) && server.Branch != "public")
                    {
                        updateText.Add("-beta");
                        updateText.Add(server.Branch);
                        if (!String.IsNullOrEmpty(server.BranchPassword))
                        {
                            updateText.Add("-betapassword");
                            updateText.Add(server.BranchPassword);
                        }

                        // TODO: Should add 'validate' param?
                    }

                    // app_update param builder
                    StringBuilder updateParams = new StringBuilder();
                    if (updateText.Count > 1)
                    {
                        updateParams.Append("\"");
                    }
                    updateParams.Append(String.Join(" ", updateText));
                    if (updateText.Count > 1)
                    {
                        updateParams.Append("\"");
                    }

                    parameterBuilder.Add(new string[] { "+app_update", updateParams.ToString() });

                    parameterBuilder.Add(new string[] { "+quit" });

                    string steamCMDArguments = String.Join(" ", parameterBuilder.Select(param => String.Join(" ", param)).ToArray());


                    _logger.LogInformation("Starting SteamCMD with arguments: {0}", steamCMDArguments);


                    // Init proccess listeners

                    IPtyConnection steamCMDProc = null;

                    var         downloadProgressRegex = @"Update state \((.+?)\) downloading, progress: ([\d.]+) \((\d*) \/ (\d*)\)";
                    CultureInfo ci = (CultureInfo)CultureInfo.CurrentCulture.Clone();
                    ci.NumberFormat.CurrencyDecimalSeparator = ".";

                    //DataReceivedEventHandler outputEventHandler = (sender, e) =>
                    EventHandler outputEventHandler = (sender, e2) =>
                    {
                        var e = (CustomDataReceivedEventArgs)e2;
                        _logger.LogDebug("SteamCMD Log {0} - {1}: {2}", server.Id, steamCMDProc.Pid, e.Data);

                        UpdateMessage?.Invoke(server, new ConsoleEventArgs()
                        {
                            NewLine = e.Data
                        });

                        if (!string.IsNullOrEmpty(e.Data))
                        {
                            Match match = Regex.Match(e.Data, downloadProgressRegex, RegexOptions.IgnoreCase);
                            if (match.Success)
                            {
                                UpdateProgress?.Invoke(server, new ServerUpdateProgressEventArgs()
                                {
                                    Progress = float.Parse(match.Groups[2].Value, NumberStyles.Any, ci)
                                });
                            }
                        }
                    };

                    //DataReceivedEventHandler errorEventHandler = (sender, e) =>
                    EventHandler errorEventHandler = (sender, e2) =>
                    {
                        var e = (CustomDataReceivedEventArgs)e2;
                        _logger.LogWarning("SteamCMD emitted {0} - {1}: {2}", server.Id, steamCMDProc.Pid, e.Data);

                        UpdateMessage?.Invoke(server, new ConsoleEventArgs()
                        {
                            NewLine = e.Data,
                            IsError = true
                        });
                    };

                    // Start process
                    var hasErrored          = false;
                    var processExitedCTS    = new CancellationTokenSource();
                    var processExitedCToken = processExitedCTS.Token;
                    try
                    {
                        steamCMDProc = await _steamCMDService.CreateSteamCMD(steamCMDArguments);

                        //steamCMDProc.OutputDataReceived += outputEventHandler;
                        //steamCMDProc.ErrorDataReceived += errorEventHandler;

                        //steamCMDProc.Start();
                        //steamCMDProc.BeginOutputReadLine();
                        //steamCMDProc.BeginErrorReadLine();

                        // Exit event
                        var processExitedTcs = new TaskCompletionSource <uint>();
                        steamCMDProc.ProcessExited += (sender, e) =>
                        {
                            processExitedTcs.TrySetResult((uint)steamCMDProc.ExitCode);
                            processExitedCTS.Cancel();
                            //steamCMDProc.ReaderStream.Close();
                            //steamCMDProc.ReaderStream.Dispose();
                        };

                        server.UpdatePID = steamCMDProc.Pid;

                        db.Update(server);
                        await db.SaveChangesAsync();

                        ServerUpdateStart?.Invoke(server, new EventArgs());                 // Event


                        // Reading console
                        var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
                        var decoder  = encoding.GetDecoder();
                        var sb       = new StringBuilder();

                        var byteBuffer        = new byte[1024];
                        var maxCharsPerBuffer = encoding.GetMaxCharCount(1024);
                        var charBuffer        = new char[maxCharsPerBuffer];

                        int  currentLinePos      = 0;
                        bool bLastCarriageReturn = false;
                        while (!processExitedTcs.Task.IsCompleted)
                        {
                            try
                            {
                                var bytesRead = await steamCMDProc.ReaderStream.ReadAsync(byteBuffer, 0, byteBuffer.Length).WithCancellation(processExitedCToken);

                                if (bytesRead == 0)
                                {
                                    break;
                                }

                                int charLen = decoder.GetChars(byteBuffer, 0, bytesRead, charBuffer, 0);
                                sb !.Append(charBuffer, 0, charLen);

                                MonitorUtils.MoveLinesFromStringBuilderToMessageQueue(ref currentLinePos, ref bLastCarriageReturn, sb,
                                                                                      (line) => outputEventHandler?.Invoke(steamCMDProc, new CustomDataReceivedEventArgs(line)));
                            }
                            catch (OperationCanceledException)
                            {
                                break;
                            }
                        }

                        if (!processExitedTcs.Task.IsCompleted)
                        {
                            await processExitedTcs.Task;
                        }


                        /*
                         * var readStdOut = Task.Run(async delegate
                         * {
                         *      string? line = null;
                         *      //while ((line = await steamCMDProc.StandardOutput.ReadLineAsync()) != null)
                         *      while (steamCMDProc.StandardOutput.Peek() > -1)
                         *      {
                         *              line = steamCMDProc.StandardOutput.ReadLine();
                         *              _logger.LogWarning("Read line! {0}", line);
                         *              outputEventHandler.Invoke(steamCMDProc, new CustomDataReceivedEventArgs(line));
                         *      }
                         * });
                         * var readErrOut = Task.Run(async delegate
                         * {
                         *      string? line = null;
                         *      //while ((line = await steamCMDProc.StandardError.ReadLineAsync()) != null)
                         *      while (steamCMDProc.StandardError.Peek() > -1)
                         *      {
                         *              line = steamCMDProc.StandardError.ReadLine();
                         *              errorEventHandler.Invoke(steamCMDProc, new CustomDataReceivedEventArgs(line));
                         *      }
                         * });
                         *
                         * await Task.WhenAll(readStdOut, readErrOut);
                         */

                        //await steamCMDProc.WaitForExitAsync();
                        //steamCMDProc.WaitForExit();

                        //steamCMDProc.CancelOutputRead();
                        //steamCMDProc.CancelErrorRead();

                        try
                        {
                            if (steamCMDProc.ExitCode != 0)
                            {
                                hasErrored = true;
                                throw new Exception();
                            }
                        }
                        catch (InvalidOperationException err)
                        {
                            // Do nothing, for some f*****g reason it seems it can't get the exit code
                        }
                    }
                    catch (Exception err)
                    {
                        _logger.LogError(err, "There has been an error while updating the server via SteamCMD");
                        return(false);
                    }
                    finally
                    {
                        _logger.LogInformation("Update finished for server {0}!", server.Id);

                        server.UpdatePID = null;
                        db.Update(server);

                        await db.SaveChangesAsync();


                        ServerUpdated?.Invoke(server, new ServerUpdateEventArgs()
                        {
                            Error = hasErrored
                        });

                        if (steamCMDProc != null)
                        {
                            //steamCMDProc.OutputDataReceived -= outputEventHandler;
                            //steamCMDProc.ErrorDataReceived -= errorEventHandler;
                            steamCMDProc.Dispose();
                        }
                        processExitedCTS.Dispose();
                    }
                }

            return(true);
        }
示例#20
0
        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);
        }