Jump to content
Sign in to follow this  
MarkShark

Moving string to buffer while encoding.

Recommended Posts

Hi all!  I'm doing the following to convert a string to utf8 and then to move it into a memory location (it happens to be a globalallocbuffer for a clipboard format, but I don't' think that matters to my question.)   It works well, but I was wondering if it's possible to do it without the intermediate byte array.  Delphi 11 btw.  Any thoughts appreciated.

 

        Buf := TEncoding.UTF8.GetBytes(AString);
        Move(Buf, PtrData^, Length(Buf));

 

Share this post


Link to post

TEncoding has a GetBytes() method that accepts PWideChar and PByte. Unfortunately it is "strict protected". So you would have to derive a class from TUTF8Encoding and then use that. Alternatively you can use the LocaleCharsFromUnicode system function.

 

  ByteCount := TEncoding.UTF8.GetByteCount(S);
  Buf := GlobalAllocPtr(0, ByteCount);
  if ByteCount > 0 then
    LocaleCharsFromUnicode(CP_UTF8, 0, PChar(S), Length(S), MarshaledAString(Buf), ByteCount, nil, nil);
  GlobalFreePtr(Buf);

 

Example for a derived TUTF8Encoding class:

type
  TUTF8EncodingEx = class(TUTF8Encoding)
  public // make the PWideChar/PByte methods public
    function GetByteCount(Chars: PWideChar; CharCount: Integer): Integer; override;
    function GetBytes(Chars: PWideChar; CharCount: Integer; Bytes: PByte; ByteCount: Integer): Integer; override;
    function GetCharCount(Bytes: PByte; ByteCount: Integer): Integer; override;
    function GetChars(Bytes: PByte; ByteCount: Integer; Chars: PWideChar; CharCount: Integer): Integer; override;
  end;

{ TUTF8EncodingEx }

function TUTF8EncodingEx.GetByteCount(Chars: PWideChar; CharCount: Integer): Integer;
begin
  Result := inherited GetByteCount(Chars, CharCount);
end;

function TUTF8EncodingEx.GetBytes(Chars: PWideChar; CharCount: Integer; Bytes: PByte; ByteCount: Integer): Integer;
begin
  Result := inherited GetBytes(Chars, CharCount, Bytes, ByteCount);
end;

function TUTF8EncodingEx.GetCharCount(Bytes: PByte; ByteCount: Integer): Integer;
begin
  Result := inherited GetCharCount(Bytes, ByteCount);
end;

function TUTF8EncodingEx.GetChars(Bytes: PByte; ByteCount: Integer; Chars: PWideChar; CharCount: Integer): Integer;
begin
  Result := inherited GetChars(Bytes, ByteCount, Chars, CharCount);
end;



begin
  ByteCount := TEncoding.UTF8.GetByteCount(S);
  Buf := GlobalAllocPtr(0, ByteCount);
  if ByteCount > 0 then
    TUTF8EncodingEx(TEncoding.UTF8).GetBytes(PChar(S), Length(S), Buf, ByteCount);
  GlobalFreePtr(Buf);
end;

 

  • Like 1
  • Thanks 1

Share this post


Link to post

Wow, great answer!  I used the LocaleCharsFromUnicode suggestion as I ended up needing to support some other codepages.  Works great!  Much appreciated!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×