Skip to content

Commit

Permalink
add Replace method
Browse files Browse the repository at this point in the history
  • Loading branch information
MeilCli committed Apr 2, 2017
1 parent fcdecf9 commit feae351
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
83 changes: 83 additions & 0 deletions Source/Plugin.CrossFormattedText.Abstractions/FormattedString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,89 @@ public FormattedString RemoveSpan(int startIndex,int count) {
return new FormattedString(nAr);
}

public FormattedString Replace(char oldChar,char newChar) {
return Replace(oldChar,newChar,null);
}

public FormattedString Replace(char oldChar,char newChar,Span newSpan) {
CharSpan[] sAr = ToCharSpanArray();

for(int i = 0;i < sAr.Length;i++) {
if(sAr[i].Character == oldChar) {
sAr[i] = new CharSpan(newChar,newSpan ?? sAr[i].Span);
}
}

return MergeCharSpan(sAr);
}

public FormattedString Replace(string oldValue,string newValue) {
return Replace(oldValue,newValue,SpanOperand.Right);
}

public FormattedString Replace(string oldValue,string newValue,SpanOperand operand) {
return Replace(oldValue,newValue,null,operand);
}

public FormattedString Replace(string oldValue,Span newSpan) {
return Replace(oldValue,newSpan.Text,newSpan);
}

public FormattedString Replace(string oldValue,string newValue,Span newSpan) {
return Replace(oldValue,newValue,newSpan,SpanOperand.Right);
}

internal FormattedString Replace(string oldValue,string newValue,Span newSpan,SpanOperand operand) {
if(oldValue == null) {
throw new ArgumentNullException(nameof(oldValue));
}
if(oldValue.Length == 0) {
throw new ArgumentException(nameof(oldValue));
}
if(newValue == null) {
newValue = string.Empty;
}

int replaceCount = 0;
int offset = 0;
while((offset = Text.IndexOf(oldValue,offset)) != -1) {
replaceCount++;
offset += oldValue.Length;
}

CharSpan[] sAr = ToCharSpanArray();
CharSpan[] nAr = new CharSpan[sAr.Length + (newValue.Length - oldValue.Length) * replaceCount];

int oldIndex = 0;
int newIndex = 0;
for(int i = 0;i < replaceCount;i++) {
int index = Text.IndexOf(oldValue,oldIndex);
int copySize = index - oldIndex;

Array.Copy(sAr,oldIndex,nAr,newIndex,copySize);

oldIndex += copySize + oldValue.Length;
newIndex += copySize;

if(newSpan == null && operand == SpanOperand.Left) {
newSpan = sAr[index].Span;
}else if(newSpan==null) {
newSpan = sAr[index + oldValue.Length - 1].Span;
}

newSpan = newSpan.Clone();
newSpan.Text = newValue;
CharSpan[] rAr = newSpan.ToArray();

Array.Copy(rAr,0,nAr,newIndex,rAr.Length);
newIndex += rAr.Length;
}

Array.Copy(sAr,oldIndex,nAr,newIndex,TextLength - oldIndex);

return MergeCharSpan(nAr);
}

public bool AnySpanReferenceEquals(FormattedString formattedString) {
foreach(var span1 in spans) {
foreach(var span2 in formattedString.spans) {
Expand Down
17 changes: 17 additions & 0 deletions Test/Test.CrossFormattedText.Unit/FormattedStringTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,22 @@ public void RemoveSpanTest() {
Assert.AreEqual(newText1.AnySpanReferenceEquals(text),false);
Assert.AreEqual(newText2.AnySpanReferenceEquals(text),false);
}

[TestMethod]
public void ReplaceTest() {
var newText1 = text.Replace('i','1');
Assert.AreEqual(newText1.Text,text.Text.Replace('i','1'));
Assert.AreEqual(newText1.AnySpanReferenceEquals(text),false);

var newText2 = text.Replace("t","tt");
var newText3 = text.Replace("1",(string)null);
var newText4 = text.Replace("t",(string)null);
Assert.AreEqual(newText2.Text,text.Text.Replace("t","tt"));
Assert.AreEqual(newText2.AnySpanReferenceEquals(text),false);
Assert.AreEqual(newText3.Text,text.Text);
Assert.AreEqual(newText3.AnySpanReferenceEquals(text),false);
Assert.AreEqual(newText4.Text,text.Text.Replace("t",null));
Assert.AreEqual(newText4.AnySpanReferenceEquals(text),false);
}
}
}

0 comments on commit feae351

Please sign in to comment.