Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-03

JSON & me - blind again?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Reinier Olislagers

Hi list,

(FPC 2.6.0 or trunk)

Been fiddling a bit too long and strongly suspect PEBKAC/PICNIC (and my seemingly perennial refusal to adapt to Object Pascal's way of dealing with object references).

Thanks for your suggestions!

See the ===> marks below

var
  CurrentPage: integer;
  RequestResult: THttpResult;
  CommJSON: TJSONObject;
begin
  result:=INVALIDID;
  CommJSON:=TJSONObject.Create;
  try
    try
// do an HTTP request and get a JSONData back.
//
RequestResult:=HttpRequestWithData(CommJSON,FCGIURL+'document/',rmPost);
      if RequestResult.Code200 then
      begin
//snip error handling
      end
      else
      begin
//===> the line below works - so CommJSON is a valid object, right?
        if Assigned(CommJSON) then
        begin
//====> however, the next line gives a runerror(210): no vmt found
          if (CommJSON.JSONType=jtObject) then
          begin
            if (CommJSON.IndexOfName('documentid',false)>-1) then
              result:=CommJSON.Integers['documentid'];
          end;
        end;
      end;
I'm not confident about
function HttpRequestWithData(AData: TJSONData; const AUrl: string;
  const AMethod: TRequestMethod; const AContentType: string): THttpResult;
...
      FreeAndNil(AData);
      VData.Position := 0;
      VParser := TJSONParser.Create(VData);
      try
        try
          AData := VParser.Parse;
//====> so it destroys the object passed to it and recreates it
//====> but AData.JSONType does seem to be JSONObject...

Reply by email

Michael Van Canneyt
to Reinier Olislagers
Reinier Olislagers wrote 33 lines
Hi list, (FPC 2.6.0 or trunk) Been fiddling a bit too long and strongly suspect PEBKAC/PICNIC (and my seemingly perennial refusal to adapt to Object Pascal's way of dealing with object references). Thanks for your suggestions! See the ===> marks below var CurrentPage: integer; RequestResult: THttpResult; CommJSON: TJSONObject; begin result:=INVALIDID; CommJSON:=TJSONObject.Create; try try // do an HTTP request and get a JSONData back. // RequestResult:=HttpRequestWithData(CommJSON,FCGIURL+'document/',rmPost); if RequestResult.Code200 then begin //snip error handling end else begin //===> the line below works - so CommJSON is a valid object, right? if Assigned(CommJSON) then

It is assigned, but not necessarily valid. If you freed CommJSON but did not nil it, it is still'assigned'.

Show quoted text 14 lines
begin //====> however, the next line gives a runerror(210): no vmt found if (CommJSON.JSONType=jtObject) then begin if (CommJSON.IndexOfName('documentid',false)>-1) then result:=CommJSON.Integers['documentid']; end; end; end; I'm not confident about function HttpRequestWithData(AData: TJSONData; const AUrl: string; const AMethod: TRequestMethod; const AContentType: string): THttpResult;

Ehm. This must be

  function HttpRequestWithData(OUT AData: TJSONData; const AUrl: string;
   const AMethod: TRequestMethod; const AContentType: string): THttpResult;

Because you are passing BACK a reference!

Michael.

Reply by email

Reinier Olislagers
to Michael Van Canneyt

On 12-3-2013 11:44, Michael Van Canneyt wrote:

Thanks for the help, Michael.

Show quoted text 6 lines
On Tue, 12 Mar 2013, Reinier Olislagers wrote: > //===> the line below works - so CommJSON is a valid object, right? > if Assigned(CommJSON) then It is assigned, but not necessarily valid. If you freed CommJSON but did not nil it, it is still'assigned'.

Understood. Then it has a pointer pointing to whatever (probably the object's former memory location).

Show quoted text 10 lines
> I'm not confident about > function HttpRequestWithData(AData: TJSONData; const AUrl: string; > const AMethod: TRequestMethod; const AContentType: string): THttpResult; Ehm. This must be function HttpRequestWithData(OUT AData: TJSONData; const AUrl: string; const AMethod: TRequestMethod; const AContentType: string): THttpResult; Because you are passing BACK a reference!
Sorry. What I hadn't attached is the first part where the request is
built up:
    if Assigned(AData) then
    begin
      VHttp.RequestBody := TMemoryStream.Create;
      VJSON := AData.AsJSON;
      VHttp.RequestBody.Write(Pointer(VJSON)^, Length(VJSON));
      VHttp.RequestBody.Position := 0;
    end;

... changing the parameter to var...

function HttpRequestWithData(var AData: TJSONData; const AUrl: string;
  const AMethod: TRequestMethod; const AContentType: string): THttpResult;

... and changing the calling objects from TJSONObject to TJSONData seemed to do the trick.

Thanks a lot.

Reply by email

Michael Van Canneyt
to Reinier Olislagers
Reinier Olislagers wrote 33 lines
On 12-3-2013 11:44, Michael Van Canneyt wrote: Thanks for the help, Michael. > On Tue, 12 Mar 2013, Reinier Olislagers wrote: >> //===> the line below works - so CommJSON is a valid object, right? >> if Assigned(CommJSON) then > > It is assigned, but not necessarily valid. If you freed CommJSON but did > not nil it, it is still'assigned'. Understood. Then it has a pointer pointing to whatever (probably the object's former memory location). >> I'm not confident about >> function HttpRequestWithData(AData: TJSONData; const AUrl: string; >> const AMethod: TRequestMethod; const AContentType: string): THttpResult; > > Ehm. This must be > > function HttpRequestWithData(OUT AData: TJSONData; const AUrl: string; > const AMethod: TRequestMethod; const AContentType: string): THttpResult; > > Because you are passing BACK a reference! Sorry. What I hadn't attached is the first part where the request is built up: if Assigned(AData) then begin VHttp.RequestBody := TMemoryStream.Create; VJSON := AData.AsJSON; VHttp.RequestBody.Write(Pointer(VJSON)^, Length(VJSON)); VHttp.RequestBody.Position := 0; end;

Yes, but as per your code: you free and rebuild:

       FreeAndNil(AData);
       VData.Position := 0;

-> so you change the parameter, and thus you need a var/out

Anyway, glad it is fixed.

Michael.

Reply by email