gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog libamf/Makefile.am libamf/amf.c...


From: Rob Savoye
Subject: [Gnash-commit] gnash ChangeLog libamf/Makefile.am libamf/amf.c...
Date: Mon, 31 Dec 2007 00:26:49 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    07/12/31 00:26:49

Modified files:
        .              : ChangeLog 
        libamf         : Makefile.am amf.cpp amf.h lcshm.cpp lcshm.h 
                         rtmp.h sol.cpp sol.h 
        testsuite/libamf.all: Makefile.am test_sol.cpp 
Added files:
        libamf         : element.cpp element.h 
        testsuite/libamf.all: test_el.cpp 

Log message:
                * libamf/element.{cpp,h}: New Elemnent class to represent an AMF
                element. 
                * libamf/Makefile.am: Add element.{cpp,h}, and lcshm.{cpp,h}.
                * libamf/amf.{cpp,h}: Use Element class instead of amf_element_t
                everywhere. Move object types to element.h. Refactor all 
encoders
                and decoders. Ifdef out for now stuff that should really be in
                rtmp.
                * libamf/lcshm.{cpp,h}: Use Element class instead of 
amf_element_t
                everywhere. 
                * libamf/sol.{cpp,h}: Use Element class instead of amf_element_t
                everywhere. Use new style encoders and decoders.
                * testsuite/libamf.all/Makefile.am: Add new test_el test case 
for
                testing the Element class.
                * testsuite/libamf.all/test_sol.cpp: Use Element class instead 
of
                amf_element_t everywhere. Use new style encoders and decoders.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5276&r2=1.5277
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/Makefile.am?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.cpp?cvsroot=gnash&r1=1.51&r2=1.52
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.h?cvsroot=gnash&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/rtmp.h?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/sol.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/sol.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/Makefile.am?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_sol.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_el.cpp?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5276
retrieving revision 1.5277
diff -u -b -r1.5276 -r1.5277
--- ChangeLog   30 Dec 2007 16:18:05 -0000      1.5276
+++ ChangeLog   31 Dec 2007 00:26:47 -0000      1.5277
@@ -1,5 +1,21 @@
 2007-12-30  Rob Savoye  <address@hidden>
 
+       * libamf/element.{cpp,h}: New Elemnent class to represent an AMF
+       element. 
+       * libamf/Makefile.am: Add element.{cpp,h}, and lcshm.{cpp,h}.
+       * libamf/amf.{cpp,h}: Use Element class instead of amf_element_t
+       everywhere. Move object types to element.h. Refactor all encoders
+       and decoders. Ifdef out for now stuff that should really be in
+       rtmp.
+       * libamf/lcshm.{cpp,h}: Use Element class instead of amf_element_t
+       everywhere. 
+       * libamf/sol.{cpp,h}: Use Element class instead of amf_element_t
+       everywhere. Use new style encoders and decoders.
+       * testsuite/libamf.all/Makefile.am: Add new test_el test case for
+       testing the Element class.
+       * testsuite/libamf.all/test_sol.cpp: Use Element class instead of
+       amf_element_t everywhere. Use new style encoders and decoders.
+       
        * libamf/lcshm.{cpp,h}: New LcShm class for manipulating AMF
        objects as used within LocalConnection shared memory segments.
 

Index: libamf/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/libamf/Makefile.am,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- libamf/Makefile.am  20 Dec 2007 03:13:41 -0000      1.30
+++ libamf/Makefile.am  31 Dec 2007 00:26:48 -0000      1.31
@@ -15,15 +15,17 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-# $Id: Makefile.am,v 1.30 2007/12/20 03:13:41 rsavoye Exp $
+# $Id: Makefile.am,v 1.31 2007/12/31 00:26:48 rsavoye Exp $
 
 AUTOMAKE_OPTIONS = 
 
 pkglib_LTLIBRARIES = libgnashamf.la
 libgnashamf_la_SOURCES = \
        amf.cpp \
-       rtmp.cpp \
+       element.cpp \
+       lcshm.cpp \
        sol.cpp
+#      rtmp.cpp
 
 libgnashamf_la_LIBADD = \
        $(top_builddir)/libbase/libgnashbase.la
@@ -42,6 +44,8 @@
 noinst_HEADERS = \
        amfutf8.h \
        amf.h \
+       element.h \
+       lcshm.h \
        rtmp.h \
        protocol.h \
        sol.h

Index: libamf/amf.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.cpp,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -b -r1.51 -r1.52
--- libamf/amf.cpp      26 Dec 2007 05:37:32 -0000      1.51
+++ libamf/amf.cpp      31 Dec 2007 00:26:48 -0000      1.52
@@ -32,7 +32,7 @@
 
 #include "log.h"
 #include "amf.h"
-#include "as_object.h"
+#include "element.h"
 #include "amfutf8.h"
 #include <boost/cstdint.hpp> // for boost::?int??_t
 
@@ -42,63 +42,41 @@
 namespace amf 
 {
 
-// These are used to print more intelligent debug messages
-const char *astype_str[] = {
-    "Number",
-    "Boolean",
-    "String",
-    "Object",
-    "MovieClip",
-    "Null",
-    "Undefined",
-    "Reference",
-    "ECMAArray",
-    "ObjectEnd",
-    "StrictArray",
-    "Date",
-    "LongString",
-    "Unsupported",
-    "Recordset",
-    "XMLObject",
-    "TypedObject"
-};
-
-// These are the textual responses
-const char *response_str[] = {
-    "/onStatus",
-    "/onResult",
-    "/onDebugEvents"
-};
-
 AMF::AMF() 
     : _type(NONE),
+#if 0
       _amf_index(0),
       _header_size(0),
       _total_size(0),
       _packet_size(0),
       _amf_data(0),
       _seekptr(0),
+#endif
       _mystery_word(0)
 {
 //    GNASH_REPORT_FUNCTION;
 }
 
-AMF::AMF(int size) 
-    : _type(NONE),
-      _amf_index(0),
-      _header_size(0),
-      _total_size(0),
-      _packet_size(0),
-      _amf_data(0),
-      _mystery_word(0)
-{
-//    GNASH_REPORT_FUNCTION;
-    if (!_amf_data) {
-        _amf_data = new uint8_t(size+1);
-        memset(_amf_data, 0, size+1);
-    }
-    _seekptr = _amf_data;
-}
+// AMF::AMF(int size) 
+//     : _type(NONE),
+// #if 0
+//       _amf_index(0),
+//       _header_size(0),
+//       _total_size(0),
+//       _packet_size(0),
+//       _amf_data(0),
+// #endif
+//       _mystery_word(0)
+// {
+// //    GNASH_REPORT_FUNCTION;
+// #if 0
+//     if (!_amf_data) {
+//         _amf_data = new uint8_t(size+1);
+//         memset(_amf_data, 0, size+1);
+//     }
+//     _seekptr = _amf_data;
+// #endif
+// }
 
 AMF::~AMF()
 {
@@ -163,105 +141,114 @@
     return word;
 }
 
-
+#if 0
 bool
-AMF::parseAMF(boost::uint8_t *in)
+AMF::parseAMF(boost::uint8_t * /* in */)
 {
 //    GNASH_REPORT_FUNCTION;
 
+#if 0
     boost::uint8_t *x = in;
 
-    while (*x != OBJECT_END) {
-        x = readElement(x);
+    while (*x != Element::OBJECT_END) {
+        x = readElements(x);
     }
     return true;
+#endif
+    return false;
 }
 
-boost::uint8_t *
-AMF::readElement(void *in)
+vector<AMF::amf_element_t *> *
+AMF::readElements(boost::uint8_t *in)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
 
-    boost::uint8_t *x = static_cast<boost::uint8_t *>(in);
+    boost::uint8_t *x = in;
     astype_e type = (astype_e)*x;
     bool boolshift;
     const char *mstr = NULL;
-    amfnum_t num;
-    amfnum_t nanosecs;
+    double *num;
+    double nanosecs;
     short length;
     
-//    log_msg(_("Type is %s"), astype_str[type]);
+    vector<AMF::amf_element_t> list;
+    AMF::amf_element_t el;
+    
 
-    x++;                        // skip the type byte
+    log_msg(_("Type is %s"), astype_str[type]);
+
+//    x++;                        // skip the type byte
     switch (type) {
-      case NUMBER:
+      case Element::NUMBER:
          // AMF numbers are 64-bit big-endian integers.
-          num = *(amfnum_t *)swapBytes(x+1, 8);
-//          log_msg(_("Number is " AMFNUM_F), num);
+         num = extractNumber(x);
+//       log_msg(_("Number is " AMFNUM_F), num));
           break;
-      case BOOLEAN:
+      case Element::BOOLEAN:
           boolshift = *x;
-//          log_msg(_("Boolean is %d"), boolshift);
+          log_msg(_("Boolean is %d"), boolshift);
           break;
-      case STRING:
+      case Element::STRING:
+          string str = extractString(x);
 //        int length = *(short *)swapBytes(x, 2);
-          length = *(short *)x;
-          x+=2;                  // skip the length bytes
-          mstr = new char[length+1];
+//           length = *(short *)x;
+//           x+=2;                  // skip the length bytes
+//           mstr = new char[length+1];
 //           memset(mstr, 0, length+1);
 //           memcpy(mstr, x, length);
           // The function converts the multibyte string beginning at
           // *src to a sequence of wide characters as if by repeated
           // calls of the form:
 //          mbsrtowcs
-//          log_msg(_("String is %s"), mstr);
+                 log_msg(_("String is %s"), mstr);
           break;
-      case OBJECT:
+      case Element::OBJECT:
+//          return reinterpret_cast<uint8_t *>(extractObject(x));
 //          readElement();
           log_unimpl("Object AMF decoder");
           break;
-      case MOVIECLIP:
+      case Element::MOVIECLIP:
         log_unimpl("MovieClip AMF decoder");
           break;
-      case UNSUPPORTED:
+      case Element::UNSUPPORTED:
         log_unimpl("Unsupported AMF decoder");
           break;
-      case NULL_VALUE: 
+      case Element::NULL_VALUE: 
           log_unimpl("Null AMF decoder");
           break;
-      case UNDEFINED:
+      case Element::UNDEFINED:
           log_msg(_("Undefined element"));
           break;
-      case REFERENCE:
+      case Element::REFERENCE:
           log_unimpl("Reference AMF decoder");
           break;
-      case ECMA_ARRAY:
+      case Element::ECMA_ARRAY:
           log_unimpl("ECMAArray AMF decoder");
           break;
-      case OBJECT_END:
+      case Element::OBJECT_END:
           log_unimpl("ObjectEnd AMF decoder");
           break;
-      case STRICT_ARRAY:
+      case Element::STRICT_ARRAY:
           log_unimpl("StrictArray AMF decoder");
           break;
-      case DATE:
-          nanosecs = *(amfnum_t *)swapBytes(x+1, 8);
+      case Element::DATE:
+          nanosecs = *(double *)swapBytes(x+1, 8);
 //          log_msg(_("Date is " AMFNUM_F " nanoseconds"), nanosecs);
           break;
-      case LONG_STRING:
+      case Element::LONG_STRING:
 //          int length = *(short *)swapBytes(x, 4);
           x+=4;                  // skip the length bytes
 //        mstr = new char[length+1];
 //          memcpy(mstr, x, length);
 //          log_msg(_("String is %s"), mstr);
           break;
-      case RECORD_SET:
+      case Element::RECORD_SET:
           log_unimpl("Recordset AMF decoder");
           break;
-      case XML_OBJECT:
+      case Element::XML_OBJECT:
           log_unimpl("XMLObject AMF decoder");
           break;
-      case TYPED_OBJECT:
+      case Element::TYPED_OBJECT:
           log_unimpl("TypedObject AMF decoder");
           break;
       default:
@@ -271,7 +258,292 @@
     
     return x;
 }
+#endif
+
 
+//
+// Methods for encoding data into big endian formatted raw AMF data.
+//
+
+/// Encode a string object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeString(const char *str)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::uint16_t length;
+    
+    int pktsize = strlen(str) + AMF_HEADER_SIZE;
+    // Encode a string value. The data follows a 2 byte length
+    // field. (which must be big-endian)
+    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = Element::STRING;
+    log_debug("Encoded data size is going to be %d", length);
+    swapBytes(&length, 2);
+    memcpy(x, &length, 2);
+    x += 2;
+    memcpy(x, str, pktsize - AMF_HEADER_SIZE);
+    x += pktsize - AMF_HEADER_SIZE;
+    
+    return x;
+}
+
+/// Encode a 64 bit number
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeNumber(double indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_NUMBER_SIZE + AMF_HEADER_SIZE;
+    double num;
+    // Encode the data as a 64 bit, big-endian, numeric value
+    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = (char)Element::NUMBER;
+    memcpy(&num, &indata, AMF_NUMBER_SIZE);
+    swapBytes(&num, AMF_NUMBER_SIZE);
+    memcpy(x, &num, AMF_NUMBER_SIZE);
+    x += pktsize - AMF_HEADER_SIZE;
+    
+    return x;
+}
+
+/// Encode a Boolean object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+/// Although a boolean is one byte in size, swf uses 16bit short integers
+/// heavily, so this value is also a short.
+boost::uint8_t *
+AMF::encodeBoolean(bool flag)
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_HEADER_SIZE;
+
+    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    // Encode a boolean value. 0 for false, 1 for true
+    *x++ = (char)Element::BOOLEAN;
+    *x = *reinterpret_cast<boost::uint8_t *>(flag);
+    swapBytes(x, 2);
+    x += sizeof(boost::uint16_t);
+    
+    return x;
+}
+
+/// Encode an object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeObject(const boost::uint8_t *data, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_HEADER_SIZE + size;
+
+    // Encode an XML object. The data follows a 4 byte length
+    // field. (which must be big-endian)
+    boost::uint8_t *x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = Element::OBJECT;
+    uint32_t num = size;
+    swapBytes(&num, 4);
+    memcpy(x, data, size);
+    
+    return x;
+}
+
+/// Encode an "Undefined" object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeUndefined()
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_HEADER_SIZE;;
+    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = (char)Element::UNDEFINED;
+//    *x = *static_cast<const char *>(flag);
+    x += pktsize - AMF_HEADER_SIZE;
+    
+    return x;
+}
+
+/// Encode an "Undefined" object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeUnsupported()
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_HEADER_SIZE;;
+    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = (char)Element::UNSUPPORTED;
+//    *x = *static_cast<const char *>(flag);
+    x += pktsize - AMF_HEADER_SIZE;
+    
+    return x;
+}
+
+/// Encode a Date
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *encodeDate(boost::uint8_t *data)
+{
+//    GNASH_REPORT_FUNCTION;
+    int pktsize = AMF_HEADER_SIZE;;
+    boost::uint8_t *x = new boost::uint8_t[pktsize + 1];
+    memset(x, 0, pktsize);
+    *x++ = Element::DATE;
+    double num = *reinterpret_cast<const double*>(data);
+    swapBytes(&num, 8);
+    memcpy(x, &num, 8);
+    
+    return x;
+}
+/// Encode a "NULL" object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeNull()
+{
+//    GNASH_REPORT_FUNCTION;
+
+    log_unimpl("NULL AMF object not supported yet");
+    return 0;
+}
+
+/// Encode an XML object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeXMLObject(boost::uint8_t * /*data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("XML AMF objects not supported yet");
+    
+    return 0;
+}
+
+/// Encode a Typed Object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeTypedObject(boost::uint8_t * /* data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Typed AMF objects not supported yet");
+
+    return 0;
+}
+
+/// Encode a Reference to an object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeReference(boost::uint8_t * /* data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Reference AMF objects not supported yet");
+    
+    return 0;
+}
+
+/// Encode a Movie Clip
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeMovieClip(boost::uint8_t * /*data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Movie Clip AMF objects not supported yet");
+    
+    return 0;
+}
+
+/// Encode an ECMA Array
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeECMAArray(boost::uint8_t * /*data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("ECMA Array AMF objects not supported yet");
+    
+    return 0;
+}
+
+/// Encode a long string
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeLongString(boost::uint8_t * /* data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Long String AMF objects not supported yet");
+    
+    return 0;
+}
+
+/// Encode a Record Set
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeRecordSet(boost::uint8_t * /* data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Reecord Set AMF objects not supported yet");
+    
+    return 0;
+}
+
+
+/// Encode a Strict Array
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeStrictArray(boost::uint8_t * /* data */, int /* size */)
+{
+//    GNASH_REPORT_FUNCTION;
+    log_unimpl("Strict Array AMF objects not supported yet");
+    
+    return 0;
+}
 
 /// \brief Write an AMF element
 ///
@@ -291,178 +563,78 @@
 /// characters, but for now we just leave them as standard multibyte
 /// characters.
 boost::uint8_t *
-AMF::encodeElement(astype_e type, const void *in, int nbytes)
+AMF::encodeElement(Element *el)
 {
 //    GNASH_REPORT_FUNCTION;
 
-    amfnum_t num;
-    int pktsize = 0;
-    boost::uint8_t* out = NULL;
-    boost::uint8_t* x = NULL;
-
-    // Packets are of varying length. A few pass in a byte count, but
-    // most packets have a hardcoded size.
-    switch (type) {
-        // Encode the data as a 64 bit, big-endian, numeric value
-      case NUMBER:
-          // one 64 bit number
-          pktsize = AMF_NUMBER_SIZE + AMF_HEADER_SIZE;
-          break;
-      case BOOLEAN:
-          pktsize = 2;          // just one data byte
-          break;
-      case STRING:
-          pktsize = nbytes + 3; // two length bytes after the header
-          break;
-      case OBJECT:
-          pktsize = 0;          // look for the terminator
-          break;
-      case MOVIECLIP:
-          pktsize = -1;         // FIXME: no clue
-          break;
-      case NULL_VALUE: 
-          pktsize = -1;         // FIXME: no clue
-          break;
-      case UNDEFINED:
-         // just the header, no data
-          pktsize = nbytes + 3; // two length bytes after the header
-          break;
-      case REFERENCE:
-          pktsize = -1;         // FIXME: no clue
-          break;
-      case ECMA_ARRAY:
-          pktsize = 0;          // look for the terminator
-          break;
-      case OBJECT_END:
-          pktsize = -1;         // FIXME: no clue
-          break;
-      case STRICT_ARRAY:
-          pktsize = nbytes + 5; // 4 length bytes, then data
+    switch (el->getType()) {
+      case Element::NOTYPE:
+         return 0;
           break;
-      case DATE:
-          pktsize = 9;          // one 64 bit number
+      case Element::NUMBER:
+         return encodeNumber(*(reinterpret_cast<double *>(el->getData())));
           break;
-      case LONG_STRING:
-          pktsize = nbytes + 5; // 4 length bytes, then data
+      case Element::BOOLEAN:
+         return encodeBoolean(*(reinterpret_cast<bool *>(el->getData())));
           break;
-      case UNSUPPORTED:
-          pktsize = -1;         // FIXME: no clue
+      case Element::STRING:
+         return encodeBoolean(*(reinterpret_cast<const char 
*>(el->getData())));
           break;
-      case RECORD_SET:
-          pktsize = -1;         // FIXME: no clue
+      case Element::OBJECT:
+         return encodeObject(el->getData(), el->getLength());
           break;
-      case XML_OBJECT:
-          pktsize = nbytes + 5;// 4 length bytes, then data
+      case Element::MOVIECLIP:
+         return encodeMovieClip(el->getData(), el->getLength());
           break;
-      case TYPED_OBJECT:
-          pktsize = 0;          // look for the terminator
+      case Element::NULL_VALUE: 
+         return encodeNull();
           break;
-// FIXME, shouldn't there be a default case here?
-      default:
-          log_error("Unknown AMF packet type %d", type);
-          return 0;
-    };
-
-    log_debug("pktsize:%d, nbytes:%d", pktsize, nbytes);
-    
-    switch (type) {
-      case NUMBER:
-          // Encode the data as a 64 bit, big-endian, numeric value
-          x = out = new boost::uint8_t[pktsize];
-          memset(x, 0, pktsize);
-          *x++ = (char)AMF::NUMBER;
-          memcpy(&num, in, AMF_NUMBER_SIZE);
-          swapBytes(&num, AMF_NUMBER_SIZE);
-          memcpy(x, &num, AMF_NUMBER_SIZE);
+      case Element::UNDEFINED:
+         return encodeUndefined();
           break;
-      case BOOLEAN:
-          // Encode a boolean value. 0 for false, 1 for true
-          out = new boost::uint8_t[pktsize];
-          x = out;    
-          *x++ = (char)AMF::BOOLEAN;
-          *x = *static_cast<const char *>(in);
+      case Element::REFERENCE:
+         return encodeReference(el->getData(), el->getLength());
           break;
-      case STRING:
-          // Encode a string value. The data follows a 2 byte length
-          // field. (which must be big-endian)
-          x = out = new uint8_t[pktsize];
-          memset(x, 0, pktsize);
-          *x++ = AMF::STRING;
-          num = nbytes;
-          log_debug("Encoded data size is going to be " AMFNUM_F, num);
-          swapBytes(&num, 2);
-          log_debug("After swapping, it's " AMFNUM_F, num);
-          memcpy(x, &num, 2);
-          x+=2;
-          memcpy(x, in, nbytes);
-          break;
-      case OBJECT:
-          log_unimpl("Object AMF encoder");
+      case Element::ECMA_ARRAY:
+         return encodeECMAArray(el->getData(), el->getLength());
           break;
-      case MOVIECLIP:
-          log_unimpl("MovieClip AMF encoder");
+         // The Object End gets added when creating the object, so we can jusy 
ignore it here.
+      case Element::OBJECT_END:
           break;
-      case NULL_VALUE: 
-          log_unimpl("Null AMF encoder");
+      case Element::STRICT_ARRAY:
+         return encodeStrictArray(el->getData(), el->getLength());
           break;
-      case UNDEFINED:
-          x = out = new boost::uint8_t[pktsize];
-          memset(x, 0, pktsize);
-          *x++ = AMF::UNDEFINED;
-          num = nbytes;
-          swapBytes(&num, 2);
-          memcpy(x, &num, 2);
-          x+=2;
-          memcpy(x, in, nbytes);
-         break;
-      case REFERENCE:
-          log_unimpl("Reference AMF encoder");
-          break;
-      case ECMA_ARRAY:
-          log_unimpl("ECMAArray AMF encoder");
-          break;
-      case OBJECT_END:
-          log_unimpl("ObjectEnd AMF encoder");
-          break;
-      case STRICT_ARRAY:
-          log_unimpl("StrictArray AMF encoder");
-          break;
-          // Encode the date as a 64 bit, big-endian, numeric value
-      case DATE:
-          x = out = new boost::uint8_t[pktsize];
-          memset(x, 0, pktsize);
-          *x++ = AMF::DATE;
-          num = *static_cast<const amfnum_t*>(in);
-          swapBytes(&num, 8);
-          memcpy(x, &num, 8);
+      case Element::DATE:
+//       return encodeDate(el->getData());
           break;
-      case LONG_STRING:
-          log_unimpl("LongString AMF encoder");
+      case Element::LONG_STRING:
+         return encodeLongString(el->getData(), el->getLength());
           break;
-      case UNSUPPORTED:
-          log_unimpl("Unsupported AMF encoder");
+      case Element::UNSUPPORTED:
+         return encodeUnsupported();
           break;
-      case RECORD_SET:
-          log_unimpl("Recordset AMF encoder");
+      case Element::RECORD_SET:
+         return encodeRecordSet(el->getData(), el->getLength());
           break;
-      case XML_OBJECT:
+      case Element::XML_OBJECT:
+         return encodeXMLObject(el->getData(), el->getLength());
           // Encode an XML object. The data follows a 4 byte length
           // field. (which must be big-endian)
-          x = out = new boost::uint8_t[pktsize];
-          memset(x, 0, pktsize);
-          *x++ = AMF::STRING;
-          num = nbytes;
-          swapBytes(&num, 4);
-          memcpy(x, in, nbytes);
           break;
-      case TYPED_OBJECT:
-          log_unimpl("TypedObject AMF encoder");
+      case Element::TYPED_OBJECT:
+         return encodeTypedObject(el->getData(), el->getLength());
+          break;
+         // This is a Gnash specific value
+      case Element::VARIABLE:
+         return 0;
           break;
     };
     
-    return out;
+    // you should never get here
+    return 0;
 }
 
+#if 0
 /// \brief \ Each RTMP header consists of the following:
 ///
 /// * Index & header size - The header size and amf channel index.
@@ -513,7 +685,6 @@
     return out;
 }
 
-#if 0
 /// \brief Each header consists of the following:
 ///
 /// * UTF string (including length bytes) - name
@@ -633,7 +804,7 @@
 }
 #endif
 
-
+#if 0
 AMF::astype_e
 AMF::extractElementHeader(void *in)
 {
@@ -648,67 +819,67 @@
 //    GNASH_REPORT_FUNCTION;
 
     char *x = (char *)in;
-    astype_e type = (astype_e)*x;
+    Element::astype_e type = (Element::astype_e)*x;
     x++;                        // skip the header byte
     
     switch (type) {
-      case NUMBER:              // a 64 bit numeric value
+      case Element::NUMBER:              // a 64 bit numeric value
           return 8;
           break;
-      case BOOLEAN:             // a single byte
+      case Element::BOOLEAN:             // a single byte
           return 1;
           break;
-      case STRING:              // the length is a 2 byte value
+      case Element::STRING:              // the length is a 2 byte value
                //FIXME, there are all kinds of byte order problems in this 
code.
           return (short)*(short *)x;
           break;
-      case OBJECT:
+      case Element::OBJECT:
           return x - strchr(x, TERMINATOR);
           break;
-      case MOVIECLIP:
+      case Element::MOVIECLIP:
           return -1;
           log_unimpl("MovieClip AMF extractor");
           break;
-      case NULL_VALUE: 
+      case Element::NULL_VALUE: 
           return -1;
           log_unimpl("Null AMF extractor");
           break;
-      case UNDEFINED:
+      case Element::UNDEFINED:
           return 0;
           break;
-      case REFERENCE:
+      case Element::REFERENCE:
           return -1;
           log_unimpl("Reference AMF extractor");
           break;
-      case ECMA_ARRAY:
+      case Element::ECMA_ARRAY:
           return x - strchr(x, TERMINATOR);
           break;
-      case OBJECT_END:
+      case Element::OBJECT_END:
           return -1;
           log_unimpl("ObjectEnd AMF extractor");
           break;
-      case STRICT_ARRAY:         // the length is a 4 byte value
+      case Element::STRICT_ARRAY:         // the length is a 4 byte value
 //          return (int *)x;
           break;
-      case DATE:              // a 64 bit numeric value
+      case Element::DATE:              // a 64 bit numeric value
           return 8;
           break;
-      case LONG_STRING:
+      case Element::LONG_STRING:
           return -1;
           log_unimpl("LongString AMF extractor");
           break;
-      case UNSUPPORTED:
+      case Element::UNSUPPORTED:
           return -1;
           log_unimpl("Unsupported AMF extractor");
           break;
-      case RECORD_SET:
+      case Element::RECORD_SET:
           return -1;
           log_unimpl("Recordset AMF extractor");
           break;
-      case XML_OBJECT:           // the length is a 4 byte value
+      case Element::XML_OBJECT:           // the length is a 4 byte value
 //          return (int)*(int *)x;
           break;
-      case TYPED_OBJECT:
+      case Element::TYPED_OBJECT:
           return x - strchr(x, TERMINATOR);
           break;
     };
@@ -716,14 +887,14 @@
     return 0;
 }
 
-boost::int8_t *
+char *
 AMF::extractString(const boost::uint8_t *in)
 {
 //    GNASH_REPORT_FUNCTION;
     boost::int8_t *buf = NULL;
     boost::uint8_t *x = const_cast<boost::uint8_t *>(in);
     
-    if (*x == AMF::STRING) {
+    if (*x == Element::STRING) {
         x++;
         short length = *(reinterpret_cast<const short *>(x));
         swapBytes(&length, 2);
@@ -736,21 +907,22 @@
         log_error("Tried to extract AMF string from non String object!");
     }
     
-    return buf;
+    return reinterpret_cast<char *>(buf);
 }
 
-amfnum_t *
+double
 AMF::extractNumber(const boost::uint8_t *in)
 {
 //    GNASH_REPORT_FUNCTION;    
     boost::uint8_t *x = const_cast<uint8_t *>(in);
-    amfnum_t *num = new amfnum_t;
-    memset(num, 0, AMF_NUMBER_SIZE);
+//    double *num = new double;
+    double num = 0.0;
+//    memset(num, 0, AMF_NUMBER_SIZE);
     
-    if (*x == AMF::NUMBER) {
+    if (*x == Element::NUMBER) {
         x++;
-        memcpy(num, x, AMF_NUMBER_SIZE);
-        swapBytes(num, AMF_NUMBER_SIZE);
+        memcpy(&num, x, AMF_NUMBER_SIZE);
+        swapBytes(&num, AMF_NUMBER_SIZE);
     } else {
         log_error("Tried to extract AMF Number from non Number object!");
     }
@@ -758,7 +930,7 @@
     return num;
 }
 
-AMF::amf_element_t *
+Element &
 AMF::createElement(amf_element_t *el, astype_e type,
                  const std::string &name, boost::uint8_t *data, int nbytes)
 {
@@ -772,30 +944,30 @@
     return el;
 }
 
-AMF::amf_element_t *
-AMF::createElement(amf_element_t *el, const char *name, amfnum_t data)
-{
-//    GNASH_REPORT_FUNCTION;
-    string str = name;
-    return createElement(el, str, data);
-}
+// AMF::amf_element_t *
+// AMF::createElement(amf_element_t *el, const char *name, double data)
+// {
+// //    GNASH_REPORT_FUNCTION;
+//     string str = name;
+//     return createElement(el, str, data);
+// }
 
-AMF::amf_element_t *
-AMF::createElement(amf_element_t *el, const std::string &name, amfnum_t data)
-{
-//    GNASH_REPORT_FUNCTION;
-    log_debug("Creating element %s", name.c_str());
+// AMF::amf_element_t *
+// AMF::createElement(amf_element_t *el, const std::string &name, double data)
+// {
+// //    GNASH_REPORT_FUNCTION;
+//     log_debug("Creating element %s", name.c_str());
 
-    el->type = AMF::NUMBER;
-    el->name = name;
-    el->length = AMF_NUMBER_SIZE;
-//    char *numptr = (char *)&data;
-    el->data = new boost::uint8_t[AMF_NUMBER_SIZE + 1];
-    memset(el->data, 0, AMF_NUMBER_SIZE + 1);
-    memcpy(el->data, &data, AMF_NUMBER_SIZE);
+//     el->type = AMF::NUMBER;
+//     el->name = name;
+//     el->length = AMF_NUMBER_SIZE;
+// //    char *numptr = (char *)&data;
+//     el->data = new boost::uint8_t[AMF_NUMBER_SIZE + 1];
+//     memset(el->data, 0, AMF_NUMBER_SIZE + 1);
+//     memcpy(el->data, &data, AMF_NUMBER_SIZE);
 
-    return el;
-}
+//     return el;
+// }
 
 AMF::amf_element_t *
 AMF::createElement(amf_element_t *el, const char *name, double data)
@@ -898,81 +1070,56 @@
 //     string str = name;
 //     return createElement(el, str, data);
 // }
+#endif
 
 uint8_t *
-AMF::encodeVariable(amf_element_t *el)
+AMF::encodeVariable(amf::Element *el)
 {
 //    GNASH_REPORT_FUNCTION;
-    int outsize = el->name.size() + el->length + 5;
+    int outsize = el->getName().size() + el->getLength() + 5;
     boost::uint8_t *out = new boost::uint8_t[outsize + 2];
     memset(out, 0, outsize + 2);
     boost::uint8_t *tmpptr = out;
 
     // Add the length of the string for the name of the variable
-    size_t length = el->name.size();
+    size_t length = el->getName().size();
     boost::uint16_t enclength = length;
     swapBytes(&enclength, 2);
     memcpy(tmpptr, &enclength, 2);
 
     // Add the actual name
     tmpptr += sizeof(uint16_t);
-    memcpy(tmpptr, el->name.c_str(), length);
+    memcpy(tmpptr, el->getName().c_str(), length);
     tmpptr += length;
     // Add the type of the variable's data
-    *tmpptr++ = el->type;
+    *tmpptr++ = el->getType();
     // Booleans appear to be encoded weird. Just a short after
     // the type byte that's the value.
-    switch (el->type) {
-      case AMF::BOOLEAN:
-         enclength = el->data[0];
+    switch (el->getType()) {
+      case Element::BOOLEAN:
+         enclength = el->to_bool();
          memcpy(tmpptr, &enclength, 2);
          tmpptr += sizeof(uint16_t);
          break;
-      case AMF::NUMBER:
-         if (el->data) {
-             swapBytes(el->data, AMF_NUMBER_SIZE);
-             memcpy(tmpptr, el->data, AMF_NUMBER_SIZE);
+      case Element::NUMBER:
+         if (el->getData()) {
+             swapBytes(el->getData(), AMF_NUMBER_SIZE);
+             memcpy(tmpptr, el->getData(), AMF_NUMBER_SIZE);
          }
          break;
       default:
-       enclength = el->length;
+         enclength = el->getLength();
        swapBytes(&enclength, 2);
        memcpy(tmpptr, &enclength, 2);
        tmpptr += sizeof(uint16_t);
        // Now the data for the variable
-       memcpy(tmpptr, el->data, el->length);
+         memcpy(tmpptr, el->getData(), el->getLength());
     }
     
     return out;    
 }
 
-boost::uint8_t *
-AMF::encodeVariable(amf_element_t &el)
-{
-//    GNASH_REPORT_FUNCTION;
-    int outsize = el.name.size() + el.length + 5;
-    boost::uint8_t *out = new uint8_t[outsize];
-    boost::uint8_t *tmpptr = out;
-
-    // Add the length of the string for the name of the variable
-    size_t length = el.name.size();
-    short enclength = length;
-    swapBytes(&enclength, 2);
-    memcpy(tmpptr, &enclength, 2);
-
-    // Add the actual name
-    tmpptr += 2;
-    memcpy(tmpptr, el.name.c_str(), length);
-    tmpptr += length;
-    *tmpptr = el.type;
-    tmpptr++;
-
-    // Now the data for the variable
-    memcpy(tmpptr, el.data, el.length);
-
-    return out;    
-}
-
+#if 0
 boost::uint8_t *
 AMF::encodeVariable(const char *name, bool flag)
 {
@@ -989,7 +1136,7 @@
     tmpptr += 2;
     memcpy(tmpptr, name, length);
     tmpptr += length;
-    *tmpptr = AMF::BOOLEAN;
+    *tmpptr = Element::BOOLEAN;
     tmpptr++;
     *tmpptr = flag;
 
@@ -1011,20 +1158,20 @@
     tmpptr += 2;
     memcpy(tmpptr, name, length);
     tmpptr += length;
-    *tmpptr = AMF::UNDEFINED;
+    *tmpptr = Element::UNDEFINED;
     tmpptr++;
 
     return out;    
 }
 
 boost::uint8_t *
-AMF::encodeVariable(const char *name, amfnum_t bignum)
+AMF::encodeVariable(const char *name, double bignum)
 {
 //    GNASH_REPORT_FUNCTION;
     int outsize = strlen(name) + AMF_NUMBER_SIZE + 5;
     boost::uint8_t *out = new boost::uint8_t[outsize];
     boost::uint8_t *tmpptr = out;
-    amfnum_t newnum = bignum;
+    double newnum = bignum;
     char *numptr = (char *)&newnum;
 
     size_t length = strlen(name);
@@ -1034,7 +1181,7 @@
     tmpptr += 2;
     memcpy(tmpptr, name, length);
     tmpptr += length;
-    *tmpptr = AMF::NUMBER;
+    *tmpptr = Element::NUMBER;
     tmpptr++;
 //    swapBytes(numptr, AMF_NUMBER_SIZE);
     memcpy(tmpptr, numptr, AMF_NUMBER_SIZE);
@@ -1058,7 +1205,7 @@
     tmpptr += 2;
     memcpy(tmpptr, name, length);
     tmpptr += length;
-    *tmpptr = AMF::STRING;
+    *tmpptr = Element::STRING;
     tmpptr++;
     length = strlen(val);
     enclength = length;
@@ -1086,7 +1233,7 @@
     tmpptr += 2;
     memcpy(tmpptr, name.c_str(), name.size());
     tmpptr += name.size();
-    *tmpptr = AMF::STRING;
+    *tmpptr = Element::STRING;
     tmpptr++;
     length = val.size() && 0xffff;
     swapBytes(&length, 2);
@@ -1219,11 +1366,11 @@
 {
 //    GNASH_REPORT_FUNCTION;
 
-    return parseBody(_amf_data, _total_size);
+//    return parseBody(_amf_data, _total_size);
 }
 
-int
-AMF::parseBody(boost::uint8_t *in, int bytes)
+uint8_t *
+AMF::extractElement(Element &el, boost::uint8_t *in)
 {
 //    GNASH_REPORT_FUNCTION;
 
@@ -1232,30 +1379,23 @@
 //    uint8_t hexint[(bytes*2)+1];
     boost::uint8_t* hexint;
 
-    char buffer[500];
-//    char *name;
     short length;
-    amf_element_t el;
-
-    if (bytes == 0) {
-        return 0;
-    }
     
     if (in == 0) {
         log_error(_("AMF body input data is NULL"));
-        return -1;
+        return 0;
     }
+//     if (reinterpret_cast<int>(el) == 0)) {
+//         log_error(_("Got NULL instead of amf_element_t!"));
+//         return 0;
+//     }
 
+#if 0
     hexint =  (boost::uint8_t*) malloc((bytes * 3) + 12);
-
-//     memcpy(_amf_data +_read_size, in, AMF_VIDEO_PACKET_SIZE);
-//     _read_size += bytes;
-#if 1
     hexify((boost::uint8_t *)hexint, (boost::uint8_t *)in, bytes, true);
     log_msg(_("The packet body is: 0x%s"), hexint);
 #endif
 
-//    tmpptr = in;
     tmpptr = in;
     
 // All elements look like this:
@@ -1267,17 +1407,17 @@
     while (tmpptr  <= (in + bytes)) {
         memset(buffer, 0, sizeof(buffer));     //FIXME, slow
         // Check the type of the element data
-        char type = *(astype_e *)tmpptr;
+        char type = *(Element::astype_e *)tmpptr;
         tmpptr++;                        // skip the header byte
 
-        switch ((astype_e)type) {
-          case NUMBER:
+        switch ((Element::astype_e)type) {
+          case Element::NUMBER:
 //              memcpy(buffer, tmpptr, 8);
               tmpptr += 8;
               continue;
               break;
-          case BOOLEAN:
-          case STRING:
+          case Element::BOOLEAN:
+          case Element::STRING:
               // get the length of the name
               length = ntohs((*(short *)tmpptr) & 0xffff);
               tmpptr += 2;
@@ -1290,37 +1430,38 @@
               log_msg(_("AMF String is: %s"), buffer);              
               el.name = buffer;
               break;
-          case OBJECT:
+          case Element::OBJECT:
               do {
                   tmpptr = extractVariable(&el, tmpptr);
-              } while (el.type != AMF::OBJECT_END);
+              } while (el.type != Element::OBJECT_END);
               break;
-          case MOVIECLIP:
-          case NULL_VALUE: 
-          case UNDEFINED:
-          case REFERENCE:
-          case ECMA_ARRAY:
-          case OBJECT_END:
-          case STRICT_ARRAY:
-          case DATE:
-          case LONG_STRING:
-          case UNSUPPORTED:
-          case RECORD_SET:
-          case XML_OBJECT:
-          case TYPED_OBJECT:
+          case Element::MOVIECLIP:
+          case Element::NULL_VALUE: 
+          case Element::UNDEFINED:
+          case Element::REFERENCE:
+          case Element::ECMA_ARRAY:
+          case Element::OBJECT_END:
+          case Element::STRICT_ARRAY:
+          case Element::DATE:
+          case Element::LONG_STRING:
+          case Element::UNSUPPORTED:
+          case Element::RECORD_SET:
+          case Element::XML_OBJECT:
+          case Element::TYPED_OBJECT:
           default:
            log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)type);
-              return -1;
+              return 0;
         }
     }
 
     free(hexint);
 
-    return -1;
+    return 0;
 }
+#endif
 
 boost::uint8_t *
-AMF::extractVariable(AMF::amf_element_t *el, boost::uint8_t *in)
+AMF::extractVariable(Element *el, boost::uint8_t *in)
 {
 //    GNASH_REPORT_FUNCTION;
     
@@ -1328,15 +1469,11 @@
     boost::uint8_t *tmpptr = in;
     boost::int16_t length;
 
-    if (el == 0) {
-       return 0;
-    }
+//     if (el == 0) {
+//     return 0;
+//     }
     
-    el->length = 0;
-    el->name.erase();
-    if (el->data) {
-        el->data = 0;
-    }
+    el->clear();
     
     memset(buffer, 0, AMF_PACKET_SIZE);
     // @@ casting generic pointers to bigger types may be dangerous
@@ -1344,12 +1481,12 @@
     length = *((short *)tmpptr);
     swapBytes(&length, 2);
 //    length = ntohs((*(const short *)tmpptr) & 0xffff);
-    el->length = length;
+    el->setLength(length);
     if (length == 0) {
-        if (*(tmpptr+2) == AMF::OBJECT_END) {
-            log_msg(_("End of Object definition"));
-            el->length = 0;
-            el->type = AMF::OBJECT_END;
+        if (*(tmpptr+2) == Element::OBJECT_END) {
+//            log_msg(_("End of Object definition"));
+            el->setLength(0);
+            el->setType(Element::OBJECT_END);
             tmpptr+=3;
             return tmpptr;
         }
@@ -1371,95 +1508,90 @@
        
 //        log_msg(_("AMF element length is: %d"), length);
         memcpy(buffer, tmpptr, length);
-        el->name = reinterpret_cast<char *>(buffer);
+        el->setName(buffer);
         tmpptr += length;
     }
     
 //    log_msg(_("AMF element name is: %s"), buffer);
-    astype_e type = (astype_e)((*tmpptr++) & 0xff);
+    Element::astype_e type = (Element::astype_e)((*tmpptr++) & 0xff);
 
-    if (type <= AMF::TYPED_OBJECT) {
-//        log_msg(_("AMF type is: %s"), astype_str[(int)type]);
-       el->type = type;
+    if (type <= Element::TYPED_OBJECT) {
+//        log_msg(_("AMF type is: %s"), Element::astype_str[(int)type]);
+       el->setType(type);
     }
     
     switch (type) {
-      case NUMBER:
+      case Element::NUMBER:
       {
           memcpy(buffer, tmpptr, AMF_NUMBER_SIZE);
           swapBytes(buffer, AMF_NUMBER_SIZE);
          uint8_t* tmp = new uint8_t[AMF_NUMBER_SIZE+1];
          memset(tmp, 0, AMF_NUMBER_SIZE+1);
          memcpy(tmp, buffer, AMF_NUMBER_SIZE);
-         el->data = tmp;
+         el->setData(tmp);
 #if 0
           uint8_t hexint[AMF_NUMBER_SIZE*3];
           hexify((uint8_t *)hexint, (uint8_t *)buffer,
                 AMF_NUMBER_SIZE, false);
-          log_msg(_("Number \"%s\" is: 0x%s"), el->name.c_str(), hexint);
-//          amfnum_t *num = extractNumber(tmpptr);
+          log_msg(_("Number \"%s\" is: 0x%s"), el->getName().c_str(), hexint);
+//          double *num = extractNumber(tmpptr);
 #endif
           tmpptr += 8;
-         el->length = AMF_NUMBER_SIZE;
+         el->setLength(AMF_NUMBER_SIZE);
           break;
       }
-      case BOOLEAN:
+      case Element::BOOLEAN:
       {
-//          int value = *tmpptr;
-         el->length = 1;
-          el->data = new uint8_t[2];
-//          memcpy(tmp, tmpptr, 2); 
-          el->data[0] =* tmpptr;
-//       log_msg((*tmpptr == 0) ? 
-//               _("Boolean \"%s\" is: true"):
-//               _("Boolean \"%s\" is: false"), el->name.c_str());
+         bool sheet = *tmpptr;
+          el->init(sheet);
          tmpptr += 1;
          break;
     }
-      case STRING:
+      case Element::STRING:
          // extractString returns a printable char *
          length = ntohs((*(const short *)tmpptr) & 0xffff);
           tmpptr += sizeof(short);
-          el->length = length;
-          el->data = tmpptr; 
-//            std::string v(el->data+3, length);
-//            log_msg(_("Variable \"%s\" is: %s"), el->name.c_str(), 
v.c_str()); // el->data);
+          el->setLength(length);
+         boost::uint8_t *str;
+         str = new boost::uint8_t[length + 1];
+         memset(str, 0, length + 1);
+         memcpy(str, tmpptr, length);
+         el->setData(str);
+//       string v(reinterpret_cast<const char *>(str) + 3, (int)length);
+//       log_msg(_("Variable \"%s\" is: %s"), el->getName().c_str(), 
v.c_str());
           tmpptr += length;
           break;
-      case OBJECT:
-         while (*(tmpptr++) != AMF::OBJECT_END) {
+      case Element::OBJECT:
+         while (*(tmpptr++) != Element::OBJECT_END) {
              log_msg("Look for end of object...");
          }
          
          break;
-      case MOVIECLIP:
-      case NULL_VALUE:
-         // Undefined types have a name, but no value
-               //FIXME this shouldn't fall through!
-      case UNDEFINED:
-//          log_msg(_("Undefined type"));
-          el->data = 0; // (const uint8_t*)tmpptr; 
-          //log_msg(_("Variable \"%s\" is of undefined type"), 
el->name.c_str());
-          el->length = 0;
-          el->type = AMF::UNDEFINED;
+      case Element::MOVIECLIP:
+      case Element::NULL_VALUE:
+         el->makeUndefined();
+         break;
+      case Element::UNDEFINED:
+         el->makeUndefined();
           break;
-      case REFERENCE:
-      case ECMA_ARRAY:
+      case Element::REFERENCE:
+      case Element::ECMA_ARRAY:
                        // FIXME this shouldn't fall thru
-      case OBJECT_END:
+      case Element::OBJECT_END:
 //          log_msg(_("End of Object definition"));
-          el->name.erase();
-          el->length = 0;
-          el->data = 0;
-          el->type = AMF::OBJECT_END;
-          break;
-      case TYPED_OBJECT:
-      case STRICT_ARRAY:
-      case DATE:
-      case LONG_STRING:
-      case UNSUPPORTED:
-      case RECORD_SET:
-      case XML_OBJECT:
+         el->makeObjectEnd();
+          break;
+      case Element::TYPED_OBJECT:
+         el->makeTypedObject(tmpptr, 0);
+          break;
+      case Element::STRICT_ARRAY:
+      case Element::DATE:
+         el->makeDate(tmpptr);
+          break;
+      case Element::LONG_STRING:
+      case Element::UNSUPPORTED:
+      case Element::RECORD_SET:
+      case Element::XML_OBJECT:
       default:
           log_unimpl(_("astype_e of value: %x"), (int)type);
           break;

Index: libamf/amf.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- libamf/amf.h        26 Dec 2007 05:37:32 -0000      1.27
+++ libamf/amf.h        31 Dec 2007 00:26:48 -0000      1.28
@@ -27,36 +27,15 @@
 #include <cstring>
 #include <map>
 
-#include "as_object.h"
-
+#include "element.h"
 #include "amfutf8.h"
 #include <boost/cstdint.hpp>
 
 namespace amf 
 {
 
-# if __WORDSIZE == 64
-typedef unsigned long amfnum_t;
-#define AMFNUM_F "%ld"
-#else
-typedef unsigned long long amfnum_t;
-#define AMFNUM_F "%lld"
-#endif
-// TIDO FIXME: this will be longer then the actual amfnum_t 
-//             if __WORDSIZE != 64 !!
 const char AMF_NUMBER_SIZE = 0x08;
 
-// These are the data types defined by AMF
-typedef char AMF_Byte_t;
-typedef short AMF_Int_t ;
-typedef char * AMF_MediumInt_t;
-typedef int AMF_Long_t;
-typedef double AMF_Double_t;
-
-// FIXME: These are probably bogus, and need to be a UTF-8 type.
-typedef char *AMF_UTF8_t;
-typedef char *AMF_LongUTF8_t;
-
 typedef enum {
     CLIENT,                     // Flash player
     SERVER                      // Flash com server
@@ -81,7 +60,7 @@
 // indicator. So far the only valid value for this field that has been
 // found is 0x00. If it is anything other than 0x00 (zero), your
 // system should consider the AMF file/stream to be
-// 'cmalformed'd. This can happen in the IDE if AMF calls are put
+// 'malformed'd. This can happen in the IDE if AMF calls are put
 // on the stack but never executed and the user exits the movie from the
 // IDE; the two top bytes will be random and the number of headers will
 // be unreliable.
@@ -93,9 +72,9 @@
 // The third and fourth bytes form an integer value that specifies the
 // number of headers. 
 typedef struct {
-    AMF_Byte_t version;
-    AMF_Byte_t source;
-    AMF_Int_t  count;
+    boost::uint8_t version;
+    boost::uint8_t source;
+    boost::uint32_t  count;
 } amfpacket_t;
 
 typedef enum {
@@ -106,26 +85,6 @@
 
 class AMF {
 public:
-    // The following elements are defined within AMF:
-    typedef enum {
-        NUMBER=0x00,
-        BOOLEAN=0x01,
-        STRING=0x02,
-        OBJECT=0x03,
-        MOVIECLIP=0x04,
-        NULL_VALUE=0x05,
-        UNDEFINED=0x06,
-        REFERENCE=0x07,
-        ECMA_ARRAY=0x08,
-        OBJECT_END=0x09,
-        STRICT_ARRAY=0x0a,
-        DATE=0x0b,
-        LONG_STRING=0x0c,
-        UNSUPPORTED=0x0d,
-        RECORD_SET=0x0e,
-        XML_OBJECT=0x0f,
-        TYPED_OBJECT=0x10
-    } astype_e;
     typedef enum {
         HEADER_12 = 0x0,
         HEADER_8  = 0x40,
@@ -133,15 +92,15 @@
         HEADER_1  = 0xc0
     } amf_headersize_e;    
     
-    typedef enum {
-        Byte,
-        Int,
-        MediumInt,
-        Long,
-        Double,
-        UTF8,
-        LongUTF8
-    } amftype_e;
+//     typedef enum {
+//         Byte,
+//         Int,
+//         MediumInt,
+//         Long,
+//         Double,
+//         UTF8,
+//         LongUTF8
+//     } amftype_e;
     typedef enum {
         NONE = 0x0,
         CHUNK_SIZE = 0x1,
@@ -172,102 +131,149 @@
         INITIAL_DATA = 0x0b
     } shared_obj_types_e;
 
-    struct amf_element_t {
-        astype_e       type;
-        boost::int16_t        length;
-        std::string    name;
-        boost::uint8_t        *data;
-
-        amf_element_t()
-                :
-                type(NUMBER),
-                length(0),
-                name(),
-                data(NULL)
-        {}
-
-    };
-
     AMF();
     AMF(int size);
     ~AMF();
-    size_t size() { return _total_size; };
+//    size_t size() { return _total_size; };
 
-    /// Encode an element
     //
-    /// @param type
-    ///                Type of element
+    // Methods for encoding data into big endian formatted raw AMF data.
+    //
+    
+    /// Encode a string object
     ///
-    /// @param in
-    ///                Input stream
+    /// @return a binary AMF packet in big endian format (header,data)
     ///
-    /// @param nbytes
-    ///                Lenght of data packet (not including header).
+    boost::uint8_t *encodeString(const char *str);
+
+    /// Encode a Boolean object
     ///
-    /// @return an amf packet (header,data)
+    /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t* encodeElement(astype_e type, const void *in, int nbytes);
+    boost::uint8_t *encodeBoolean(bool flag);
 
-    /// Encode a string
+    /// Encode an "Undefined" object
     ///
-    /// @return an amf packet (header,data)
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeUndefined();
+
+    /// Encode a "NULL" object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeNull();
+
+    /// Encode a "Unsupported" object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeUnsupported();
+
+    /// Encode an XML object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeXMLObject(boost::uint8_t *data, int size);
+
+    /// Encode a Typed Object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeTypedObject(boost::uint8_t *data, int size);
+
+    /// Encode a Reference to an object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeReference(boost::uint8_t *data, int size);
+
+    /// Encode a Movie Clip
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeMovieClip(boost::uint8_t *data, int size);
+
+    /// Encode an ECMA Array
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeECMAArray(boost::uint8_t *data, int size);
+
+    /// Encode a long string
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeLongString(boost::uint8_t *data, int size);
+
+    /// Encode a Record Set
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeRecordSet(boost::uint8_t *data, int size);
+
+    /// Encode a Date
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t* encodeString(const char *str)  {
-        return encodeElement (STRING, str, strlen(str));
-    };
+    boost::uint8_t *encodeDate(boost::uint8_t *data);
+
+    /// Encode a Strict Array
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeStrictArray(boost::uint8_t *data, int size);
+    
+    /// Encode an object
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+    ///
+    boost::uint8_t *encodeObject(const boost::uint8_t *data, int size);
 
     /// Encode a 64 bit number
     ///
-    /// @return an amf packet (header,data)
+    /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t* encodeNumber(amfnum_t num)  {
-        return encodeElement (NUMBER, &num, AMF_NUMBER_SIZE);
-    };
-
-    /// Encode a variable. These are a name, followed by a string or number
-
-    ///
-    /// @ return an element all filled in correctly for passing to other
-    /// methods.
-    amf_element_t *createElement(amf_element_t *el, astype_e type,
-                                const std::string &name, boost::uint8_t *data, 
int nbytes);
-    amf_element_t *createElement(amf_element_t *el, const std::string &name,
-                                amfnum_t data);
-    amf_element_t *createElement(amf_element_t *el, const char *name,
-                                double data);
-    amf_element_t *createElement(amf_element_t *el, const std::string &name,
-                                double data);
-    amf_element_t *createElement(amf_element_t *el, const char *name,
-                                amfnum_t data);
-    amf_element_t *createElement(amf_element_t *el, const std::string &name,
-                                std::string &data);
-    amf_element_t *createElement(amf_element_t *el, const char *name,
-                                const char *data);
-    amf_element_t *createElement(amf_element_t *el, const std::string &name,
-                                bool data);
-    amf_element_t *createElement(amf_element_t *el, const char *name,
-                                bool data);
-    amf_element_t *createElement(amf_element_t *el, const std::string &name,
-                                 boost::intrusive_ptr<gnash::as_object> &data);
-    amf_element_t *createElement(amf_element_t *el, const char *name,
-                                boost::intrusive_ptr<gnash::as_object> &data);
-//     amf_element_t *createElement(amf_element_t *el, const std::string &name,
-//                              const gnash::as_value &data);
-//     amf_element_t *createElement(amf_element_t *el, const char *name,
-//                              const gnash::as_value &data);
-    //
-    /// @return a newly allocated byte array,
+    boost::uint8_t *encodeNumber(double num);
+    
+    /// Encode a element. 
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+
+    /// @return a newly allocated byte array.
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(const char *name);
+    boost::uint8_t *encodeElement(amf::Element *el);
 
     /// Encode a variable. 
+    ///
+    /// @return a binary AMF packet in big endian format (header,data)
+
+    /// @return a newly allocated byte array.
+    /// to be deleted by caller using delete [] operator, or NULL
+    ///
+    boost::uint8_t *encodeVariable(amf::Element *el);
+
+#if 0
+    /// Encode an element
     //
+    /// @param type
+    ///                Type of element
+    ///
+    /// @param in
+    ///                Input stream
+    ///
+    /// @param nbytes
+    ///                Lenght of data packet (not including header).
+    ///
+    /// @return an amf packet (header,data)
+    ///
+    boost::uint8_t* encodeElement(Element::astype_e type, const void *in, int 
nbytes);
+
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(amf_element_t &el);
-    boost::uint8_t* encodeVariable(amf_element_t *el);
+    boost::uint8_t* encodeVariable(const char *name);
 
     /// Encode a boolean variable. This is a name followed by a boolean value.
     //
@@ -281,7 +287,7 @@
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(const char *name, amfnum_t num);
+    boost::uint8_t* encodeVariable(const char *name, double num);
 
     /// Encode a variable. 
     //
@@ -303,7 +309,7 @@
 //     amfbody_t *encodeBody(amfutf8_t *target, amfutf8_t *response, int 
nbytes, void *data);
 //    amfpacket_t *encodePacket(std::vector<amfhead_t *> messages);
 
-    boost::uint8_t *readElement(void *in);
+//    std::vector<amf_element_t> *readElements(boost::uint8_t *in);
     
     /// Extract the string from a string-type AMF packet
     //
@@ -312,53 +318,65 @@
     ///
     /// Caller is responsible for deletion using delete [] operator.
     ///
-    boost::int8_t *extractString(const boost::uint8_t* in);
+#endif
+    
+    //
+    // Methods for extracting data from big endian formatted raw AMF data.
+    //
+    amf::Element::astype_e extractElementHeader(boost::uint8_t *in)
+       { return *(reinterpret_cast<amf::Element::astype_e *>(in)); };
 
-    amfnum_t *extractNumber(const boost::uint8_t *in);
-    amf_element_t *extractObject(const boost::uint8_t *in);
+    boost::uint8_t *extractElement(amf::Element *el, boost::uint8_t *in);
+    boost::uint8_t *extractVariable(amf::Element *el, boost::uint8_t *in);
+#if 0
+    // FIXME: these should return an Element, and then use to_*() to convert.
+    char *extractString(const boost::uint8_t* in);
     
-    unsigned char *extractVariable(amf_element_t *el, boost::uint8_t *in);
+    double extractNumber(const boost::uint8_t *in);
+    Element &extractObject(const boost::uint8_t *in);
     
+
+    // FIXME: these are all for RTMP, and should be moved
     bool parseAMF(boost::uint8_t *in);
     static int headerSize(int8_t header);
     int packetReadAMF(int bytes);
 
     int parseHeader(boost::uint8_t *in);
     int parseBody();
-    int parseBody(boost::uint8_t *in, int bytes);
-    
     int getHeaderSize()         { return _header_size; }; 
     int getTotalSize()          { return _total_size; }; 
     int getPacketSize()         { return _packet_size; };
     int getMysteryWord()        { return _mystery_word; };
     amfsource_e getRouting()    { return _src_dest; };
     int getAMFIndex()           { return _amf_index; };
+    boost::uint8_t *addPacketData(boost::uint8_t *data, int bytes);
+#endif    
 
     content_types_e getType()   { return _type; };
-    
-    boost::uint8_t *addPacketData(boost::uint8_t *data, int bytes);
-    std::map<std::string, amf_element_t *> *getElements() { return &_elements; 
};
-    boost::uint8_t *appendPtr(boost::uint8_t *data, boost::uint8_t *var, int 
bytes) {
+//    std::map<std::string, Element> *getElements() { return &_elements; };
+    boost::uint8_t *appendPtr(boost::uint8_t *data, boost::uint8_t *var,
+                             int bytes) {
       memcpy(data, var, bytes);
       return data += bytes;
     }
         
  private:
-    astype_e extractElementHeader(void *in);
+#if 0
+    Element::astype_e extractElementHeader(void *in);
     int extractElementLength(void *in);
-    content_types_e     _type;
-    std::map<std::string, amf_element_t *> _elements;
+//    std::map<std::string, Element &> _elements;
     int                 _amf_index;
     int                 _header_size;
     int                 _total_size;
     int                 _packet_size;
     boost::uint8_t             *_amf_data;
     boost::uint8_t             *_seekptr;
-    int                 _mystery_word;
     amfsource_e         _src_dest;
+#endif
+    content_types_e     _type;
+    int                 _mystery_word;
 };
 
- 
 void *swapBytes(void *word, int size);
 
 

Index: libamf/lcshm.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libamf/lcshm.cpp    30 Dec 2007 16:18:04 -0000      1.1
+++ libamf/lcshm.cpp    31 Dec 2007 00:26:48 -0000      1.2
@@ -62,6 +62,12 @@
 LcShm::~LcShm()
 {
     GNASH_REPORT_FUNCTION;
+    
+    vector<amf::Element *>::iterator it;
+    for (it = _amfobjs.begin(); it != _amfobjs.end(); it++) {
+       amf::Element *el = (*(it));
+       delete el;
+    }
 }
 
 Listener::Listener()
@@ -185,12 +191,13 @@
     closeMem();
 }
 
+#if 0
 boost::uint8_t *
-LcShm::parseElement(amf::AMF::amf_element_t *el, boost::uint8_t *data)
+LcShm::parseElement(amf::Element *el, boost::uint8_t *data)
 {
     GNASH_REPORT_FUNCTION;
     boost::uint8_t *ptr = reinterpret_cast<uint8_t *>(data);
-    AMF::astype_e type = (AMF::astype_e)*ptr;
+    Element::astype_e type = (Element::astype_e)*ptr;
     switch (type) {
       case AMF::NUMBER:
           double dub = 50.0;
@@ -203,17 +210,17 @@
           break;
     };
 }
+#endif
 
-
-vector<AMF::amf_element_t> 
+vector<amf::Element *> 
 LcShm::parseBody(boost::uint8_t *data)
 {
     GNASH_REPORT_FUNCTION;
 
     boost::uint8_t *ptr = reinterpret_cast<uint8_t *>(data);
-    AMF::astype_e type = (AMF::astype_e)*ptr;
+    Element::astype_e type = (Element::astype_e)*ptr;
 //    log_msg(_("Type is %s"), astype_str[type]);
-    AMF::amf_element_t el;
+    amf::Element el;
     AMF amf;
 
 #if 0
@@ -269,6 +276,7 @@
 //     log_debug("name: %s", _object.hostname);
     ptr += LC_HEADER_SIZE;
     AMF amf;
+#if 0
     _object.connection_name = amf.extractString(ptr);
     ptr += _object.connection_name.size() + 3;
     _object.hostname = amf.extractString(ptr);
@@ -279,6 +287,7 @@
     ptr += AMF_NUMBER_SIZE + 1;
     _object.unknown_num1 = amf.extractNumber(ptr);
     ptr += AMF_NUMBER_SIZE + 2;
+#endif
 
 //    memcpy(&_object, data + LC_HEADER_SIZE, _header.length);
     log_debug("Connection: %s", _object.connection_name.c_str());
@@ -321,7 +330,7 @@
 }
 
 bool
-LcShm::addObject(AMF::amf_element_t &el)
+LcShm::addObject(amf::Element * /* el */)
 {
     GNASH_REPORT_FUNCTION;
     
@@ -329,7 +338,7 @@
 
 /// \brief Invokes a method on a specified LcShm object.
 void
-LcShm::send(std::string &name, std::string &dataname, amf::AMF::amf_element_t 
data)
+LcShm::send(std::string &name, std::string &dataname, amf::Element *data)
 {
     
     log_unimpl (__FUNCTION__);

Index: libamf/lcshm.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libamf/lcshm.h      30 Dec 2007 16:18:04 -0000      1.1
+++ libamf/lcshm.h      31 Dec 2007 00:26:48 -0000      1.2
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include "amf.h"
+#include "element.h"
 #include "shm.h"
 
 namespace gnash {
@@ -61,7 +62,7 @@
         std::string connection_name;
         std::string protocol;
         std::string method_name;
-        std::vector<amf::AMF::amf_element_t> data; // this can be any AMF data 
type
+        std::vector<amf::Element *> data; // this can be any AMF data type
     } lc_message_t;
     typedef struct {
        std::string connection_name;
@@ -74,19 +75,19 @@
     ~LcShm();
     bool connect(std::string &name);
     void close(void);
-    void send(std::string &name, std::string &dataname, 
amf::AMF::amf_element_t data);
-    void recv(std::string &name, std::string &dataname, 
amf::AMF::amf_element_t *data);
-    std::vector<amf::AMF::amf_element_t> parseBody(boost::uint8_t *data);
+    void send(std::string &name, std::string &dataname, amf::Element *data);
+    void recv(std::string &name, std::string &dataname, amf::Element *data);
+    std::vector<amf::Element *> parseBody(boost::uint8_t *data);
     boost::uint8_t *parseHeader(boost::uint8_t *data);
     boost::uint8_t *formatHeader(boost::uint8_t *data);
-    bool addObject(amf::AMF::amf_element_t &el);
+    bool addObject(amf::Element *el);
     size_t size() { return _amfobjs.size(); };
-    std::vector<amf::AMF::amf_element_t> getElements() { return _amfobjs; };
+    std::vector<amf::Element *> getElements() { return _amfobjs; };
 private:
     uint8_t *_baseaddr;
     lc_header_t _header;
     lc_object_t _object;
-    std::vector<amf::AMF::amf_element_t> _amfobjs;
+    std::vector<amf::Element *> _amfobjs;
 };
 
 } // end of gnash namespace

Index: libamf/rtmp.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/rtmp.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- libamf/rtmp.h       1 Jul 2007 10:54:06 -0000       1.9
+++ libamf/rtmp.h       31 Dec 2007 00:26:48 -0000      1.10
@@ -24,6 +24,7 @@
 
 #include "tu_config.h"
 
+#include <boost/cstdint.hpp>
 #include <vector>
 
 #include "amf.h"
@@ -36,6 +37,13 @@
 #define RTMP_BODY_SIZE 1536
 #define MAX_AMF_INDEXES 64
 
+// These are the textual responses
+const char *response_str[] = {
+    "/onStatus",
+    "/onResult",
+    "/onDebugEvents"
+};
+
 class DSOEXPORT RTMPproto : public Protocol
 {
 public:
@@ -83,8 +91,8 @@
 // * Variable - Actual data (including a type code)
     typedef struct {
         amf::amfutf8_t name;
-        amf::AMF_Byte_t required;
-        amf::AMF_Long_t length;
+       boost::uint8_t required;
+       boost::uint32_t length;
         void *data;
     } rtmp_head_t;
     
@@ -97,7 +105,7 @@
     typedef struct {
         amf::amfutf8_t target;
         amf::amfutf8_t response;
-        amf::AMF_Long_t length;
+       boost::uint32_t length;
         void *data;
     } rtmp_body_t;
     

Index: libamf/sol.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/sol.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- libamf/sol.cpp      27 Dec 2007 19:29:04 -0000      1.8
+++ libamf/sol.cpp      31 Dec 2007 00:26:48 -0000      1.9
@@ -71,6 +71,12 @@
 SOL::~SOL()
 {
 //    GNASH_REPORT_FUNCTION;
+
+    vector<amf::Element *>::iterator it;
+    for (it = _amfobjs.begin(); it != _amfobjs.end(); it++) {
+       amf::Element *el = (*(it));
+       delete el;
+    }
 }
 
 bool
@@ -86,11 +92,11 @@
 }
 
 void
-SOL::addObj(AMF::amf_element_t &el)
+SOL::addObj(amf::Element *el)
 {
 //    GNASH_REPORT_FUNCTION;
     _amfobjs.push_back(el);
-    _filesize += el.name.size() + el.length + 5;
+    _filesize += el->getName().size() + el->getLength() + 5;
 }
 
 bool
@@ -208,7 +214,7 @@
 //    GNASH_REPORT_FUNCTION;
     ofstream ofs(filespec.c_str(), ios::binary);
     vector<uint8_t>::iterator it;
-    vector<AMF::amf_element_t>::iterator ita; 
+    vector<amf::Element *>::iterator ita; 
     AMF amf_obj;
     char *ptr;
 
@@ -222,31 +228,31 @@
     ptr = body;
 
     for (ita = _amfobjs.begin(); ita != _amfobjs.end(); ita++) {
-        AMF::amf_element_t *el = &(*(ita));
-        int outsize = el->name.size() + el->length + 5;
+        amf::Element *el = (*(ita));
+        int outsize = el->getName().size() + el->getLength() + 5;
         uint8_t *foo = amf_obj.encodeVariable(el); 
-        switch (el->type) {
-         case AMF::BOOLEAN:
-             outsize = el->name.size() + 5;
+        switch (el->getType()) {
+         case Element::BOOLEAN:
+             outsize = el->getName().size() + 5;
              memcpy(ptr, foo, outsize);
              ptr += outsize;
              break;
-         case AMF::OBJECT:
-             outsize = el->name.size() + 5;
+         case Element::OBJECT:
+             outsize = el->getName().size() + 5;
              memcpy(ptr, foo, outsize);
              ptr += outsize;
-             *ptr++ = AMF::OBJECT_END;
+             *ptr++ = Element::OBJECT_END;
              *ptr++ = 0;       // objects are terminated too!
              break;
-         case AMF::NUMBER:
-             outsize = el->name.size() + AMF_NUMBER_SIZE + 2;
+         case Element::NUMBER:
+             outsize = el->getName().size() + AMF_NUMBER_SIZE + 2;
              memcpy(ptr, foo, outsize);
              ptr += outsize;
              *ptr++ = 0;       // doubles are terminated too!
              *ptr++ = 0;       // doubles are terminated too!
              break;
-         case AMF::STRING:
-             if (el->length == 0) {
+         case Element::STRING:
+             if (el->getLength() == 0) {
                  memcpy(ptr, foo, outsize+1);
                  ptr += outsize+1;
              } else {          // null terminate the string
@@ -286,24 +292,24 @@
 {
 //    GNASH_REPORT_FUNCTION;
     struct stat st;
-    uint16_t magic, size;
-    char *buf, *ptr;
+    boost::uint16_t magic, size;
+    boost::uint8_t *buf, *ptr;
 
     // Make sure it's an SOL file
     if (stat(filespec.c_str(), &st) == 0) {
         ifstream ifs(filespec.c_str(), ios::binary);
         _filesize = st.st_size;
         _filespec = filespec;
-        ptr = buf = new char[_filesize+1];
-        ifs.read(buf, _filesize);
+        ptr = buf = new boost::uint8_t[_filesize+1];
+        ifs.read(reinterpret_cast<char *>(buf), _filesize);
 
         // extract the magic number
-        magic = *(reinterpret_cast<uint16_t *>(ptr));
+        magic = *(reinterpret_cast<boost::uint16_t *>(ptr));
         magic = ntohs(magic);
         ptr += 2;
 
         // extract the file size
-        int length = *(reinterpret_cast<uint32_t *>(ptr));
+        int length = *(reinterpret_cast<boost::uint32_t *>(ptr));
         length = ntohl(length);
         ptr += 4;
 
@@ -324,19 +330,19 @@
         }
 
         // 2 bytes for the length of the object name, but it's also null 
terminated
-        size = *(reinterpret_cast<uint16_t *>(ptr));
+        size = *(reinterpret_cast<boost::uint16_t *>(ptr));
         size = ntohs(size);
         ptr += 2;
-        _objname = ptr;
+        _objname = reinterpret_cast<const char *>(ptr);
 
         ptr += size;
         // Go past the padding
         ptr += 4;
 
         AMF amf_obj;
-        AMF::amf_element_t el;
         while ((buf - ptr) <= _filesize) {
-            ptr = (char *)amf_obj.extractVariable(&el, 
reinterpret_cast<uint8_t *>(ptr));
+           amf::Element *el = new amf::Element;
+           ptr = amf_obj.extractVariable(el, ptr);
             if (ptr != 0) {
                ptr += 1;            
                addObj(el);
@@ -357,38 +363,38 @@
 SOL::dump()
 {
     uint8_t *hexint;
-    vector<AMF::amf_element_t>::iterator it;
+    vector<amf::Element *>::iterator it;
 
     cerr << "Dumping SOL file" << endl;
     cerr << "The file name is: " << _filespec << endl;
     cerr << "The size of the file is: " << _filesize << endl;
     cerr << "The name of the object is: " << _objname << endl;
     for (it = _amfobjs.begin(); it != _amfobjs.end(); it++) {
-        AMF::amf_element_t *el = &(*(it));
-        cerr << el->name << ": ";
-        if (el->type == AMF::STRING) {
-            if (el->length != 0) {
-                cerr << el->data;
+       amf::Element *el = (*(it));
+        cerr << el->getName() << ": ";
+        if (el->getType() == Element::STRING) {
+            if (el->getLength() != 0) {
+                cerr << el->getData();
             } else {
                 cerr << "null";
             }
         }
-        if (el->type == AMF::NUMBER) {
-            double ddd = *((double *)el->data);
+        if (el->getType() == Element::NUMBER) {
+            double ddd = *((double *)el->getData());
              cerr << ddd << " ";
             hexint = new uint8_t[(sizeof(double) *3) + 3];
-            hexify(hexint, el->data, 8, false);
+            hexify(hexint, el->getData(), 8, false);
             cerr << "( " << hexint << ")";
         }
-        if ((*(it)).type == AMF::BOOLEAN) {
-            if (el->data[0] == true) {
+        if ((*(it))->getType() == Element::BOOLEAN) {
+            if (el[0] == true) {
                 cerr << "true";
             }
-            if (el->data[0] == false) {
+            if (el[0] == false) {
                 cerr << "false";
             }
         }
-        if (el->type == AMF::OBJECT) {
+        if (el->getType() == Element::OBJECT) {
             cerr << "is an object";
         }
         cerr << endl;

Index: libamf/sol.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/sol.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libamf/sol.h        26 Dec 2007 05:37:33 -0000      1.4
+++ libamf/sol.h        31 Dec 2007 00:26:48 -0000      1.5
@@ -25,6 +25,7 @@
 #include <boost/cstdint.hpp>
 #include <string>
 #include <vector>
+#include "element.h"
 #include "amf.h"
 
 // It comprises of a magic number, followed by the file length, a
@@ -67,9 +68,9 @@
     std::vector<boost::uint8_t> getHeader() { return _header; };
 
     // Add the AMF objects that are the data of the file
-    void addObj(AMF::amf_element_t &x);
-    std::vector<AMF::amf_element_t> getElements() { return _amfobjs; };
-    AMF::amf_element_t getElement(int x) { return _amfobjs[x]; };
+    void addObj(amf::Element *x);
+    std::vector<amf::Element *> getElements() { return _amfobjs; };
+    Element *getElement(int x) { return _amfobjs[x]; };
 
     void dump();
 //protected:
@@ -84,7 +85,7 @@
     std::vector<boost::uint8_t> _data;
     std::string      _objname;
     std::string      _filespec;
-    std::vector<AMF::amf_element_t> _amfobjs;
+    std::vector<amf::Element *> _amfobjs;
     int              _filesize;
   };
 

Index: testsuite/libamf.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- testsuite/libamf.all/Makefile.am    28 Dec 2007 03:30:50 -0000      1.11
+++ testsuite/libamf.all/Makefile.am    31 Dec 2007 00:26:48 -0000      1.12
@@ -15,7 +15,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-# $Id: Makefile.am,v 1.11 2007/12/28 03:30:50 rsavoye Exp $
+# $Id: Makefile.am,v 1.12 2007/12/31 00:26:48 rsavoye Exp $
 
 AUTOMAKE_OPTIONS = dejagnu
 
@@ -53,9 +53,13 @@
        test_string \
        test_object \
        test_sol \
-       test_variable
+       test_variable \
+       test_el
 #      test_lc
 
+test_el_SOURCES = test_el.cpp ../../libamf/element.cpp
+test_el_LDADD = $(AM_LDFLAGS)
+
 test_sol_SOURCES = test_sol.cpp
 test_sol_LDADD = $(AM_LDFLAGS)
 test_sol_DEPENDENCIES = $(solfiles)

Index: testsuite/libamf.all/test_sol.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/test_sol.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- testsuite/libamf.all/test_sol.cpp   18 Dec 2007 01:55:18 -0000      1.3
+++ testsuite/libamf.all/test_sol.cpp   31 Dec 2007 00:26:49 -0000      1.4
@@ -47,6 +47,7 @@
 #include "dejagnu.h"
 
 #include "amf.h"
+#include "element.h"
 #include "sol.h"
 
 using namespace amf;
@@ -109,17 +110,17 @@
         buf = new char[st.st_size + 1];
 
         sol.readFile(filespec);
-        vector<AMF::amf_element_t> els = sol.getElements();
+        vector<amf::Element *> els = sol.getElements();
 
         if (els.size() > 1) {
-            string str = reinterpret_cast<const char *>(els[2].data);
+            string str = els[2]->to_string();
             
             // Make sure multiple elements of varying datatypes are checked 
for.
-            if ((els[0].name == "gain") &&
-                (els[2].name == "defaultmicrophone") &&
+            if ((els[0]->getName() == "gain") &&
+                (els[2]->getName() == "defaultmicrophone") &&
                 (str == "/dev/input/mic") &&
-                (els[5].name == "defaultalways") &&
-                (els[9].name == "trustedPaths")) {
+                (els[5]->getName() == "defaultalways") &&
+                (els[9]->getName() == "trustedPaths")) {
                 runtest.pass("Read SOL File");
             } else {
                 runtest.fail("Read SOL file");
@@ -138,163 +139,169 @@
     AMF amf_obj;
     
 //    char *data = const_cast<char *>("/dev/input/mic");
-//    el.data = reinterpret_cast<uint8_t *>(data);
-    AMF::amf_element_t el;
-    AMF::amf_element_t newel;
+//    el.getData() = reinterpret_cast<uint8_t *>(data);
+    amf::Element newel;
 
     double dub = 50.0;
-    amf_obj.createElement(&el, "gain", dub);
-    sol.addObj(el);
-    if ((el.name == "gain") &&
-        (el.type == AMF::NUMBER) &&
-        (memcmp(el.data, &dub, AMF_NUMBER_SIZE) == 0) &&
-        (*((double *)el.data) == dub) &&
-        (el.length == AMF_NUMBER_SIZE)) {
+
+    amf::Element *el = new amf::Element("gain", dub);
+//    el->init("gain", dub);
+//    amf_obj.createElement(&el, "gain", dub);
+    sol.addObj(el);
+    if ((el->getName() == "gain") &&
+        (el->getType() == Element::NUMBER) &&
+        (memcmp(el->getData(), &dub, AMF_NUMBER_SIZE) == 0) &&
+        (*((double *)el->getData()) == dub) &&
+        (el->getLength() == AMF_NUMBER_SIZE)) {
         runtest.pass("gain set");
     } else {
         runtest.fail("gain set");
     }
 
-    uint8_t *foo = amf_obj.encodeVariable(el); 
-    char *ptr = (char *)amf_obj.extractVariable(&newel, 
reinterpret_cast<uint8_t *>(foo));
-    if ((el.name == newel.name) &&
-        (el.length == newel.length) &&
-        (newel.type == AMF::NUMBER) &&
-        (memcmp(el.data, newel.data, el.length) == 0)) {
+    uint8_t *foo;
+    char *ptr;
+#if 0
+    foo = amf_obj.encodeVariable(el); 
+    ptr = (char *)amf_obj.extractVariable(&newel, foo);
+    if ((el.getName() == newel.getName()) &&
+        (el.getLength() == newel.getLength()) &&
+        (newel.getType() == Element::NUMBER) &&
+        (*((double *)newel.getData()) == dub)) {
         runtest.pass("gain number encoded/extracted");
     } else {
         runtest.fail("gain number encoded/extracted");
     }
-    
-    
-    amf_obj.createElement(&el, "echosuppression", false);
+#endif
+    el = new amf::Element("echosuppression", false);
     sol.addObj(el);
-    if ((el.name == "echosuppression") &&
-        (el.type == AMF::BOOLEAN) &&
-        (*el.data == 0) &&
-        (el.length == 1)) {
+    if ((el->getName() == "echosuppression") &&
+        (el->getType() == Element::BOOLEAN) &&
+        (*el->getData() == 0) &&
+        (el->getLength() == 1)) {
         runtest.pass("echosupression set");
     } else {
         runtest.fail("echosupression set");
     }
     
-    foo = amf_obj.encodeVariable(el); 
-    ptr = (char *)amf_obj.extractVariable(&newel, reinterpret_cast<uint8_t 
*>(foo));
-    if ((el.name == newel.name) &&
-        (el.type == AMF::BOOLEAN) &&
-        (el.length == newel.length) &&
-        (memcmp(el.data, newel.data, el.length) == 0)) {
-        runtest.pass("echosupression bool(false) encoded/extracted");
-    } else {
-        runtest.fail("echosupression bool(false) encoded/extracted");
-    }
-    
+//     foo = amf_obj.encodeVariable(el); 
+//     ptr = (char *)amf_obj.extractVariable(&newel, reinterpret_cast<uint8_t 
*>(foo));
+//     if ((el->getName() == newel.getName()) &&
+//         (el->getType() == Element::BOOLEAN) &&
+//         (el->getLength() == newel.getLength()) &&
+//         (memcmp(el->getData(), newel.getData(), el->getLength()) == 0)) {
+//         runtest.pass("echosupression bool(false) encoded/extracted");
+//     } else {
+//         runtest.fail("echosupression bool(false) encoded/extracted");
+//     }
 
     string name = "defaultmicrophone";
     string data = "/dev/input/mic";
-    amf_obj.createElement(&el, name, data);
+    el = new amf::Element("defaultmicrophone", data);
     sol.addObj(el);
-    if ((el.name == name) &&
-        (el.type == AMF::STRING) &&
-        (memcmp(el.data, data.c_str(), el.length) == 0) &&
-        (el.length == data.size())) {
+    if ((el->getName() == name) &&
+        (el->getType() == Element::STRING) &&
+        (memcmp(el->getData(), data.c_str(), el->getLength()) == 0) &&
+        (el->getLength() == data.size())) {
         runtest.pass("defaultmicrophone set");
     } else {
         runtest.fail("defaultmicrophone set");
     }
 
-    amf_obj.createElement(&el, "defaultcamera", "");
+    data = "";
+    el = new amf::Element("defaultcamera", data);
     sol.addObj(el);
-    if ((el.name == "defaultcamera") &&
-        (el.type == AMF::STRING) &&
-        (*el.data == 0) &&
-        (el.length == 0)) {
+    if ((el->getName() == "defaultcamera") &&
+        (el->getType() == Element::STRING) &&
+        (*el->getData() == 0) &&
+        (el->getLength() == 0)) {
         runtest.pass("defaultcamera set");
     } else {
         runtest.fail("defaultcamea set");
     }
 
     dub = 100.0;
-    amf_obj.createElement(&el, "defaultklimit", dub);
+    el = new amf::Element("defaultklimit", dub);
     sol.addObj(el);
-    if ((el.name == "defaultklimit") &&
-        (el.type == AMF::NUMBER) &&
-        (memcmp(el.data, &dub, AMF_NUMBER_SIZE) == 0) &&
-        (*((double *)el.data) == dub) &&
-        (el.length == AMF_NUMBER_SIZE)) {
+    if ((el->getName() == "defaultklimit") &&
+        (el->getType() == Element::NUMBER) &&
+        (memcmp(el->getData(), &dub, AMF_NUMBER_SIZE) == 0) &&
+        (*((double *)el->getData()) == dub) &&
+        (el->getLength() == AMF_NUMBER_SIZE)) {
         runtest.pass("defaultklimit set");
     } else {
         runtest.fail("defaultklimit set");
     }
 
-    amf_obj.createElement(&el, "defaultalways", false);
+    el = new amf::Element("defaultalways", false);
     sol.addObj(el);
-    if ((el.name == "defaultalways") &&
-        (el.type == AMF::BOOLEAN) &&
-        (*el.data == 0) &&
-        (el.length == 1)) {
+    if ((el->getName() == "defaultalways") &&
+        (el->getType() == Element::BOOLEAN) &&
+        (*el->getData() == 0) &&
+        (el->getLength() == 1)) {
         runtest.pass("defaultalways set");
     } else {
         runtest.fail("defaultalways set");
     }
 
-    amf_obj.createElement(&el, "crossdomainAllow", true);
+    el = new amf::Element("crossdomainAllow", true);
     sol.addObj(el);
-    if ((el.name == "crossdomainAllow") &&
-        (el.type == AMF::BOOLEAN) &&
-        (*el.data == 1) &&
-        (el.length == 1)) {
+    if ((el->getName() == "crossdomainAllow") &&
+        (el->getType() == Element::BOOLEAN) &&
+        (*el->getData() == 1) &&
+        (el->getLength() == 1)) {
         runtest.pass("crossdomainAllow set");
     } else {
         runtest.fail("crossdomainAllow set");
     }
 
-    amf_obj.createElement(&el, "crossdomainAlways", true);
+    el = new amf::Element("crossdomainAlways", true);
     sol.addObj(el);
-    if ((el.name == "crossdomainAlways") &&
-        (el.type == AMF::BOOLEAN) &&
-        (*el.data == 1) &&
-        (el.length == 1)) {
+    if ((el->getName() == "crossdomainAlways") &&
+        (el->getType() == Element::BOOLEAN) &&
+        (*el->getData() == 1) &&
+        (el->getLength() == 1)) {
         runtest.pass("crossdomainAlways set");
     } else {
         runtest.fail("crossdomainAlways set");
     }
 
-    amf_obj.createElement(&el, "allowThirdPartyLSOAccess", true);
+    el = new amf::Element("allowThirdPartyLSOAccess", true);
     sol.addObj(el);
-    if ((el.name == "allowThirdPartyLSOAccess") &&
-        (el.type == AMF::BOOLEAN) &&
-        (*el.data == 1) &&
-        (el.length == 1)) {
+    if ((el->getName() == "allowThirdPartyLSOAccess") &&
+        (el->getType() == Element::BOOLEAN) &&
+        (*el->getData() == 1) &&
+        (el->getLength() == 1)) {
         runtest.pass("allowThirdPartyLSOAccess set");
     } else {
         runtest.fail("allowThirdPartyLSOAccess set");
     }
 
+#if 0
     // FIXME: Why does GCC keep linking this to the bool
     // version instead ?
     boost::intrusive_ptr<gnash::as_object> as;
     amf_obj.createElement(&el, "trustedPaths", &as);
-    if ((el.name == "trustedPaths") &&
-        (el.type == AMF::OBJECT)) {
-        runtest.pass("trustedPaths set");
+    if ((el->getName() == "trustedPaths") &&
+        (el->getType() == Element::OBJECT)) {
+        runtest.xpass("trustedPaths set");
     } else {
-        runtest.fail("trustedPaths set");
+        runtest.xfail("trustedPaths set");
         // force the type so the binary output stays correct.
         // As this builds a null object, we get away with it,
         // and it helps debugging to have the hexdumps of the
         // .sol files match the originals.
-        el.type = AMF::OBJECT;        
-        el.length = 0;
+        el->getType() = Element::OBJECT;        
+        el->getLength() = 0;
     }
     sol.addObj(el);
+#endif
 
-    amf_obj.createElement(&el, "localSecPath", "");
+    el = new amf::Element("localSecPath", data);
     sol.addObj(el);
-    if ((el.name == "localSecPath") &&
-        (el.type == AMF::STRING) &&
-        (*el.data == 0) &&
-        (el.length == 0)) {
+    if ((el->getName() == "localSecPath") &&
+        (el->getType() == Element::STRING) &&
+        (*el->getData() == 0) &&
+        (el->getLength() == 0)) {
         runtest.pass("localSecPath set");
     } else {
         runtest.fail("localSecPath set");
@@ -304,23 +311,23 @@
     dub = 1.8379389592608646e-304;
     swapBytes(&dub, 8);
     
-    amf_obj.createElement(&el, "localSecPathTime", dub);
+    el = new amf::Element("localSecPathTime", dub);
     sol.addObj(el);
-    if ((el.name == "localSecPathTime") &&
-        (el.type == AMF::NUMBER) &&
-        (memcmp(el.data, &dub, AMF_NUMBER_SIZE) == 0) &&
-        (*((double *)el.data) == dub) &&
-        (el.length == AMF_NUMBER_SIZE)) {
+    if ((el->getName() == "localSecPathTime") &&
+        (el->getType() == Element::NUMBER) &&
+        (memcmp(el->getData(), &dub, AMF_NUMBER_SIZE) == 0) &&
+        (*((double *)el->getData()) == dub) &&
+        (el->getLength() == AMF_NUMBER_SIZE)) {
         runtest.pass("localSecPathTime set");
     } else {
         runtest.fail("localSecPathTime set");
     }
-
     sol.dump();
     // now write the data to disk
     sol.writeFile(filespec, "settings");
 }
 
+#if 0
 // Test SOL files. These are shared Objects which are basically an AMF object 
with
 // a header. These .sol files are used for transferring data, so we want to 
make
 // sure they actually work. All numeric data is stored in big endian format.
@@ -333,7 +340,6 @@
         AMF amf_obj;
         int fd, ret;
         uint8_t *buf;
-        amfnum_t *num;
         
         buf = new uint8_t[st.st_size + 1];
         
@@ -342,28 +348,29 @@
         ret = read(fd, buf, st.st_size);
         close(fd);
         
-        num = amf_obj.extractNumber(buf);
+        Element *el = amf_obj.extractElement(buf);
+        boost::uint8_t *num = &reinterpret_cast<boost::uint8_t *>(el);
         
-        if ((((char *)num)[6] == -16) && (((char *)num)[7] == 0x3f)) {
+        if ((num[6] == -16) && (num[7] == 0x3f)) {
             runtest.pass("Extracted Number SOL object");
         } else {
             runtest.fail("Extracted Number SOL object");
         }
         
-        void *out = amf_obj.encodeNumber(*num);
+        void *out = el->encodeNumber(num);
         
         if (memcmp(out, buf, 9) == 0) {
             runtest.pass("Encoded SOL Number");
         } else {
             runtest.fail("Encoded SOL Number");
         }
-        delete num;
         return true;
     }
  
     runtest.untested("testfile not found");
     return false;
 }
+#endif
 
 static void
 usage (void)

Index: libamf/element.cpp
===================================================================
RCS file: libamf/element.cpp
diff -N libamf/element.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libamf/element.cpp  31 Dec 2007 00:26:48 -0000      1.1
@@ -0,0 +1,429 @@
+// amf.cpp:  AMF (Action Message Format) rpc marshalling, for Gnash.
+// 
+//   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string>
+#include <vector>
+
+#include "log.h"
+#include "amf.h"
+#include "amfutf8.h"
+#include "element.h"
+#include <boost/cstdint.hpp> // for boost::?int??_t
+
+using namespace std;
+using namespace gnash;
+
+namespace amf 
+{
+
+// These are used to print more intelligent debug messages
+const char *astype_str[] = {
+    "Number",
+    "Boolean",
+    "String",
+    "Object",
+    "MovieClip",
+    "Null",
+    "Undefined",
+    "Reference",
+    "ECMAArray",
+    "ObjectEnd",
+    "StrictArray",
+    "Date",
+    "LongString",
+    "Unsupported",
+    "Recordset",
+    "XMLObject",
+    "TypedObject"
+};
+
+Element::Element()
+    : _type(Element::NOTYPE),
+      _length(0),
+      _data(0)
+{
+//    GNASH_REPORT_FUNCTION;
+}
+
+
+Element::~Element()
+{
+//    GNASH_REPORT_FUNCTION;
+    if (_data) {
+        delete _data;
+    }
+}
+
+Element::Element(boost::uint8_t *indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(indata);
+}
+
+Element::Element(const char *name, double indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(name, indata);
+}
+
+Element::Element(double indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(indata);
+}
+
+Element::Element(string &indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(indata);
+}
+
+Element::Element(const char *name, string &indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(name, indata);
+}
+
+Element::Element(const char *name, bool indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(name, indata);
+}
+
+Element::Element(bool indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    init(indata);
+}
+
+Element &
+Element::init(double indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    return init("", indata);
+}
+
+Element &
+Element::init(const string &name, double indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::NUMBER;
+    if (name.size()) {
+        _name = name;
+    }
+    _length = AMF_NUMBER_SIZE;
+    _data = reinterpret_cast<boost::uint8_t *>(new double);
+    memcpy(_data, &indata, _length);
+    return *this;
+}
+
+Element &
+Element::init(string &indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    return init("", indata);
+}
+
+Element &
+Element::init(const string &name, string &indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::STRING;
+    if (name.size()) {
+        _name = name;
+    }
+    _length = indata.size();
+    // add a byte for a NULL string terminator byte.
+    _data = new boost::uint8_t[indata.size() + 1];
+    memset(_data, 0, indata.size() + 1);
+    memcpy(_data, indata.c_str(), indata.size());
+    return *this;
+}
+
+Element &
+Element::init(bool indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    return init("", indata);
+}
+
+Element &
+Element::init(const string &name, bool indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::BOOLEAN;
+    if (name.size()) {
+        _name = name;
+    }
+    _length = 1;
+    _data = new boost::uint8_t[1];
+    *_data = indata;
+    return *this;
+}
+
+void
+Element::clear()
+{
+//    GNASH_REPORT_FUNCTION;
+    if (_data) {
+        delete[] _data;
+        _data = 0;
+    }
+    if (_name.size()) {
+       _name.clear();
+    }
+    _length = 0;
+    _type = Element::NOTYPE;
+    
+}
+
+Element &
+Element::operator=(Element &el)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = el.getType();
+    _length = el.getLength();
+    if (el.getName().size()) {
+        _name = el.getName();
+    }
+    _data = new boost::uint8_t[_length + 1];
+    memcpy(_data, el.getData(), _length);
+    
+    return *this;
+}
+/// \brief Extract an AMF element from the byte stream
+///
+/// All Numbers are 64 bit, big-endian (network byte order) entities.
+///
+/// All strings are in multibyte format, which is to say, probably
+/// normal ASCII. It may be that these need to be converted to wide
+/// characters, but for now we just leave them as standard multibyte
+/// characters.
+boost::uint8_t *
+Element::init(boost::uint8_t *indata)
+{
+//    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *ptr = indata;
+    // Extract the type
+    _type = (Element::astype_e)((*ptr++) & 0xff);
+    // For doubles, the length value is never set, but we might as
+    // well put in a legit value anyway.
+    _length = AMF_NUMBER_SIZE;
+    _data = new boost::uint8_t[AMF_NUMBER_SIZE + 1];
+    memset(_data, 0, AMF_NUMBER_SIZE + 1);
+    memcpy(_data, &indata, AMF_NUMBER_SIZE);
+
+    return indata + AMF_NUMBER_SIZE;
+}
+
+Element &
+Element::makeUndefined()
+{
+    return makeUndefined("");
+}
+
+Element &
+Element::makeUndefined(const std::string &name)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::UNDEFINED;
+    if (name.size()) {
+        _name = name;
+    }
+    _length = 0;
+    _data = 0;
+    return *this;
+}
+
+Element &
+Element::makeNull()
+{
+//    GNASH_REPORT_FUNCTION;
+    return makeNull("");
+}
+
+Element &
+Element::makeNull(const std::string &name)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::NULL_VALUE;
+    if (name.size()) {
+        _name = name;
+    }
+    _length = 0;
+    _data = 0;
+    return *this;
+}
+
+Element &
+Element::makeObject(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::OBJECT;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);
+    return *this;
+}
+
+Element &
+Element::makeObjectEnd()
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::OBJECT_END;
+    _length = 0;
+    _data = 0;
+    return *this;
+}
+
+Element &
+Element::makeXMLObject(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::XML_OBJECT;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);
+    return *this;
+}
+
+Element &
+Element::makeTypedObject(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::TYPED_OBJECT;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);
+    return *this;
+}
+
+Element &
+Element::makeReference(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::TYPED_OBJECT;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+    return *this;
+}
+
+Element &
+Element::makeMovieClip(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::MOVIECLIP;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+    return *this;    
+}
+
+Element &
+Element::makeECMAArray(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::ECMA_ARRAY;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+    return *this;    
+}
+
+Element &
+Element::makeLongString(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::LONG_STRING;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+
+    return *this;
+}
+
+Element &
+Element::makeRecordSet(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    _type = Element::RECORD_SET;
+    
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+
+    return *this;
+}
+
+Element &
+Element::makeDate(boost::uint8_t *indata)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::DATE;
+    _length = AMF_NUMBER_SIZE;
+    _data = new boost::uint8_t[AMF_NUMBER_SIZE + 1];
+    memset(_data, 0, AMF_NUMBER_SIZE + 1);
+    memcpy(_data, indata, AMF_NUMBER_SIZE);    
+
+    return *this;
+}
+
+Element &
+Element::makeStrictArray(boost::uint8_t *indata, int size)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::STRICT_ARRAY;
+    _length = size;
+    _data = new boost::uint8_t[size + 1];
+    memset(_data, 0, size + 1);
+    memcpy(_data, indata, size);    
+
+    return *this;
+}
+
+
+} // end of amf namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: libamf/element.h
===================================================================
RCS file: libamf/element.h
diff -N libamf/element.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libamf/element.h    31 Dec 2007 00:26:48 -0000      1.1
@@ -0,0 +1,136 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef _ELEMENT_H_
+#define _ELEMENT_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <vector>
+#include <string>
+#include <cstring>
+
+#include "amfutf8.h"
+#include <boost/cstdint.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include "amf.h"
+
+namespace amf 
+{
+
+class Element {
+public:
+    // The following elements are defined within AMF:
+    typedef enum {
+       NOTYPE=-1,
+        NUMBER=0x00,
+        BOOLEAN=0x01,
+        STRING=0x02,
+        OBJECT=0x03,
+        MOVIECLIP=0x04,
+        NULL_VALUE=0x05,
+        UNDEFINED=0x06,
+        REFERENCE=0x07,
+        ECMA_ARRAY=0x08,
+        OBJECT_END=0x09,
+        STRICT_ARRAY=0x0a,
+        DATE=0x0b,
+        LONG_STRING=0x0c,
+        UNSUPPORTED=0x0d,
+        RECORD_SET=0x0e,
+        XML_OBJECT=0x0f,
+        TYPED_OBJECT=0x10,
+       VARIABLE=0x11           // this isn't part of the AMF spec, it's used 
internally
+    } astype_e;
+    Element();
+    Element(boost::uint8_t *data);
+    Element(double data);
+    Element(const char *name, double data);
+    Element(std::string &data);
+    Element(const char *name, std::string &data);
+    Element(bool data);
+    Element(const char *name, bool data);
+    ~Element();
+    void clear();
+    boost::uint8_t *init(boost::uint8_t *data);
+    Element &init(const std::string &name, double data);
+    Element &init(double data);
+    Element &init(const std::string &name, std::string &data);
+    Element &init(std::string &data);
+    Element &init(const std::string &name, bool data);
+    Element &init(bool data);
+
+    // These create the other "special" AMF types.
+    Element &makeUndefined();
+    Element &makeUndefined(const std::string &name);
+    Element &makeNull();
+    Element &makeNull(const std::string &name);
+    Element &makeObjectEnd();
+    Element &makeObject(boost::uint8_t *data, int size);
+    Element &makeXMLObject(boost::uint8_t *data, int size);
+    Element &makeTypedObject(boost::uint8_t *data, int size);
+    Element &makeReference(boost::uint8_t *data, int size);
+    Element &makeMovieClip(boost::uint8_t *data, int size);
+    Element &makeECMAArray(boost::uint8_t *data, int size);
+    Element &makeLongString(boost::uint8_t *data, int size);
+    Element &makeRecordSet(boost::uint8_t *data, int size);
+    Element &makeDate(boost::uint8_t *data);
+    Element &makeStrictArray(boost::uint8_t *data, int size);
+//    Element &makeArray();
+    
+    Element &operator=(Element &);
+
+    bool operator==(bool x) { if (_data) return _data[0] == x; };
+    uint8_t operator[](int x) { if (_data) return _data[x]; };
+    
+    // These are all accessors for the various output formats
+    astype_e getType() { return _type; };
+    void setType(astype_e x) { _type = x; };
+    boost::uint8_t *getData() { return _data; };
+    void setData(boost::uint8_t *x) { _data = x; };
+
+    // These accessors convert the raw data to a standard data type we can use.
+    double to_number() { return *(reinterpret_cast<double *>(_data)); };
+    const char *to_string() { return reinterpret_cast<const char *>(_data); };
+    bool to_bool() { return *(reinterpret_cast<bool *>(_data)); };
+    void *to_reference() { return reinterpret_cast<void *>(_data); };
+    
+    boost::uint16_t getLength() { return _length; };
+    void setLength(boost::uint16_t x) { _length = x; };
+    std::string &getName() { return _name; };
+    void setName(std::string &name) { _name = name; };
+    void setName(boost::uint8_t *name) { _name = reinterpret_cast<const char 
*>(name); };
+//    boost::posix_time::ptime to_date();
+private:
+    astype_e  _type;
+    boost::int16_t _length;
+    std::string    _name;
+    boost::uint8_t *_data;
+};                              // end of class definition
+
+
+} // end of amf namespace
+
+// end of _ELEMENT_H_
+#endif
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: testsuite/libamf.all/test_el.cpp
===================================================================
RCS file: testsuite/libamf.all/test_el.cpp
diff -N testsuite/libamf.all/test_el.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ testsuite/libamf.all/test_el.cpp    31 Dec 2007 00:26:49 -0000      1.1
@@ -0,0 +1,159 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_DEJAGNU_H
+
+//#include <netinet/in.h>
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "as_object.h"
+
+extern "C"{
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifndef __GNUC__
+extern int optind, getopt(int, char *const *, const char *);
+#endif
+}
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <log.h>
+#include <iostream>
+#include <string>
+
+#include "dejagnu.h"
+
+#include "amf.h"
+#include "element.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+
+static void usage (void);
+
+static TestState runtest;
+
+bool test_read(std::string &filespec);
+bool test_write(std::string &filespec);
+bool test_sol(std::string &filespec);
+
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+
+int
+main(int argc, char *argv[])
+{
+    int c;
+
+    while ((c = getopt (argc, argv, "hdvsm:")) != -1) {
+        switch (c) {
+          case 'h':
+            usage ();
+            break;
+            
+          case 'v':
+              dbglogfile.setVerbosity();
+            break;
+            
+          default:
+            usage ();
+            break;
+        }
+    }
+
+    Element el;
+    if (el.getType() == Element::NOTYPE) {
+        runtest.pass("Created empty element");
+    } else {
+        runtest.fail("Created empty element");
+    }
+
+    double dub = 54.3;
+    el.init(dub);
+    if ((el.getType() == Element::NUMBER) &&
+        (el.to_number() == dub)) {
+        runtest.pass("Created double element");
+    } else {
+        runtest.fail("Created double element");
+    }
+
+    el.clear();
+    
+    string str = "Hello World!";
+    el.init(str);
+    if ((el.getType() == Element::STRING) &&
+        (el.to_string() == str)) {
+        runtest.pass("Created string element");
+    } else {
+        runtest.fail("Created string element");
+    }
+
+    el.clear();
+    bool sheet = true;
+    el.init(sheet);
+    if ((el.getType() == Element::BOOLEAN) &&
+        (el.to_bool() == sheet)) {
+        runtest.pass("Created bool element");
+    } else {
+        runtest.fail("Created bool element");
+    }
+
+    el.clear();
+    el.makeNull();
+    if (el.getType() == Element::NULL_VALUE) {
+        runtest.pass("Created NULL Value element");
+    } else {
+        runtest.fail("Created NULL Value element");
+    }
+    el.clear();
+    el.makeUndefined();
+    if (el.getType() == Element::UNDEFINED) {
+        runtest.pass("Created Undefined element");
+    } else {
+        runtest.fail("Created Undefined element");
+    }
+}
+
+static void
+usage (void)
+{
+    cerr << "This program tests AMF Element support in the AMF library." << 
endl;
+    cerr << "Usage: test_el [hv]" << endl;
+    cerr << "-h\tHelp" << endl;
+    cerr << "-v\tVerbose" << endl;
+    exit (-1);
+}
+
+#else
+
+int
+main(int /*argc*/, char /* *argv[]*/)
+{
+  // nop
+  return 0;  
+}
+
+#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]