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