xmliconv.pas 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. {
  2. This file is part of the Free Component Library
  3. libiconv-based XML decoder.
  4. Copyright (c) 2009 by Sergei Gorelkin, [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit xmliconv;
  12. interface
  13. implementation
  14. uses
  15. xmlread, iconvenc, unixtype, baseunix, initc;
  16. const
  17. {$ifdef FPC_LITTLE_ENDIAN}
  18. utf16_encoding = 'UTF-16LE';
  19. {$else FPC_LITTLE_ENDIAN}
  20. utf16_encoding = 'UTF-16BE';
  21. {$endif FPC_LITTLE_ENDIAN}
  22. function Iconv_Decode(Context: Pointer; InBuf: PChar; var InCnt: Cardinal; OutBuf: PWideChar; var OutCnt: Cardinal): Integer; stdcall;
  23. var
  24. OutChars: size_t;
  25. InChars: size_t;
  26. begin
  27. OutChars := OutCnt * sizeof(WideChar);
  28. InChars := InCnt;
  29. Result := iconv(Context, @InBuf, @InChars, @OutBuf, @OutChars);
  30. InCnt := InChars;
  31. OutCnt := OutChars div sizeof(WideChar);
  32. if Result = -1 then
  33. begin
  34. case cerrno of
  35. // when iconv reports insufficient input or output space, still return
  36. // a positive number of converted chars
  37. ESysE2BIG, ESysEINVAL:
  38. Result := OutCnt - (OutChars div sizeof(WideChar));
  39. else
  40. Result := -cerrno;
  41. end;
  42. end;
  43. end;
  44. procedure Iconv_Cleanup(Context: Pointer); stdcall;
  45. begin
  46. iconv_close(Context);
  47. end;
  48. function GetIconvDecoder(const AEncoding: string; out Decoder: TDecoder): Boolean; stdcall;
  49. var
  50. f: iconv_t;
  51. begin
  52. f := iconv_open(utf16_encoding, PChar(AEncoding));
  53. if f <> Pointer(-1) then
  54. begin
  55. Decoder.Context := f;
  56. Decoder.Decode := @Iconv_Decode;
  57. Decoder.Cleanup := @Iconv_Cleanup;
  58. Result := True;
  59. end
  60. else
  61. Result := False;
  62. end;
  63. initialization
  64. RegisterDecoder(@GetIconvDecoder);
  65. end.