Search code examples
jsondelphidelphi-xe6

XSuperObject Segmentation fault 11 Delphi XE6


I downloaded the XSuperObject for reading a Json from a web server, but I get a Segmentation fault at moment where I add the Json string to the ISuperArray.

JsonResult : string;
JsonResult := IdHTTP1.Get('http://.................');
LoadJSONXSuperObject(JsonResult);

procedure TDataForm.LoadJSONXSuperObject(S: String);
var
aobj: ISuperArray;
obj2: ISuperObject;
I: Integer;
MyString: String;
begin

aobj := SA(S); // RIGHT HERE I GET THE fault (11) or bus (10)
for I := 0 to aobj.Length-1 do
    begin
    end;

The following code works, but it takes 2 seconds to read each record which have 17 fields and there is 800 I make the same application in Eclipse it takes 10 seconds for all 800.

try
     LResult := LJsonObj.Get('d').JsonValue as TJsonObject;
     LElements := LResult.Get('results').JsonValue as TJsonArray;

  for i := 0 to LElements.count -1 do
    begin
         Try
         LItem := (LElements.Get(i) as TJsonObject).Get('pbutton').JsonValue as TJsonString;
         if LItem <> nil then
            PButton := RemoveQuotes(LItem.ToString)
         else PButton := '';
         except
           PButton := '';
         End;
         Try
         LItem := (LElements.Get(i) as TJsonObject).Get('text').JsonValue as TJsonString;
         if LItem <> nil then
            InvText := RemoveQuotes(LItem.ToString)
         else InvText := '';
         except
            InvText := '';
         End;
         Try
         LItem := (LElements.Get(i) as TJsonObject).Get('buttontext').JsonValue as TJsonString;
         if LItem <> nil then
            ButtonText := RemoveQuotes(LItem.ToString)
         else ButtonText := '';
         except
             ButtonText := '';
         End;
 end;
  finally

  end;

Here is a sample of the Json file.

{
    "d": {
        "results": [
            {
                "__metadata": {
                    "uri": "http://myserver",
                    "key_fields": "",
                    "rows_affected": -1,
                    "last_autoinc": 0
                },
                "pbutton": 1,
                "text": "Pizza",
                "buttontext": "Pizza",
                "price1": 10.99
            },
            {
                "__metadata": {
                    "uri": "http://myserver",
                    "key_fields": "",
                    "rows_affected": -1,
                    "last_autoinc": 0
                },
                "pbutton": 2,
                "text": "Pizza 2",
                "buttontext": "Pizza 2",
                "price1": 10.99
            },
           {
                "__metadata": {
                    "uri": "http://myserver",
                    "key_fields": "",
                    "rows_affected": -1,
                    "last_autoinc": 0
                },
                "pbutton": 98,
                "text": null,
                "buttontext": null,
                "price1": 0
            }
        ]
    }
}

Solution

  • The sample json you provided shows that you don't get a json array ([data, data, data]), but a json object ({data}). You have to use SO(S) instead of SA(S).

    uses
     XSuperObject,
     XSuperJSON;
    
    procedure TDataForm.LoadJSONXSuperObject(const S: string);
       var
        jsonObj, currentObj: ISuperObject;
        enum: TSuperEnumerator<IJSONAncestor>;
       begin
        jsonObj:= SO(S);
        enum := jsonObj['d.results'].AsArray.GetEnumerator;
    
        while enum.MoveNext do
           begin
            currentObj := enum.Current.AsObject;
    
            PButton := currentObj.I['pbutton'];
            InvText := currentObj.S['text'];
            ButtonText := currentObj.S['buttontext'];
    //      Price := currentObj.F['price1'];
           end;
       end;
    

    See also the X-SuperObject samples here: https://code.google.com/p/x-superobject/wiki/Sample