private static bool Execute_XLOG_Command(DataStream <int> ParameterStream) { /* Currently we are only emulating color codes. */ /* XXX: Implement emulation for other codes such as the cursor controls */ XLOG_CODE Code = (XLOG_CODE)Int32.MinValue; if (!ParameterStream.atEnd) { Code = (XLOG_CODE)ParameterStream.Consume(); } switch (Code) { case XLOG_CODE.PUSH_FG: Color_Stack_FG.Push(ANSI.Color_Console_To_ANSI(Console.ForegroundColor)); break; case XLOG_CODE.POP_FG: { if (Color_Stack_FG.Count == 0) { break; } ANSI_COLOR clr = Color_Stack_FG.Pop(); Console.ForegroundColor = ANSI.Color_ANSI_To_Console(clr); } break; case XLOG_CODE.PUSH_BG: Color_Stack_BG.Push(ANSI.Color_Console_To_ANSI(Console.BackgroundColor)); break; case XLOG_CODE.POP_BG: { if (Color_Stack_BG.Count == 0) { break; } ANSI_COLOR clr = Color_Stack_BG.Pop(); Console.BackgroundColor = ANSI.Color_ANSI_To_Console(clr); } break; default: { throw new ArgumentException($"Unrecognized xLOG code: {(XLOG_CODE)Code}"); } } return(true); }
/// <summary> /// Compiles a list of differences between the current text and some given text /// </summary> /// <param name="NewText"></param> /// <returns>List of start/end ranges</returns> public static LinkedList <TextDiff> Difference(StringPtr OldText, StringPtr NewText) { if ((OldText == null || OldText.Length <= 0) && (NewText == null || NewText.Length <= 0)) { return(new LinkedList <TextDiff>()); } else if ((OldText == null || OldText.Length <= 0) && NewText.Length > 0) { return(new LinkedList <TextDiff>(new TextDiff[] { new TextDiff(0, NewText.Length, EDiffType.Insertion) })); } else if ((NewText == null || NewText.Length <= 0) && OldText.Length > 0) { return(new LinkedList <TextDiff>(new TextDiff[] { new TextDiff(0, OldText.Length, EDiffType.Insertion) })); } var A = new DataStream <char>(OldText.AsMemory(), '\0'); var B = new DataStream <char>(NewText.AsMemory(), '\0'); var Chunks = new LinkedList <TextDiff>(); while (true) { if (A.Next != B.Next)/* Just entered a spot where the texts stopped matching */ { var diff = TextDiff.Consume_Diff(A, B); if (diff == null || diff.Length <= 0) {/* No more diffs available */ return(Chunks); } /* Progress the spplicable stream by the difference ammount */ switch (diff.Type) { case EDiffType.Insertion: { B.Consume(diff.Length); } break; case EDiffType.Removal: { A.Consume(diff.Length); } break; case EDiffType.Mutation: { A.Consume(diff.Length); B.Consume(diff.Length); } break; default: throw new NotImplementedException($"Handling for {nameof(EDiffType)} \"{diff.Type}\" has not been implemented!"); } Chunks.AddLast(diff); } if (A.atEnd && B.atEnd) { break; } } /* Check for text diff past the end of stream */ return(Chunks); }
private static bool Execute_SGR_Command(DataStream <int> ParameterStream) { /* Currently we are only emulating color codes. */ /* XXX: Implement emulation for other codes such as the cursor controls */ SGR_CODE Code = SGR_CODE.INVALID; if (!ParameterStream.atEnd) { Code = (SGR_CODE)ParameterStream.Consume(); } switch (Code) { case SGR_CODE.RESET_STYLE: { /* All Attribute OFF */ bModeInvertVideo = false; Color_Stack_FG.Clear(); Color_Stack_BG.Clear(); Console.ResetColor(); } break; case SGR_CODE.RESET_COLOR_FG: { var Defaults = Get_Console_Default_Colors(); var Clr = bModeInvertVideo ? Defaults.Item2 : Defaults.Item1; Set_FG(Clr); } break; case SGR_CODE.RESET_COLOR_BG: { var Defaults = Get_Console_Default_Colors(); var Clr = bModeInvertVideo ? Defaults.Item1 : Defaults.Item2; Set_BG(Clr); } break; case SGR_CODE.INVERT: Set_Inverted(true); break; case SGR_CODE.INVERT_OFF: Set_Inverted(false); break; /* 8-bit Colors */ case SGR_CODE.SET_COLOR_CUSTOM_FG: { if (ParameterStream.Remaining < 2) { throw new SgrFormatError($"Malformed command({Code}) requires atleast 2 parameters!"); } ANSI_COLOR Clr = ANSI_COLOR.WHITE; /* Read custom mode */ int mode = ParameterStream.Consume(); switch (mode) { case 2: /* 8-bit */ { if (ParameterStream.Remaining < 3) { throw new SgrFormatError($"Malformed command. 8-bit colors require 3 parameters!"); } } break; case 5: /* 4-bit */ Clr = (ANSI_COLOR)ParameterStream.Consume(); break; default: throw new SgrFormatError($"Malformed command. '{mode}' is not a valid mode for {Code}"); } if (!bModeInvertVideo) { Set_FG(Clr); } else { Set_BG(Clr); } } break; case SGR_CODE.SET_COLOR_CUSTOM_BG: { if (ParameterStream.Remaining < 2) { throw new SgrFormatError($"Malformed command({Code}) requires atleast 2 parameters!"); } ANSI_COLOR Clr = ANSI_COLOR.BLACK; /* Read custom mode */ int mode = ParameterStream.Consume(); switch (mode) { case 2: /* 8-bit */ { if (ParameterStream.Remaining < 3) { throw new SgrFormatError($"Malformed command. 8-bit colors require 3 parameters!"); } } break; case 5: /* 4-bit */ Clr = (ANSI_COLOR)ParameterStream.Consume(); break; default: throw new SgrFormatError($"Malformed command. '{mode}' is not a valid mode for {Code}"); } if (!bModeInvertVideo) { Set_BG(Clr); } else { Set_FG(Clr); } } break; /* 3/4-bit Colors */ case SGR_CODE n when(n >= SGR_CODE.SET_COLOR_FG && n <= SGR_CODE.SET_COLOR_FG + 7): { var Clr = (ANSI_COLOR)(n - SGR_CODE.SET_COLOR_FG); if (!bModeInvertVideo) { Set_FG(Clr); } else { Set_BG(Clr); } } break; case SGR_CODE n when(n >= SGR_CODE.SET_COLOR_FG_BRIGHT && n <= SGR_CODE.SET_COLOR_FG_BRIGHT + 7): { var Clr = (ANSI_COLOR)(n - SGR_CODE.SET_COLOR_FG_BRIGHT); if (!bModeInvertVideo) { Set_FG(Clr); } else { Set_BG(Clr); } } break; case SGR_CODE n when(n >= SGR_CODE.SET_COLOR_BG && n <= SGR_CODE.SET_COLOR_BG + 7): { var Clr = (ANSI_COLOR)(n - SGR_CODE.SET_COLOR_BG); if (!bModeInvertVideo) { Set_BG(Clr); } else { Set_FG(Clr); } } break; case SGR_CODE n when(n >= SGR_CODE.SET_COLOR_BG_BRIGHT && n <= SGR_CODE.SET_COLOR_BG_BRIGHT + 7): { var Clr = (ANSI_COLOR)(n - SGR_CODE.SET_COLOR_BG_BRIGHT); if (!bModeInvertVideo) { Set_BG(Clr); } else { Set_FG(Clr); } } break; default: { throw new ArgumentException($"Unrecognized (SelectGraphicRendition) code: {(SGR_CODE)Code}"); } } return(true); }
private static bool Consume_CSI_Parameters(DataStream <char> Stream, out List <int> outCodes, out byte?outFinalByte) { var RetList = new List <int>(3); byte?FinalByte = null; /* Check if the stream is currently at a Control Sequence Initiator */ if (Stream.Next == ANSI.CSI && Stream.NextNext == '[') { Stream.Consume(2);/* Consume the CSI block start */ /* Extract the control sequence block */ var BlockStream = Stream.Substream(x => !Is_Final_Byte(Stream.Next) && Stream.Next != ANSI.CSI); if (!Is_Final_Byte(Stream.Next)) { throw new FormatException($"Malformed ANSI escape sequence. The sequence lacks a terminator character @ \"{BlockStream.AsMemory().ToString()}{Stream.Slice(0, 15).ToString()}\""); } FinalByte = (byte)Stream.Consume(); /* Consume CSI terminator */ /* Exctract all CSI block codes from the BlockStream */ if (!BlockStream.atEnd) { /* Extract the parameter bytes */ var ParamStream = BlockStream.Substream(x => Is_Parameter_Byte(x)); /* Consume all intermediate bytes */ /*if (!BlockStream.Consume_While(x => Is_Intermediate_Byte(x))) * { * //throw new FormatException($"Malformed ANSI escape sequence. Expected an intermidate character such as ';' @ \"{BlockStream.AsMemory().ToString()}{Stream.Slice(0, 15).ToString()}\""); * } */ bool bLastWasDigit = false; while (!ParamStream.atEnd) { int paramCode = 0; if (char.IsDigit(ParamStream.Next)) { if (!ParamStream.Consume_While(x => char.IsDigit(x), out ReadOnlyMemory <char> outDigits)) { throw new Exception($"Unable to read from stream @ \"{ParamStream.AsMemory().ToString()}\""); } else { paramCode = Int32.Parse(outDigits.ToString()); } RetList.Add(paramCode); bLastWasDigit = true; } else { ParamStream.Consume(); if (!bLastWasDigit) { RetList.Add(paramCode); } bLastWasDigit = false; } } } } outCodes = RetList; outFinalByte = FinalByte; return(true); }