private static bool AreEquals(PredictableList <Rules.Context> a, Rules.Context[] b) { if (b == null || a.count != b.Length) { return(false); } for (int i = 0; i < b.Length; i++) { if (a.buffer[i] != b[i]) { return(false); } } return(true); }
public bool Parse(LineArray lines, int maxMilliseconds) { #if HIGHLIGHTER_DEBUG if (_debugStopwatch == null) { _debugStopwatch = new System.Diagnostics.Stopwatch(); _debugStopwatch.Start(); Console.WriteLine("HIGHLIGHTER START"); } #endif DateTime startTime = DateTime.Now; int changesBeforeTimeCheck = 0; bool timeElapsed = false; bool changed = false; stack = new PredictableList <Rules.Context>(8); stack.Add(contexts[0]); Rules.Context[] state = stack.ToArray(); bool needSetStack = false; bool lastLineChanged = false; for (int i = 0; i < lines.blocksCount; i++) { LineBlock block = lines.blocks[i]; if (timeElapsed && lastLineChanged) { while (block.count == 0) { i++; if (i >= lines.blocksCount) { block = null; break; } block = lines.blocks[i]; } if (block != null) { block.valid &= ~LineBlock.ColorValid; Line line = block.array[0]; line.startState = state; line.endState = null; } stack = null; return(changed); } { bool noChangesInBlock = (block.valid & LineBlock.ColorValid) != 0 && !lastLineChanged; if (noChangesInBlock && block.count > 0) { Rules.Context[] nextState = block.array[block.count - 1].endState; if (nextState == null) { noChangesInBlock = false; } else { state = nextState; } } if (noChangesInBlock) { needSetStack = true; continue; } } block.valid |= LineBlock.ColorValid; for (int j = 0; j < block.count; j++) { Line line = block.array[j]; if (AreEquals(line.startState, state) && line.endState != null) { state = line.endState; needSetStack = true; lastLineChanged = false; continue; } if (needSetStack) { needSetStack = false; stack.Resize(state.Length); Array.Copy(state, stack.buffer, stack.count); } line.startState = state; string text = line.Text; Array.Clear(awakePositions, 0, awakePositions.Length); int position = 0; int count = line.charsCount; Rules.Rule lastMatched = null; while (position < count) { Rules.Context context = stack.count > 0 ? stack.Peek() : contexts[0]; lastMatched = null; foreach (Rules.Rule rule in context.childs) { int nextPosition; if ((rule.column == -1 || position == rule.column) && rule.Match(text, position, out nextPosition)) { if (!rule.lookAhead) { for (; position < nextPosition; position++) { line.chars[position].style = rule.attribute.index; } } if (rule.childs != null && position < count) { foreach (Rules.Rule childRule in rule.childs) { int childNextPosition; if (childRule.Match(text, nextPosition, out childNextPosition)) { for (; position < childNextPosition; position++) { line.chars[position].style = childRule.attribute.index; } Switch(rule.context); } } } Switch(rule.context); lastMatched = rule; break; } } if (lastMatched == null) { if (context.fallthrough) { Switch(context.fallthroughContext); } else { line.chars[position].style = context.attribute.index; position++; } } } if (lastMatched == null || !lastMatched.isLineContinue) { while (stack.count > 0) { Rules.Context contextI = stack.Peek(); if (contextI.lineEndContext.next == null && contextI.lineEndContext.pops == 0) { break; } Switch(contextI.lineEndContext); } } if (AreEquals(stack, state)) { line.endState = state; } else { state = stack.ToArray(); line.endState = state; } changesBeforeTimeCheck++; lastLineChanged = true; changed = true; } if (changesBeforeTimeCheck > 50) { changesBeforeTimeCheck = 0; DateTime nextTime = DateTime.Now; timeElapsed = (nextTime - startTime).TotalMilliseconds > maxMilliseconds; if (timeElapsed) { startTime = nextTime; } } } stack = null; lastParsingChanged = changed; if (!changed && lines.ranges != null) { foreach (StyleRange range in lines.ranges) { lines.SetStyleRange(range); } } #if HIGHLIGHTER_DEBUG if (!changed) { _debugStopwatch.Stop(); Console.WriteLine("HIGHLIGHTER TIME: " + (_debugStopwatch.Elapsed.TotalMilliseconds / 1000).ToString("0.00")); } #endif return(changed); }