Strange ObjectModelParser behavior

Posted by GregHiggins on 20-Apr-2018 08:24

I have a path variable fileSource which points to a valid Json file ( verified by JsonLint https://jsonlint.com/, seriously, $2 / month is too much for you? ).

cpStream is utf-8, cpInternal is utf-8 (verified).

/* This fails */

define variable myPArser as ObjectModelParser no-undo.
define variable jc       as JsonCOnstruct     no-undo.

assign
  myParser = new ObjectModelParser ( )
  jc       = myParser:Parse ( fileSource )

  .

/* with message Json Parser Error at offset 1: lexical error: invalid char in json text. (11608) */

 

/* This succeeds */

define variable lc as longchar no-undo.

copy-lob from file fileSource to lc.

assign
  myParser = new ObjectModelParser ( )
  jc       = myParser:Parse ( lc )

  .

Isn't it about time ABL stopped doing stupid stuff? It's been 10 fn years since we started processing json. 

 

Posted by Peter Judge on 20-Apr-2018 08:28

ParseFile() is used to load JSON from files.
Parse() is used to load JSON from variables.
 

All Replies

Posted by Peter Judge on 20-Apr-2018 08:28

ParseFile() is used to load JSON from files.
Parse() is used to load JSON from variables.

Posted by GregHiggins on 20-Apr-2018 08:29

Version 10 was actually 2003, so maybe it's been closer to 15 years.

Posted by GregHiggins on 20-Apr-2018 08:33

Hey, maybe it's about time I started wearing my classes while programming.  

Posted by GregHiggins on 20-Apr-2018 09:57

/*------------------------------------------------------------------------

   File        : OverParser

   Purpose     :

   Syntax      :

   Description :

   Author(s)   :

   Created     : Fri Apr 20 10:01:48 EDT 2018

   Notes       : Just for kicks

 ----------------------------------------------------------------------*/

using Progress.Lang.*.

using Progress.Json.ObjectModel.*.

block-level on error undo, throw.

class OverParser inherits ObjectModelParser use-widget-pool:

 /*------------------------------------------------------------------------------

  Purpose:

  Notes:

 ------------------------------------------------------------------------------*/

 define protected variable myParser as ObjectModelParser no-undo.

 method public logical isJsony ( source as character ):

   define variable result as logical no-undo.

   define variable tSource   as character no-undo.

   define variable startChar as character no-undo.

   define variable endChar   as character no-undo.

   define variable wSize     as integer   no-undo.

   assign

     tSource = trim ( source )

     wSize   = length ( tSource, "character":u )

     .

   if wSize gt 0 then do:

     assign

       startChar = substring ( tSource, 1, 1 )

       endChar   = substring ( tSource, wSize, 1 )

       .

     assign

       result = false

       result = ( startChar eq endChar ) when index ( startChar, "~{[":u ) gt 0

       .

   end.

   finally:

     return result.

   end finally.

 end.

 method public JsonConstruct OverParse ( source as longchar ):

   define variable result as JsonCOnstruct no-undo.

   assign

     result = myParser:Parse ( source )

     .

   return result.

 end method /* OverParse */.

 method public JsonConstruct OverParse ( source as memptr ):

   define variable result as JsonCOnstruct no-undo.

   assign

     result = myParser:Parse ( source )

     .

   return result.

 end method /* OverParse */.

 method public JsonConstruct OverParse ( source as handle ):

   define variable result as JsonCOnstruct no-undo.

   assign

     result = myParser:Parse ( source )

     .

   return result.

 end method /* OverParse */.

 method public JsonConstruct OverParse ( source as character ):

   define variable result as JsonConstruct no-undo.

   define variable lc     as longchar      no-undo.

   fix-codepage ( lc ) = "utf-8".

   if isJsony ( source ) then do:

     assign

       result = myParser:Parse ( source )

       .

   end.

   else do:

     assign

       file-info:pathname = source

       .

     if file-info:full-pathname gt "" then do:

       copy-lob from file file-info:full-pathname to lc.

       assign

         result = myParser:Parse ( lc )

         .    

     end.

     else result = ?.      

   end.

   return result.

 end method /* OverParse */.

 constructor public OverParser (  ):

   super ().

   assign

     myParser = new ObjectModelParser ( )

     .    

 end constructor.

end class /* OverParser */.

Posted by Mike Fechner on 20-Apr-2018 10:02

Out of curiosity. You're inheriting from ObjectModelParser. So your OverParser instance is already an ObjectModelParser Instance. Rather than NEW'ing a second ObjectModelParser

myParser = new ObjectModelParser ( )

Why don't you just do

myParser = THIS-OBJECT .

Speak to yourself - instead of speaking to a twin.

Posted by Mike Fechner on 20-Apr-2018 10:28

... remove a set of parens from the code above.

Posted by Peter Judge on 20-Apr-2018 11:29

I should point out that it is possible to do something along the lines of

def var jsonData as JsonConstruct.

jsonData = (new ObjectModelParser()):Parse( " [~"data~"] " ).

Not as pretty but it works.

I'd be tempted to make the Parse() methods static since it cleans the calling syntax up a bit, and the built-in ObjectModelParser has no context for each Parse*() call.

I'd also note that things like "null" , 12345 and "hello greg" are valid JSON (though not yet supported by our parser.

Posted by GregHiggins on 20-Apr-2018 14:13

Mostly because I wasn't paying attention to that part and once it compiled I shoved it out.

This thread is closed