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