Page 1 of 2

InsertString: #PB_String_InPlace would be useful

Posted: Sun Oct 02, 2011 6:52 pm
by netmaestro
ReplaceString has this option and today I find a need for it with InsertString, but it isn't available. I wrote my own:

Code: Select all

Procedure.s UpdateString(target$, insert$, pos)
  *target.Character = @target$ + (pos*SizeOf(character))
  *insert.Character = @insert$
  While *insert\c
    *target\c = *insert\c
    *target+SizeOf(Character)
    *insert+SizeOf(Character)
  Wend
  ProcedureReturn target$
EndProcedure

a$ = "Hello World!"
b$ = "Girls"

a$ = UpdateString(a$, b$, 6)

Debug a$
But I think having the core functionality would be superior to this.

[edit] Made code unicode-friendly before somebody yells at me :mrgreen:

Re: InsertString: #PB_String_InPlace would be useful

Posted: Sun Oct 02, 2011 7:43 pm
by ts-soft
netmaestro wrote:[edit] Made code unicode-friendly before somebody yells at me :mrgreen:
better is it :wink:

Re: InsertString: #PB_String_InPlace would be useful

Posted: Sun Oct 02, 2011 8:39 pm
by STARGĂ…TE
:?: that is no insert, it is an overwrite.

and your code don't work like ReplaceString with #PB_String_InPlace without return:

Code: Select all

Define Text.s = "Hallo World!"
ReplaceString(Text, "World", "Girls", #PB_String_InPlace)
Debug Text
what you want would be something like this:

Code: Select all

Procedure OverwriteString(*String, *NewString, Position.i)
	If MemoryStringLength(*NewString) + Position - 1 <= MemoryStringLength(*String) And Position > 0
		CopyMemory(*NewString, *String+(Position-1)*SizeOf(Character), MemoryStringLength(*NewString)*SizeOf(Character))
	EndIf
EndProcedure

Define Text.s = "Hello World!"
Define NewString.s = "Girls"
OverwriteString(@Text, @NewString, 7)
Debug Text

Re: InsertString: #PB_String_InPlace would be useful

Posted: Sun Oct 02, 2011 8:42 pm
by netmaestro
Destructive insert = overwrite, that's just semantics. I prefer it to return the result, which is why my code works as it does. If the team implements the flag, I expect it will work in place as ReplaceString does.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Sun Oct 02, 2011 11:29 pm
by netmaestro
what you want would be something like this:
Actually, what I'd want would be something like this:

http://www.purebasic.fr/english/viewtop ... 59#p362759

where the execution time is cut by two thirds.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 7:24 am
by Little John
netmaestro wrote:

Code: Select all

Procedure.s UpdateString(target$, insert$, pos)
  *target.Character = @target$ + (pos*SizeOf(character))
  *insert.Character = @insert$
  While *insert\c
    *target\c = *insert\c
    *target+SizeOf(Character)
    *insert+SizeOf(Character)
  Wend
  ProcedureReturn target$
EndProcedure

a$ = "Hello World!"
b$ = "Girls"

a$ = UpdateString(a$, b$, 6)

Debug a$
If insert$ is too long, or pos is too big, respectively, then accidentally the excess characters of insert$ will be written behind the end of target$. And additional check will prevent this:

Code: Select all

While *insert\c And *target\c
Regards, Little John

PS: I saw that you wrote an assembly procedure now, but since I'm not good in understanding assembly at 8 o'clock in the morning, I commented on this PB code. :-)

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 11:46 am
by freak
If you don't care about the length check on the target, you can just use PokeS() ;)

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 2:51 pm
by netmaestro
If you don't care about the length check on the target, you can just use PokeS()
That was my first thought, but I rejected it because PokeS() will write a terminating zero, effectively ending the string at the end of my insert, is that right? If not I went to a lot of trouble for nothing.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:28 pm
by luis
It does so (adding the zero).

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:30 pm
by Demivec
netmaestro wrote:
If you don't care about the length check on the target, you can just use PokeS()
That was my first thought, but I rejected it because PokeS() will write a terminating zero, effectively ending the string at the end of my insert, is that right? If not I went to a lot of trouble for nothing.
@netmaestro: PokeS() always writes a terminating zero. I favor an overwrite method also. Preferably one replaces characters without making the target string longer or shorter. Does your ideal solution include making the target string longer if placing the new characters near the end?

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:34 pm
by netmaestro
Does your ideal solution include making the target string longer if placing the new characters near the end?
No, because it's for updating an ISAM file with fixed-length records. The length of the target string never changes.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:41 pm
by Little John
netmaestro wrote:That was my first thought, but I rejected it because PokeS() will write a terminating zero, effectively ending the string at the end of my insert, is that right?
What about CopyMemory() or CopyMemoryString()?

Regards, Little John

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:50 pm
by Demivec
Little John wrote:
netmaestro wrote:That was my first thought, but I rejected it because PokeS() will write a terminating zero, effectively ending the string at the end of my insert, is that right?
What about CopyMemory() or CopyMemoryString()?
@Little John: CopyMemoryString() will always place a terminating zero also. CopyMemory() would be the only viable choice.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:52 pm
by netmaestro
CopyMemory is usable but the code you have to write to allow for unicode, while it works, looks ugly to me. CopyMemoryString also writes the terminating zero, so it's no use either. I just want the flag.

Re: InsertString: #PB_String_InPlace would be useful

Posted: Mon Oct 03, 2011 3:57 pm
by wilbert
It would make sense to have a flag for CopyMemoryString to not write the terminating zero.