Search content:

 

Personal Menu
Username:
Password:
Save password

Become a member

Forgot Password?

 

Don't miss these
Killer Transitions
Media Make & Go
MPEG Xtra Simple Control
UpDown Timer
cXtraTransitions3
WebXtra
Sprite Recorder
CatCube
Dual Button With Rollover Effect
SID6581
MediaMacros Xtras Mall
 

 

 

Behavior Store and restore Director objects as an XML string

Added on 4/19/2004

 

Compatibilities:
D9

This item has not yet been rated

Author: mildavw

This is a movie script containing two handlers: toXML() and fromXML(). These will convert the the following data types to XML and back. See the comments for more details and requirements. #list (containing any of the convertible types in this list) #propList (see #list) #void #integer #float #string #symbol #rect #point #color ( #rgb or #paletteIndex ) #date #member #castLib #sprite #xtra

-- XML Object Storage v1.0
-- Copyright 2004 Dave Miller, DMiller Studios
-- davmil@tenet.edu

-- Version History:
-- v20040215 - First Release

-- Requires a text member named "decoder" in a cast somewhere.
-- This also requires the Director MX 2004 XML parser Xtra

-- This is a group of scripts that allow one to store various Director objects as a giant string.
-- And as if that weren't handy enough, it also restores the objects from the string!
-- The string is damn near an XML document (all it it lacks is the tag at the beginning.)

-- Why would you want this? Well, if you want to store data anywhere, say, using setPrefs or on a server using postNetText,
-- you can only send the data as a string. What if you want to store a sprite reference? Or a vertexList? or a float with all of
-- its precision? You could use string() to convert your object and value() to restore it, but that has problems.  Try these in the
-- message window and see if you get back what you tried to convert:

-- x = VOID
-- arg = [1,2,x]
-- put value(string(arg))
--
-- the floatPrecision = 4
-- arg = 1.123456789
-- result = value(string(arg))
-- the floatPrecision = 9
-- put result

-- arg = ["I said," & QUOTE & "Oops!" & QUOTE]
-- put value(string(arg))

-- There are probably more, but those were enough reason for me to write the scripts below. Also, it is well formed XML so if you have
-- some other application that you want to send data to, you can use it for that too!

-- The two handlers to use are toXML() and fromXML()
-- The objects you can convert are listed in the case statement in the toXML() handler.
-- Lists and pLists can only contain convertible objects.
-- If you come with with other data that is storable this way, let me know and I'll share it with the world.

-- To see the scripts in action run these in the message window
--
-- x = toXML( [#p:1 , "test":[1,2,VOID] , #sym:rect(1,2,3,4) , #mem:member("decoder"), #sp:sprite(1) ]  ,1)
-- put x
-- put fromXML(x)
-- x = VOID
-- arg = [1,2,x]
-- put fromXML(toXML(arg))
--
-- the floatPrecision = 4
-- arg = 1.123456789
-- result = fromXML(toXML(arg))
-- the floatPrecision = 9
-- put result
--
-- arg = ["I said," & QUOTE & "Oops!" & QUOTE]
-- put fromXML(toXML(arg))


on toXML arg, aMode
  -- if aMode = 1 then make the XML human readable with returns and spaces.
  -- If aMode = 0 or VOID then save a few bytes and omit the dressing.
  
  vSpace = EMPTY
  if aMode > 0 then
    put RETURN after vSpace
    repeat with i = 1 to aMode-1
      put "  " after vSpace
    end repeat
  else
    aMode = -1
  end if
  
  txt = EMPTY
  case arg.ilk of
    (#void):
      put vSpace & "" after txt
    (#integer):
      put vSpace & "" & arg & "" after txt
    (#float):
      f = the floatPrecision
      the floatPrecision = 15
      put vSpace & "" & arg & "" after txt
      the floatPrecision = f
    (#string):
      if arg = EMPTY then
        put vSpace & "" & QUOTE & QUOTE & "" after txt
      else
        put vSpace & "" & enCode(arg) & "" after txt
      end if
    (#symbol):
      put vSpace & "" & enCode(string(arg)) & "" after txt
    (#rect):
      put vSpace & "" after txt
      repeat with i = 1 to 4
        put toXML(arg[i], aMode+1) after txt
      end repeat
      put vSpace & "
" after txt
    (#point):
      put vSpace & "

" after txt
      repeat with i = 1 to 2
        put toXML(arg[i]) after txt
      end repeat
      put vSpace & "

" after txt
    (#list):
      put vSpace & "" after txt
      lim = arg.count
      repeat with i = 1 to lim
        put toXML(arg[i], aMode+1) after txt
      end repeat
      put vSpace & "
" after txt
    (#propList):
      put vSpace & "" after txt
      lim = arg.count
      repeat with i = 1 to lim
        put toXML( arg.getPropAt(i) ,aMode+1 ) after txt
        put toXML( arg[i] ,aMode+1 ) after txt
      end repeat
      put vSpace & "
" after txt
    (#color):
      put vSpace & "" after txt  
      case arg.colorType of
        (#rgb):
          put toXML( arg.red  ,aMode+1 ) after txt
          put toXML( arg.green  ,aMode+1 )  after txt
          put toXML( arg.blue  ,aMode+1 ) after txt
        (#paletteIndex):
          put arg.paletteIndex after txt
      end case
      put vSpace & "
" after txt
    (#date):
      put vSpace & "" after txt
      put toXML( arg.year  ,aMode+1 ) after txt
      put toXML( arg.month  ,aMode+1 ) after txt
      put toXML( arg.day  ,aMode+1 ) after txt
      put vSpace & "
" after txt
    (#member):
      put vSpace & "" after txt
      put toXML( arg.name ,aMode+1 ) after txt
      --put toXML( arg.number ,aMode+1 ) after txt
      -- put toXML( arg.castLibNum  ,aMode+1 ) after txt
      put vSpace & "
" after txt
    (#castLib):
      put vSpace & "" & arg.number & "" after txt
    (#sprite):
      put vSpace & "" & arg.spriteNum & "" after txt
    (#xtra):
      put vSpace & "" & enCode( arg.name ) & "" after txt
    otherwise
      if voidP(arg.ill) then
        alert("XML parser error: Could not find a data type for" && arg)
      else
        alert("XML parser error: Data type" && arg.ilk &&  "not supported for XML conversion")
      end if
  end case
  return txt
end toXML

on fromXML aXML
  -- aXML is a string of XML created by toXML above.
  -- It returns the object(s) described in the XML
  vX = new(xtra "xmlparser")
  errCode = vX.parseString(aXML)
  errorString = vX.getError()
  if voidP(errorString) then
    vResult = convertXML( vX.makePropList() )
  else
    alert "Error parsing XML string:" && errorString
    exit
  end if
  return vResult
end fromXML

on convertXML aList
  --put aList
  -- XML to object converter.  Expects the makePropList() from an XML object created by toXML  
  case aList.name of
    ("v"): return VOID
    ("i"): return integer( aList.charData )
    ("f"): return float( aList.charData )
    ("s"): return decode( aList.charData )
    ("sy"): return symbol( decode(aList.charData) )
    ("r"): return rect( convertXML(aList.child[1]), convertXML(aList.child[2]), convertXML(aList.child[3]), convertXML(aList.child[4]) )
    ("p"): return point ( convertXML( aList.child[1]) , convertXML(aList.child[2]) )
    ("ll"):
      vList = []
      lim = aList.child.count
      repeat with i = 1 to lim
        vList.add( convertXML( aList.child[i] ) )
      end repeat
      return vList
    ("pl"):
      vList = [:]
      lim = aList.child.count/2
      repeat with i = 1 to lim
        vList.addProp( convertXML( aList.child[i*2-1] ) , convertXML( aList.child[i*2] ) )
      end repeat
      return vList  
    ("c"):
      if aList.child.count = 0 then
        return paletteIndex( integer(aList.charData) )
      else
        return rgb( integer(aList.child[1].charData), integer(aList.child[2].charData), integer(aList.child[3].charData) )        
      end if
    ("d"): return date ( integer(aList.child[1].charData) , integer(aList.child[2].charData), integer(aList.child[3].charData) )
    ("m"): return member(aList.child[1].charData)
      --return member integer(aList.child[1].charData) of castLib integer(aList.child[2].charData)
    ("cl"): return castLib integer(aList.charData)
    ("sp"): return sprite integer(aList.charData)
    ("x"): return xtra( decode ( aList.charData ) )
    otherwise
      alert("Can't convert XML" && aList.name && "to data type.")
      return VOID
  end case
end convertXML

-- The next two handlers convert special characters for XML.  e.g.  & <=> &
-- It requires a text member named "decoder" in a cast somewhere.
on deCode aTxt
  
  -- replace returns with


  newTxt = EMPTY
  the itemDelimiter = RETURN
  lim = aTxt.items.count
  repeat with i = 1 to lim
    put aTxt.item[i] after newTxt
    if i < lim then put "
" after newTxt
  end repeat
  
  -- use the internal HTML handler to decode.
  member("decoder").html = "" & newTxt & ""  
  aTxt = member("decoder").text
  return (aTxt)
end deCode

on enCode aTxt
  if aTxt = "" then return EMPTY
  vCharList = [ ["&","&"] , ["<","<"] , [">",">"] , [QUOTE,"""] , ["'","'"] ] -- "&" must be first in this list!
  lim = vCharList.count
  repeat with i = 1 to lim
    the itemDelimiter = vCharList[i][1]
    lim2 = aTxt.item.count
    if lim2 > 1 then
      tempTxt = EMPTY
      repeat with j = 1 to lim2
        put aTxt.item[j] after tempTxt
        if j < lim2 then put vCharList[i][2] after tempTxt
      end repeat
      aTxt = tempTxt
    end if
  end repeat
  
  return aTxt
end enCode  

 


Upload Provided by ABCUpload ASP

Contact

MMI
22 West Court Sq
Suite 2C
Newnan, GA 30263
USA

Fax - (206) 339-5833

Send e-mail