123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2012 by Jonas Maebe
- Helper routines for cwstring AIX
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- function Ansi2AnsiMove(source:pchar; fromcp:TSystemCodePage; const tocp: pchar; out dest:rawbytestring; len:SizeInt): boolean;
- var
- outlength,
- outoffset,
- outleft : size_t;
- use_iconv: iconv_t;
- srcpos,
- destpos: pchar;
- mynil : pchar;
- my0 : size_t;
- err: cint;
- begin
- use_iconv:=open_iconv_for_cps(fromcp,tocp,true);
- { unsupported encoding -> default move }
- if use_iconv=iconv_t(-1) then
- exit(false);
- mynil:=nil;
- my0:=0;
- // extra space
- outlength:=len;
- setlength(dest,outlength);
- srcpos:=source;
- destpos:=pchar(dest);
- outleft:=outlength;
- while iconv(use_iconv,@srcpos,psize(@len),@destpos,@outleft)=size_t(-1) do
- begin
- err:=fpgetCerrno;
- case err of
- ESysEINVAL,
- ESysEILSEQ:
- begin
- { skip and set to '?' }
- inc(srcpos);
- dec(len);
- pchar(destpos)^:='?';
- inc(destpos,2);
- dec(outleft,2);
- { reset }
- iconv(use_iconv,@mynil,@my0,@mynil,@my0);
- if err=ESysEINVAL then
- break;
- end;
- ESysE2BIG:
- begin
- outoffset:=destpos-pchar(dest);
- { extend }
- setlength(dest,outlength+len);
- inc(outleft,len);
- inc(outlength,len);
- { string could have been moved }
- destpos:=pchar(dest)+outoffset;
- end;
- else
- runerror(231);
- end;
- end;
- // truncate string
- setlength(dest,length(dest)-outleft);
- iconv_close(use_iconv);
- result:=true;
- end;
- function handle_aix_intermediate(source: pchar; sourcecp: TSystemCodePage; out newcp: TSystemCodePage; out str: rawbytestring; len: SizeInt): boolean;
- begin
- result:=false;
- { for some reason, IBM's iconv only supports converting cp866 to/from
- ISO8859-5. This conversion is lossy, but it's better than completely
- failing. At least it keeps the cyrillic characters intact }
- case sourcecp of
- 866:
- begin
- handle_aix_intermediate:=Ansi2AnsiMove(source,sourcecp,'ISO8859-5',str, len);
- if handle_aix_intermediate then
- begin
- newcp:=28595;
- setcodepage(str,newcp,false);
- end;
- end;
- 28595:
- begin
- handle_aix_intermediate:=Ansi2AnsiMove(source,sourcecp,'IBM-866',str, len);
- if handle_aix_intermediate then
- begin
- newcp:=866;
- setcodepage(str,newcp,false);
- end;
- end;
- end;
- end;
|