It doesn't encode and decode to JSON, but it handles the other things like saving and managing the object.
Dependencies:
JSON loader/dumper by cocobelgica: https://github.com/cocobelgica/AutoHotkey-JSON
However the class can easily be modified to use another JSON dump/load lib.
To create a new JSON file wrapper and destroy it:
Code: Select all
MyJSON := new JSONFile(filepath)
MyJSON := ""
Code: Select all
.Save(Prettify := false) - save object to file
.JSON(Prettify := false) - Get JSON text
.Fill(Object) - fill keys in from another object into the instance object
Instance variables:
Code: Select all
.File() - get file path
.Object() - get data object
Code: Select all
#SingleInstance force
#NoEnv
jf := new JSONFile("test.json")
; jf now behaves (nearly) identical to a normal object when setting/getting keys
; you can set keys/value pairs
jf.key := "value"
msgbox % jf.JSON(true)
; you can also make subobjects like normally
jf.arr := ["sub", "array", 42]
msgbox % jf.JSON(true)
jf.obj := {mykey: "my value", subobj: {morekeys: "more values", keyseverywhere: "and even more values!"}}
msgbox % jf.JSON(true)
; you can also use object functions and methods like normally
msgbox % jf.HasKey("obj")
jf.obj.Delete("subobj")
msgbox % jf.JSON(true)
jf.Delete("obj")
msgbox % jf.JSON(true)
; you can also call several methods
; this method fills the object with keys from another object, in this case the default settings object from a project
; if a key already exists, it does nothing, it will only fill in keys that are missing
jf.Fill({ StartUp: true
, Font: "Segoe UI Light"
, Color: {Selection: 0x44C6F6, Tab: {Dark: 0x404040, Orange: 0xFE9A2E}} ; FE9A2E
, GuiState: {ActiveTab: 1, GameListPos: 1, BindListPos: 1}
, Plugins: ["text", "moretext"]
, VibrancyScreens: [1]
, VibrancyDefault: 50})
; to get the json call JSON(). you can call JSON(true) to get the prettified JSON
msgbox % jf.JSON(true)
; to save do Save()
jf.Save(true) ; save prettified JSON
; to for-loop over the shallow object, you have to get the actual data object and not the instance, so you gotta do
; this is practically the only difference from using a normal object
for Key, Value in jf.Object()
msgbox % Key " => " (IsObject(Value) ? "*OBJECT*" : Value)
; similarly you can get the file name and file object via
msgbox % "File: " jf.File()
msgbox % "FileObj is object: " IsObject(jf.FileObj())
; to close the file object and clean up, simply delete the instance
jf := ""
ExitApp
Code: Select all
/*
Class JSONFile
Written by Runar "RUNIE" Borge
Dependencies:
JSON loader/dumper by cocobelgica: https://github.com/cocobelgica/AutoHotkey-JSON
However the class can easily be modified to use another JSON dump/load lib.
To create a new JSON file wrapper:
MyJSON := new JSONFile(filepath)
And to destroy it:
MyJSON := ""
Methods:
.Save(Prettify := false) - save object to file
.JSON(Prettify := false) - Get JSON text
.Fill(Object) - fill keys in from another object into the instance object
Instance variables:
.File() - get file path
.Object() - get data object
*/
Class JSONFile {
static Instances := []
__New(File) {
FileExist := FileExist(File)
JSONFile.Instances[this] := {File: File, Object: {}}
ObjRelease(&this)
FileObj := FileOpen(File, "rw")
if !IsObject(FileObj)
throw Exception("Can't access file for JSONFile instance: " File, -1)
if FileExist {
try
JSONFile.Instances[this].Object := JSON.Load(FileObj.Read())
catch e {
this.__Delete()
throw e
} if (JSONFile.Instances[this].Object = "")
JSONFile.Instances[this].Object := {}
} else
JSONFile.Instances[this].IsNew := true
return this
}
__Delete() {
if JSONFile.Instances.HasKey(this) {
ObjAddRef(&this)
JSONFile.Instances.Delete(this)
}
}
__Call(Func, Param*) {
; return instance value (File, Object, FileObj, IsNew)
if JSONFile.Instances[this].HasKey(Func)
return JSONFile.Instances[this][Func]
; return formatted json
if (Func = "JSON")
return StrReplace(JSON.Dump(this.Object(),, Param.1 ? A_Tab : ""), "`n", "`r`n")
; save the json file
if (Func = "Save") {
try
New := this.JSON(Param.1)
catch e
return false
FileObj := FileOpen(this.File(), "w")
FileObj.Length := 0
FileObj.Write(New)
FileObj.__Handle
return true
}
; fill from specified array into the JSON array
if (Func = "Fill") {
if !IsObject(Param.2)
Param.2 := []
for Key, Val in Param.1 {
if (A_Index > 1)
Param.2.Pop()
HasKey := Param.2.MaxIndex()
? this.Object()[Param.2*].HasKey(Key)
: this.Object().HasKey(Key)
Param.2.Push(Key)
if IsObject(Val) && HasKey
this.Fill(Val, Param.2), Param.2.Pop()
else if !HasKey
this.Object()[Param.2*] := Val
} return
}
return Obj%Func%(this.Object(), Param*)
}
__Set(Key, Val) {
return this.Object()[Key] := Val
}
__Get(Key) {
return this.Object()[Key]
}
}