Jump to content

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

Object from/to file or string - data structures


  • Please log in to reply
10 replies to this topic
Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009

Warning: This code is made obsolete by String-object-file (data structures in YAML-like style)
 

 

Object from/to file or string - another way to set/get/edit/store data structures
Very easy for both humans and machines to read and write. Fast, simple, flexible.

Download - includes functions and example

ObjFromFile(FilePath) ; creates object from file. Returns: object
ObjToFile(Object, FilePath) ; saves object to file. Returns: 1 if there was a problem or 0 otherwise
ObjFromStr(String) ; creates object from string. Returns: object
ObjToStr(Object) ; converts object to string. Returns: string

Hierarchy in data structure string is defined by using indentation, more precisely; tab character. Can be changed.

See also:
- Yaml
- JSON
- IniWrite, IniRead



tomoe_uehara
  • Members
  • 2166 posts
  • Last active: Jun 11 2015 05:33 PM
  • Joined: 05 Sep 2009
huh...? :?

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009

huh...? :?

I guess this is your respond to original (temporary) post that was:

Upload in progress...



Asking One
  • Guests
  • Last active:
  • Joined: --
I assume this is the uploaded code? :lol:

;===Description=========================================================================
/*
Object from/to file or string - another way to set/get/edit/store data structures. By Learning one.

Very easy for both humans and machines to read and write. Fast, simple, flexible.
Hierarchy in data structure string is defined by using indentation, more precisely; tab character. Can be changed.

Functions, obligatory parameters, and return values:
	ObjFromFile(FilePath)		; creates object from file. 	Returns: object
	ObjToFile(Object, FilePath)	; saves object to file. 		Returns: 1 if there was a problem or 0 otherwise
	ObjFromStr(String) 			; creates object from string. 	Returns: object
	ObjToStr(Object) 			; converts object to string. 	Returns: string
	
	
Link:	http://www.autohotkey.com/forum/viewtopic.php?t=71503
*/


;===How to use example==================================================================
DataPath := A_ScriptDir "\AppData.txt"

if !FileExist(DataPath)
Gosub, CreateDemoFile			; first time creation

oData := ObjFromFile(DataPath)	; creates (loads) object from file

MsgBox, % oData.Version "`n" oData.Menu.Item1.Action "`n" oData["Tip of the day?"]	; get some
MsgBox, % ObjToStr(oData)		; get and see all - converts whole object to string

oData.Version := "3.33"			; modify
;oData.Menu.Remove("Item2")		; remove (delete)
oData.Sounds := "Yes"			; add

;MsgBox, % ObjToStr(oData)		; see all after modifications
ObjToFile(oData, DataPath)		; save modified object (data structure) back to file. Ready to load next time.
ExitApp



;===Functions===========================================================================
ObjFromStr(String, Rows="`n", Equal="=", Indent="`t") {		; creates object from string which represents data structure.
	obj := Object(), kn := Object()	; kn means "key names" - simple array object
	IndentLen := StrLen(Indent)
	Loop, parse, String, %Rows%
	{
		if A_LoopField is space
		continue
		Field := RTrim(A_LoopField, " `t`r")
		
		CurLevel := 1, k := "", v := ""	; clear, reset
		While (SubStr(Field,1,IndentLen) = Indent) {
			StringTrimLeft, Field, Field, %IndentLen%
			CurLevel++
		}
		
		EqualPos := InStr(Field, Equal)
		if (EqualPos = 0)
		k := Field
		else
		k := SubStr(Field, 1, EqualPos-1), v := SubStr(Field, EqualPos+1)
		
		k := Trim(k, " `t`r"), v := Trim(v, " `t`r")
		kn[CurLevel] := k
		if !(EqualPos = 0)	; key-value
		{
			if (CurLevel = 1)
			obj[kn.1] := v
			else if (CurLevel = 2)
			obj[kn.1][k] := v
			else if (CurLevel = 3)
			obj[kn.1][kn.2][k] := v
			else if (CurLevel = 4)
			obj[kn.1][kn.2][kn.3][k] := v
			else if (CurLevel = 5)
			obj[kn.1][kn.2][kn.3][kn.4][k] := v
			else if (CurLevel = 6)
			obj[kn.1][kn.2][kn.3][kn.4][kn.5][k] := v
			else if (CurLevel = 7)
			obj[kn.1][kn.2][kn.3][kn.4][kn.5][kn.6][k] := v		; etc...
		}
		else	; sub-object
		{
			if (CurLevel = 1)
			obj.Insert(kn.1,Object())
			else if (CurLevel = 2)
			obj[kn.1].Insert(kn.2,Object())
			else if (CurLevel = 3)
			obj[kn.1][kn.2].Insert(kn.3,Object())
			else if (CurLevel = 4)
			obj[kn.1][kn.2][kn.3].Insert(kn.4,Object())
			else if (CurLevel = 5)
			obj[kn.1][kn.2][kn.3][kn.4].Insert(kn.5,Object())
			else if (CurLevel = 6)
			obj[kn.1][kn.2][kn.3][kn.4][kn.5].Insert(kn.6,Object())		; etc...
		}
	}
	return obj
}

ObjToStr(Obj, Rows="`n", Equal=" = ", Indent="`t", Depth=7, CurIndent="") {	; converts object to string
    For k,v in Obj
        ToReturn .= CurIndent . k . (IsObject(v) && depth>1 ? Rows . ObjToStr(v, Rows, Equal, Indent, Depth-1, CurIndent . Indent) : Equal . v) . Rows
    return RTrim(ToReturn, Rows)
}	; http://www.autohotkey.com/forum/post-426623.html#426623

ObjFromFile(FilePath, Rows="`n", Equal="=", Indent="`t") {		; creates object from file
	if !FileExist(FilePath)
	return
	FileRead, String, %FilePath%
	return ObjFromStr(String, Rows, Equal, Indent)	; creates and returns object from string
}

ObjToFile(Obj, FilePath, Rows="`n", Equal=" = ", Indent="`t", Depth=7, CurIndent="") {	; saves object to file
	if FileExist(FilePath)
	FileDelete, %FilePath%	; delete old
	FileAppend, % ObjToStr(Obj, Rows, Equal, Indent, Depth, CurIndent), %FilePath%, UTF-8	; store new
	return ErrorLevel
}



;===Subroutines=========================================================================
CreateDemoFile:
SomeData =			; demo data structure
(
Date modified = 05.05.2011.
Hotkeys
	Win + C = Calculator
	Win + P = Paint
Menu
	Item1
		Action = C:\
		Text = C disk
	Item2
		Action = C:\Script.ahk
		Icon = AHK.png
	Skin = Black
Tip of the day? = No
Version = 1.00
)
FileAppend, %SomeData%, %DataPath%, UTF-8	; save to file
SomeData := ""		; not needed any more
return


Escape::ExitApp


Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
Hello Asking One :)

Yes it is - almost. My code you posted in codebox will not work for someone who copies it from there, because in codebox, tabs are automatically replaced with spaces (and tabs are important for this script because they define hierarchy). Therefore, I uploaded it on AutoHotkey.net - tabs are preserved there.

Crazy_Cat
  • Guests
  • Last active:
  • Joined: --
Thanks for the clarification!
Posted Image :lol:

flak
  • Members
  • 283 posts
  • Last active: Jan 01 2012 06:20 PM
  • Joined: 02 Oct 2009
My code you posted in codebox will not work for someone who copies it from there, because in codebox, tabs are automatically replaced with spaces (and tabs are important for this script because they define hierarchy).
Why don't you use `t?

shajul
  • Members
  • 571 posts
  • Last active: Aug 01 2015 03:45 PM
  • Joined: 15 Sep 2006
This is really nice. This makes loading and saving settings a breeze. Thanks for this :).
BTW, is there any chance that a tab can be substituted for two spaces (optionally)?
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor

Learning one
  • Members
  • 1483 posts
  • Last active: Jan 02 2016 02:30 PM
  • Joined: 04 Apr 2009
:!: I changed order for optional parameters in all functions to: Indent, Rows, Equal (Old order was: Rows, Equal, Indent)

@flak:
I prefer to see this
Menu
	Item1
		Action = C:\
		Text = C disk
instead of this
Menu
`tItem1
`t`tAction = C:\
`t`tText = C disk
@shajul: Sure. In example below, Indent parameter is two spaces instead of tab.
oData := ObjFromFile(DataPath, "  ")
ObjToFile(oData, DataPath, "  ")
User is free to adapt Indent, Rows and Equal parameters to fit his needs.

fredchf
  • Guests
  • Last active:
  • Joined: --
Hi Learning One!
Thanks for this helpful script. :D

bichlepa
  • Members
  • 62 posts
  • Last active: Dec 17 2016 08:45 PM
  • Joined: 04 Jul 2011

Thank you very much for that script! :)  I'm using it in my new project AutoHotFlow to store global variables, that can be objects, into files.

 

Edit: I noticed, I have overseen the big warning.  :shy: Now I'm using the "String-object-file" Script. It works the same but it's a little bit more bautiful.