Jump to content

A Non-Strict JSON UDF (JSMN)


Ward
 Share

Recommended Posts

1 hour ago, TheXman said:

I'm not exactly sure how AutoIt works in this regard without testing it, but in other languages, objects are passed ByRef.  Therefore, if the same holds true you aren't using a copy of the $jsonfunc object in myfunc(), you are using/manipulating the object itself.

For the record, when I used the term "ByRef" above, I was not referring to the keyword ByRef.  It was just my shorthand way of saying "by reference", in other words using a pointer.  :)

Link to comment
Share on other sites

  • Developers
4 minutes ago, TheXman said:

For the record, when I used the term "ByRef" above, I was not referring to the keyword ByRef.  It was just my shorthand way of saying "by reference", in other words using a pointer.  :)

Understand, but just wanted to avoid confusion.
All that Byref would do is created a PTR ($jsonparam) to a PTR ($jsonfunc) which obviously still point to the same memory space, hence my comment it being  a mute point. :) 

Jos

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

First of all, sorry for being tenacious, i am really impressed by the whole work that the autoit team does here, so i really take my time before responding and i'm gratefull for you to take time. o:)

But in fact, i still disagree :)   (sorry for that)

The problem here, is that is seems that the parameter passed, is a pointer to the json passed when we call the function. I agree with that... but why ?

 It is not the case when called with a string variable ... You must agree that, for a same function, we do not have the same result, depending of the type of parameter passed. (string or json.. for example). I do not understand why it would be normal.

 

$json param point to the same memory allocation that $jsonfunc,  why ?

A function parameter MUST be in local scope, so it should allocate memory et duplicate data not point to the variable (something like that).  Am i wrong ?

Nicolas
[Edit: adding signature and my prettiest smileys :) ]

Edited by satanico64
Link to comment
Share on other sites

  • Developers
6 minutes ago, satanico64 said:

But in fact, i still disagree :)   (sorry for that)

... and that is fine, but it is what it is.  ;)   

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • 1 month later...

I just downloaded 

Quote

and file Json.au3 first line says:

Quote

; File        : Json.au3 (2015.01.08)

are you sure you uploaded right version?

you also said you fixed Au3Check warnings

On 7.02.2013 at 12:11 PM, Ward said:

== Update 2018/10/01b==   (Jos)
* Added Json_ObjGetItems, Tidied source and fixed au3check warnings - tnx @TheXman .

== Update 2018/10/28==   (Jos)
* Added declaration for $value to avoid au3check warning - tnx @DerPensionist

but I still see one:

Przechwytywanie.JPG.4c87baf4eff41691490a70e4c4d83ff0.JPG

Link to comment
Share on other sites

  • Developers

Thanks for the report ... I've update the file and made a new update available in the first post. :)

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • 2 weeks later...

Hey, uh... Its fast, very nice and thank you :)!

Can I use Json_ObjGet through several "levels"? I have a JSON with Object>Object>Object>Object>Object>Object>Array and I want to get the Array behind all the know objects. Do I need 6x Json_ObjGet or how do I adress that more simple? :)

Thanks

 

*edit*

Json_Dump is showing me "." as seperator between the objects, but with

        Local $oTest = Json_ObjGet($oTemp, 'd.1')
        $aTest = Json_ObjGetItems($oTest)

Local $oTest = Json_ObjGet($oTemp, 'd.1')
        $aTest = Json_ObjGetItems($oTest)
        _ArrayDisplay($aTest)

I get "==> Variable must be of type "Object".:"

If i just use 'd', its working, so the seperator isnt right, or maybe its not possitble?

Edited by Acanis
Link to comment
Share on other sites

  • Developers
19 minutes ago, Acanis said:

Ah, Json_Dump helped me understanding the formatting, still not sure, how I do check, if there is a special string in an array behind 6 objects.

Post an example JSON data, the script you have that isn't working yet and an exact explanation of what you want so we can have a look.

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

13 minutes ago, Jos said:

Post an example JSON data, the script you have that isn't working yet and an exact explanation of what you want so we can have a look.

Jos

Hey,

Iam looking for a short way to do something like this:

$sJson = ClipGet()
$oTemp = Json_Decode($sJson)

If Json_IsObject($oTemp) Then
    $oTemp1 = Json_ObjGet($oTemp, "d")
    $oTemp2 = Json_ObjGet($oTemp1, "5")
    $oTemp3 = Json_ObjGet($oTemp2, "4")
    $oTemp4 = Json_ObjGet($oTemp3, "6")
    MsgBox(4096, "", Json_ObjExists($oTemp4, "h") & @CRLF)
EndIf

("h" is an array, which holds some informations)

Can "Json_ObjGet" do this in 1 line? Like

$oObject = Json_ObjGet($oTemp, "d.5.4.6")

Thanks :) 

Link to comment
Share on other sites

  • Developers

I am missing some test data to play with. ;)

Simply change the first line and put the actual JSON data there.

 

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

48 minutes ago, Jos said:

I am missing some test data to play with. ;)

Simply change the first line and put the actual JSON data there.

 

Sorry, I thoughts that if its possible, it would be easier to see the code. I created a short example:

#include <Json.au3>
#include <Array.au3>

$sJson = '{'& _
            '"d": {' & _
                '"5": {' & _
                    '"4": {' & _
                        '"6": {' & _
                            '"h": [' & _
                                '{' & _
                                    '"id": "1286",' & _
                                    '"status": "sunny",' & _
                                    '"earth": true' & _
                                '}' & _
                            ']' & _
                        '}' & _
                    '}' & _
                '}' & _
            '}' & _
        '}'

$oTemp = Json_Decode($sJson)

If Json_IsObject($oTemp) Then
    $oTemp1 = Json_ObjGet($oTemp, "d")
    $oTemp2 = Json_ObjGet($oTemp1, "5")
    $oTemp3 = Json_ObjGet($oTemp2, "4")
    $oTemp4 = Json_ObjGet($oTemp3, "6")

    If Json_ObjExists($oTemp4, "h") Then
        Local $aH = Json_ObjGet($oTemp4, "h")

        For $i = 0 To Ubound($aH) - 1
            $iID = Json_ObjGet($aH[$i], "id")
            ConsoleWrite($iID & @CRLF)
        Next

    EndIf
EndIf

I want to check, if there is a "h"-object in d > 5 > 4 > 6 and if yes, get for example all the ids. Iam curious, if I need all the "temp"-objects. Maybe there is a notation for Json_ObjGet, that is doing this in less lines. :)

 

Thank you

Edited by Acanis
Link to comment
Share on other sites

  • Developers

mmm... don't think that is possible yet.
Maybe we should add a recursive check to Json_ObjGet() and Json_ObjExists() like this:

#include <Json.au3>
$sJson = '{"d": {"5": {"4": {"6": {"h": [{"id": "1286","status": "sunny","earth": true}]}}}}}'
Json_dump($sJson)
$oTemp = Json_Decode($sJson)
If Json_IsObject($oTemp) Then
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d") = ' & Json_ObjExistsR($oTemp, "d") & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d.5") = ' & Json_ObjExistsR($oTemp, "d.5") & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d.5.4") = ' & Json_ObjExistsR($oTemp, "d.5.4") & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d.5.4.6") = ' & Json_ObjExistsR($oTemp, "d.5.4.6") & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d.5.4.6.h") = ' & Json_ObjExistsR($oTemp, "d.5.4.6.h") & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Json_ObjExists($oTemp, "d.5.4.6.x") = ' & Json_ObjExistsR($oTemp, "d.5.4.6.x") & @CRLF) ;### Debug Console
    $oTempb = Json_ObjGetR($oTemp, "d.5.4.6.h")
    ConsoleWrite('@@ json_get($oTempb,''[0].id'') = ' & json_get($oTempb, '[0].id') & '         >Error code: ' & @error & @CRLF) ;### Debug Console
    $oTempb = Json_ObjGetR($oTemp, "d.5.4.6.x")
    ConsoleWrite('@@ json_get($oTempb,''[0].id'') = ' & json_get($oTempb, '[0].id') & '         >Error code: ' & @error & @CRLF) ;### Debug Console
EndIf

Func Json_ObjExistsR(ByRef $Object, $Key)
    Local $DynObject = $Object
    Local $Keys = StringSplit($Key, ".")
    For $x = 1 To $Keys[0]
        If $DynObject.Exists($Keys[$x]) Then
            If $x = $Keys[0] Then
                Return True
            Else
                $DynObject = Json_ObjGet($DynObject, $Keys[$x])
            EndIf
        Else
            Return False
        EndIf
    Next
    Return $Object.Exists(String($Key))
EndFunc   ;==>Json_ObjExistsR


Func Json_ObjGetR(ByRef $Object, $Key)
    Local $DynObject = $Object
    Local $Keys = StringSplit($Key, ".")
    For $x = 1 To $Keys[0]
        If $DynObject.Exists($Keys[$x]) Then
            If $x = $Keys[0] Then
                Return $DynObject.Item($Keys[$x])
            Else
                $DynObject = Json_ObjGet($DynObject, $Keys[$x])
            EndIf
        EndIf
    Next
    Return SetError(1, 0, '')
EndFunc   ;==>Json_ObjGetR

Thoughts?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Developers

Updated the first page with the changed UDFs in the JSON.au3 include.

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Happy New Year :)!

I have very often problems like that:

Quote

"C:\PROGRA~2\AutoIt3\Include\Json.au3" (351) : ==> Variable must be of type "Object".:
Return $Object.Keys()
Return $Object^ ERROR

Is there a way to easy find the calling point in my script? I use a lot of "Json_ObjGetKeys()" and I would like to find the reason, why I sometimes dont get an object at this part. How do you debug this in a good way :)?

I could secure it with lots of "Json_ObjExists()", but maybe I should have an object there and my code isnt stable enough.

Edited by Acanis
Link to comment
Share on other sites

@Acanis Generally you would want to implement error checking in your code as much as possible, so that your script does't stop because of an error like that. There is no easy way (as far as I am aware) to capture these error without getting AutoIt interrupted...

2 hours ago, Acanis said:

but maybe I should have an object there and my code isnt stable enough.

Yes, you are right about this.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Should we add a little bit error handling to the UDF?!

Quote

"C:\PROGRA~2\AutoIt3\Include\Json.au3" (343) : ==> Variable must be of type "Object".:
Return $Object.Exists(String($Key))
Return $Object^ ERROR


Every of this could have a for example a "IsObject Else SetError Return".

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...