Pārlūkot izejas kodu

* Patch to allow use of UTF8 in ansistring (as requested in Bug ID #22310)

git-svn-id: trunk@21837 -
michael 13 gadi atpakaļ
vecāks
revīzija
a7d55bc92b

+ 28 - 4
packages/fcl-json/src/jsonparser.pp

@@ -28,9 +28,12 @@ Type
   TJSONParser = Class(TObject)
   Private
     FScanner : TJSONScanner;
+    FuseUTF8,
     FStrict: Boolean;
     function ParseNumber: TJSONNumber;
     procedure SetStrict(const AValue: Boolean);
+    function GetUTF8 : Boolean;
+    procedure SetUTF8(const AValue: Boolean);
   Protected
     procedure DoError(const Msg: String);
     function DoParse(AtCurrent,AllowEOF: Boolean): TJSONData;
@@ -42,11 +45,13 @@ Type
     Property Scanner : TJSONScanner read FScanner;
   Public
     function Parse: TJSONData;
-    Constructor Create(Source : TStream); overload;
-    Constructor Create(Source : TJSONStringType); overload;
+    Constructor Create(Source : TStream; AUseUTF8 : Boolean = False); overload;
+    Constructor Create(Source : TJSONStringType; AUseUTF8 : Boolean = False); overload;
     destructor Destroy();override;
     // Use strict JSON: " for strings, object members are strings, not identifiers
     Property Strict : Boolean Read FStrict Write SetStrict;
+    // if set to TRUE, then strings will be converted to UTF8 ansistrings, not system codepage ansistrings.
+    Property UseUTF8 : Boolean Read GetUTF8 Write SetUTF8;
   end;
   
   EJSONParser = Class(EParserError);
@@ -152,6 +157,23 @@ begin
     end;
 end;
 
+function TJSONParser.GetUTF8 : Boolean;
+
+begin
+  if Assigned(FScanner) then
+    Result:=FScanner.UseUTF8
+  else
+    Result:=FUseUTF8;  
+end;
+
+procedure TJSONParser.SetUTF8(const AValue: Boolean);
+
+begin
+  FUseUTF8:=AValue;
+  if Assigned(FScanner) then
+    FScanner.UseUTF8:=FUseUTF8;
+end;
+
 procedure TJSONParser.SetStrict(const AValue: Boolean);
 begin
   if (FStrict=AValue) then
@@ -250,16 +272,18 @@ begin
   Raise EJSONParser.Create(S);
 end;
 
-constructor TJSONParser.Create(Source: TStream);
+constructor TJSONParser.Create(Source: TStream; AUseUTF8 : Boolean = False);
 begin
   Inherited Create;
   FScanner:=TJSONScanner.Create(Source);
+  UseUTF8:=AUseUTF8;
 end;
 
-constructor TJSONParser.Create(Source: TJSONStringType);
+constructor TJSONParser.Create(Source: TJSONStringType; AUseUTF8 : Boolean = False);
 begin
   Inherited Create;
   FScanner:=TJSONScanner.Create(Source);
+  UseUTF8:=AUseUTF8;
 end;
 
 destructor TJSONParser.Destroy();

+ 14 - 6
packages/fcl-json/src/jsonscanner.pp

@@ -59,6 +59,7 @@ type
     FCurTokenString: string;
     FCurLine: string;
     FStrict: Boolean;
+    FUseUTF8 : Boolean;
     TokenStr: PChar;
     function GetCurColumn: Integer;
   protected
@@ -66,8 +67,8 @@ type
     procedure Error(const Msg: string; Args: array of Const);overload;
     function DoFetchToken: TJSONToken;
   public
-    constructor Create(Source : TStream); overload;
-    constructor Create(const Source : String); overload;
+    constructor Create(Source : TStream; AUseUTF8 : Boolean = False); overload;
+    constructor Create(const Source : String; AUseUTF8 : Boolean = False); overload;
     destructor Destroy; override;
     function FetchToken: TJSONToken;
 
@@ -80,6 +81,8 @@ type
     property CurTokenString: string read FCurTokenString;
     // Use strict JSON: " for strings, object members are strings, not identifiers
     Property Strict : Boolean Read FStrict Write FStrict;
+    // if set to TRUE, then strings will be converted to UTF8 ansistrings, not system codepage ansistrings.
+    Property UseUTF8 : Boolean Read FUseUTF8 Write FUseUTF8;
   end;
 
 const
@@ -104,17 +107,19 @@ const
 
 implementation
 
-constructor TJSONScanner.Create(Source : TStream);
+constructor TJSONScanner.Create(Source : TStream; AUseUTF8 : Boolean = False);
 
 begin
   FSource:=TStringList.Create;
   FSource.LoadFromStream(Source);
+  FUseUTF8:=AUseUTF8;
 end;
 
-constructor TJSONScanner.Create(const Source : String);
+constructor TJSONScanner.Create(const Source : String; AUseUTF8 : Boolean = False);
 begin
   FSource:=TStringList.Create;
   FSource.Text:=Source;
+  FUseUTF8:=AUseUTF8;
 end;
 
 destructor TJSONScanner.Destroy;
@@ -235,8 +240,11 @@ begin
                         Error(SErrInvalidCharacter, [CurRow,CurColumn,TokenStr[0]]);
                       end;
                       end;
-                    // Takes care of conversion...  
-                    S:=WideChar(StrToInt('$'+S));  
+                    // WideChar takes care of conversion...  
+                    if UseUTF8 then
+                      S:=Utf8Encode(WideString(WideChar(StrToInt('$'+S))))
+                    else
+                      S:=WideChar(StrToInt('$'+S));  
                     end;
               #0  : Error(SErrOpenString);
             else