stream - Delphi ReadStreamStr, WriteStreamStr implementation check -
i'm using these implementations found on post on so. when reading string in sometimes, readstreamstr puts in characters string. i'm posting implementation here have checked , approved, , if there fault, corrected.
function readstreamstr(stream: tstream): string; { returns string stream } var lenstr: integer; begin result := ''; { length of string } lenstr := readstreamint(stream); { set string memory } setlength(result, lenstr); { read characters } stream.read(result[1], lenstr); end; procedure writestreamstr(stream: tstream; str: string); { writes string stream } var strlen: integer; begin { length of string } strlen := bytelength(str); { write length of string } writestreamint(stream, strlen); if strlen > 0 { write characters } stream.write(str[1], strlen); end; thank you.
the integer written in front of characters number of bytes, readstreamstr() interpreting number of characters instead. in d2007 , earlier, string ansi, works fine. in d2009 , later, string unicode, not work. assuming using d2009+, means readstreamstr() allocating twice memory should be, filling in half of it, leave other half uninitialized. not taking sizeof(char) account when reading (but bytelength() when writing).
try this:
function readstreamstr(stream: tstream): string; { returns string stream } var lenstr: integer; leftover: array[0..sizeof(char)-1] of byte; begin result := ''; { length of string } lenstr := readstreamint(stream); { set string memory } setlength(result, lenstr div sizeof(char)); if lenstr > 0 begin { read characters } stream.readbuffer(result[1], lenstr); { in case length not } lenstr := lenstr mod sizeof(char); if lenstr > 0 stream.readbuffer(leftover[0], lenstr); end; end; alternatively:
function readstreamstr(stream: tstream): string; { returns string stream } var lenstr: integer; buf: tbytes; begin result := ''; { length of string } lenstr := readstreamint(stream); if lenstr > 0 begin { memory } setlength(buf, lenstr); { read characters } stream.readbuffer(buf[1], lenstr); { convert string } result := tencoding.unicode.getstring(buf); end; end; either way, keep in mind if stream data written in d2007 or earlier, read in d2009 or later, code not work as-is. have go tbytes approach, use more appropriate tencoding decoding, such tencoding.default.
personally, have opted instead read/write strings utf-8 beginning:
function readstreamstr(stream: tstream): utf8string; { returns string stream } var lenstr: integer; begin result := ''; { length of string } lenstr := readstreamint(stream); { set string memory } setlength(result, lenstr); if lenstr > 0 { read characters } stream.read(pansichar(result)^, lenstr); end; procedure writestreamstr(stream: tstream; const str: utf8tring); { writes string stream } var strlen: integer; begin { length of string } strlen := length(str); { write length of string } writestreamint(stream, strlen); if strlen > 0 { write characters } stream.write(pansichar(str)^, strlen); end;
Comments
Post a Comment