On Wed, Mar 2, 2011 at 9:20 AM, Dave Cridland <[email protected]> wrote:
> The current <rtt/> tag syntax is really very complex, and at the same time
> very simgle purpose. Yet what it's doing is, fundamentally, quite generic -
> it's doing remote editing.
Correct. As an example, see how surprisingly simple the C# code is,
for real time editing.
Real time editing is just common string operations.
/// <summary>Decode Edit Codes on a string of text.
/// This follows the XMPP Real Time Text Specification, Version
0.91</summary>
/// <param name="oldText">Text to execute Edit Codes on.</param>
/// <param name="rtt">The rtt element containing edit codes</param>
/// <param name="cursorPos">Cursor position to update</param>
/// <param name="ignoreDelayCodes">Ignore delay codes
(simulation of typing inter-character delay)</param>
/// <returns></returns>
public static string DecodeRawRTT(string text, XmlElement rtt,
ref int cursorPos, ref int delay, bool ignoreDelayCodes)
{
int count;
int pos;
XmlNode editCode;
XmlAttribute p;
XmlAttribute n;
delay = 0;
// Verify rtt element is defined
Debug.Assert(rtt != null);
if (rtt == null) return text;
if (!rtt.HasChildNodes) return text;
// Loop to process the XML edit codes
while (rtt.HasChildNodes)
{
editCode = rtt.FirstChild;
rtt.RemoveChild(editCode);
try
{
// Get the "p" attribute (cursor position). p
always default to end of line if not provided.
p = editCode.Attributes["p"];
pos = (p == null) ? text.Length : int.Parse(p.Value);
if (pos > text.Length) pos = text.Length;
if (pos < 0) cursorPos = 0;
// Get the "n" attribute (count). n always default
to 1 if not provided.
n = editCode.Attributes["n"];
count = (n == null) ? 1 : int.Parse(n.Value);
if (count < 0) count = 0;
switch (editCode.Name)
{
//--------------------------------------------------------------------
case "t": // Insert edit code: <i
p="#">text</i>
cursorPos = pos;
text = text.Insert(cursorPos, editCode.InnerText);
cursorPos = cursorPos + editCode.InnerText.Length;
break;
//--------------------------------------------------------------------
case "e": // Backspace edit code: <e
p="#" n="#"/>
cursorPos = pos;
if (count > cursorPos) count = cursorPos;
text = text.Remove(cursorPos - count, count);
cursorPos -= count;
break;
//--------------------------------------------------------------------
case "d": // Delete edit code: <d
p="#" n="#"/>
cursorPos = pos;
text = text.Remove(cursorPos, count);
break;
//--------------------------------------------------------------------
case "r": // Reset edit code: <r/>
cursorPos = 0;
text = "";
break;
//--------------------------------------------------------------------
case "c": // Cursor Position edit code: <c p="#"/>
cursorPos = pos;
break;
//--------------------------------------------------------------------
case "w": // Delay code <w n="#"/>
if (!ignoreDelayCodes)
{
delay = count;
goto ExitLoop;
// We exit the loop so that the caller
can decide to use a timer for the delay code,
// and come back to this loop later to
finish remaining nodes that have not finished processing.
}
break;
}
}
catch (Exception ex)
{
Console.Write("EXCEPTION: DecodeRawRTT - " + ex.ToString());
}
}
ExitLoop:
return text;
}
}