blob: 796bf5926955ce7eb421116f44ed9516b495f14d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
{
This file is part of the Free Component Library
libiconv-based XML decoder (Windows version).
Binds to the native (not Cygwin or Mingw) build of libiconv.
Copyright (c) 2009 by Sergei Gorelkin, sergei_gorelkin@mail.ru
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.
**********************************************************************}
unit xmliconv_windows;
interface
implementation
uses
xmlread;
type
iconv_t = Pointer;
const
iconvlib = 'iconv.dll';
function iconv_open(ToCode, FromCode: PChar): iconv_t; cdecl; external iconvlib name 'libiconv_open';
function iconv(__cd: iconv_t; __inbuf: PPChar; var __inbytesleft: size_t; __outbuf:ppchar; var __outbytesleft: size_t): size_t; cdecl; external iconvlib name 'libiconv';
function iconv_close(cd: iconv_t): Integer; cdecl; external iconvlib name 'libiconv_close';
function errno_location: PInteger; cdecl; external 'msvcrt.dll' name '_errno';
function Iconv_Decode(Context: Pointer; InBuf: PChar; var InCnt: Cardinal; OutBuf: PWideChar; var OutCnt: Cardinal): Integer; stdcall;
var
OutChars: size_t;
InChars : size_t;
begin
OutChars := OutCnt * sizeof(WideChar);
InChars:=InCnt;
Result := iconv(Context, @InBuf, InChars, @OutBuf, OutChars);
InCnt:=InChars;
OutCnt := OutChars div sizeof(WideChar);
if Result = -1 then
begin
case errno_location^ of
// when iconv reports insufficient input or output space, still return
// a positive number of converted chars
7, 22: Result := OutCnt - (OutChars div sizeof(WideChar));
else
Result := -errno_location^;
end;
end;
end;
procedure Iconv_Cleanup(Context: Pointer); stdcall;
begin
iconv_close(Context);
end;
function GetIconvDecoder(const AEncoding: string; out Decoder: TDecoder): Boolean; stdcall;
var
f: iconv_t;
begin
f := iconv_open('UCS-2-INTERNAL', PChar(AEncoding));
if f <> Pointer(-1) then
begin
Decoder.Context := f;
Decoder.Decode := @Iconv_Decode;
Decoder.Cleanup := @Iconv_Cleanup;
Result := True;
end
else
Result := False;
end;
initialization
RegisterDecoder(@GetIconvDecoder);
end.
|