I haven't read all the code, but
without force to allocate new RAM anytime.
You can't completely avoid that.
Strings are refcounted, and "copy on write"
That means:
var a,b: AnsiString; // string in {$H+}
begin
a := randomString();
b := a;
There is only
ONE copy of the text. a and b both point to the same memory. (a and b both have a refcount of 2 / maybe even more, as their may be temp refcounts)
If you do, after the above
then that triggers "copy on write" => you write to the string, and it is currently sharing its memory, so you need a new copy for "b". This makes sure that a is not modified.
But if instead you do
b := a;
p := pchar(b); // or any pointer type
p[0] := 'a';
Then that does
NOT trigger copy on write.
This will
modify both (a and b).
And that is not what you want.
Before you modify a string, using any kind of pointer like that, you must call UniqueString
b := a;
UniqueString(b); // before taking the pointer, because this may change the mem location, and any pointer you already have may be wrong after this.
p := pchar(b); // or any pointer type
p[0] := 'a';
So what you want to do is.
- using a pointer search for the first char that needs to be replaced
- if there is nothing to be replaced, then exit
- compute the distance/offset of that pointer from the state (index of the first char that needs to be replaced)
- call UniqueString // if the string may grow, then use SetLength instead SetLength also always makes the string unique
- take a new pointer to the string => then add the index, so you are again at the first char to be replaced
- do the replacing
I am pretty sure some such replace function already exists. StringReplace or TextReplace or similar.
You need to find the one that does not deal with upper/lower casing...
Also, why PByte and not PChar?
MyPchar := PChar(MyString);