StreamPos and WriteInt

BlitzMax Forums/BlitzMax Beginners Area/StreamPos and WriteInt

ima747(Posted 2010) [#1]
an int should be 4 bytes since it's 32 bit...

If I get StreamPos() on a stream, then WriteInt() and get the streamPos() again the difference between the 2 positions is 3, not 4... why is that?


GfK(Posted 2010) [#2]
Dunno.

I get 0 then 4 with this test code:
Local file:TStream = WriteFile("out.txt")
Local i:Int = 16384
Print StreamPos(file)
WriteInt(file,i)
Print StreamPos(file)
file.close()



ima747(Posted 2010) [#3]
huh... I get 4 with that test code too... time to dig deeper I guess


ima747(Posted 2010) [#4]
in my program after I write a bunch of other stuff to the file, I get

pos 519
WriteInt()
pos 522

I'm writing a bunch of ints and WriteLine's ahead of this particular writeint, but that shouldn't matter... an int should bump the offset by 4...

[UPDATE]
I found it... I had UTF8 encoding on the stream to handle the text but when you writeInt(streamn, 0) it only writes 3 bytes... if you WriteInt(stream, 100) it writes 4... removing the UTF8 gives proper handling...

So, followup, is there a way to do UTF8 WriteLine() and still be able to do byte accurate WriteInt()?


Brucey(Posted 2010) [#5]
Max's UTF8 conversion code is 3-bytes maximum, I'm afraid. Something to do with Mark not wanting to deal with characters that would be bigger than the 2-byte BlitzMax character size (ie. > 65535).

You could always code your own custom stream which will expect characters as UTF-8 and other stuff as is..


ima747(Posted 2010) [#6]
Sounds like the way to go... how would I go about reading/writing a string in UTF8, or even just raw data would be fine (text storage size is not a big concern for me)... I assume there's some way to put a string into a bank and then I can read/write that...


ima747(Posted 2010) [#7]
http://www.blitzbasic.com/Community/posts.php?topic=76246#852423 is a starting point...

Is it possible to get a UTF8 bank stream?

Seems like there should just be a way to get a string in an encoding in a bank, or byte array or whatever... getting a CString doesn't seem to do it... atleast I can't get it back out... again probably because I can't control the encoding...

Getting a WString from a string works better, but it isn't proper UTF8 so I'm not really comfortable with it... there's still a chance for data loss since it's 16 bit characters instead of 32...


ima747(Posted 2010) [#8]
At the moment the only path I see for getting a UTF8 encoded string into a standard file stream is to write it to a UTF8 encoded stream (another file... I can't figure out how to get a UTF8 encoded anything else...) then read it back into a bank, then write the bank to the main stream... seems wasteful and slow to use a swap file to convert text encoding so I know I'm getting lost.


ima747(Posted 2010) [#9]
Well for now I'm going with 2 byte characters which seems good enough for now... I'm sure one of my testers who loves to mash option while naming things will make this blow up in my face... And I'm sure there's a better way to do this as well...

Seems like WriteString and WriteLine could have an optional encoding field added that would default to ASCII to preserve current function...

' WString.bmx

SuperStrict

Function WriteWString(stream:TStream, text:String)
	Local buff:Short Ptr = text.ToWString()
	WriteInt(stream, Len(text))
	For Local onPos:Int = 0 Until Len(text)
		WriteShort(stream, buff[onPos])
	Next
	MemFree(buff)
End Function

Function ReadWString:String(stream:TStream)
	Local length:Int = ReadInt(stream)
	Local buff:Short[length + 1]
	For Local onPos:Int = 0 Until length
		buff[onPos] = ReadShort(stream)
	Next
	Local text:String = String.FromWString(buff)
	Return text
End Function