StreamPos and WriteInt
BlitzMax Forums/BlitzMax Beginners Area/StreamPos and WriteInt
| ||
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? |
| ||
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() |
| ||
huh... I get 4 with that test code too... time to dig deeper I guess |
| ||
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()? |
| ||
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.. |
| ||
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... |
| ||
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... |
| ||
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. |
| ||
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 |