瀏覽代碼

+ cwstring multithreading safe, fixes #6873

git-svn-id: trunk@3948 -
florian 19 年之前
父節點
當前提交
f32b1ccbe0
共有 1 個文件被更改,包括 29 次插入5 次删除
  1. 29 5
      rtl/unix/cwstring.pp

+ 29 - 5
rtl/unix/cwstring.pp

@@ -126,7 +126,13 @@ procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
     destpos: pchar;
     destpos: pchar;
     mynil : pchar;
     mynil : pchar;
     my0 : size_t;
     my0 : size_t;
+    iconv : iconv_t;
   begin
   begin
+    { conversion descriptors aren't thread safe }
+    if IsMultithreaded then
+      iconv:=iconv_open(nl_langinfo(CODESET),unicode_encoding)
+    else
+      iconv:=iconv_wide2ansi;
     mynil:=nil;
     mynil:=nil;
     my0:=0;
     my0:=0;
     { rought estimation }
     { rought estimation }
@@ -136,7 +142,7 @@ procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
     srcpos:=source;
     srcpos:=source;
     destpos:=pchar(dest);
     destpos:=pchar(dest);
     outleft:=outlength;
     outleft:=outlength;
-    while iconv(iconv_wide2ansi,@srcpos,@srclen,@destpos,@outleft)=size_t(-1) do
+    while iconv(iconv,@srcpos,@srclen,@destpos,@outleft)=size_t(-1) do
       begin
       begin
         case fpgetCerrno of
         case fpgetCerrno of
           ESysEILSEQ:
           ESysEILSEQ:
@@ -148,7 +154,7 @@ procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
               inc(destpos);
               inc(destpos);
               dec(outleft);
               dec(outleft);
               { reset }
               { reset }
-              iconv(iconv_wide2ansi,@mynil,@my0,@mynil,@my0);
+              iconv(iconv,@mynil,@my0,@mynil,@my0);
             end;
             end;
           ESysE2BIG:
           ESysE2BIG:
             begin
             begin
@@ -166,6 +172,8 @@ procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
       end;
       end;
     // truncate string
     // truncate string
     setlength(dest,length(dest)-outleft);
     setlength(dest,length(dest)-outleft);
+    if IsMultithreaded then
+      iconv_close(iconv);
   end;
   end;
 
 
 
 
@@ -178,7 +186,13 @@ procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt);
     destpos: pchar;
     destpos: pchar;
     mynil : pchar;
     mynil : pchar;
     my0 : size_t;
     my0 : size_t;
+    iconv : iconv_t;
   begin
   begin
+    { conversion descriptors aren't thread safe }
+    if IsMultithreaded then
+      iconv:=iconv_open(unicode_encoding,nl_langinfo(CODESET));
+    else
+      iconv:=iconv_ansi2wide;
     mynil:=nil;
     mynil:=nil;
     my0:=0;
     my0:=0;
     // extra space
     // extra space
@@ -188,7 +202,7 @@ procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt);
     srcpos:=source;
     srcpos:=source;
     destpos:=pchar(dest);
     destpos:=pchar(dest);
     outleft:=outlength*2;
     outleft:=outlength*2;
-    while iconv(iconv_ansi2wide,@srcpos,@len,@destpos,@outleft)=size_t(-1) do
+    while iconv(iconv,@srcpos,@len,@destpos,@outleft)=size_t(-1) do
       begin
       begin
         case fpgetCerrno of
         case fpgetCerrno of
          ESysEILSEQ:
          ESysEILSEQ:
@@ -199,7 +213,7 @@ procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt);
               inc(destpos,2);
               inc(destpos,2);
               dec(outleft,2);
               dec(outleft,2);
               { reset }
               { reset }
-              iconv(iconv_wide2ansi,@mynil,@my0,@mynil,@my0);
+              iconv(iconv,@mynil,@my0,@mynil,@my0);
             end;
             end;
           ESysE2BIG:
           ESysE2BIG:
             begin
             begin
@@ -217,6 +231,8 @@ procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt);
       end;
       end;
     // truncate string
     // truncate string
     setlength(dest,length(dest)-outleft div 2);
     setlength(dest,length(dest)-outleft div 2);
+    if IsMultithreaded then
+      iconv_close(iconv);
   end;
   end;
 
 
 
 
@@ -249,7 +265,13 @@ procedure Ansi2UCS4Move(source:pchar;var dest:UCS4String;len:SizeInt);
     destpos: pchar;
     destpos: pchar;
     mynil : pchar;
     mynil : pchar;
     my0 : size_t;
     my0 : size_t;
+    iconv : iconv_t;
   begin
   begin
+    { conversion descriptors aren't thread safe }
+    if IsMultithreaded then
+      iconv:=iconv_open('UCS4',nl_langinfo(CODESET));
+    else
+      iconv:=iconv_ansi2ucs4;
     mynil:=nil;
     mynil:=nil;
     my0:=0;
     my0:=0;
     // extra space
     // extra space
@@ -259,7 +281,7 @@ procedure Ansi2UCS4Move(source:pchar;var dest:UCS4String;len:SizeInt);
     srcpos:=source;
     srcpos:=source;
     destpos:=pchar(dest);
     destpos:=pchar(dest);
     outleft:=outlength*4;
     outleft:=outlength*4;
-    while iconv(iconv_ansi2ucs4,@srcpos,@len,@destpos,@outleft)=size_t(-1) do
+    while iconv(iconv,@srcpos,@len,@destpos,@outleft)=size_t(-1) do
       begin
       begin
         case fpgetCerrno of
         case fpgetCerrno of
           ESysE2BIG:
           ESysE2BIG:
@@ -278,6 +300,8 @@ procedure Ansi2UCS4Move(source:pchar;var dest:UCS4String;len:SizeInt);
       end;
       end;
     // truncate string
     // truncate string
     setlength(dest,length(dest)-outleft div 4);
     setlength(dest,length(dest)-outleft div 4);
+    if IsMultithreaded then
+      iconv_close(iconv);
   end;
   end;