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

_______________________________________________
use-revolution mailing list
use-revolution@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution

Reply via email to