Page 1 of 1

String indexes, spaces, and WriteTable()

Posted: Mon Nov 17, 2025 10:53 pm
by Flinx
I have a table with string indexes, and the strings come from outside the program and may also contain spaces. Now I wanted to write this table using WriteTable(), but this did not work.
The following example works with the legacy serializer, but with Adapter="Default" I get an “Error serializing item!” message. With the real strings in my program the legacy serializer stops at some of it with "Could not read all characters from file!", maybe other characters make problems too.
I know that spaces in the index also cause trouble elsewhere, because the dot syntax variant doesn't work with them either, but I wanted to report this anyway.
I see a solution in converting the strings to a hexadecimal representation or something similar or a MD5 hash, but perhaps there is an easier way.

Code: Select all

testtable={["a b"] = 1}
DebugPrint(testtable["a b"])

OpenFile(1, "test.json", #MODE_WRITE)
WriteTable(1, testtable, {Adapter = "Default"})
CloseFile(1)

Re: String indexes, spaces, and WriteTable()

Posted: Wed Nov 19, 2025 3:34 pm
by Flinx
So, my first solution was to use the index strings in Base64 coded form, but because I wanted the file human readable, I now build a serializable list and save this. And convert it back after reading. If someone is interested:

Code: Select all

Function  p_WriteNowPlayingTable()
	Local serializableTable=CreateList()
	If IsNil(gNowPlayingTable) Or IsTableEmpty(gNowPlayingTable) Then Return
	ForEach(gNowPlayingTable,
		Function(a, b)
			InsertItem(serializableTable, {a,b})
		EndFunction
	       )
	gLastNowPlayingSaveTime=gCurrentTimer
	Local filename$="NowPlayingStrings.json"
	Local err, id=?OpenFile(Nil, filename$, #MODE_WRITE)
	If err=#ERR_NONE
		WriteTable(id, serializableTable, {Adapter = "Default"})
		CloseFile(id)
	EndIf
EndFunction

Function  p_ReadNowPlayingTable()
	Local serializedTable
	Local filename$="NowPlayingStrings.json"
	Local err, id=?OpenFile(Nil, filename$, #MODE_READ)
	If err=#ERR_NONE
		serializedTable= ReadTable(id, {Adapter = "Default"})
		CloseFile(id)
		gNowPlayingTable={}
		ForEach(serializedTable,
			Function(a, b)
				gNowPlayingTable[b[0]]=b[1]
			EndFunction
		       )
	EndIf
EndFunction

Re: String indexes, spaces, and WriteTable()

Posted: Fri Nov 21, 2025 9:05 pm
by airsoftsoftwair
Flinx wrote: Mon Nov 17, 2025 10:53 pm I have a table with string indexes, and the strings come from outside the program and may also contain spaces.
The space character is currently reserved as a special marker for the data type serialized into a JSON key in case the data is non-standard. It is mentioned here. This is necessary so that Hollywood is able to serialize functions and binary data, e.g. if you do this:

Code: Select all

testtable={["a"] = Function(a,b) Return(a+b) EndFunction}
OpenFile(1, "test.json", #MODE_WRITE)
WriteTable(1, testtable, {Adapter = "Default"})
CloseFile(1)
The resulting JSON will look like this:

Code: Select all

{
	"a f": "G0hXQgEECAQGCAkJCLYJk2jn9X1BAgAAAAAAAAA/AAEAAAAAAgADAwAAAAEAAAABAAAAAQAAAAIAAAACAAAAAAAAAGEAAAAAAAIAAAACAAAAAAAAAGIAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAASwAAAiIAAQIigAAA"
}
You can see that there is an "f" behind the key name ("a"). This "f" tells Hollywood that the key data is to be interpreted as function data. When serializing binary data there'll be a "b" marker etc. That's why you currently have to find a way to avoid spaces in key names because they will be blocked.