Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Funktion] JSON (encode und decode)


  • Please log in to reply
7 replies to this topic
Bentschi
  • Moderators
  • 120 posts
  • Last active: Sep 05 2014 02:12 AM
  • Joined: 26 Nov 2008

Hallo,
 
Viele Onlineanbieter (bsp. Google, Yahoo, ...) bieten Services (Wetter, Suche, ...) die ein Textdokument ausgeben, das man als JSON parsen kann.
Natürlich kann man per PHP auch seinen eigenen Service machen, der JSON-Code erzeugt, der dann mit AHK geparst wird.
Eine weitere Verwendung wäre Objekte über IPC oder Netzwerk von einem AHK-Script zu einem anderen zu bringen.
 
Die Funktion ist relativ einfach:
- Wird ein Objekt übergeben, wird ein JSON-String ausgegeben.
- Wird ein JSON-String übergeben, wird ein Objekt ausgegeben.
 
 

json(i)
{
  ;ENCODE
  if (isobject(i))
  {
    o := "", a := 1, x := 1
    for k,v in i
    {
      if (k!=x)
        a := 0, break
      x += 1
    }
    o .= (a) ? "[" : "{", f := 1
    for k,v in i
      o .= ((f) ? "" : ",")((a) ? "" : """" k """:")((isobject(v)) ? json(v) : ((v+0=v) ? v : """" v """")), f := 0
    return o ((a) ? "]" : "}")
  }
  ;DECODE
  if (regexmatch(i, "s)^__chr(A|W):(.*)", m))
  {
    VarSetCapacity(b, 4, 0), NumPut(m2, b, 0, "int")
    return StrGet(&b, 1, (m1="A") ? "cp28591" : "utf-16")
  }
  if (regexmatch(i, "s)^__str:((\\""|[^""])*)", m))
  {
    str := m1
    for p,r in {b:"`b", f:"`f", n:"`n", 0:"", r:"`r", t:"`t", v:"`v", "'":"'", """":"""", "/":"/"}
      str := regexreplace(str, "\\" p, r)
    while (regexmatch(str, "s)^(.*?)\\x([0-9a-fA-F]{2})(.*)", m))
      str := m1 json("__chrA:0x" m2) m3
    while (regexmatch(str, "s)^(.*?)\\u([0-9a-fA-F]{4})(.*)", m))
      str := m1 json("__chrW:0x" m2) m3
    while (regexmatch(str, "s)^(.*?)\\([0-9]{1,3})(.*)", m))
      str := m1 json("__chrA:" m2) m3
    return regexreplace(str, "\\\\", "\")
  }
  str := [], obj := []
  while (RegExMatch(i, "s)^(.*?[^\\])""((\\""|[^""])*?[^\\]|)""(.*)$", m))
    str.insert(json("__str:" m2)), i := m1 "__str<" str.maxIndex() ">" m4
  while (RegExMatch(RegExReplace(i, "\s+", ""), "s)^(.*?)(\{|\[)([^\{\[\]\}]*?)(\}|\])(.*)$", m))
  {
    a := (m2="{") ? 0 : 1, c := m3, i := m1 "__obj<" ((obj.maxIndex()+1) ? obj.maxIndex()+1 : 1) ">" m5, tmp := []
    while (RegExMatch(c, "^(.*?),(.*)$", m))
      tmp.insert(m1), c := m2
    tmp.insert(c), tmp2 := {}, obj.insert(cobj := {})
    for k,v in tmp
    {
      if (RegExMatch(v, "^(.*?):(.*)$", m))
        tmp2[m1] := m2
      else
        tmp2.insert(v)
    }
    for k,v in tmp2
    {
      for x,y in str
        k := RegExReplace(k, "__str<" x ">", y), v := RegExReplace(v, "__str<" x ">", y)
      for x,y in obj
        v := RegExMatch(v, "^__obj<" x ">$") ? y : v
      cobj[k] := v
    }
  }
  return obj[obj.maxIndex()]
}

28.08.2014 - Rewrite Decoding wegen Fehler wenn Strings Objekte/Arrays enthalten

28.08.2014 - Ausgabe für leere Strings korrigiert



lasso
  • Members
  • 111 posts
  • Last active: May 19 2013 04:19 PM
  • Joined: 02 Nov 2012
nicht übel Sprach der Dübel und verschwand in der Wandhappy.png

sieht aus wie übersetzter C-Code



Bentschi
  • Moderators
  • 120 posts
  • Last active: Sep 05 2014 02:12 AM
  • Joined: 26 Nov 2008

sieht aus wie übersetzter C-Code

 

Hast du schonmal eine RegEx-Funktion in C gesehen?

Nein, der Code entstammt meinen Hirn.



Alibaba
  • Members
  • 435 posts
  • Last active: Nov 19 2014 04:21 PM
  • Joined: 01 Nov 2012

*meinem

(mit m!)

 

wink.png


Find the recent autohotkey version here: ahkscript.org


lasso
  • Members
  • 111 posts
  • Last active: May 19 2013 04:19 PM
  • Joined: 02 Nov 2012

Hast du schonmal eine RegEx-Funktion in C gesehen?

 

sicher hab ich das schon gesehen

es gibt etliche Implementierungen

zum beispiel pcre oder posix

http://www.gnu.org/s...xpressions.html

ganz normales C-gelumpe

wollte dir aber nicht auf die Füße treten
dein Code hat mich nur an die Parser erinnert,
die ich beruflich in C schreibe ... das ist alles
soll heißen gefällt mir



SAPlayer
  • Members
  • 403 posts
  • Last active: Apr 11 2014 04:45 PM
  • Joined: 06 Nov 2012

Leider hat die Funktion Probleme mit JSON-Arrays wie diesem hier:

{
	"items": [
		{
			"kind": "youtube#searchResult"
		}
	]
}

(In diesem Fall ein kleiner Teil der YouTube-API, sind aber auch sonst nicht unüblich)

 

Das ist leicht zu fixen, es muss nur eine Zeile geändert werden:

while (b && regexmatch(b, "s)^\s*" ((a) ? "" : "(?P<k>(""(\\""|[^""])*""|[^:])*)\s*:\s*") "(?P<v>(""(\\""|[^""])*""|[^,])*)\s*,?\s*((?P<p>.*))?", m))


SAPlayer
  • Members
  • 403 posts
  • Last active: Apr 11 2014 04:45 PM
  • Joined: 06 Nov 2012

Habe leider noch einen Fehler gefunden, den ich nicht so leicht fixen kann:

JSON:

{
	"description": "[Full HD]",
	"title": "{Full HD}"
}

Output:

Array
(
	[description] => __obj1
	[title] => __obj2
)

(wobei __obj1 und __obj2 Strings sind)



Bentschi
  • Moderators
  • 120 posts
  • Last active: Sep 05 2014 02:12 AM
  • Joined: 26 Nov 2008

Hallo,

Hab das dekodieren komplett neu geschrieben.

Diesmal werden zuerst die Strings in Sicherheit gebracht (in nem Array) und dann wird erst wirklich dekodiert.

Wenn die Objekte/Arrays dekodiert sind werden die Strings erst wieder eingefügt.

Sollte so keine Probleme mehr machen.

 

Edit:

Leere Strings machen doch noch probleme...

 

Edit2:

fixed