1{ 2 This file is part of the Free Pascal run time library. 3 Copyright (c) 2012 by Jonas Maebe 4 5 Helper routines for cwstring AIX 6 7 See the file COPYING.FPC, included in this distribution, 8 for details about the copyright. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 **********************************************************************} 15 16function Ansi2AnsiMove(source:pchar; fromcp:TSystemCodePage; const tocp: pchar; out dest:rawbytestring; len:SizeInt): boolean; 17 var 18 outlength, 19 outoffset, 20 outleft : size_t; 21 use_iconv: iconv_t; 22 srcpos, 23 destpos: pchar; 24 mynil : pchar; 25 my0 : size_t; 26 err: cint; 27 begin 28 use_iconv:=open_iconv_for_cps(fromcp,tocp,true); 29 { unsupported encoding -> default move } 30 if use_iconv=iconv_t(-1) then 31 exit(false); 32 mynil:=nil; 33 my0:=0; 34 // extra space 35 outlength:=len; 36 setlength(dest,outlength); 37 srcpos:=source; 38 destpos:=pchar(dest); 39 outleft:=outlength; 40 while iconv(use_iconv,@srcpos,psize(@len),@destpos,@outleft)=size_t(-1) do 41 begin 42 err:=fpgetCerrno; 43 case err of 44 ESysEINVAL, 45 ESysEILSEQ: 46 begin 47 { skip and set to '?' } 48 inc(srcpos); 49 dec(len); 50 pchar(destpos)^:='?'; 51 inc(destpos,2); 52 dec(outleft,2); 53 { reset } 54 iconv(use_iconv,@mynil,@my0,@mynil,@my0); 55 if err=ESysEINVAL then 56 break; 57 end; 58 ESysE2BIG: 59 begin 60 outoffset:=destpos-pchar(dest); 61 { extend } 62 setlength(dest,outlength+len); 63 inc(outleft,len); 64 inc(outlength,len); 65 { string could have been moved } 66 destpos:=pchar(dest)+outoffset; 67 end; 68 else 69 runerror(231); 70 end; 71 end; 72 // truncate string 73 setlength(dest,length(dest)-outleft); 74 iconv_close(use_iconv); 75 result:=true; 76 end; 77 78 79function handle_aix_intermediate(source: pchar; sourcecp: TSystemCodePage; out newcp: TSystemCodePage; out str: rawbytestring; len: SizeInt): boolean; 80 begin 81 result:=false; 82 { for some reason, IBM's iconv only supports converting cp866 to/from 83 ISO8859-5. This conversion is lossy, but it's better than completely 84 failing. At least it keeps the cyrillic characters intact } 85 case sourcecp of 86 866: 87 begin 88 handle_aix_intermediate:=Ansi2AnsiMove(source,sourcecp,'ISO8859-5',str, len); 89 if handle_aix_intermediate then 90 begin 91 newcp:=28595; 92 setcodepage(str,newcp,false); 93 end; 94 end; 95 28595: 96 begin 97 handle_aix_intermediate:=Ansi2AnsiMove(source,sourcecp,'IBM-866',str, len); 98 if handle_aix_intermediate then 99 begin 100 newcp:=866; 101 setcodepage(str,newcp,false); 102 end; 103 end; 104 end; 105 end; 106 107