XML encoding oddities
Mark Smith
lists at futilism.com
Mon Nov 10 12:30:30 EST 2008
Trevor, this is nice. I'd started doing something similar, but then
realised that what I was after for what I'm working on was a way to
neatly package up pretty much any non-binary data, array or not,
whatever platform, and send to to a linux server (also running
revolution) where it could be unpacked and used as is - hence the
encoding issue.
What I've come up with is considerably longer than yours :-) (Partly
because I've factored out quite a lot of stuff to sub-handlers).
But it seems to work well, and even produces slightly more compact
output than yours when dealing with chunks of data 2-3Kb or more in
size, which is no bad thing even in today's "bandwidth? what's
bandwidth?" world.
I also wrote a handy function arraysMatch() to test the input/output.
For what it's worth, here it all is, below,
Best,
Mark
-- pack and unpack are the 'high-level' functions
function pack pData
if pData is not an array then
put pData into tArray["futpak"]
put tArray into pData
end if
put atx(pData) into tXml
put base64encode(compress(tXml)) into tB64data
replace cr with empty in tB64data
return "futpak" & tB64data
end pack
-----
function unpack pData
if char 1 to 6 of pData is not "futpak" then return empty
put decompress(base64decode(char 7 to -1 of pData)) into tXml
put xta(tXml) into tArray
if keys(tArray) = "futpak" then
return tArray["futpak"]
else
return tArray
end if
end unpack
------------------------------------------------------------------------
--------------------------------------
-- turns any revolution array into xml. (not nice to look at, though)
-- array keys are stored as attributes of nodes
-- all element and attribute contents are utf8encoded and base64encoded
------------------------------------------------------------------------
--------------------------------------
function atx pArray
put "<revarray>" after tXml
put atxNodes(pArray) after tXml
put "</revarray>" after tXml
return tXml
end atx
private function atxNodes pArray pLevel
if pLevel is empty then put 0 into pLevel
add 1 to pLevel
repeat for each key k in pArray
add 1 to n
put "atx" & pLevel & "-" & n into tName
put "<" & tName && "key=" & q(b64U8encode(k)) & ">" after tXml
if pArray[k] is an array then
put atxNodes(pArray[k], pLevel) after tXml
else
put b64U8encode(pArray[k]) after tXml
end if
put "</" & tName & ">" after tXml
end repeat
return tXml
end atxNodes
------------------------------------------------------------------------
-----------------------
-- takes xml and attempts to turn it into an array
-- see atx() above.
------------------------------------------------------------------------
-----------------------
function xta pXml
put revCreateXmlTree(pXml, true, true, false) into tTree
put xtaNodes(tTree, "revarray") into tArray
revDeleteXmlTree tTree
return tArray
end xta
-----
private function xtaNodes pTree, pNode
put revXmlFirstChild(pTree, pNode) into tNode
repeat while tNode is not empty and "xmlerr" is not in tNode
put b64U8decode(revXmlAttribute(pTree, tNode, "key")) into tKey
if revXmlChildNames(pTree, tNode,cr,, false) is empty then
put b64U8decode(revXmlNodeContents(pTree, tNode)) into
tArray[tKey]
else
put xtaNodes(pTree, tNode) into tArray[tKey]
end if
put revXmlNextSibling(pTree, tNode) into tNode
end repeat
return tArray
end xtaNodes
-----
function utf8encode pString
return unidecode(uniencode(pString),"UTF8")
end utf8encode
-----
function utf8decode pString
return unidecode(uniencode(pString,"UTF8"))
end utf8decode
-----
function b64U8encode pData
put base64encode(utf8encode(pData)) into tEnc
replace cr with empty in tEnc
return tEnc
end b64U8encode
-----
function b64U8decode pData
return utf8decode(base64decode(pData))
end b64U8decode
-----
function arraysMatch a1, a2
put keys(a1) into k1 ; put keys(a2) into k2
sort lines of k1; sort lnes of k2
put (k1 = k2) into tArraysMatch
if tArraysMatch then
repeat for each key k in a1
if a1[k] is an array then
put arraysMatch(a1[k], a2[k]) into tArraysMatch
else
put (a1[k] = a2[k]) into tArraysMatch
end if
if not tArraysMatch then exit repeat
end repeat
end if
return tArraysMatch
end arraysMatch
-----
function q aString
return quote & aString & quote
end q
More information about the use-livecode
mailing list