#1 2015-02-27 00:00:38

zed
Member
From: Belarus
Registered: 2015-02-26
Posts: 105

ObjectToJSON don't work with Delphi2007 and "string" properties

Hi, I try save some object to JSON, like this (Delphi 2007):

type
  TMyClass = class
  private
    FText: string;
  published
    property Text: string read FText write FText;
  end;

  ...

var
  m: TMyClass;
  s: RawUTF8;
begin
  m := TMyClass.Create;
  m.Text := 'One-Один'; // chars in win-1251 encoding (Russian)

  s := ObjectToJson(m, [woStoreClassName]);
  ...
end;

and result is:

{"ClassName":"TMyClass","Text":"One-"}

all Russian chars just disappeared!

Then I take a look to the mORMot sources and found that in string conversions (in my case string type is tkLString) used AnsiStringCodePage property. And this CodePage is always 65535. I talk about this part of code in mORMot.pas:

         procedure TJSONSerializer.WriteObject(Value: TObject; Options: TTextWriterWriteObjectOptions);
        
        ...
        
        {$ifdef FPC}tkAString,{$endif} tkLString: begin
          HR(P);
          Add('"');
          P^.GetLongStrProp(Value,tmp);          
          AddAnyAnsiString(tmp,twJSONEscape,P^.PropType^.AnsiStringCodePage); // AnsiStringCodePage = 65535 ($FFFF)
          Add('"');
        end;

I think that problem in TSynAnsiConvert.Engine function (SynCommons.pas). When I modify it and set to return CurrentAnsiConvert if CodePage is 65535, all my code starts work as expected.

        class function TSynAnsiConvert.Engine(aCodePage: cardinal): TSynAnsiConvert;
        var i: integer;
        begin
          if SynAnsiConvertList=nil then begin
            GarbageCollectorFreeAndNil(SynAnsiConvertList,TObjectList.Create);
            CurrentAnsiConvert := TSynAnsiConvert.Engine(GetACP);
            WinAnsiConvert := TSynAnsiConvert.Engine(CODEPAGE_US) as TSynAnsiFixedWidth;
            UTF8AnsiConvert := TSynAnsiConvert.Engine(CP_UTF8) as TSynAnsiUTF8;
          end;
 --      if aCodePage=0 then begin
 ++      if (aCodePage=0) or (aCodePage=65535) then begin
            result := CurrentAnsiConvert;
            exit;
          end;
          with SynAnsiConvertList do
            for i := 0 to Count-1 do begin
              result := List[i];
              if result.CodePage=aCodePage then
                exit;
            end;
          if aCodePage=CP_UTF8 then
            result := TSynAnsiUTF8.Create(CP_UTF8) else
          if aCodePage=CP_UTF16 then
            result := TSynAnsiUTF16.Create(CP_UTF16) else
          if IsFixedWidthCodePage(aCodePage) then
            result := TSynAnsiFixedWidth.Create(aCodePage) else
            result := TSynAnsiConvert.Create(aCodePage);
          SynAnsiConvertList.Add(result);
        end;

What do you think?

Last edited by zed (2015-02-27 00:07:10)

Offline

#2 2015-02-27 08:32:32

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

There was a confusion due to RawByteString = AnsiString type definition.

I've made a new dedicated type (using RawByteString = type AnsiString syntax), so that RawByteString would be identified with code page 65535, and AnsiString as code page 0.
See http://synopse.info/fossil/info/9cc20b356d

It should fix your problem.
Sorry for the issue - difficult to maintain all those incompatible Delphi versions!

Offline

#3 2015-02-27 09:25:24

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

About Delphi - Versions: What is the Reason do support 15Year old Delphi Versions ?
I'm Delphi Developer since Delphi3 and actual using XE7. I have a contract with Embarcadero to get every new Version automatically. You also can download Demo Versions.
As Windows XP has no Support. The old Delphi Versions are also not updated.

I keep all my useful VCL and other Classes up to date with the Delphi actual Version and eliminated almost the most ifdefs concerning outdated versions to keep my code clean.
I use some professional vcl where i also pay money for. They also have trouble to support old Versions and some stopped support for very old versions.

Here: http://en.wikipedia.org/wiki/Delphi_%28 … anguage%29 you can read about the Version history.

the new Version also contain new vcl and other nice features the old Version doesn't have e.g.
System.Generics.Collections,
Actual Indy Support,
FMX, ...
32/64Bit
MacOS
iOS,Android smile Hopefully Windows Mobile and Blackberry to come
to call only a litte bit of this.

I by myself only use Delphi XE5 upwards. And would prefer to update Delphi before writing some code to support older Versions. It's cheaper... in the end...

Last edited by itSDS (2015-02-27 09:27:28)


Rad Studio 12.1 Santorini

Offline

#4 2015-02-27 10:41:12

zed
Member
From: Belarus
Registered: 2015-02-26
Posts: 105

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

ab
Thanks, bug fixed.

Offline

#5 2015-02-27 11:37:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

About Delphi version support,

0. Of course, staying in synch with the current Delphi compiler version is fine.
We try to support all Delphi platforms for clients, including mobile.

1. There are a lot of existing applications which would benefit from introducing new features using mORMot, but upgrading to newer version of Delphi would cost more (Unicode, third-party components).

2. Apps compiled with Delphi 6 or 7 still works perfectly on latest Windows (once you apply some simple patches, or use maintained third-party components), especially for server apps (and our framework is Unicode ready even on old versions, since we use UTF-8).

3. Delphi pricing policy could be expensive, if you are not a corporate user.

4. We rely mostly on non visual features, so we do not care about the VCL in 90% of the framework source code.
We found no mandatory feature in the new compiler (yet).

5. We want to be FPC compatible, so stay away from some breaking changes.
FPC supports more targets - e.g. it was reported that mORMot servers runs on Linux ARM.
FPC has a cleaner orientation for the future: if EMB decides to generalize ARC or NextGEN, it would be a showstopper for us.

6. We still use CrossKylix for Linux servers.

7. The current Delphi IDE is slower and less multi-monitor friendly than Delphi 7 - the "classic undocked" mode is just buggy as hell.

Of course, nothing is written in stone, and we may change our policy.
But from user feedback, it sounds to me that older versions are still around, especially for people with huge existing code base.

Offline

#6 2015-02-27 12:13:11

itSDS
Member
From: Germany
Registered: 2014-04-24
Posts: 506

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

Hi AB it was not meant as critic on your work.


Rad Studio 12.1 Santorini

Offline

#7 2015-02-27 13:19:16

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: ObjectToJSON don't work with Delphi2007 and "string" properties

I know, I just wanted to be accurate.
smile

Offline

Board footer

Powered by FluxBB