[Class] JSONFile - easily work with JSON files
Posted: 29 Jun 2017, 16:16
This is the class I use when I work with JSON files to keep it all tidy and nice.
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:
Methods:
Instance variables:
Here's an example of it in use:
And the actual class:
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]
}
}