No mapping for the Unicode character exists in the target multi-byte code page ? (Delphi XE6)

delphi, delphi-xe6

Solution

I would say that you need to throw this code away and start again. Like all compression algorithms that I have ever encountered, zlib does not operate on text. It operates on byte arrays. Back in the days when a Delphi string used 8 bit encoding, people played fast and loose with such strings, treating them as if they were byte arrays. And ever since those days, the misconception that compression can operate on strings has endured.

You need to pick an encoding to use to convert text into byte arrays. A good choice would be UTF-8. And then if you want to represent the compressed data as text, you need to use an encoding like base64.

The compression process is as follows:

- Encode the text as a UTF-8 byte array.

- Compress with zlib.

- Encode the compressed byte array with base64.

In the opposite direction you would:

- Decode the base64 text to a compressed byte array.

- Decompress this with zlib.

- Decode the UTF-8 encoded byte array to text.

To encode/decode UTF-8 you use `TEncoding.UTF8`. The `GetBytes` and `GetString` methods are what you need. And for base64 encode/decode you would probably be best advised to use the Indy library since you are already using it.

According to the comments, you've got as far as decompressing to a UTF-8 encoded byte array. In which case the final step is to write:

text := TEncoding.UTF8.GetString(utf8byteArray);

Problem

The following code works on Win32, anyway it is trowing exception if run on Android or iOS. The exception is : "No mapping for the Unicode character exists in the target multi-byte code page" ``` function Form1.ZDecompressString(aText: String): String; var strInput, strOutput : TStringStream; Unzipper : TZDecompressionStream; begin Result := ''; strInput := TStringStream.Create( aText ); strOutput := TStringStream.Create; try Unzipper := TZDecompressionStream.Create( strInput ); try strOutput.CopyFrom( Unzipper, Unzipper.Size ); finally Unzipper.Free; end; Result := strOutput.DataString; finally strInput.Free; strOutput.Free; end; end; procedure Form1.getUsers; var XMLRqst : String; XMLResponse : TStringStream; XMLRequest : TStringStream; idHTTP : TIdHTTP; s : String; begin XMLRqst := UTF8ToString( '<root company="belvew"/>' ); XMLRequest := TStringStream.Create( XMLRqst, TEncoding.UTF8 ); XMLResponse := TStringStream.Create( '' ); try try idHTTP := TIdHTTP.Create( Self ); idHTTP.CookieManager := idCookieManager; idHTTP.ReadTimeout := 60000;{ IdTimeoutInfinite; } idHTTP.ConnectTimeout := 60000; idHTTP.HandleRedirects := True; XMLResponse.Position := 0; XMLRequest.Position := 0; idHTTP.Post( 'http://localhost/API/getUsers.aspx', XMLRequest, XMLResponse ); idHTTP.Disconnect; unique_id := ZDecompressString( XMLResponse.DataString ); XMLRequest.Free; XMLResponse.Free; except on E : Exception do begin ShowMessage( 'exception : '#13 + E.Message ); end; end; finally idHTTP.Free; end; end; procedure Form1.onCreate( Sender : TObject ); begin getUsers; end; ``` - Why the code does not work under Android or iOS ?

Original source