[Lazarus] Indy 10.5.8 idHTTP client not working under Ubuntu due to iconv problem.

Joshua Lim joshua__lim at hotmail.com
Mon May 9 17:47:59 CEST 2011


Hi,

I'm having problems getting idHTTP (from indy 10.5.8) to work due to a 
bug that causes the follow function not to work under Ubuntu (or any 
Linux platform i guess).  It works under Windows however.  I've been 
corresponding with Remy Lebeau since 2 weeks ago on this issue, you can 
find a list of emails on the Indy Dev Yahoo Group - 
http://tech.groups.yahoo.com/group/Indy-Dev-Public/messages  (last post 
here - http://tech.groups.yahoo.com/group/Indy-Dev-Public/message/6445).

Has anyone of you encountered a similar problem?

Grateful for any comments.  Thanks.


function TIdMBCSEncoding.GetCharCount(Bytes: PByte; ByteCount: Integer): 
Integer;
{$IFDEF USE_ICONV}
var
  LChars: array[0..3] of WideChar;
  LBytesPtr, LCharsPtr: PAnsiChar;
  LByteCount, LCharsSize: size_t;
{$ENDIF}
begin
  {$IFDEF USE_ICONV}
  // RLebeau: iconv() does not allow for querying a pre-calculated 
character count
  // for the input like Microsoft does, so have to determine the max 
characters
  // by actually encoding the Ansi data to a real buffer.  We'll encode to a
  // small local buffer so we don't have to use a lot of memory...
  Result := 0;
  LBytesPtr := PAnsiChar(Bytes);
  LByteCount := ByteCount;
  while LByteCount > 0 do
  begin
    LCharsPtr := PAnsiChar(@LChars[0]);
    LCharsSize := SizeOf(LChars);
    //Kylix has an odd definition in iconv.  In Kylix, __outbytesleft is 
defined as a var
    //while in FreePascal's libc and our IdIconv units define it as a 
pSize_t
    if iconv(FToUTF16, @LBytesPtr, @LByteCount, @LCharsPtr, {$IFNDEF 
KYLIX}@{$ENDIF}LCharsSize) = size_t(-1) then
    begin
      Result := 0;
      Exit;
    end;
    // LBufferCount was decremented by the number of bytes stored in the 
output buffer
    Inc(Result, (SizeOf(LChars)-LCharsSize) div SizeOf(WideChar));
  end;
  {$ELSE}
    {$IFDEF WINDOWS}
  Result := MultiByteToWideChar(FCodePage, FMBToWCharFlags, 
PAnsiChar(Bytes), ByteCount, nil, 0);
    {$ELSE}
  ToDo('GetCharCount() method of TIdMBCSEncoding class is not 
implemented for this platform yet'); {do not localize}
    {$ENDIF}
  {$ENDIF}
end;                 



{$IFDEF USE_ICONV}
constructor TIdMBCSEncoding.Create(const CharSet: AnsiString);
const
  // RLebeau: iconv() does not provide a maximum character byte size like
  // Microsoft does, so have to determine the max bytes by manually encoding
  // an actual Unicode codepoint.  We'll encode the largest codepoint that
  // UTF-16 supports, $10FFFD, for now...
  cValue: array[0..1] of Word = ($DBFF, $DFFD);
begin
      writelog('sys', 'Main', #9 + '0' + #9 + '1TIdMBCSEncoding.Create');
        writelog('sys', 'Main', #9 + '0' + #9 + 'CharSet:'+CharSet);
  inherited Create;
  FCharSet := CharSet;
//  FToUTF16 := iconv_open(PAnsiChar(CharSet), 'UTF-16');    {do not 
localize}
//  FFromUTF16 := iconv_open('UTF-16', PAnsiChar(CharSet));  {do not 
localize}
FToUTF16 := iconv_open('UTF-16', PAnsiChar(CharSet)); {do not 
localize}   //amended by joshua on remy's instruction
FFromUTF16 := iconv_open(PAnsiChar(CharSet), 'UTF-16'); {do not 
localize}  //amended by joshua on remy's instruction

  if (FToUTF16 = iconv_t(-1)) or (FFromUTF16 = iconv_t(-1)) then begin
    if FToUTF16 <> iconv_t(-1) then begin
      iconv_close(FToUTF16);
      FToUTF16 := iconv_t(-1);
    end;
    if FFromUTF16 <> iconv_t(-1) then begin
      iconv_close(FFromUTF16);
      FFromUTF16 := iconv_t(-1);
    end;
    raise EIdException.CreateResFmt(@RSInvalidCharSet, [CharSet]);
  end;

  FMaxCharSize := GetByteCount(PWideChar(@cValue[0]), 2);
  FIsSingleByte := FMaxCharSize = 1;
end;        




More information about the Lazarus mailing list