浏览代码

* Patch from Mattias gaertner to support lazarus lfm encoding in TParser

git-svn-id: trunk@15415 -
michael 15 年之前
父节点
当前提交
037c783442
共有 3 个文件被更改,包括 57 次插入18 次删除
  1. 14 6
      rtl/objpas/classes/classes.inc
  2. 9 1
      rtl/objpas/classes/classesh.inc
  3. 34 11
      rtl/objpas/classes/parser.inc

+ 14 - 6
rtl/objpas/classes/classes.inc

@@ -842,7 +842,7 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure ObjectBinaryToText(Input, Output: TStream);
+procedure ObjectBinaryToText(Input, Output: TStream; Encoding: TObjectTextEncoding);
 
 
   procedure OutStr(s: String);
   procedure OutStr(s: String);
   begin
   begin
@@ -855,7 +855,8 @@ procedure ObjectBinaryToText(Input, Output: TStream);
     OutStr(s + LineEnding);
     OutStr(s + LineEnding);
   end;
   end;
 
 
-  procedure Outchars(P, LastP : Pointer; CharToOrdFunc: CharToOrdFuncty);
+  procedure Outchars(P, LastP : Pointer; CharToOrdFunc: CharToOrdFuncty;
+    UseBytes: boolean = false);
 
 
   var
   var
     res, NewStr: String;
     res, NewStr: String;
@@ -879,8 +880,8 @@ procedure ObjectBinaryToText(Input, Output: TStream);
           NewInString := True;
           NewInString := True;
         NewStr := '''''';
         NewStr := '''''';
         end 
         end 
-      else if (Ord(w) >= 32) and (Ord(w) < 127) then 
-        begin //printable ascii
+      else if (Ord(w) >= 32) and ((Ord(w) < 127) or (UseBytes and (Ord(w)<256))) then
+        begin //printable ascii or bytes
         if not InString then
         if not InString then
           NewInString := True;
           NewInString := True;
         NewStr := char(w);
         NewStr := char(w);
@@ -906,7 +907,7 @@ procedure ObjectBinaryToText(Input, Output: TStream);
 
 
   procedure OutString(s: String);
   procedure OutString(s: String);
   begin
   begin
-    OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd);
+    OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd,Encoding=oteLFM);
   end;
   end;
 
 
   procedure OutWString(W: WideString);
   procedure OutWString(W: WideString);
@@ -921,7 +922,10 @@ procedure ObjectBinaryToText(Input, Output: TStream);
 
 
   procedure OutUtf8Str(s: String);
   procedure OutUtf8Str(s: String);
   begin
   begin
-    OutChars(Pointer(S),PChar(S)+Length(S),@Utf8ToOrd);
+    if Encoding=oteLFM then
+      OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd)
+    else
+      OutChars(Pointer(S),PChar(S)+Length(S),@Utf8ToOrd);
   end;
   end;
 
 
   function ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE}
   function ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE}
@@ -1260,6 +1264,10 @@ begin
   ReadObject('');
   ReadObject('');
 end;
 end;
 
 
+procedure ObjectBinaryToText(Input, Output: TStream);
+begin
+  ObjectBinaryToText(Input,Output,oteDFM);
+end;
 
 
 procedure ObjectTextToBinary(Input, Output: TStream);
 procedure ObjectTextToBinary(Input, Output: TStream);
 var
 var

+ 9 - 1
rtl/objpas/classes/classesh.inc

@@ -1423,7 +1423,8 @@ type
     procedure HandleNumber;
     procedure HandleNumber;
     procedure HandleHexNumber;
     procedure HandleHexNumber;
     function HandleQuotedString : string;
     function HandleQuotedString : string;
-    function HandleDecimalString(var ascii : boolean) : widestring;
+    procedure HandleDecimalCharacter(var ascii : boolean;
+                                     out WideChr: widechar; out StringChr: char);
     procedure HandleString;
     procedure HandleString;
     procedure HandleMinus;
     procedure HandleMinus;
     procedure HandleUnknown;
     procedure HandleUnknown;
@@ -1973,6 +1974,13 @@ function CollectionsEqual(C1, C2: TCollection; Owner1, Owner2: TComponent): Bool
 
 
 { Object conversion routines }
 { Object conversion routines }
 
 
+type
+  TObjectTextEncoding = (
+    oteDFM,
+    oteLFM
+    );
+
+procedure ObjectBinaryToText(Input, Output: TStream; Encoding: TObjectTextEncoding);
 procedure ObjectBinaryToText(Input, Output: TStream);
 procedure ObjectBinaryToText(Input, Output: TStream);
 procedure ObjectTextToBinary(Input, Output: TStream);
 procedure ObjectTextToBinary(Input, Output: TStream);
 
 

+ 34 - 11
rtl/objpas/classes/parser.inc

@@ -249,41 +249,64 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TParser.HandleDecimalString(var ascii : boolean): widestring;
+procedure TParser.HandleDecimalCharacter(var ascii: boolean; out
+  WideChr: widechar; out StringChr: char);
 var i : integer;
 var i : integer;
 begin
 begin
-  Result:='';
   inc(fPos);
   inc(fPos);
   CheckLoadBuffer;
   CheckLoadBuffer;
-  while IsNumber do
+  // read a word number
+  i:=0;
+  while IsNumber and (i<high(word)) do
   begin
   begin
-    Result:=Result+fBuf[fPos];
+    i:=i*10+ord(fBuf[fPos])-ord('0');
     inc(fPos);
     inc(fPos);
     CheckLoadBuffer;
     CheckLoadBuffer;
   end;
   end;
-  if not TryStrToInt(Result,i) then
-  i:=0;
+  if i>high(word) then i:=0;
   if i>127 then ascii:=false;
   if i>127 then ascii:=false;
-  setlength(Result,1);
-  Result[1]:=widechar(word(i));
+  WideChr:=widechar(word(i));
+  if i<256 then
+    StringChr:=chr(i)
+  else
+    StringChr:=#0;
 end;
 end;
 
 
 procedure TParser.HandleString;
 procedure TParser.HandleString;
 var ascii : boolean;
 var ascii : boolean;
+  s: string;
+  w: WideChar;
+  c: char;
 begin
 begin
   fLastTokenWStr:='';
   fLastTokenWStr:='';
+  fLastTokenStr:='';
   ascii:=true;
   ascii:=true;
   while true do
   while true do
+  begin
     case fBuf[fPos] of
     case fBuf[fPos] of
-      '''' : fLastTokenWStr:=fLastTokenWStr+HandleQuotedString;
-      '#'  : fLastTokenWStr:=fLastTokenWStr+HandleDecimalString(ascii)
+      '''' :
+        begin
+          // avoid conversions,
+          // On some systems conversion from ansistring to widestring and back
+          // to ansistring does not give the original ansistring.
+          // See bug http://bugs.freepascal.org/view.php?id=15841
+          s:=HandleQuotedString;
+          fLastTokenWStr:=fLastTokenWStr+s;
+          fLastTokenStr:=fLastTokenStr+s;
+        end;
+      '#'  :
+        begin
+          HandleDecimalCharacter(ascii,w,c);
+          fLastTokenWStr:=fLastTokenWStr+w;
+          fLastTokenStr:=fLastTokenStr+c;
+        end;
       else break;
       else break;
     end;
     end;
+  end;
   if ascii then
   if ascii then
     fToken:=Classes.toString
     fToken:=Classes.toString
   else
   else
     fToken:=toWString;
     fToken:=toWString;
-  fLastTokenStr:=fLastTokenWStr;
 end;
 end;
 
 
 procedure TParser.HandleMinus;
 procedure TParser.HandleMinus;