|
@@ -27,7 +27,7 @@ implementation
|
|
|
|
|
|
{$linklib c}
|
|
{$linklib c}
|
|
|
|
|
|
-{$if not defined(linux) and not defined(solaris)} // Linux (and maybe glibc platforms in general), have iconv in glibc.
|
|
|
|
|
|
+{$if not defined(linux) and not defined(solaris) and not defined(android)} // Linux (and maybe glibc platforms in general), have iconv in glibc.
|
|
{$if defined(haiku)}
|
|
{$if defined(haiku)}
|
|
{$linklib textencoding}
|
|
{$linklib textencoding}
|
|
{$linklib locale}
|
|
{$linklib locale}
|
|
@@ -81,6 +81,15 @@ function wctomb(s: pchar; wc: wchar_t): size_t; cdecl; external clib name 'wctom
|
|
function mblen(const s: pchar; n: size_t): size_t; cdecl; external clib name 'mblen';
|
|
function mblen(const s: pchar; n: size_t): size_t; cdecl; external clib name 'mblen';
|
|
{$endif beos}
|
|
{$endif beos}
|
|
|
|
|
|
|
|
+const
|
|
|
|
+{ en_US.UTF-8 needs maximally 6 chars, UCS-4/UTF-32 needs 4 }
|
|
|
|
+{ -> 10 should be enough? Should actually use MB_CUR_MAX, but }
|
|
|
|
+{ that's a libc macro mapped to internal functions/variables }
|
|
|
|
+{ and thus not a stable external API on systems where libc }
|
|
|
|
+{ breaks backwards compatibility every now and then }
|
|
|
|
+ MB_CUR_MAX = 10;
|
|
|
|
+
|
|
|
|
+{$ifndef android} // There is no iconv on Android
|
|
|
|
|
|
const
|
|
const
|
|
{$if defined(linux) or defined(Android)}
|
|
{$if defined(linux) or defined(Android)}
|
|
@@ -140,13 +149,6 @@ const
|
|
{$endif AIX}
|
|
{$endif AIX}
|
|
{$endif FPC_LITTLE_ENDIAN}
|
|
{$endif FPC_LITTLE_ENDIAN}
|
|
|
|
|
|
-{ en_US.UTF-8 needs maximally 6 chars, UCS-4/UTF-32 needs 4 }
|
|
|
|
-{ -> 10 should be enough? Should actually use MB_CUR_MAX, but }
|
|
|
|
-{ that's a libc macro mapped to internal functions/variables }
|
|
|
|
-{ and thus not a stable external API on systems where libc }
|
|
|
|
-{ breaks backwards compatibility every now and then }
|
|
|
|
- MB_CUR_MAX = 10;
|
|
|
|
-
|
|
|
|
{ Requests for iconvctl }
|
|
{ Requests for iconvctl }
|
|
ICONV_TRIVIALP = 0; // int *argument
|
|
ICONV_TRIVIALP = 0; // int *argument
|
|
ICONV_GET_TRANSLITERATE = 1; // int *argument
|
|
ICONV_GET_TRANSLITERATE = 1; // int *argument
|
|
@@ -184,10 +186,7 @@ const
|
|
{$endif}
|
|
{$endif}
|
|
var
|
|
var
|
|
iconvctl:function(__cd:iconv_t; __request:cint; __argument:pointer):cint;cdecl;
|
|
iconvctl:function(__cd:iconv_t; __request:cint; __argument:pointer):cint;cdecl;
|
|
-
|
|
|
|
-procedure fpc_rangeerror; [external name 'FPC_RANGEERROR'];
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
threadvar
|
|
threadvar
|
|
iconv_ansi2wide,
|
|
iconv_ansi2wide,
|
|
iconv_wide2ansi : iconv_t;
|
|
iconv_wide2ansi : iconv_t;
|
|
@@ -199,7 +198,6 @@ threadvar
|
|
threads }
|
|
threads }
|
|
current_DefaultSystemCodePage: TSystemCodePage;
|
|
current_DefaultSystemCodePage: TSystemCodePage;
|
|
|
|
|
|
-
|
|
|
|
{$i winiconv.inc}
|
|
{$i winiconv.inc}
|
|
|
|
|
|
procedure InitThread;
|
|
procedure InitThread;
|
|
@@ -498,7 +496,60 @@ procedure Ansi2WideMove(source:pchar; cp:TSystemCodePage; var dest:widestring; l
|
|
if free_iconv then
|
|
if free_iconv then
|
|
iconv_close(use_iconv);
|
|
iconv_close(use_iconv);
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+{$else android}
|
|
|
|
|
|
|
|
+procedure Wide2AnsiMove(source:pwidechar; var dest:RawByteString; cp:TSystemCodePage; len:SizeInt);
|
|
|
|
+var
|
|
|
|
+ i : SizeInt;
|
|
|
|
+ hs : RawByteString;
|
|
|
|
+begin
|
|
|
|
+ dest:='';
|
|
|
|
+ if len = 0 then
|
|
|
|
+ exit;
|
|
|
|
+ if (cp = CP_UTF8) or (cp = CP_ACP) then
|
|
|
|
+ begin
|
|
|
|
+ // Only UTF-8 is supported for Android
|
|
|
|
+ SetLength(hs,len*3);
|
|
|
|
+ i:=UnicodeToUtf8(pchar(hs),length(hs)+1,source,len);
|
|
|
|
+ if i > 0 then
|
|
|
|
+ begin
|
|
|
|
+ SetLength(hs,i-1);
|
|
|
|
+ dest:=hs;
|
|
|
|
+ end;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ DefaultUnicode2AnsiMove(source,dest,DefaultSystemCodePage,len);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure Ansi2WideMove(source:pchar; cp:TSystemCodePage; var dest:widestring; len:SizeInt);
|
|
|
|
+var
|
|
|
|
+ i : SizeInt;
|
|
|
|
+ hs : UnicodeString;
|
|
|
|
+begin
|
|
|
|
+ // Only UTF-8 is supported for Android
|
|
|
|
+ dest:='';
|
|
|
|
+ if len = 0 then
|
|
|
|
+ exit;
|
|
|
|
+ if (cp = CP_UTF8) or (cp = CP_ACP) then
|
|
|
|
+ begin
|
|
|
|
+ SetLength(hs,len);
|
|
|
|
+ i:=Utf8ToUnicode(PUnicodeChar(hs),length(hs)+1,pchar(source),len);
|
|
|
|
+ if i>0 then
|
|
|
|
+ begin
|
|
|
|
+ SetLength(hs,i-1);
|
|
|
|
+ dest:=hs;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ dest:='';
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ DefaultAnsi2UnicodeMove(source,DefaultSystemCodePage,dest,len);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+{$endif android}
|
|
|
|
+
|
|
|
|
+procedure fpc_rangeerror; [external name 'FPC_RANGEERROR'];
|
|
|
|
|
|
function LowerWideString(const s : WideString) : WideString;
|
|
function LowerWideString(const s : WideString) : WideString;
|
|
var
|
|
var
|
|
@@ -971,9 +1022,14 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
|
|
function GetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
|
|
|
|
+{$ifndef android}
|
|
var
|
|
var
|
|
langinfo: pchar;
|
|
langinfo: pchar;
|
|
|
|
+{$endif android}
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef android}
|
|
|
|
+ Result := CP_UTF8; // Android has only UTF-8
|
|
|
|
+{$else}
|
|
langinfo:=nl_langinfo(CODESET);
|
|
langinfo:=nl_langinfo(CODESET);
|
|
{ there's a bug in the Mac OS X 10.5 libc (based on FreeBSD's)
|
|
{ there's a bug in the Mac OS X 10.5 libc (based on FreeBSD's)
|
|
that causes it to return an empty string of UTF-8 locales
|
|
that causes it to return an empty string of UTF-8 locales
|
|
@@ -983,6 +1039,7 @@ begin
|
|
(langinfo^=#0) then
|
|
(langinfo^=#0) then
|
|
langinfo:='UTF-8';
|
|
langinfo:='UTF-8';
|
|
Result := iconv2win(ansistring(langinfo));
|
|
Result := iconv2win(ansistring(langinfo));
|
|
|
|
+{$endif android}
|
|
end;
|
|
end;
|
|
|
|
|
|
{$ifdef FPC_HAS_CPSTRING}
|
|
{$ifdef FPC_HAS_CPSTRING}
|
|
@@ -1034,8 +1091,13 @@ begin
|
|
StrLICompAnsiStringProc:=@AnsiStrLIComp;
|
|
StrLICompAnsiStringProc:=@AnsiStrLIComp;
|
|
StrLowerAnsiStringProc:=@AnsiStrLower;
|
|
StrLowerAnsiStringProc:=@AnsiStrLower;
|
|
StrUpperAnsiStringProc:=@AnsiStrUpper;
|
|
StrUpperAnsiStringProc:=@AnsiStrUpper;
|
|
|
|
+{$ifdef android}
|
|
|
|
+ ThreadInitProc:=nil;
|
|
|
|
+ ThreadFiniProc:=nil;
|
|
|
|
+{$else}
|
|
ThreadInitProc:=@InitThread;
|
|
ThreadInitProc:=@InitThread;
|
|
ThreadFiniProc:=@FiniThread;
|
|
ThreadFiniProc:=@FiniThread;
|
|
|
|
+{$endif android}
|
|
{ Unicode }
|
|
{ Unicode }
|
|
Unicode2AnsiMoveProc:=@Wide2AnsiMove;
|
|
Unicode2AnsiMoveProc:=@Wide2AnsiMove;
|
|
Ansi2UnicodeMoveProc:=@Ansi2WideMove;
|
|
Ansi2UnicodeMoveProc:=@Ansi2WideMove;
|
|
@@ -1049,12 +1111,14 @@ begin
|
|
SetUnicodeStringManager(CWideStringManager);
|
|
SetUnicodeStringManager(CWideStringManager);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{$ifndef android}
|
|
var
|
|
var
|
|
iconvlib:TLibHandle;
|
|
iconvlib:TLibHandle;
|
|
|
|
+{$endif android}
|
|
|
|
|
|
initialization
|
|
initialization
|
|
SetCWideStringManager;
|
|
SetCWideStringManager;
|
|
-
|
|
|
|
|
|
+{$ifndef android}
|
|
{ you have to call setlocale(LC_ALL,'') to initialise the langinfo stuff }
|
|
{ you have to call setlocale(LC_ALL,'') to initialise the langinfo stuff }
|
|
{ with the information from the environment variables according to POSIX }
|
|
{ with the information from the environment variables according to POSIX }
|
|
{ (some OSes do this automatically, but e.g. Darwin and Solaris don't) }
|
|
{ (some OSes do this automatically, but e.g. Darwin and Solaris don't) }
|
|
@@ -1064,6 +1128,7 @@ initialization
|
|
iconvlib:=LoadLibrary(libprefix+libiconvname+'.'+SharedSuffix);
|
|
iconvlib:=LoadLibrary(libprefix+libiconvname+'.'+SharedSuffix);
|
|
if iconvlib<>0 then
|
|
if iconvlib<>0 then
|
|
pointer(iconvctl):=GetProcAddress(iconvlib,iconvctlname);
|
|
pointer(iconvctl):=GetProcAddress(iconvlib,iconvctlname);
|
|
|
|
+{$endif android}
|
|
|
|
|
|
{ set the DefaultSystemCodePage }
|
|
{ set the DefaultSystemCodePage }
|
|
DefaultSystemCodePage:=GetStandardCodePage(scpAnsi);
|
|
DefaultSystemCodePage:=GetStandardCodePage(scpAnsi);
|
|
@@ -1072,12 +1137,16 @@ initialization
|
|
SetStdIOCodePages;
|
|
SetStdIOCodePages;
|
|
{$endif FPC_HAS_CPSTRING}
|
|
{$endif FPC_HAS_CPSTRING}
|
|
|
|
|
|
|
|
+{$ifndef android}
|
|
{ init conversion tables for main program }
|
|
{ init conversion tables for main program }
|
|
InitThread;
|
|
InitThread;
|
|
|
|
+{$endif android}
|
|
finalization
|
|
finalization
|
|
|
|
+{$ifndef android}
|
|
{ fini conversion tables for main program }
|
|
{ fini conversion tables for main program }
|
|
FiniThread;
|
|
FiniThread;
|
|
{ unload iconv library }
|
|
{ unload iconv library }
|
|
if iconvlib<>0 then
|
|
if iconvlib<>0 then
|
|
FreeLibrary(iconvlib);
|
|
FreeLibrary(iconvlib);
|
|
|
|
+{$endif android}
|
|
end.
|
|
end.
|