Exemplo n.º 1
0
		internal static void ReadConsoleOutputCJK(SafeFileHandle consoleHandle, uint codePage, Coordinates origin, Rectangle contentsRegion, ref BufferCell[,] contents)
		{
			int bottom = contentsRegion.Bottom - contentsRegion.Top + 1;
			int right = contentsRegion.Right - contentsRegion.Left + 1;
			if (bottom <= 0 || right <= 0)
			{
				ConsoleControl.tracer.WriteLine("invalid contents region", new object[0]);
				return;
			}
			else
			{
				int num = 0x800;
				ConsoleControl.SMALL_RECT y;
                y.Top = (short)origin.Y;
				int y1 = bottom;
				while (y1 > 0)
				{
					y.Left = (short)origin.X;
					ConsoleControl.COORD cOORD;
                    cOORD.X = (short)Math.Min(right, num);
					cOORD.Y = (short)Math.Min(y1, num / cOORD.X);
					y.Bottom = (short)(y.Top + cOORD.Y - 1);
					int top = bottom - y1 + contentsRegion.Top;
					int x = right;
					while (x > 0)
					{
						int left = right - x + contentsRegion.Left;
						y.Right = (short)(y.Left + cOORD.X - 1);
						Rectangle rectangle = new Rectangle(left, top, left + cOORD.X - 1, top + cOORD.Y - 1);
						bool flag = ConsoleControl.ReadConsoleOutputCJKSmall(consoleHandle, codePage, new Coordinates(y.Left, y.Top), rectangle, ref contents);
						if (flag)
						{
							x = x - cOORD.X;
							y.Left = (short)(y.Left + cOORD.X);
							if (x > 0 && cOORD.Y == 1 && contents[rectangle.Bottom, rectangle.Right].Character == ' ')
							{
								x++;
								y.Left = (short)(y.Left - 1);
							}
							cOORD.X = (short)Math.Min(x, num);
						}
						else
						{
							if (num >= 2)
							{
								num = num / 2;
								if (right != x)
								{
									cOORD.X = (short)Math.Min(x, num);
								}
								else
								{
									cOORD.Y = 0;
									break;
								}
							}
							else
							{
								int lastWin32Error = Marshal.GetLastWin32Error();
								HostException hostException = ConsoleControl.CreateHostException(lastWin32Error, "ReadConsoleOutput", ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
								throw hostException;
							}
						}
					}
					y1 = y1 - cOORD.Y;
					y.Top = (short)(y.Top + cOORD.Y);
				}
				int lowerBound = contents.GetLowerBound(0);
				int upperBound = contents.GetUpperBound(0);
				int lowerBound1 = contents.GetLowerBound(1);
				int upperBound1 = contents.GetUpperBound(1);
				ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo = ConsoleControl.GetConsoleScreenBufferInfo(consoleHandle);
				ConsoleColor consoleColor = ConsoleColor.Black;
				ConsoleColor consoleColor1 = ConsoleColor.Black;
				ConsoleControl.WORDToColor(consoleScreenBufferInfo.Attributes, out consoleColor, out consoleColor1);
				while (lowerBound <= upperBound)
				{
					int right1 = lowerBound1;
					while (true)
					{
						if (contentsRegion.Top <= lowerBound && lowerBound <= contentsRegion.Bottom && contentsRegion.Left <= right1 && right1 <= contentsRegion.Right)
						{
							right1 = contentsRegion.Right + 1;
						}
						if (right1 > upperBound1)
						{
							break;
						}
						contents[lowerBound, right1] = new BufferCell(' ', consoleColor, consoleColor1, BufferCellType.Complete);
						right1++;
					}
					lowerBound++;
				}
				return;
			}
		}
Exemplo n.º 2
0
        private static void ReadConsoleOutputPlain
        (
            ConsoleHandle consoleHandle,
            Coordinates origin,
            Rectangle contentsRegion,
            ref BufferCell[,] contents
        )
        {
            int rows = contentsRegion.Bottom - contentsRegion.Top + 1;
            int cols = contentsRegion.Right - contentsRegion.Left + 1;

            if ((rows <= 0) || cols <= 0)
            {
                tracer.WriteLine("invalid contents region");
                return;
            }

            int bufferLimit = 2 * 1024; // Limit is 8K bytes as each CHAR_INFO takes 4 bytes

            COORD bufferCoord;

            bufferCoord.X = 0;
            bufferCoord.Y = 0;

            // keeps track of which screen area read
            SMALL_RECT readRegion;

            readRegion.Top = (short)origin.Y;

            int rowsRemaining = rows;

            while (rowsRemaining > 0)
            {
                // Iteration of columns is nested inside iteration of rows.
                // If the size of contents exceeds the buffer limit, reading is
                // done in blocks of size equal to the bufferlimit from left to right
                // then top to bottom.
                // For each iteration of rows,
                // - readRegion.Left and bufferSize.X are reset
                // - rowsRemaining, readRegion.Top, readRegion.Bottom, and bufferSize.Y
                //     are updated
                //   For each iteration of columns,
                //   - readRegion.Left, readRegion.Right and bufferSize.X are updated

                readRegion.Left = (short)origin.X;

                COORD bufferSize;
                bufferSize.X = (short)Math.Min(cols, bufferLimit);
                bufferSize.Y = (short)Math.Min
                                        (
                                            rowsRemaining,
                                            bufferLimit / bufferSize.X
                                        );
                readRegion.Bottom = (short)(readRegion.Top + bufferSize.Y - 1);

                // atContentsRow is at which row of contents a particular iteration is operating
                int atContentsRow = rows - rowsRemaining + contentsRegion.Top;

                // number of columns yet to be read
                int colsRemaining = cols;

                while (colsRemaining > 0)
                {
                    readRegion.Right = (short)(readRegion.Left + bufferSize.X - 1);

                    // Now readRegion and bufferSize are updated.
                    // Call NativeMethods.ReadConsoleOutput
                    CHAR_INFO[] characterBuffer = new CHAR_INFO[bufferSize.Y * bufferSize.X];
                    bool result = NativeMethods.ReadConsoleOutput(
                                        consoleHandle.DangerousGetHandle(),
                                        characterBuffer,
                                        bufferSize,
                                        bufferCoord,
                                        ref readRegion);

                    if (result == false)
                    {
                        // When WriteConsoleOutput fails, half bufferLimit
                        if (bufferLimit < 2)
                        {
                            int err = Marshal.GetLastWin32Error();

                            HostException e = CreateHostException(err, "ReadConsoleOutput",
                                ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
                            throw e;
                        }
                        // if cols == colsRemaining, nothing is guaranteed read in this pass and
                        //  the unread area is still rectangular
                        bufferLimit /= 2;
                        if (cols == colsRemaining)
                        {
                            bufferSize.Y = 0;
                            break;
                        }
                        else
                        {
                            // some areas have been read. This could only happen when the number of columns
                            // to write is larger than bufferLimit. In that case, the algorithm reads one row
                            // at a time => bufferSize.Y == 1. Then, we can safely leave bufferSize.Y unchanged
                            // to retry with a smaller bufferSize.X.
                            Dbg.Assert(bufferSize.Y == 1, string.Format(CultureInfo.InvariantCulture, "bufferSize.Y should be 1, but is {0}", bufferSize.Y));
                            bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                            continue;
                        }
                    }

                    // atContentsCol is at which column of contents a particular iteration is operating
                    int atContentsCol = cols - colsRemaining + contentsRegion.Left;

                    // copy characterBuffer to contents;
                    int characterBufferIndex = 0;
                    for (int r = atContentsRow; r < bufferSize.Y + atContentsRow; r++)
                    {
                        for (int c = atContentsCol; c < bufferSize.X + atContentsCol; c++, characterBufferIndex++)
                        {
                            contents[r, c].Character = (char)
                                characterBuffer[characterBufferIndex].UnicodeChar;
                            ConsoleColor fgColor, bgColor;
                            WORDToColor(characterBuffer[characterBufferIndex].Attributes,
                                out fgColor,
                                out bgColor);
                            contents[r, c].ForegroundColor = fgColor;
                            contents[r, c].BackgroundColor = bgColor;
                        }
                    }
                    colsRemaining -= bufferSize.X;
                    readRegion.Left += bufferSize.X;
                    bufferSize.X = (short)Math.Min(colsRemaining, bufferLimit);
                }  // column iteration

                rowsRemaining -= bufferSize.Y;
                readRegion.Top += bufferSize.Y;
            }  // row iteration

            // The following nested loop set the value of the empty cells in contents:
            // character to ' '
            // foreground color to console's foreground color
            // background color to console's background color
            int rowIndex = contents.GetLowerBound(0);
            int rowEnd = contents.GetUpperBound(0);
            int colBegin = contents.GetLowerBound(1);
            int colEnd = contents.GetUpperBound(1);
            CONSOLE_SCREEN_BUFFER_INFO bufferInfo =
                        GetConsoleScreenBufferInfo(consoleHandle);
            ConsoleColor foreground = 0;
            ConsoleColor background = 0;

            WORDToColor(
                            bufferInfo.Attributes,
                            out foreground,
                            out background
                       );

            while (rowIndex <= rowEnd)
            {
                int colIndex = colBegin;
                while (true)
                {
                    // if contents[rowIndex,colIndex] is in contentsRegion, hence a non-empty cell,
                    // move colIndex to one past the right end of contentsRegion
                    if (contentsRegion.Top <= rowIndex && rowIndex <= contentsRegion.Bottom &&
                        contentsRegion.Left <= colIndex && colIndex <= contentsRegion.Right)
                    {
                        colIndex = contentsRegion.Right + 1;
                    }
                    // colIndex past contents last column
                    if (colIndex > colEnd)
                    {
                        break;
                    }
                    contents[rowIndex, colIndex].Character = ' ';
                    contents[rowIndex, colIndex].ForegroundColor = foreground;
                    contents[rowIndex, colIndex].BackgroundColor = background;
                    colIndex++;
                }
                rowIndex++;
            }
        }
Exemplo n.º 3
0
		private static void ReadConsoleOutputPlain(SafeFileHandle consoleHandle, Coordinates origin, Rectangle contentsRegion, ref BufferCell[,] contents)
		{
			ConsoleColor consoleColor = ConsoleColor.Black;
			ConsoleColor consoleColor1 = ConsoleColor.Black;
			int bottom = contentsRegion.Bottom - contentsRegion.Top + 1;
			int right = contentsRegion.Right - contentsRegion.Left + 1;
			if (bottom <= 0 || right <= 0)
			{
				ConsoleControl.tracer.WriteLine("invalid contents region", new object[0]);
				return;
			}
			else
			{
				int num = 0x800;
				ConsoleControl.COORD cOORD;
                cOORD.X = 0;
				cOORD.Y = 0;
				ConsoleControl.SMALL_RECT y;
                y.Top = (short)origin.Y;
				int y1 = bottom;
				while (y1 > 0)
				{
					y.Left = (short)origin.X;
					ConsoleControl.COORD cOORD1;
                    cOORD1.X = (short)Math.Min(right, num);
					cOORD1.Y = (short)Math.Min(y1, num / cOORD1.X);
					y.Bottom = (short)(y.Top + cOORD1.Y - 1);
					int top = bottom - y1 + contentsRegion.Top;
					int x = right;
					while (x > 0)
					{
						y.Right = (short)(y.Left + cOORD1.X - 1);
						ConsoleControl.CHAR_INFO[] cHARINFOArray = new ConsoleControl.CHAR_INFO[cOORD1.Y * cOORD1.X];
						bool flag = ConsoleControl.NativeMethods.ReadConsoleOutput(consoleHandle.DangerousGetHandle(), cHARINFOArray, cOORD1, cOORD, ref y);
						if (flag)
						{
							int left = right - x + contentsRegion.Left;
							int num1 = 0;
							for (int i = top; i < cOORD1.Y + top; i++)
							{
								int num2 = left;
								while (num2 < cOORD1.X + left)
								{
									contents[i, num2].Character = Convert.ToChar(cHARINFOArray[num1].UnicodeChar);
									ConsoleControl.WORDToColor(cHARINFOArray[num1].Attributes, out consoleColor, out consoleColor1);
									contents[i, num2].ForegroundColor = consoleColor;
									contents[i, num2].BackgroundColor = consoleColor1;
									num2++;
									num1++;
								}
							}
							x = x - cOORD1.X;
							y.Left = (short)(y.Left + cOORD1.X);
							cOORD1.X = (short)Math.Min(x, num);
						}
						else
						{
							if (num >= 2)
							{
								num = num / 2;
								if (right != x)
								{
									cOORD1.X = (short)Math.Min(x, num);
								}
								else
								{
									cOORD1.Y = 0;
									break;
								}
							}
							else
							{
								int lastWin32Error = Marshal.GetLastWin32Error();
								HostException hostException = ConsoleControl.CreateHostException(lastWin32Error, "ReadConsoleOutput", ErrorCategory.ReadError, ConsoleControlStrings.ReadConsoleOutputExceptionTemplate);
								throw hostException;
							}
						}
					}
					y1 = y1 - cOORD1.Y;
					y.Top = (short)(y.Top + cOORD1.Y);
				}
				int lowerBound = contents.GetLowerBound(0);
				int upperBound = contents.GetUpperBound(0);
				int lowerBound1 = contents.GetLowerBound(1);
				int upperBound1 = contents.GetUpperBound(1);
				ConsoleControl.CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo = ConsoleControl.GetConsoleScreenBufferInfo(consoleHandle);
				ConsoleColor consoleColor2 = ConsoleColor.Black;
				ConsoleColor consoleColor3 = ConsoleColor.Black;
				ConsoleControl.WORDToColor(consoleScreenBufferInfo.Attributes, out consoleColor2, out consoleColor3);
				while (lowerBound <= upperBound)
				{
					int right1 = lowerBound1;
					while (true)
					{
						if (contentsRegion.Top <= lowerBound && lowerBound <= contentsRegion.Bottom && contentsRegion.Left <= right1 && right1 <= contentsRegion.Right)
						{
							right1 = contentsRegion.Right + 1;
						}
						if (right1 > upperBound1)
						{
							break;
						}
						contents[lowerBound, right1].Character = ' ';
						contents[lowerBound, right1].ForegroundColor = consoleColor2;
						contents[lowerBound, right1].BackgroundColor = consoleColor3;
						right1++;
					}
					lowerBound++;
				}
				return;
			}
		}