gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libamf/amf.cpp libamf/amf.h lib...


From: Rob Savoye
Subject: [Gnash-commit] gnash ChangeLog libamf/amf.cpp libamf/amf.h lib...
Date: Fri, 01 Feb 2008 01:42:41 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    08/02/01 01:42:41

Modified files:
        .              : ChangeLog 
        libamf         : amf.cpp amf.h element.cpp element.h lcshm.cpp 
                         lcshm.h 

Log message:
                * libamf/amf.cpp: Oops, return original pointer as returned by
                new, not the incremented pointer. Use :encodeElement() for
                strings. Encode an array of AMF objects.
                * libamf/amf.h: Make all the encoding methods static.
                * libamf/element.{cpp,h}: Add function and variable data types,
                internal to Gnash. Initialize with an array of AMF objects. 
Create
                a new function block object in memory. Don't return nan, BSD
                doesn't support it.
                * libamf/lcshm.cpp: Correctly remove Listeners. Format a memory
                segment header. Send now works, and puts AMF objects into the
                memory segment.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5543&r2=1.5544
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.cpp?cvsroot=gnash&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.h?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.h?cvsroot=gnash&r1=1.6&r2=1.7

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5543
retrieving revision 1.5544
diff -u -b -r1.5543 -r1.5544
--- ChangeLog   1 Feb 2008 01:30:28 -0000       1.5543
+++ ChangeLog   1 Feb 2008 01:42:40 -0000       1.5544
@@ -1,5 +1,17 @@
 2008-01-31  Rob Savoye  <address@hidden>
 
+       * libamf/amf.cpp: Oops, return original pointer as returned by
+       new, not the incremented pointer. Use :encodeElement() for
+       strings. Encode an array of AMF objects.
+       * libamf/amf.h: Make all the encoding methods static.
+       * libamf/element.{cpp,h}: Add function and variable data types,
+       internal to Gnash. Initialize with an array of AMF objects. Create
+       a new function block object in memory. Don't return nan, BSD
+       doesn't support it.
+       * libamf/lcshm.cpp: Correctly remove Listeners. Format a memory
+       segment header. Send now works, and puts AMF objects into the
+       memory segment.
+       
        * configure.ac: Add test for IPC_INFO, which isn't portable to
        BSD.
        * server/asobj/LocalConnection.cpp: Don;t define any LC constants

Index: libamf/amf.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- libamf/amf.cpp      31 Jan 2008 11:25:57 -0000      1.58
+++ libamf/amf.cpp      1 Feb 2008 01:42:40 -0000       1.59
@@ -162,8 +162,7 @@
 AMF::readElements(boost::uint8_t *in)
 {
     GNASH_REPORT_FUNCTION;
-
-    boost::uint8_t *x = in;
+boost::uint8_t *x = in;
     astype_e type = (astype_e)*x;
     bool boolshift;
     const char *mstr = NULL;
@@ -265,33 +264,6 @@
 // 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
@@ -304,15 +276,16 @@
     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];
+    boost::uint8_t *ptr = new boost::uint8_t[pktsize + 1];
+    boost::uint8_t *x = ptr;
     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;
+//    x += pktsize - AMF_HEADER_SIZE;
     
-    return x;
+    return ptr;
 }
 
 /// Encode a Boolean object
@@ -328,15 +301,17 @@
 //    GNASH_REPORT_FUNCTION;
     int pktsize = AMF_HEADER_SIZE;
 
-    boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+    boost::uint8_t*ptr = new boost::uint8_t[pktsize + 1];
+    boost::uint8_t* x = ptr;
     memset(x, 0, pktsize);
     // Encode a boolean value. 0 for false, 1 for true
     *x++ = (char)Element::BOOLEAN;
+    x++;
     *x = flag;
-    swapBytes(x, 2);
-    x += sizeof(boost::uint16_t);
+//    swapBytes(x, 2);
+//    x += sizeof(boost::uint16_t);
     
-    return x;
+    return ptr;
 }
 
 /// Encode an object
@@ -545,6 +520,35 @@
     return 0;
 }
 
+/// 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::encodeElement(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 *ptr = new boost::uint8_t[pktsize + 1];
+    boost::uint8_t *x = ptr;
+    memset(x, 0, pktsize);
+    *x++ = Element::STRING;
+    length = strlen(str);
+    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 ptr;
+}
+
 /// \brief Write an AMF element
 ///
 /// This encodes the data supplied to an AMF formatted one. As the
@@ -572,13 +576,13 @@
          return 0;
          break;
       case Element::NUMBER:
-         return encodeNumber(*(reinterpret_cast<double *>(el->getData())));
+         return encodeNumber(el->to_number());
           break;
       case Element::BOOLEAN:
-         return encodeBoolean(*(reinterpret_cast<bool *>(el->getData())));
+         return encodeBoolean(el->to_bool());
           break;
       case Element::STRING:
-         return encodeBoolean(*(reinterpret_cast<const char 
*>(el->getData())));
+         return encodeElement(el->to_string());
           break;
       case Element::OBJECT:
          return encodeObject(el->getData(), el->getLength());
@@ -634,6 +638,85 @@
     return 0;
 }
 
+/// Encode an array of elements. 
+///
+/// @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
+///
+vector<boost::uint8_t> *
+AMF::encodeElement(vector<amf::Element *> &data)
+{
+    GNASH_REPORT_FUNCTION;
+
+    int size = 0;
+    bool pad = false;
+
+    // Calculate how large the buffer has to be.
+    vector<amf::Element *>::iterator ait;
+    cerr << "# of Elements in file: " << data.size() << endl;
+    for (ait = data.begin(); ait != data.end(); ait++) {
+       amf::Element *el = (*(ait));
+       size += el->getLength() + AMF_HEADER_SIZE;
+//        el->dump();
+    }
+    vector<boost::uint8_t> *vec = new vector<boost::uint8_t>;
+    boost::uint8_t* ptr = new boost::uint8_t[size + 1];
+    memset(ptr, 0, size + 1);
+    
+    boost::uint8_t *x = ptr;
+    size = 0;
+    for (ait = data.begin(); ait != data.end(); ait++) {
+       amf::Element *el = (*(ait));
+//     el->dump();
+       boost::uint8_t *tmp = encodeElement(el);
+       boost::uint8_t *y = tmp;
+#if 0
+       boost::uint8_t *hexint;
+       hexint = new boost::uint8_t[(el->getLength() + 4) *3];
+       hexify((boost::uint8_t *)hexint, (boost::uint8_t *)tmp,
+              el->getLength() + AMF_HEADER_SIZE, true);
+       log_msg(_("The packet head is: 0x%s"), hexint);
+#endif
+       // The 'pad' in this case is a serious hack. I think it
+       // may be an artifact, but one guess is it's a 16bit word
+       // aligned memory segment due to some ancient heritage in
+       // the other player, so after a 3 byte bool, and two 9 byte
+       // numbers, another byte is needed for padding.
+       // My guess is the pattern of boolean->number->number->methodname
+       // is a function block ID. I need to dp more testing with a
+       // wider variety of sef movies that use LocalConnection to
+       // really tell.
+       if (el->getType() == Element::NUMBER) {
+           size = AMF_NUMBER_SIZE + 1;
+           pad = true;
+       }
+       if (el->getType() == Element::STRING) {
+           if (pad) {
+               vec->push_back('\0');
+               pad = false;
+           }
+           size = el->getLength() + AMF_HEADER_SIZE;
+       }
+       if (el->getType() == Element::FUNCTION) {
+           // _children
+       }
+       if (el->getType() == Element::BOOLEAN) {
+           size = 3;
+       }
+       for (int i=0; i<size; i++) {
+           boost::uint8_t c = *y;
+           y++;
+//         printf("0x%x(%c) ", c, (isalpha(c)) ? c : '.');
+           vec->push_back(c);
+       }
+//     delete[] tmp;
+    }
+    return vec;
+}
+
+
 #if 0
 /// \brief \ Each RTMP header consists of the following:
 ///
@@ -1387,8 +1470,6 @@
     boost::uint8_t *tmpptr;
 
 //    uint8_t hexint[(bytes*2)+1];
-    boost::uint8_t* hexint;
-
     short length;
 
     if (in == 0) {
@@ -1401,6 +1482,7 @@
 //     }
 
 #if 0
+    boost::uint8_t* hexint;
     hexint =  (boost::uint8_t*) malloc((bytes * 3) + 12);
     hexify((boost::uint8_t *)hexint, (boost::uint8_t *)in, bytes, true);
     log_msg(_("The packet body is: 0x%s"), hexint);
@@ -1462,7 +1544,7 @@
       case Element::XML_OBJECT:
       case Element::TYPED_OBJECT:
       default:
-         log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)type);
+//       log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)type);
          return 0;
     }
     

Index: libamf/amf.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- libamf/amf.h        31 Jan 2008 11:25:57 -0000      1.30
+++ libamf/amf.h        1 Feb 2008 01:42:41 -0000       1.31
@@ -144,97 +144,97 @@
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeString(const char *str);
+    static boost::uint8_t *encodeElement(const char *str);
 
     /// Encode a Boolean object
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeBoolean(bool flag);
+    static boost::uint8_t *encodeBoolean(bool flag);
 
     /// Encode an "Undefined" object
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeUndefined();
+    static boost::uint8_t *encodeUndefined();
 
     /// Encode a "NULL" object
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeNull();
+    static boost::uint8_t *encodeNull();
 
     /// Encode a "Unsupported" object
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeUnsupported();
+    static  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);
+    static 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);
+    static 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);
+    static 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);
+    static 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);
+    static 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);
+    static 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);
+    static 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 *encodeDate(boost::uint8_t *data);
+    static 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);
+    static 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);
+    static boost::uint8_t *encodeObject(const boost::uint8_t *data, int size);
 
     /// Encode a 64 bit number
     ///
     /// @return a binary AMF packet in big endian format (header,data)
     ///
-    boost::uint8_t *encodeNumber(double num);
+    static boost::uint8_t *encodeNumber(double num);
     
     /// Encode a element. 
     ///
@@ -243,7 +243,16 @@
     /// @return a newly allocated byte array.
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t *encodeElement(amf::Element *el);
+    static boost::uint8_t *encodeElement(amf::Element *el);
+
+    /// Encode an array of elements. 
+    ///
+    /// @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
+    ///
+    static std::vector<boost::uint8_t> *encodeElement(std::vector<amf::Element 
*> &els);
 
     /// Encode a variable. 
     //
@@ -271,40 +280,40 @@
     ///
     /// @return an amf packet (header,data)
     ///
-    boost::uint8_t* encodeElement(Element::astype_e type, const void *in, int 
nbytes);
+    static 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(const char *name);
+    static boost::uint8_t* encodeVariable(const char *name);
 
     /// Encode a boolean variable. This is a name followed by a boolean value.
     //
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(const char *name, bool flag);
+    static boost::uint8_t* encodeVariable(const char *name, bool flag);
 
     /// Encode a variable. 
     //
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(const char *name, double num);
+    static boost::uint8_t* encodeVariable(const char *name, double num);
 
     /// Encode a variable. 
     //
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(std::string &name, std::string &val);
+    static boost::uint8_t* encodeVariable(std::string &name, std::string &val);
 
     /// Encode a variable. 
     //
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
     ///
-    boost::uint8_t* encodeVariable(const char *name, const char *val);
+    static boost::uint8_t* encodeVariable(const char *name, const char *val);
 
     void *encodeRTMPHeader(int amf_index, amf_headersize_e head_size, int 
total_size,
                            content_types_e type, amfsource_e routing);
@@ -331,6 +340,7 @@
     
     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);

Index: libamf/element.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- libamf/element.cpp  31 Jan 2008 10:27:06 -0000      1.8
+++ libamf/element.cpp  1 Feb 2008 01:42:41 -0000       1.9
@@ -23,6 +23,8 @@
 
 #include <string>
 #include <vector>
+#include <cmath>
+#include <climits>
 
 #include "log.h"
 #include "amf.h"
@@ -54,7 +56,9 @@
     "Unsupported",
     "Recordset",
     "XMLObject",
-    "TypedObject"
+    "TypedObject",
+    "Varible (gnash)",
+    "Function (gnash)"
 };
 
 Element::Element()
@@ -72,44 +76,91 @@
     if (_data) {
         delete [] _data;
     }
+    for (size_t i=0; i< _children.size(); i++) {
+       delete _children[i];
+    }
 }
 
 Element::Element(boost::uint8_t *indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(indata);
 }
 
 Element::Element(double indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(indata);
 }
 
+// Element(vector<double> &indata)
+// {
+//     GNASH_REPORT_FUNCTION;
+//     init(indata);
+// }
+
 Element::Element(const string &indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(indata);
 }
 
 Element::Element(const string &name, const string &indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(name, indata);
 }
 
 Element::Element(const string &name, bool indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(name, indata);
 }
 
 Element::Element(bool indata)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     init(indata);
 }
 
+// Create a function block for AMF
+Element::Element(bool flag, double unknown1, double unknown2,
+                const string &methodname)
+{
+    GNASH_REPORT_FUNCTION;
+    init(flag, unknown1, unknown2, methodname);
+}
+
+Element &
+Element::init(bool flag, double unknown1, double unknown2,
+                const string &methodname)
+{
+    GNASH_REPORT_FUNCTION;
+    _type = Element::FUNCTION;
+    if (methodname.size()) {
+       _name = methodname;
+    }
+
+    // Build up the children for the function block
+    Element *el = new Element(flag);
+    _children.push_back(el);
+    
+    el = new Element(unknown1);
+    _children.push_back(el);
+    
+    el = new Element(unknown2);
+    _children.push_back(el);
+    
+    el = new Element(methodname);
+    _children.push_back(el);
+    
+    _length = 3
+       + ((AMF_HEADER_SIZE + AMF_NUMBER_SIZE) * 2)
+       + methodname.size() + AMF_HEADER_SIZE;
+//     memcpy(_data, &indata, _length);
+    return *this;
+}
+
 Element &
 Element::init(double indata)
 {
@@ -197,7 +248,8 @@
     if (_data) {
        return *(reinterpret_cast<double *>(_data));
     }
-    return nan("NaN");
+//    return ::nan("NaN");
+    return -1.0;
 }
 
 const char *
@@ -287,6 +339,19 @@
 }
 
 Element &
+Element::makeBoolean(bool &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    _type = Element::BOOLEAN;
+    _length = 1;
+    _data = new boost::uint8_t[2];
+    memset(_data, 0, 2);
+    _data[1]= data;
+    return *this;
+}
+
+Element &
 Element::makeBoolean(boost::uint8_t *data)
 {
 //    GNASH_REPORT_FUNCTION;
@@ -488,17 +553,19 @@
 //    GNASH_REPORT_FUNCTION;
     
     if (_name.size()) {
-       cerr << "Dumping AMF Varible: " << _name << endl;
+       cerr << "AMF object name: " << _name << endl;
     }
 
     cerr << astype_str[_type] << ": ";
 
     switch (_type) {
+      case Element::NOTYPE:
+         break;
       case Element::NUMBER:
-         cerr << "AMF Numeric value: " << to_number() << endl;
+         cerr << to_number() << endl;
          break;
       case Element::BOOLEAN:
-         cerr << "AMF Boolean value: " << (to_bool() ? "true" : "false") << 
endl;
+         cerr << (to_bool() ? "true" : "false") << endl;
          break;
       case Element::STRING:
          cerr << "(" << _length << " bytes): ";
@@ -528,10 +595,17 @@
          hexify((boost::uint8_t *)hexint, _data, _length, false);
          cerr << "AMF data is: 0x%s" << hexint << endl;
          break;
+      case Element::VARIABLE:
+      case Element::FUNCTION:
+         cerr << "# of children in object: " << _children.size() << endl;
+         for (size_t i=0; i< _children.size(); i++) {
+             _children[i]->dump();
+         }
+         break;
       default:
-         log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)_type);
+//       log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)_type);
+         break;
     }
-    
 }
 
 } // end of amf namespace

Index: libamf/element.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- libamf/element.h    25 Jan 2008 18:08:00 -0000      1.7
+++ libamf/element.h    1 Feb 2008 01:42:41 -0000       1.8
@@ -56,29 +56,38 @@
         RECORD_SET=0x0e,
         XML_OBJECT=0x0f,
         TYPED_OBJECT=0x10,
-       VARIABLE=0x11           // this isn't part of the AMF spec, it's used 
internally
+       // these aren't part of the AMF spec, they're used internally
+       VARIABLE=0x11,
+       FUNCTION=0x12
     } astype_e;
     Element();
     Element(boost::uint8_t *data);
     Element(double data);
+    Element(std::vector<double> &data);
     Element(const std::string &data);
     Element(const std::string &name, const std::string &data);
     Element(bool data);
     Element(const std::string &name, bool data);
+    // Create a function block for AMF
+    Element(bool, double, double, const std::string &str);
     ~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(std::vector<double> &data);
     Element &init(const std::string &name, const std::string &data);
     Element &init(const std::string &data);
     Element &init(const std::string &name, bool data);
     Element &init(bool data);
+    // Create a function block for AMF
+    Element &init(bool, double, double, const std::string &str);
 
     // These create the other "special" AMF types.
     Element &makeString(boost::uint8_t *data, int size); 
     Element &makeNumber(boost::uint8_t *data); 
     Element &makeBoolean(boost::uint8_t *data); 
+    Element &makeBoolean(bool &data); 
     Element &makeUndefined();
     Element &makeUndefined(const std::string &name);
     Element &makeNull();
@@ -126,6 +135,7 @@
     boost::int16_t _length;
     std::string    _name;
     boost::uint8_t *_data;
+    std::vector<Element        *> _children;
 };                              // end of class definition
 
 

Index: libamf/lcshm.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libamf/lcshm.cpp    25 Jan 2008 18:48:29 -0000      1.6
+++ libamf/lcshm.cpp    1 Feb 2008 01:42:41 -0000       1.7
@@ -45,6 +45,9 @@
 namespace gnash {
 
 // The maximum 
+// although a bool is one byte, it appears to be a short in AMF,
+// plus the type byte.
+const int AMF_BOOLEAN_SIZE = 3;
 const int LC_HEADER_SIZE = 16;
 const int MAX_LC_HEADER_SIZE = 40960;
 const int LC_LISTENERS_START  = MAX_LC_HEADER_SIZE +  LC_HEADER_SIZE;
@@ -109,7 +112,7 @@
 
 // see if a connection name exists in our list of listeners
 bool
-Listener::findListener(std::string &name)
+Listener::findListener(const string &name)
 {
 //    GNASH_REPORT_FUNCTION;
 
@@ -127,7 +130,7 @@
 }
 
 bool
-Listener::addListener(std::string &name)
+Listener::addListener(const string &name)
 {
     GNASH_REPORT_FUNCTION;
 
@@ -156,7 +159,7 @@
         return false;
     }
     item += 4;
-    const char *x2 = "::4";
+    const char *x2 = "::2";
     if (!memcpy(item, x2, 4)) {
         return false;
     }
@@ -164,28 +167,36 @@
     return true;
 }
 
+// I don't believe this function is support by other swf players,
+// but we do, as it's nice to remove oneself from the listeners
+// list so nobody knows we were here listening.
 bool
-Listener::removeListener(std::string &name)
+Listener::removeListener(const string &name)
 {
     GNASH_REPORT_FUNCTION;
 
     boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
 
+    int len;
     char *item = reinterpret_cast<char *>(addr);
     while (*item != 0) {
         if (name == item) {
-            int len = strlen(item) + 1;
             while (*item != 0) {
+                len = strlen(item) + 8 + 1;
                 strcpy(item, item + len);
-                item += len + 1;
+                item += len + strlen(item + len);
             }
+            
+            memset(item - len, 0, len);
             return true;
         }
         item += strlen(item) + 1;
     }
+    
     return false;
 }
 
+// Get a list of alll the listeners waiting on this channel
 auto_ptr< vector<string> >
 Listener::listListeners()
 {
@@ -251,7 +262,9 @@
                 continue;
             }
         }
+        if (el->getType() != Element::NOTYPE) {
         addObject(el);
+        }
     };
     
     return _amfobjs;
@@ -291,12 +304,19 @@
     Element *el = new amf::Element;
     AMF amf;
     ptr = amf.extractElement(el, ptr);
+    if (ptr == 0) {
+        log_error("Didn't extract element from byte stream!");
+        return 0;
+    }
+    
     _object.connection_name = el->to_string();
     delete el;
     
     el = new amf::Element;
     ptr = amf.extractElement(el, ptr);
+    if (ptr != 0) {
     _object.hostname = el->to_string();
+    }
     delete el;
     
 //     el = new amf::Element;
@@ -326,10 +346,35 @@
 }
 
 boost::uint8_t *
-LcShm::formatHeader(boost::uint8_t * /*data*/)
+LcShm::formatHeader(const std::string &con, const std::string &host, bool 
domain)
 {
-//    GNASH_REPORT_FUNCTION;
-    return NULL;
+    GNASH_REPORT_FUNCTION;
+//    boost::uint8_t *ptr = data + LC_HEADER_SIZE;
+    int size = con.size() + host.size() + 9;
+    
+    boost::uint8_t *header = new boost::uint8_t[size + 1];
+    boost::uint8_t *ptr = header;
+
+    // This is the initial 16 bytes of the header
+    memset(ptr, 0, size + 1);
+    *ptr = 1;
+    ptr += 3;
+    *ptr = 1;
+    ptr = header + LC_HEADER_SIZE;
+
+    // Which is then always followed by 3 AMF objects.
+    boost::uint8_t *tmp = AMF::encodeElement(con.c_str());
+    memcpy(ptr, tmp, con.size());
+    ptr +=  con.size();
+    delete[] tmp;
+
+    tmp = AMF::encodeElement(host.c_str());
+    memcpy(ptr, tmp, host.size());
+    ptr +=  host.size();
+    
+    delete[] ptr;
+    
+//     return ptr;
 }
 
 /// \brief Prepares the LcShm object to receive commands from a
@@ -339,12 +384,16 @@
 /// send() command to signify which local connection to send the
 /// object to.
 bool
-LcShm::connect(string &name)
+LcShm::connect(const string &name)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     
     _name = name;
     
+    // the name here is optional, Gnash will pick a good default.
+    // When using sysv shared memory segments in compatibility mode,
+    // the name is ignored, and the SHMkey is specified in the user's
+    // ~/.gnashrc file.
     if (Shm::attach(name.c_str(), true) == false) {
         return false;
     }
@@ -355,8 +404,13 @@
     }
     
     Listener::setBaseAddress(reinterpret_cast<uint8_t *>(Shm::getAddr()));
+    _baseaddr = reinterpret_cast<uint8_t *>(Shm::getAddr());
     boost::uint8_t *ptr = parseHeader(Listener::getBaseAddress());
-    vector<amf::Element *> ellist = parseBody(ptr);
+//    vector<amf::Element *> ellist = parseBody(ptr);
+//     log_debug("Base address is: 0x%x, 0x%x",
+//               (unsigned int)Listener::getBaseAddress(), (unsigned 
int)_baseaddr);
+
+    addListener(name);
     
     return true;
 }
@@ -364,7 +418,7 @@
 bool
 LcShm::connect(key_t key)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     
     if (Shm::attach(key, true) == false) {
         return false;
@@ -376,18 +430,92 @@
     }
     
     Listener::setBaseAddress(reinterpret_cast<uint8_t *>(Shm::getAddr()));
+    _baseaddr = reinterpret_cast<uint8_t *>(Shm::getAddr());
     boost::uint8_t *ptr = parseHeader(Listener::getBaseAddress());
-    vector<amf::Element *> ellist = parseBody(ptr);
+//    vector<amf::Element *> ellist = parseBody(ptr);
+//     log_debug("Base address is: 0x%x, 0x%x",
+//               (unsigned int)Listener::getBaseAddress(), (unsigned 
int)_baseaddr);
     
     return true;
 }
 
 /// \brief Invokes a method on a specified LcShm object.
 void
-LcShm::send(const std::string & /*name*/, const std::string & /*dataname*/, 
amf::Element * /*data*/)
+LcShm::send(const string &name, const string &domainname,
+            vector<amf::Element *> &data)
 {
+    GNASH_REPORT_FUNCTION;
+
+//     log_debug("Base address is: 0x%x, 0x%x",
+//               (unsigned int)Listener::getBaseAddress(), (unsigned 
int)_baseaddr);
+
+//    formatHeader(name, domainname, _object.domain);
+
+    // Update the connection name
+    boost::uint8_t *ptr = Listener::getBaseAddress();
+    if (ptr == reinterpret_cast<boost::uint8_t *>(0)) {
+        log_error("base address not set!");
+    }
+
+//    boost::uint8_t *tmp = AMF::encodeElement(name.c_str());
+//     memcpy(ptr, tmp, name.size());
+//     ptr +=  name.size() + AMF_HEADER_SIZE;
+//     delete[] tmp;
+
+//     tmp = AMF::encodeElement(domainname.c_str());
+//     memcpy(ptr, tmp, domainname.size());
+//     ptr +=  domainname.size() + AMF_HEADER_SIZE;
+
+//    ptr += LC_HEADER_SIZE;
+    boost::uint8_t *x = ptr;    // just for debugging from gdb. temporary
+
+    // This is the initial 16 bytes of the header
+    memset(ptr, 0, LC_HEADER_SIZE + 200);
+    *ptr = 1;
+    ptr += 4;
+    *ptr = 1;
+    ptr += LC_HEADER_SIZE - 4;
+
+    // Which is then always followed by 3 AMF objects.
+    
+    boost::uint8_t *tmp = AMF::encodeElement(name.c_str());
+    memcpy(ptr, tmp, name.size() + AMF_HEADER_SIZE);
+    delete[] tmp;
+
+    ptr += name.size() + AMF_HEADER_SIZE;
+
+    // Update the host on the other end of the connection.
+    tmp = AMF::encodeElement(domainname.c_str());
+    memcpy(ptr, tmp, domainname.size() + AMF_HEADER_SIZE );
+    delete[] tmp;
+
+    ptr += domainname.size() + AMF_HEADER_SIZE;
+
+//     // Set the domain flag to whatever it's current value is.
+// //    Element domain(_object.domain);
+//     tmp = AMF::encodeBoolean(_object.domain);
+//     memcpy(ptr, tmp, AMF_BOOLEAN_SIZE);
+// //    delete[] tmp;
+    
+//     ptr += AMF_BOOLEAN_SIZE;
+    
+    vector<boost::uint8_t> *vec = AMF::encodeElement(data);
+    vector<boost::uint8_t>::iterator vit;
+    // Can't do a memcpy with a std::vector
+//    log_debug("Number of bytes in the vector: %x", vec->size());
+    for (vit = vec->begin(); vit != vec->end(); vit++) {
+       *ptr = *vit;
+#if 0                           // debugging crapola
+        if (isalpha(*ptr))
+            printf("%c ", *ptr);
+        else
+            printf("0x%x ", *ptr);
+#endif
+        ptr++;
+    }
+    
+//    delete[] tmp;
     
-    log_unimpl (__FUNCTION__);
 }
 
 void
@@ -402,7 +530,7 @@
     cerr << "Hostname Name:\t\t" << _object.hostname << endl;
     cerr << "Domain Allowed:\t\t" << ((_object.domain) ? "true" : "false") << 
endl;
     vector<amf::Element *>::iterator ait;
-//    cerr << "# of Elements in file: " << _amfobjs.size() << endl;
+    cerr << "# of Elements in file: " << _amfobjs.size() << endl;
     for (ait = _amfobjs.begin(); ait != _amfobjs.end(); ait++) {
        amf::Element *el = (*(ait));
         el->dump();
@@ -410,11 +538,11 @@
 
     vector<string>::const_iterator lit;
     auto_ptr< vector<string> > listeners ( listListeners() );
+    cerr << "# of Listeners in file: " << listeners->size() << endl;
     for (lit=listeners->begin(); lit!=listeners->end(); lit++) {
         string str = *lit;
         if (str[0] != ':') {
             cerr << "Listeners:\t" << str << endl;
-//             total++;
         }
     }
 }

Index: libamf/lcshm.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libamf/lcshm.h      25 Jan 2008 18:48:29 -0000      1.6
+++ libamf/lcshm.h      1 Feb 2008 01:42:41 -0000       1.7
@@ -33,16 +33,16 @@
 namespace gnash {
 
 // Manipulate the list of LocalConnection Listeners. We've made this a separate
-// class from LocalConnection as it's used standalone for the dumpshm utility 
to
-// dump the Listener lists.
+// class from LocalConnection as it's used standalone for the
+// dumpshm utility to dump the Listener lists.
 class Listener {
 public:
     Listener();
     Listener(boost::uint8_t *baseaddr);
     ~Listener();
-    bool addListener(std::string &name);
-    bool findListener(std::string &name);
-    bool removeListener(std::string &name);
+    bool addListener(const std::string &name);
+    bool findListener(const std::string &name);
+    bool removeListener(const std::string &name);
     std::auto_ptr< std::vector<std::string> > listListeners();
     void setBaseAddress(boost::uint8_t *addr) { _baseaddr = addr; };
     boost::uint8_t *getBaseAddress() { return _baseaddr; };
@@ -57,7 +57,8 @@
     typedef struct {
         uint32_t unknown1;
         uint32_t unknown2;
-        uint32_t timestamp; // number of milliseconds that have elapsed since 
the system was started
+        uint32_t timestamp;    // number of milliseconds that have
+                               // elapsed since the system was started
         uint32_t length;
     } lc_header_t;
     typedef struct {
@@ -77,14 +78,17 @@
     LcShm(boost::uint8_t *baseaddr);
     LcShm(key_t key);
     ~LcShm();
-    bool connect(std::string &name);
+    bool connect(const std::string &name);
     bool connect(key_t key);
     void close(void);
-    void send(const std::string &name, const std::string &dataname, 
amf::Element *data);
+    void send(const std::string &name, const std::string &dataname,
+             std::vector<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);
+    boost::uint8_t *formatHeader(const std::string &con, const std::string 
&host, bool domain);
+    void addConnectionName(std::string &name);
+    void addHostname(std::string &name);
     void addObject(amf::Element *el) { _amfobjs.push_back(el); };
     size_t size() { return _amfobjs.size(); };
     std::vector<amf::Element *> getElements() { return _amfobjs; };




reply via email to

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