dc_iconvert.inc 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. function Iconvert(S: string; var Res: string; const FromEncoding, ToEncoding: string): cint;
  2. var
  3. InLen, OutLen, Offset: size_t;
  4. Src, Dst: pchar;
  5. H: iconv_t;
  6. lerr: cint;
  7. iconvres: size_t;
  8. begin
  9. H := iconv_open(PChar(ToEncoding), PChar(FromEncoding));
  10. if h=Iconv_t(-1) then
  11. begin
  12. Res := S;
  13. exit(-1);
  14. end;
  15. try
  16. InLen:=Length(s);
  17. outlen:=InLen;
  18. setlength(res,outlen);
  19. Src := PChar(S);
  20. Dst := PChar(Res);
  21. while InLen > 0 do
  22. begin
  23. iconvres := iconv(H, @Src, @InLen, @Dst, @OutLen);
  24. if iconvres = size_t(-1) then
  25. begin
  26. lerr := cerrno;
  27. if lerr = ESysEILSEQ then // unknown char, skip
  28. begin
  29. Inc(Src);
  30. Dec(InLen);
  31. end
  32. else
  33. if lerr = ESysE2BIG then
  34. begin
  35. Offset := Dst - PChar(Res);
  36. SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
  37. Dst := PChar(Res) + Offset;
  38. OutLen := Length(Res) - Offset;
  39. end
  40. else
  41. exit(-1)
  42. end;
  43. end;
  44. finally
  45. setlength(Res,Length(Res) - Outlen);
  46. iconv_close(H);
  47. end;
  48. Result := 0;
  49. end;