quick string to tbank

BlitzMax Forums/BlitzMax Programming/quick string to tbank

PantsOn(Posted 2006) [#1]
Hi

Is the a quick way/command to convert a string to a bank, apart from creating a bank and then poking each character into the bank.

I've even tried i:tbank = tbank("hello") just incase ;-)

cheers
Rich


Dreamora(Posted 2006) [#2]
CreateStaticBank() and toCString() should do the trick.


PantsOn(Posted 2006) [#3]
cheers for the quick response.

not sure if createstaticbank would work in my situation as the string will be deleted but the bank wants to keep alive (i think)
I will double check later.

not sure what toCstring() does as it doesn't highlight as a command. I am running v1.22

cheers
Rich


Fabian.(Posted 2006) [#4]
String.ToCString calls MemAlloc with the string's length + 1 as parameter, then copies the string data to the returned memory block and returns it. You should use MemFree to free the block of memory returned by String.ToCString.

If the string stays valid all the time the TBank does, and if you don't write to the bank you could create a static bank just onto the string, otherwise you can create a bank a then copy all bytes to it, as you said in your first post.


AlexO(Posted 2006) [#5]
local bank:TBank = createbank(1)
local stream:TBankStream = createBankStream(bank)
writestring(stream, "hello world")
closestream(stream)

sure beats poking each character in individually.


tonyg(Posted 2006) [#6]
Could you use CreateBankStream and write to it as if it were a file?


AlexO(Posted 2006) [#7]
As far as I know, you can. I've used it extensively for writing out map files and then compressing the bank, then writing that to an actual file. It extends TStream so all functions work exactly the same. I created a bank of 1 byte in size but the writing automatically makes it bigger if it exceeds the size, so no need to worry about overflow.


Fabian.(Posted 2006) [#8]
writestring(stream, "hello world")
...
sure beats poking each character in individually.
I'd guess it's much faster to copy each single byte.


AlexO(Posted 2006) [#9]

I'd guess it's much faster to copy each byte.



I don't know which is faster. If I had to guess I'd say that pokeByte would be rather than writeString(). But most of the time when writing out a bank, speed isn't a crucial issue for me (the Tstream interface is plenty fast for my needs), and the stream writing method is much less error prone than pushing bits and bytes.


PantsOn(Posted 2006) [#10]
in this case speed is quite important.
I think CreateStaticBank works for me at the mo.

Cheers for all your help.

At least I have other methods to choose if CreateStaticBank doesn't work.


SculptureOfSoul(Posted 2006) [#11]
Not sure if this is faster, but here's another method. Unlike CreateStaticBank, you should still be able to resize this bank should the need arise.




PantsOn(Posted 2006) [#12]
memcopy works really well.
Millisecs of a test copying 50000 bytes of data, 1000 times.
pokebyte = 11895
memcopy = 111

not bad.

many thanks


SculptureOfSoul(Posted 2006) [#13]
Wow, that's a bigger difference than I expected.

I'm assuming the savings in your test are because of the magnitude of difference in the function calls.

50,000 per loop iteration versus one (well, okay, 3 - Memcopy(), BankBuf(), and length()).

Did you happen to test the CreateStaticBank() or any other methods? I'd be curious to see the results.


SculptureOfSoul(Posted 2006) [#14]
Oh, one more thing to note. String.length returns the length of the string - not the length + 1. Also, unless you explicitly add a /0 to the end of the string, it won't be there (the only reason I didn't use teststring.toCstring() is because that calls memalloc for the new string therefore introducing more overhead. I figured it would be faster, and easy enough, to just add the null character yourself.


Fabian.(Posted 2006) [#15]
Varptr teststring
I guess you don't want to have a pointer to a variable containing an object (which you're doing with Varptr), because such pointers are normally not useful. I think you wanted to get a pointer to the string data itself, so better use code like this:
Short Ptr Byte Ptr Object str + 2 'works, but is also not the proper solution
Also note that MemCopy's first parameter is the destination, so
MemCopy( Varptr teststring, BankBuf(testbank), teststring.length)
would surely cause a memory exception. I'd suggest you better to use String.ToCString which is much more safety.