System.Diagnostics.Debug.Assert(bool)

Here are the examples of the csharp api System.Diagnostics.Debug.Assert(bool) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

12000 Examples 7

19 Source : KnownSymbols.cs
with MIT License
from 0xd4d

public void Bad(ulong address) {
			Debug.replacedert(!symbols.ContainsKey(address));
			noSymbolAddress.Add(address);
		}

19 Source : KnownSymbols.cs
with MIT License
from 0xd4d

public void Add(ulong address, SymbolResult symbol) {
			Debug.replacedert(!noSymbolAddress.Contains(address));
			symbols.Add(address, symbol);
		}

19 Source : AsyncLock.cs
with MIT License
from 1100100

private bool TryEnter()
            {
                lock (_parent._reentrancy)
                {
                    Debug.replacedert((_parent._owningId == UnlockedThreadId) == (_parent._reentrances == 0));
                    if (_parent._owningId != UnlockedThreadId && _parent._owningId != AsyncLock.ThreadId)
                    {
                        //another thread currently owns the lock
                        return false;
                    }
                    //we can go in
                    Interlocked.Increment(ref _parent._reentrances);
                    _parent._owningId = AsyncLock.ThreadId;
                    return true;
                }
            }

19 Source : Helpers.cs
with MIT License
from 71

internal static bool IsMethodOverriden(this Type type, Type baseType, string methodName, params Type[] parameters)
        {
            Debug.replacedert(type != null);
            Debug.replacedert(baseType != null);
            Debug.replacedert(methodName != null);

            return type.GetMethod(methodName, parameters)?.DeclaringType == baseType;
        }

19 Source : Helpers.cs
with MIT License
from 71

internal static void Setreplacedembly(this CSharpCompilation compilation, IreplacedemblySymbol replacedembly)
        {
            Debug.replacedert(replacedembly.GetType().Name == "SourcereplacedemblySymbol");

            LazySetreplacedembly.Value(compilation, replacedembly);
        }

19 Source : Helpers.cs
with MIT License
from 71

internal static Lazy<TDelegate> MakeLazyDelegate<TDelegate>(string name, Action<ILGenerator> ilgen)
            where TDelegate : Delegate
        {
            Debug.replacedert(typeof(TDelegate).GetMethod("Invoke") != null);

            return new Lazy<TDelegate>(() => MakeDelegate<TDelegate>(name, ilgen));
        }

19 Source : Helpers.cs
with MIT License
from 71

internal static TDelegate MakeDelegate<TDelegate>(string name, Action<ILGenerator> ilgen, Type owner = null)
            where TDelegate : Delegate
        {
            MethodInfo invokeMethod = typeof(TDelegate).GetMethod("Invoke");

            Debug.replacedert(invokeMethod != null);

            ParameterInfo[] parameters = invokeMethod.GetParameters();
            Type[] parameterTypes = new Type[parameters.Length];

            for (int i = 0; i < parameters.Length; i++)
            {
                parameterTypes[i] = parameters[i].ParameterType;
            }

            DynamicMethod method = owner == null
                ? new DynamicMethod(name, invokeMethod.ReturnType, parameterTypes, true)
                : new DynamicMethod(name, invokeMethod.ReturnType, parameterTypes, owner, true);

            ILGenerator il = method.GetILGenerator();

            ilgen(il);

            return (TDelegate)method.CreateDelegate(typeof(TDelegate));
        }

19 Source : CompilationProcessor.cs
with MIT License
from 71

public static CompilationProcessor Create(
            Func<CSharpCompilation, object> moduleBuilderGetter,
            Action<Diagnostic> addDiagnostic,
            Func<IEnumerable<Diagnostic>> getDiagnostics,
            params CompilationEditor[] editors)
        {
            Debug.replacedert(editors != null);
            Debug.replacedert(editors.All(x => x != null));

            return new CompilationProcessor(moduleBuilderGetter, addDiagnostic, getDiagnostics, editors);
        }

19 Source : ByteBuffer.cs
with MIT License
from a1q123456

private void AddNewBufferSegment()
        {
            var arr = _arrayPool.Rent(BufferSegmentSize);
            Debug.replacedert(_buffers.IndexOf(arr) == -1);
            _buffers.Add(arr);
            _bufferEnd = 0;
        }

19 Source : ChunkStreamContext.cs
with MIT License
from a1q123456

internal async Task MultiplexMessageAsync(uint chunkStreamId, Message message)
        {
            if (!message.MessageHeader.MessageStreamId.HasValue)
            {
                throw new InvalidOperationException("cannot send message that has not attached to a message stream");
            }
            byte[] buffer = null;
            uint length = 0;
            using (var writeBuffer = new ByteBuffer())
            {
                var context = new Serialization.SerializationContext()
                {
                    Amf0Reader = _amf0Reader,
                    Amf0Writer = _amf0Writer,
                    Amf3Reader = _amf3Reader,
                    Amf3Writer = _amf3Writer,
                    WriteBuffer = writeBuffer
                };
                message.Serialize(context);
                length = (uint)writeBuffer.Length;
                Debug.replacedert(length != 0);
                buffer = _arrayPool.Rent((int)length);
                writeBuffer.TakeOutMemory(buffer);
            }

            try
            {
                message.MessageHeader.MessageLength = length;
                Debug.replacedert(message.MessageHeader.MessageLength != 0);
                if (message.MessageHeader.MessageType == 0)
                {
                    message.MessageHeader.MessageType = message.GetType().GetCustomAttribute<RtmpMessageAttribute>().MessageTypes.First();
                }
                Debug.replacedert(message.MessageHeader.MessageType != 0);
                Task ret = null;
                // chunking
                bool isFirstChunk = true;
                _rtmpSession.replacedertStreamId(message.MessageHeader.MessageStreamId.Value);
                for (int i = 0; i < message.MessageHeader.MessageLength;)
                {
                    _previousWriteMessageHeader.TryGetValue(chunkStreamId, out var prevHeader);
                    var chunkHeaderType = SelectChunkType(message.MessageHeader, prevHeader, isFirstChunk);
                    isFirstChunk = false;
                    GenerateBasicHeader(chunkHeaderType, chunkStreamId, out var basicHeader, out var basicHeaderLength);
                    GenerateMesesageHeader(chunkHeaderType, message.MessageHeader, prevHeader, out var messageHeader, out var messageHeaderLength);
                    _previousWriteMessageHeader[chunkStreamId] = (MessageHeader)message.MessageHeader.Clone();
                    var headerLength = basicHeaderLength + messageHeaderLength;
                    var bodySize = (int)(length - i >= _writeChunkSize ? _writeChunkSize : length - i);

                    var chunkBuffer = _arrayPool.Rent(headerLength + bodySize);
                    await _sync.WaitAsync();
                    try
                    {
                        basicHeader.replacedpan(0, basicHeaderLength).CopyTo(chunkBuffer);
                        messageHeader.replacedpan(0, messageHeaderLength).CopyTo(chunkBuffer.replacedpan(basicHeaderLength));
                        _arrayPool.Return(basicHeader);
                        _arrayPool.Return(messageHeader);
                        buffer.replacedpan(i, bodySize).CopyTo(chunkBuffer.replacedpan(headerLength));
                        i += bodySize;
                        var isLastChunk = message.MessageHeader.MessageLength - i == 0;

                        long offset = 0;
                        long totalLength = headerLength + bodySize;
                        long currentSendSize = totalLength;

                        while (offset != (headerLength + bodySize))
                        {
                            if (WriteWindowAcknowledgementSize.HasValue && Interlocked.Read(ref WriteUnAcknowledgedSize) + headerLength + bodySize > WriteWindowAcknowledgementSize.Value)
                            {
                                currentSendSize = Math.Min(WriteWindowAcknowledgementSize.Value, currentSendSize);
                                //var delayCount = 0;
                                while (currentSendSize + Interlocked.Read(ref WriteUnAcknowledgedSize) >= WriteWindowAcknowledgementSize.Value)
                                {
                                    await Task.Delay(1);
                                }
                            }
                            var tsk = _ioPipeline.SendRawData(chunkBuffer.AsMemory((int)offset, (int)currentSendSize));
                            offset += currentSendSize;
                            totalLength -= currentSendSize;

                            if (WriteWindowAcknowledgementSize.HasValue)
                            {
                                Interlocked.Add(ref WriteUnAcknowledgedSize, currentSendSize);
                            }
                            
                            if (isLastChunk)
                            {
                                ret = tsk;
                            }
                        }
                        if (isLastChunk)
                        {
                            if (message.MessageHeader.MessageType == MessageType.SetChunkSize)
                            {
                                var setChunkSize = message as SetChunkSizeMessage;
                                _writeChunkSize = setChunkSize.ChunkSize;
                            }
                            else if (message.MessageHeader.MessageType == MessageType.SetPeerBandwidth)
                            {
                                var m = message as SetPeerBandwidthMessage;
                                ReadWindowAcknowledgementSize = m.WindowSize;
                            }
                            else if (message.MessageHeader.MessageType == MessageType.WindowAcknowledgementSize)
                            {
                                var m = message as WindowAcknowledgementSizeMessage;
                                WriteWindowAcknowledgementSize = m.WindowSize;
                            }
                        }
                    }
                    finally
                    {
                        _sync.Release();
                        _arrayPool.Return(chunkBuffer);
                    }
                }
                Debug.replacedert(ret != null);
                await ret;

            }
            finally
            {
                _arrayPool.Return(buffer);
            }

        }

19 Source : IOPipeLine.cs
with MIT License
from a1q123456

private async Task Writer(CancellationToken ct)
        { 
            while (!ct.IsCancellationRequested && !disposedValue)
            {
                await _writerSignal.WaitAsync(ct);
                if (_writerQueue.TryDequeue(out var data))
                {
                    Debug.replacedert(data != null);
                    Debug.replacedert(_socket != null);
                    Debug.replacedert((data.Buffer[0] & 0x3F) < 10);
                    await _socket.SendAsync(data.Buffer.AsMemory(0, data.Length), SocketFlags.None, ct);
                    _arrayPool.Return(data.Buffer);
                    data.TaskSource?.SetResult(1);
                }
                else
                {
                    Debug.replacedert(false);
                }
            }
        }

19 Source : RtmpSession.cs
with MIT License
from a1q123456

internal void replacedertStreamId(uint msid)
        {
            Debug.replacedert(_messageStreams.ContainsKey(msid));
        }

19 Source : CommandMessage.cs
with MIT License
from a1q123456

public void SerializeAmf0(SerializationContext context)
        {
            using (var writeContext = new Amf.Serialization.Amf0.SerializationContext(context.WriteBuffer))
            {
                if (ProcedureName == null)
                {
                    ProcedureName = GetType().GetCustomAttribute<RtmpCommandAttribute>().Name;
                }
                Debug.replacedert(!string.IsNullOrEmpty(ProcedureName));
                context.Amf0Writer.WriteBytes(ProcedureName, writeContext);
                context.Amf0Writer.WriteBytes(TranscationID, writeContext);
                context.Amf0Writer.WriteValueBytes(CommandObject, writeContext);
                var optionArguments = GetType().GetProperties().Where(p => p.GetCustomAttribute<OptionalArgumentAttribute>() != null).ToList();
                foreach (var optionArgument in optionArguments)
                {
                    context.Amf0Writer.WriteValueBytes(optionArgument.GetValue(this), writeContext);
                }
            }
        }

19 Source : CommandMessage.cs
with MIT License
from a1q123456

public void SerializeAmf3(SerializationContext context)
        {
            using (var writeContext = new Amf.Serialization.Amf3.SerializationContext(context.WriteBuffer))
            {
                if (ProcedureName == null)
                {
                    ProcedureName = GetType().GetCustomAttribute<RtmpCommandAttribute>().Name;
                }
                Debug.replacedert(!string.IsNullOrEmpty(ProcedureName));
                context.Amf3Writer.WriteBytes(ProcedureName, writeContext);
                context.Amf3Writer.WriteBytes(TranscationID, writeContext);
                context.Amf3Writer.WriteValueBytes(CommandObject, writeContext);
                var optionArguments = GetType().GetProperties().Where(p => p.GetCustomAttribute<OptionalArgumentAttribute>() != null).ToList();
                foreach (var optionArgument in optionArguments)
                {
                    context.Amf3Writer.WriteValueBytes(optionArgument.GetValue(this), writeContext);
                }
            }
        }

19 Source : DocumentChangeOperation.cs
with MIT License
from Abdesol

public void Undo(UndoStack stack)
		{
			Debug.replacedert(stack.state == UndoStack.StatePlayback);
			stack.RegisterAffectedDoreplacedent(doreplacedent);
			stack.state = UndoStack.StatePlaybackModifyDoreplacedent;
			this.Undo();
			stack.state = UndoStack.StatePlayback;
		}

19 Source : DocumentChangeOperation.cs
with MIT License
from Abdesol

public void Redo(UndoStack stack)
		{
			Debug.replacedert(stack.state == UndoStack.StatePlayback);
			stack.RegisterAffectedDoreplacedent(doreplacedent);
			stack.state = UndoStack.StatePlaybackModifyDoreplacedent;
			this.Redo();
			stack.state = UndoStack.StatePlayback;
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

public void RebuildTree(List<DoreplacedentLine> doreplacedentLines)
		{
			LineNode[] nodes = new LineNode[doreplacedentLines.Count];
			for (int i = 0; i < doreplacedentLines.Count; i++) {
				DoreplacedentLine ls = doreplacedentLines[i];
				LineNode node = ls.InitLineNode();
				nodes[i] = node;
			}
			Debug.replacedert(nodes.Length > 0);
			// now build the corresponding balanced tree
			int height = GetTreeHeight(nodes.Length);
			Debug.WriteLine("DoreplacedentLineTree will have height: " + height);
			root = BuildTree(nodes, 0, nodes.Length, height);
			root.color = BLACK;
#if DEBUG
			CheckProperties();
#endif
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

LineNode BuildTree(LineNode[] nodes, int start, int end, int subtreeHeight)
		{
			Debug.replacedert(start <= end);
			if (start == end) {
				return null;
			}
			int middle = (start + end) / 2;
			LineNode node = nodes[middle];
			node.left = BuildTree(nodes, start, middle, subtreeHeight - 1);
			node.right = BuildTree(nodes, middle + 1, end, subtreeHeight - 1);
			if (node.left != null) node.left.parent = node;
			if (node.right != null) node.right.parent = node;
			if (subtreeHeight == 1)
				node.color = RED;
			UpdateAfterChildrenChange(node);
			return node;
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

LineNode GetNodeByIndex(int index)
		{
			Debug.replacedert(index >= 0);
			Debug.replacedert(index < root.nodeTotalCount);
			LineNode node = root;
			while (true) {
				if (node.left != null && index < node.left.nodeTotalCount) {
					node = node.left;
				} else {
					if (node.left != null) {
						index -= node.left.nodeTotalCount;
					}
					if (index == 0)
						return node;
					index--;
					node = node.right;
				}
			}
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

LineNode GetNodeByOffset(int offset)
		{
			Debug.replacedert(offset >= 0);
			Debug.replacedert(offset <= root.nodeTotalLength);
			if (offset == root.nodeTotalLength) {
				return root.RightMost;
			}
			LineNode node = root;
			while (true) {
				if (node.left != null && offset < node.left.nodeTotalLength) {
					node = node.left;
				} else {
					if (node.left != null) {
						offset -= node.left.nodeTotalLength;
					}
					offset -= node.TotalLength;
					if (offset < 0)
						return node;
					node = node.right;
				}
			}
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void InsertAsLeft(LineNode parentNode, LineNode newNode)
		{
			Debug.replacedert(parentNode.left == null);
			parentNode.left = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAfterChildrenChange(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void InsertAsRight(LineNode parentNode, LineNode newNode)
		{
			Debug.replacedert(parentNode.right == null);
			parentNode.right = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAfterChildrenChange(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void FixTreeOnInsert(LineNode node)
		{
			Debug.replacedert(node != null);
			Debug.replacedert(node.color == RED);
			Debug.replacedert(node.left == null || node.left.color == BLACK);
			Debug.replacedert(node.right == null || node.right.color == BLACK);

			LineNode parentNode = node.parent;
			if (parentNode == null) {
				// we inserted in the root -> the node must be black
				// since this is a root node, making the node black increments the number of black nodes
				// on all paths by one, so it is still the same for all paths.
				node.color = BLACK;
				return;
			}
			if (parentNode.color == BLACK) {
				// if the parent node where we inserted was black, our red node is placed correctly.
				// since we inserted a red node, the number of black nodes on each path is unchanged
				// -> the tree is still balanced
				return;
			}
			// parentNode is red, so there is a conflict here!

			// because the root is black, parentNode is not the root -> there is a grandparent node
			LineNode grandparentNode = parentNode.parent;
			LineNode uncleNode = Sibling(parentNode);
			if (uncleNode != null && uncleNode.color == RED) {
				parentNode.color = BLACK;
				uncleNode.color = BLACK;
				grandparentNode.color = RED;
				FixTreeOnInsert(grandparentNode);
				return;
			}
			// now we know: parent is red but uncle is black
			// First rotation:
			if (node == parentNode.right && parentNode == grandparentNode.left) {
				RotateLeft(parentNode);
				node = node.left;
			} else if (node == parentNode.left && parentNode == grandparentNode.right) {
				RotateRight(parentNode);
				node = node.right;
			}
			// because node might have changed, rereplacedign variables:
			parentNode = node.parent;
			grandparentNode = parentNode.parent;

			// Now recolor a bit:
			parentNode.color = BLACK;
			grandparentNode.color = RED;
			// Second rotation:
			if (node == parentNode.left && parentNode == grandparentNode.left) {
				RotateRight(grandparentNode);
			} else {
				// because of the first rotation, this is guaranteed:
				Debug.replacedert(node == parentNode.right && parentNode == grandparentNode.right);
				RotateLeft(grandparentNode);
			}
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void FixTreeOnDelete(LineNode node, LineNode parentNode)
		{
			Debug.replacedert(node == null || node.parent == parentNode);
			if (parentNode == null)
				return;

			// warning: node may be null
			LineNode sibling = Sibling(node, parentNode);
			if (sibling.color == RED) {
				parentNode.color = RED;
				sibling.color = BLACK;
				if (node == parentNode.left) {
					RotateLeft(parentNode);
				} else {
					RotateRight(parentNode);
				}

				sibling = Sibling(node, parentNode); // update value of sibling after rotation
			}

			if (parentNode.color == BLACK
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				FixTreeOnDelete(parentNode, parentNode.parent);
				return;
			}

			if (parentNode.color == RED
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				parentNode.color = BLACK;
				return;
			}

			if (node == parentNode.left &&
				sibling.color == BLACK &&
				GetColor(sibling.left) == RED &&
				GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				sibling.left.color = BLACK;
				RotateRight(sibling);
			} else if (node == parentNode.right &&
					   sibling.color == BLACK &&
					   GetColor(sibling.right) == RED &&
					   GetColor(sibling.left) == BLACK) {
				sibling.color = RED;
				sibling.right.color = BLACK;
				RotateLeft(sibling);
			}
			sibling = Sibling(node, parentNode); // update value of sibling after rotation

			sibling.color = parentNode.color;
			parentNode.color = BLACK;
			if (node == parentNode.left) {
				if (sibling.right != null) {
					Debug.replacedert(sibling.right.color == RED);
					sibling.right.color = BLACK;
				}
				RotateLeft(parentNode);
			} else {
				if (sibling.left != null) {
					Debug.replacedert(sibling.left.color == RED);
					sibling.left.color = BLACK;
				}
				RotateRight(parentNode);
			}
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void ReplaceNode(LineNode replacedNode, LineNode newNode)
		{
			if (replacedNode.parent == null) {
				Debug.replacedert(replacedNode == root);
				root = newNode;
			} else {
				if (replacedNode.parent.left == replacedNode)
					replacedNode.parent.left = newNode;
				else
					replacedNode.parent.right = newNode;
			}
			if (newNode != null) {
				newNode.parent = replacedNode.parent;
			}
			replacedNode.parent = null;
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void RotateLeft(LineNode p)
		{
			// let q be p's right child
			LineNode q = p.right;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's right child to be q's left child
			p.right = q.left;
			if (p.right != null) p.right.parent = p;
			// set q's left child to be p
			q.left = p;
			p.parent = q;
			UpdateAfterRotateLeft(p);
		}

19 Source : DocumentLineTree.cs
with MIT License
from Abdesol

void RotateRight(LineNode p)
		{
			// let q be p's left child
			LineNode q = p.left;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's left child to be q's right child
			p.left = q.right;
			if (p.left != null) p.left.parent = p;
			// set q's right child to be p
			q.right = p;
			p.parent = q;
			UpdateAfterRotateRight(p);
		}

19 Source : LineManager.cs
with MIT License
from Abdesol

public void Remove(int offset, int length)
		{
			Debug.replacedert(length >= 0);
			if (length == 0) return;
			DoreplacedentLine startLine = doreplacedentLineTree.GetByOffset(offset);
			int startLineOffset = startLine.Offset;

			Debug.replacedert(offset < startLineOffset + startLine.TotalLength);
			if (offset > startLineOffset + startLine.Length) {
				Debug.replacedert(startLine.DelimiterLength == 2);
				// we are deleting starting in the middle of a delimiter

				// remove last delimiter part
				SetLineLength(startLine, startLine.TotalLength - 1);
				// remove remaining text
				Remove(offset, length - 1);
				return;
			}

			if (offset + length < startLineOffset + startLine.TotalLength) {
				// just removing a part of this line
				//startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, length);
				SetLineLength(startLine, startLine.TotalLength - length);
				return;
			}
			// merge startLine with another line because startLine's delimiter was deleted
			// possibly remove lines in between if multiple delimiters were deleted
			int charactersRemovedInStartLine = startLineOffset + startLine.TotalLength - offset;
			Debug.replacedert(charactersRemovedInStartLine > 0);
			//startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, charactersRemovedInStartLine);


			DoreplacedentLine endLine = doreplacedentLineTree.GetByOffset(offset + length);
			if (endLine == startLine) {
				// special case: we are removing a part of the last line up to the
				// end of the doreplacedent
				SetLineLength(startLine, startLine.TotalLength - length);
				return;
			}
			int endLineOffset = endLine.Offset;
			int charactersLeftInEndLine = endLineOffset + endLine.TotalLength - (offset + length);
			//endLine.RemovedLinePart(ref deferredEventList, 0, endLine.TotalLength - charactersLeftInEndLine);
			//startLine.MergedWith(endLine, offset - startLineOffset);

			// remove all lines between startLine (excl.) and endLine (incl.)
			DoreplacedentLine tmp = startLine.NextLine;
			DoreplacedentLine lineToRemove;
			do {
				lineToRemove = tmp;
				tmp = tmp.NextLine;
				RemoveLine(lineToRemove);
			} while (lineToRemove != endLine);

			SetLineLength(startLine, startLine.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
		}

19 Source : LineManager.cs
with MIT License
from Abdesol

public void Insert(int offset, ITextSource text)
		{
			DoreplacedentLine line = doreplacedentLineTree.GetByOffset(offset);
			int lineOffset = line.Offset;

			Debug.replacedert(offset <= lineOffset + line.TotalLength);
			if (offset > lineOffset + line.Length) {
				Debug.replacedert(line.DelimiterLength == 2);
				// we are inserting in the middle of a delimiter

				// shorten line
				SetLineLength(line, line.TotalLength - 1);
				// add new line
				line = InsertLineAfter(line, 1);
				line = SetLineLength(line, 1);
			}

			SimpleSegment ds = NewLineFinder.NextNewLine(text, 0);
			if (ds == SimpleSegment.Invalid) {
				// no newline is being inserted, all text is inserted in a single line
				//line.InsertedLinePart(offset - line.Offset, text.Length);
				SetLineLength(line, line.TotalLength + text.TextLength);
				return;
			}
			//DoreplacedentLine firstLine = line;
			//firstLine.InsertedLinePart(offset - firstLine.Offset, ds.Offset);
			int lastDelimiterEnd = 0;
			while (ds != SimpleSegment.Invalid) {
				// split line segment at line delimiter
				int lineBreakOffset = offset + ds.Offset + ds.Length;
				lineOffset = line.Offset;
				int lengthAfterInsertionPos = lineOffset + line.TotalLength - (offset + lastDelimiterEnd);
				line = SetLineLength(line, lineBreakOffset - lineOffset);
				DoreplacedentLine newLine = InsertLineAfter(line, lengthAfterInsertionPos);
				newLine = SetLineLength(newLine, lengthAfterInsertionPos);

				line = newLine;
				lastDelimiterEnd = ds.Offset + ds.Length;

				ds = NewLineFinder.NextNewLine(text, lastDelimiterEnd);
			}
			//firstLine.SplitTo(line);
			// insert rest after last delimiter
			if (lastDelimiterEnd != text.TextLength) {
				//line.InsertedLinePart(0, text.Length - lastDelimiterEnd);
				SetLineLength(line, line.TotalLength + text.TextLength - lastDelimiterEnd);
			}
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void InsertText(int offset, int length, bool defaultAnchorMovementIsBeforeInsertion)
		{
			if (length == 0 || root == null || offset > root.totalLength)
				return;

			// find the range of nodes that are placed exactly at offset
			// beginNode is inclusive, endNode is exclusive
			if (offset == root.totalLength) {
				PerformInsertText(FindActualBeginNode(root.RightMost), null, length, defaultAnchorMovementIsBeforeInsertion);
			} else {
				TextAnchorNode endNode = FindNode(ref offset);
				Debug.replacedert(endNode.length > 0);

				if (offset > 0) {
					// there are no nodes exactly at offset
					endNode.length += length;
					UpdateAugmentedData(endNode);
				} else {
					PerformInsertText(FindActualBeginNode(endNode.Predecessor), endNode, length, defaultAnchorMovementIsBeforeInsertion);
				}
			}
			DeleteMarkedNodes();
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void PerformInsertText(TextAnchorNode beginNode, TextAnchorNode endNode, int length, bool defaultAnchorMovementIsBeforeInsertion)
		{
			Debug.replacedert(beginNode != null);
			// endNode may be null at the end of the anchor tree

			// now we need to sort the nodes in the range [beginNode, endNode); putting those with
			// MovementType.BeforeInsertion in front of those with MovementType.AfterInsertion
			List<TextAnchorNode> beforeInsert = new List<TextAnchorNode>();
			//List<TextAnchorNode> afterInsert = new List<TextAnchorNode>();
			TextAnchorNode temp = beginNode;
			while (temp != endNode) {
				TextAnchor anchor = (TextAnchor)temp.Target;
				if (anchor == null) {
					// afterInsert.Add(temp);
					MarkNodeForDelete(temp);
				} else if (defaultAnchorMovementIsBeforeInsertion
						   ? anchor.MovementType != AnchorMovementType.AfterInsertion
						   : anchor.MovementType == AnchorMovementType.BeforeInsertion) {
					beforeInsert.Add(temp);
					//				} else {
					//					afterInsert.Add(temp);
				}
				temp = temp.Successor;
			}
			// now again go through the range and swap the nodes with those in the beforeInsert list
			temp = beginNode;
			foreach (TextAnchorNode node in beforeInsert) {
				SwapAnchors(node, temp);
				temp = temp.Successor;
			}
			// now temp is pointing to the first node that is afterInsert,
			// or to endNode, if there is no afterInsert node at the offset
			// So add the length to temp
			if (temp == null) {
				// temp might be null if endNode==null and no afterInserts
				Debug.replacedert(endNode == null);
			} else {
				temp.length += length;
				UpdateAugmentedData(temp);
			}
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

public void HandleTextChange(OffsetChangeMapEntry entry, DelayedEvents delayedEvents)
		{
			//Log("HandleTextChange(" + entry + ")");
			if (entry.RemovalLength == 0) {
				// This is a pure insertion.
				// Unlike a replace with removal, a pure insertion can result in nodes at the same location
				// to split depending on their MovementType.
				// Thus, we handle this case on a separate code path
				// (the code below looks like it does something similar, but it can only split
				// the set of deletion survivors, not all nodes at an offset)
				InsertText(entry.Offset, entry.InsertionLength, entry.DefaultAnchorMovementIsBeforeInsertion);
				return;
			}
			// When handling a replacing text change, we need to:
			// - find all anchors in the deleted segment and delete them / move them to the appropriate
			//   surviving side.
			// - adjust the segment size between the left and right side

			int offset = entry.Offset;
			int remainingRemovalLength = entry.RemovalLength;
			// if the text change is happening after the last anchor, we don't have to do anything
			if (root == null || offset >= root.totalLength)
				return;
			TextAnchorNode node = FindNode(ref offset);
			TextAnchorNode firstDeletionSurvivor = null;
			// go forward through the tree and delete all nodes in the removal segment
			while (node != null && offset + remainingRemovalLength > node.length) {
				TextAnchor anchor = (TextAnchor)node.Target;
				if (anchor != null && (anchor.SurviveDeletion || entry.RemovalNeverCausesAnchorDeletion)) {
					if (firstDeletionSurvivor == null)
						firstDeletionSurvivor = node;
					// This node should be deleted, but it wants to survive.
					// We'll just remove the deleted length segment, so the node will be positioned
					// in front of the removed segment.
					remainingRemovalLength -= node.length - offset;
					node.length = offset;
					offset = 0;
					UpdateAugmentedData(node);
					node = node.Successor;
				} else {
					// delete node
					TextAnchorNode s = node.Successor;
					remainingRemovalLength -= node.length;
					RemoveNode(node);
					// we already deleted the node, don't delete it twice
					nodesToDelete.Remove(node);
					if (anchor != null)
						anchor.OnDeleted(delayedEvents);
					node = s;
				}
			}
			// 'node' now is the first anchor after the deleted segment.
			// If there are no anchors after the deleted segment, 'node' is null.

			// firstDeletionSurvivor was set to the first node surviving deletion.
			// Because all non-surviving nodes up to 'node' were deleted, the node range
			// [firstDeletionSurvivor, node) now refers to the set of all deletion survivors.

			// do the remaining job of the removal
			if (node != null) {
				node.length -= remainingRemovalLength;
				Debug.replacedert(node.length >= 0);
			}
			if (entry.InsertionLength > 0) {
				// we are performing a replacement
				if (firstDeletionSurvivor != null) {
					// We got deletion survivors which need to be split into BeforeInsertion
					// and AfterInsertion groups.
					// Take care that we don't regroup everything at offset, but only the deletion
					// survivors - from firstDeletionSurvivor (inclusive) to node (exclusive).
					// This ensures that nodes immediately before or after the replaced segment
					// stay where they are (independent from their MovementType)
					PerformInsertText(firstDeletionSurvivor, node, entry.InsertionLength, entry.DefaultAnchorMovementIsBeforeInsertion);
				} else if (node != null) {
					// No deletion survivors:
					// just perform the insertion
					node.length += entry.InsertionLength;
				}
			}
			if (node != null) {
				UpdateAugmentedData(node);
			}
			DeleteMarkedNodes();
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

public TextAnchor CreateAnchor(int offset)
		{
			Log("CreateAnchor(" + offset + ")");
			TextAnchor anchor = new TextAnchor(doreplacedent);
			anchor.node = new TextAnchorNode(anchor);
			if (root == null) {
				// creating the first text anchor
				root = anchor.node;
				root.totalLength = root.length = offset;
			} else if (offset >= root.totalLength) {
				// append anchor at end of tree
				anchor.node.totalLength = anchor.node.length = offset - root.totalLength;
				InsertAsRight(root.RightMost, anchor.node);
			} else {
				// insert anchor in middle of tree
				TextAnchorNode n = FindNode(ref offset);
				Debug.replacedert(offset < n.length);
				// split segment 'n' at offset
				anchor.node.totalLength = anchor.node.length = offset;
				n.length -= offset;
				InsertBefore(n, anchor.node);
			}
			DeleteMarkedNodes();
			return anchor;
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void InsertAsLeft(TextAnchorNode parentNode, TextAnchorNode newNode)
		{
			Debug.replacedert(parentNode.left == null);
			parentNode.left = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAugmentedData(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void InsertAsRight(TextAnchorNode parentNode, TextAnchorNode newNode)
		{
			Debug.replacedert(parentNode.right == null);
			parentNode.right = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAugmentedData(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void FixTreeOnInsert(TextAnchorNode node)
		{
			Debug.replacedert(node != null);
			Debug.replacedert(node.color == RED);
			Debug.replacedert(node.left == null || node.left.color == BLACK);
			Debug.replacedert(node.right == null || node.right.color == BLACK);

			TextAnchorNode parentNode = node.parent;
			if (parentNode == null) {
				// we inserted in the root -> the node must be black
				// since this is a root node, making the node black increments the number of black nodes
				// on all paths by one, so it is still the same for all paths.
				node.color = BLACK;
				return;
			}
			if (parentNode.color == BLACK) {
				// if the parent node where we inserted was black, our red node is placed correctly.
				// since we inserted a red node, the number of black nodes on each path is unchanged
				// -> the tree is still balanced
				return;
			}
			// parentNode is red, so there is a conflict here!

			// because the root is black, parentNode is not the root -> there is a grandparent node
			TextAnchorNode grandparentNode = parentNode.parent;
			TextAnchorNode uncleNode = Sibling(parentNode);
			if (uncleNode != null && uncleNode.color == RED) {
				parentNode.color = BLACK;
				uncleNode.color = BLACK;
				grandparentNode.color = RED;
				FixTreeOnInsert(grandparentNode);
				return;
			}
			// now we know: parent is red but uncle is black
			// First rotation:
			if (node == parentNode.right && parentNode == grandparentNode.left) {
				RotateLeft(parentNode);
				node = node.left;
			} else if (node == parentNode.left && parentNode == grandparentNode.right) {
				RotateRight(parentNode);
				node = node.right;
			}
			// because node might have changed, rereplacedign variables:
			parentNode = node.parent;
			grandparentNode = parentNode.parent;

			// Now recolor a bit:
			parentNode.color = BLACK;
			grandparentNode.color = RED;
			// Second rotation:
			if (node == parentNode.left && parentNode == grandparentNode.left) {
				RotateRight(grandparentNode);
			} else {
				// because of the first rotation, this is guaranteed:
				Debug.replacedert(node == parentNode.right && parentNode == grandparentNode.right);
				RotateLeft(grandparentNode);
			}
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void FixTreeOnDelete(TextAnchorNode node, TextAnchorNode parentNode)
		{
			Debug.replacedert(node == null || node.parent == parentNode);
			if (parentNode == null)
				return;

			// warning: node may be null
			TextAnchorNode sibling = Sibling(node, parentNode);
			if (sibling.color == RED) {
				parentNode.color = RED;
				sibling.color = BLACK;
				if (node == parentNode.left) {
					RotateLeft(parentNode);
				} else {
					RotateRight(parentNode);
				}

				sibling = Sibling(node, parentNode); // update value of sibling after rotation
			}

			if (parentNode.color == BLACK
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				FixTreeOnDelete(parentNode, parentNode.parent);
				return;
			}

			if (parentNode.color == RED
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				parentNode.color = BLACK;
				return;
			}

			if (node == parentNode.left &&
				sibling.color == BLACK &&
				GetColor(sibling.left) == RED &&
				GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				sibling.left.color = BLACK;
				RotateRight(sibling);
			} else if (node == parentNode.right &&
					   sibling.color == BLACK &&
					   GetColor(sibling.right) == RED &&
					   GetColor(sibling.left) == BLACK) {
				sibling.color = RED;
				sibling.right.color = BLACK;
				RotateLeft(sibling);
			}
			sibling = Sibling(node, parentNode); // update value of sibling after rotation

			sibling.color = parentNode.color;
			parentNode.color = BLACK;
			if (node == parentNode.left) {
				if (sibling.right != null) {
					Debug.replacedert(sibling.right.color == RED);
					sibling.right.color = BLACK;
				}
				RotateLeft(parentNode);
			} else {
				if (sibling.left != null) {
					Debug.replacedert(sibling.left.color == RED);
					sibling.left.color = BLACK;
				}
				RotateRight(parentNode);
			}
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void ReplaceNode(TextAnchorNode replacedNode, TextAnchorNode newNode)
		{
			if (replacedNode.parent == null) {
				Debug.replacedert(replacedNode == root);
				root = newNode;
			} else {
				if (replacedNode.parent.left == replacedNode)
					replacedNode.parent.left = newNode;
				else
					replacedNode.parent.right = newNode;
			}
			if (newNode != null) {
				newNode.parent = replacedNode.parent;
			}
			replacedNode.parent = null;
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void RotateLeft(TextAnchorNode p)
		{
			// let q be p's right child
			TextAnchorNode q = p.right;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's right child to be q's left child
			p.right = q.left;
			if (p.right != null) p.right.parent = p;
			// set q's left child to be p
			q.left = p;
			p.parent = q;
			UpdateAugmentedData(p);
			UpdateAugmentedData(q);
		}

19 Source : TextAnchorTree.cs
with MIT License
from Abdesol

void RotateRight(TextAnchorNode p)
		{
			// let q be p's left child
			TextAnchorNode q = p.left;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's left child to be q's right child
			p.left = q.right;
			if (p.left != null) p.left.parent = p;
			// set q's right child to be p
			q.right = p;
			p.parent = q;
			UpdateAugmentedData(p);
			UpdateAugmentedData(q);
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void ReplaceText(OffsetChangeMapEntry change)
		{
			Debug.replacedert(change.RemovalLength > 0);
			int offset = change.Offset;
			foreach (TextSegment segment in FindOverlappingSegments(offset, change.RemovalLength)) {
				if (segment.StartOffset <= offset) {
					if (segment.EndOffset >= offset + change.RemovalLength) {
						// Replacement inside segment: adjust segment length
						segment.Length += change.InsertionLength - change.RemovalLength;
					} else {
						// Replacement starting inside segment and ending after segment end: set segment end to removal position
						//segment.EndOffset = offset;
						segment.Length = offset - segment.StartOffset;
					}
				} else {
					// Replacement starting in front of text segment and running into segment.
					// Keep segment.EndOffset constant and move segment.StartOffset to the end of the replacement
					int remainingLength = segment.EndOffset - (offset + change.RemovalLength);
					RemoveSegment(segment);
					segment.StartOffset = offset + change.RemovalLength;
					segment.Length = Math.Max(0, remainingLength);
					AddSegment(segment);
				}
			}
			// move start offsets of all segments > offset
			TextSegment node = FindFirstSegmentWithStartAfter(offset + 1);
			if (node != null) {
				Debug.replacedert(node.nodeLength >= change.RemovalLength);
				node.nodeLength += change.InsertionLength - change.RemovalLength;
				UpdateAugmentedData(node);
			}
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void AddSegment(TextSegment node)
		{
			int insertionOffset = node.StartOffset;
			node.distanceToMaxEnd = node.segmentLength;
			if (root == null) {
				root = node;
				node.totalNodeLength = node.nodeLength;
			} else if (insertionOffset >= root.totalNodeLength) {
				// append segment at end of tree
				node.nodeLength = node.totalNodeLength = insertionOffset - root.totalNodeLength;
				InsertAsRight(root.RightMost, node);
			} else {
				// insert in middle of tree
				TextSegment n = FindNode(ref insertionOffset);
				Debug.replacedert(insertionOffset < n.nodeLength);
				// split node segment 'n' at offset
				node.totalNodeLength = node.nodeLength = insertionOffset;
				n.nodeLength -= insertionOffset;
				InsertBefore(n, node);
			}
			node.ownerTree = this;
			count++;
			CheckProperties();
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

public T FindFirstSegmentWithStartAfter(int startOffset)
		{
			if (root == null)
				return null;
			if (startOffset <= 0)
				return (T)root.LeftMost;
			TextSegment s = FindNode(ref startOffset);
			// startOffset means that the previous segment is starting at the offset we were looking for
			while (startOffset == 0) {
				TextSegment p = (s == null) ? root.RightMost : s.Predecessor;
				// There must always be a predecessor: if we were looking for the first node, we would have already
				// returned it as root.LeftMost above.
				Debug.replacedert(p != null);
				startOffset += p.nodeLength;
				s = p;
			}
			return (T)s;
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void InsertAsLeft(TextSegment parentNode, TextSegment newNode)
		{
			Debug.replacedert(parentNode.left == null);
			parentNode.left = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAugmentedData(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void InsertAsRight(TextSegment parentNode, TextSegment newNode)
		{
			Debug.replacedert(parentNode.right == null);
			parentNode.right = newNode;
			newNode.parent = parentNode;
			newNode.color = RED;
			UpdateAugmentedData(parentNode);
			FixTreeOnInsert(newNode);
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void FixTreeOnInsert(TextSegment node)
		{
			Debug.replacedert(node != null);
			Debug.replacedert(node.color == RED);
			Debug.replacedert(node.left == null || node.left.color == BLACK);
			Debug.replacedert(node.right == null || node.right.color == BLACK);

			TextSegment parentNode = node.parent;
			if (parentNode == null) {
				// we inserted in the root -> the node must be black
				// since this is a root node, making the node black increments the number of black nodes
				// on all paths by one, so it is still the same for all paths.
				node.color = BLACK;
				return;
			}
			if (parentNode.color == BLACK) {
				// if the parent node where we inserted was black, our red node is placed correctly.
				// since we inserted a red node, the number of black nodes on each path is unchanged
				// -> the tree is still balanced
				return;
			}
			// parentNode is red, so there is a conflict here!

			// because the root is black, parentNode is not the root -> there is a grandparent node
			TextSegment grandparentNode = parentNode.parent;
			TextSegment uncleNode = Sibling(parentNode);
			if (uncleNode != null && uncleNode.color == RED) {
				parentNode.color = BLACK;
				uncleNode.color = BLACK;
				grandparentNode.color = RED;
				FixTreeOnInsert(grandparentNode);
				return;
			}
			// now we know: parent is red but uncle is black
			// First rotation:
			if (node == parentNode.right && parentNode == grandparentNode.left) {
				RotateLeft(parentNode);
				node = node.left;
			} else if (node == parentNode.left && parentNode == grandparentNode.right) {
				RotateRight(parentNode);
				node = node.right;
			}
			// because node might have changed, rereplacedign variables:
			parentNode = node.parent;
			grandparentNode = parentNode.parent;

			// Now recolor a bit:
			parentNode.color = BLACK;
			grandparentNode.color = RED;
			// Second rotation:
			if (node == parentNode.left && parentNode == grandparentNode.left) {
				RotateRight(grandparentNode);
			} else {
				// because of the first rotation, this is guaranteed:
				Debug.replacedert(node == parentNode.right && parentNode == grandparentNode.right);
				RotateLeft(grandparentNode);
			}
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void FixTreeOnDelete(TextSegment node, TextSegment parentNode)
		{
			Debug.replacedert(node == null || node.parent == parentNode);
			if (parentNode == null)
				return;

			// warning: node may be null
			TextSegment sibling = Sibling(node, parentNode);
			if (sibling.color == RED) {
				parentNode.color = RED;
				sibling.color = BLACK;
				if (node == parentNode.left) {
					RotateLeft(parentNode);
				} else {
					RotateRight(parentNode);
				}

				sibling = Sibling(node, parentNode); // update value of sibling after rotation
			}

			if (parentNode.color == BLACK
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				FixTreeOnDelete(parentNode, parentNode.parent);
				return;
			}

			if (parentNode.color == RED
				&& sibling.color == BLACK
				&& GetColor(sibling.left) == BLACK
				&& GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				parentNode.color = BLACK;
				return;
			}

			if (node == parentNode.left &&
				sibling.color == BLACK &&
				GetColor(sibling.left) == RED &&
				GetColor(sibling.right) == BLACK) {
				sibling.color = RED;
				sibling.left.color = BLACK;
				RotateRight(sibling);
			} else if (node == parentNode.right &&
					   sibling.color == BLACK &&
					   GetColor(sibling.right) == RED &&
					   GetColor(sibling.left) == BLACK) {
				sibling.color = RED;
				sibling.right.color = BLACK;
				RotateLeft(sibling);
			}
			sibling = Sibling(node, parentNode); // update value of sibling after rotation

			sibling.color = parentNode.color;
			parentNode.color = BLACK;
			if (node == parentNode.left) {
				if (sibling.right != null) {
					Debug.replacedert(sibling.right.color == RED);
					sibling.right.color = BLACK;
				}
				RotateLeft(parentNode);
			} else {
				if (sibling.left != null) {
					Debug.replacedert(sibling.left.color == RED);
					sibling.left.color = BLACK;
				}
				RotateRight(parentNode);
			}
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void ReplaceNode(TextSegment replacedNode, TextSegment newNode)
		{
			if (replacedNode.parent == null) {
				Debug.replacedert(replacedNode == root);
				root = newNode;
			} else {
				if (replacedNode.parent.left == replacedNode)
					replacedNode.parent.left = newNode;
				else
					replacedNode.parent.right = newNode;
			}
			if (newNode != null) {
				newNode.parent = replacedNode.parent;
			}
			replacedNode.parent = null;
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void RotateLeft(TextSegment p)
		{
			// let q be p's right child
			TextSegment q = p.right;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's right child to be q's left child
			p.right = q.left;
			if (p.right != null) p.right.parent = p;
			// set q's left child to be p
			q.left = p;
			p.parent = q;
			UpdateAugmentedData(p);
			UpdateAugmentedData(q);
		}

19 Source : TextSegmentCollection.cs
with MIT License
from Abdesol

void RotateRight(TextSegment p)
		{
			// let q be p's left child
			TextSegment q = p.left;
			Debug.replacedert(q != null);
			Debug.replacedert(q.parent == p);
			// set q to be the new root
			ReplaceNode(p, q);

			// set p's left child to be q's right child
			p.left = q.right;
			if (p.left != null) p.left.parent = p;
			// set q's right child to be p
			q.right = p;
			p.parent = q;
			UpdateAugmentedData(p);
			UpdateAugmentedData(q);
		}

See More Examples