AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

JSON in-place parser with asynchronous read/write

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Mon Aug 11, 2008 2:15 pm    Post subject: JSON in-place parser with asynchronous read/write Reply with quote

I wrote this to help with automated hacking of my xulrunner/prism code. Others may also find it useful as a faster and more compact alternative to XML or INI.

Code:
; JSON example:
j = {"version":"1","window":{"state":3,"screenX":25,"screenY":25,"width":790,"height":605,"test":{"nested":"object"}},"sidebar":{"visible":false,"width":"200"}}

MsgBox, % json(j, "version") ; returns "1"
MsgBox, % json(j, "*[2].visible") ; anonymous select third element ("sidebar")->visible
MsgBox, % json(j, "window.width", 800) ; returns 790, sets window->width to 800


SVN checkout: svn://www.autohotkey.net/~Titan/repos/json.ahk
_________________

Back to top
View user's profile Send private message Visit poster's website
heresy



Joined: 11 Mar 2008
Posts: 291

PostPosted: Mon Aug 11, 2008 3:51 pm    Post subject: Reply with quote

it reminds me Python's dictionary data type too. good for handling large variables.
i think it would be comfortable if we can skip first parameter and it creates a global variable automatically.
which would look like below
Code:
json("Screen.Width", A_ScreenWidth) ;set
MsgBox % ("Screen.Width") ;get

Thanks for sharing
_________________
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com
Back to top
View user's profile Send private message
n-l-i-d
Guest





PostPosted: Mon Aug 11, 2008 4:38 pm    Post subject: Reply with quote

Impressive! Cool
Back to top
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Tue Aug 12, 2008 11:10 am    Post subject: Reply with quote

heresy wrote:
i think it would be comfortable if we can skip first parameter and it creates a global variable automatically
Good idea, you can use static variable too. The main version will stay the same so you can modify external objects.
_________________

Back to top
View user's profile Send private message Visit poster's website
haichen



Joined: 05 Feb 2007
Posts: 140
Location: Osnabrück, Germany

PostPosted: Wed Sep 10, 2008 4:33 pm    Post subject: Reply with quote

There is a problem with spaces after the :.
Would be nice if you (or someone else) could include this.
I tried to figure the problem and I think if there is Whitespace after : z is too small. But the RegexMatch with backreferences ist to complicated for me. Very Happy

edit: Forgot to say: there's only a problem when changing values like ..."width": 790,...

Thanks for this nice piece of code.
Back to top
View user's profile Send private message
Ice_Tea



Joined: 12 Jan 2008
Posts: 114

PostPosted: Wed Sep 10, 2008 8:50 pm    Post subject: Reply with quote

it seems to be a kickass function imho, think I'll use it
Back to top
View user's profile Send private message
haichen



Joined: 05 Feb 2007
Posts: 140
Location: Osnabrück, Germany

PostPosted: Thu Sep 11, 2008 12:45 am    Post subject: Reply with quote

I changed the function a little bit. Now it works with structured json files and with spaces after the :.
Code:
json(ByRef js, s, v = "") {
   j = %js%
   Loop, Parse, s, .
   {
      p = 2
      RegExMatch(A_LoopField, "([+\-]?)([^[]+)(?:\[(\d+)\])?", q), q3 := q3 ? q3 : 0
      Loop {
         If (!p := RegExMatch(j, "(""|')([^\1]+?)\1\s*:\s*((""|')?[^\4]*?\4|(\{(?:[^{}]*+|(?5))*\})|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
            Return
         Else If (-1 == q3 -= x2 == q2 or q2 == "*") {
            j = %x3%
            z += p + StrLen(x2) - 2
            Break
         }
         Else p += StrLen(x)
      }
   }

  z-=StrLen(x)
  If (v !="" ) {
    NewStr := RegExReplace(x, x3 , v)
    js := RegExReplace(js, x , NewStr,"",1,z)
  }


   Return, x3 == "false" ? 0 : x3 == "true" ? 1 : x3 == "null" or x3 == "nul" ? "" : SubStr(x3, 1, 1) == "" ? SubStr(x3, 2, -1) : x3
}


Example:
Code:
j=
(
{
   "intl": {
      "app_locale": "de"
   },
   "options_window": {
      "last_tab_index": "2"

   }
}
)


test="1212"
MsgBox, % json(j,"options_window.last_tab_index", test)
MsgBox, % json(j,"options_window.last_tab_index")
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Thu Sep 11, 2008 10:35 am    Post subject: Reply with quote

haichen wrote:
I changed the function a little bit. Now it works with structured json files and with spaces after the :.
Thanks for writing a fix. This function is not standards compliant with array handling, the wildcard selector is also a custom extension. I had planned to release a fully conformant update but left AutoHotkey to use C# in my toolchain for which I wrote SimpleJSON. I'll look at the ahk code again tonight and will try to make the final adjustments.
_________________

Back to top
View user's profile Send private message Visit poster's website
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Thu Sep 11, 2008 9:46 pm    Post subject: Reply with quote

For those who are interested version 2a is what I currently use. It includes a few bug fixes and supports complex nested arrays:

Code:
j = { "a" : true, "b" : [ 1, [ 2.1, 2.2, { "sub" : false, "test" : [ null, "pass" ] } ], 3 ] }
MsgBox, % json(j, "b[1][2].test[1]")


The only problem is an odd quirk in pcre which causes a failure to match {"v":"1"} where "1" could be any one or two digit number, with or without quotes. I think this is due to conflicting atomic alternations; if anyone can write better regex please post them.
_________________

Back to top
View user's profile Send private message Visit poster's website
Rabiator



Joined: 17 Apr 2005
Posts: 271
Location: Sauerland

PostPosted: Thu Sep 11, 2008 10:04 pm    Post subject: Reply with quote

Unfortunately the example in your first post doesn't work any more.
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Thu Sep 11, 2008 10:55 pm    Post subject: Reply with quote

Rabiator wrote:
Unfortunately the example in your first post doesn't work any more.
Yes, v2 has a bug I previously mentioned - notice "version":"1" in the example and "last_tab_index": "\"1212\"" haichens code.
_________________

Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group