gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash cygnal/testsuite/cygnal.all/Makefile.am C...


From: Rob Savoye
Subject: [Gnash-commit] gnash cygnal/testsuite/cygnal.all/Makefile.am C...
Date: Tue, 18 Dec 2007 01:55:18 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    07/12/18 01:55:18

Modified files:
        cygnal/testsuite/cygnal.all: Makefile.am 
        .              : ChangeLog 
        libamf         : amf.cpp amf.h sol.cpp sol.h 
        testsuite/libamf.all: test_sol.cpp 

Log message:
                * cygnal/testsuite/cygnal.all/Makefile.am: Add server to include
                paths.
                * libamf/amf.{cpp,h}: Include as_objecth Don't make swapBytes
                static, we want to use it elsewhere. Add methods for creating
                elements, and encoding elements.
                * libamf/sol.cpp: Store elements in a vactor as they get
                added. Format a header for a .sol file. Write a SOL object to 
disk
                as an .sol file.
                * libamf/sol.h: Use boost cstdint.hpp instead of homegrown
                typedefs. Write a SOL object to disk as an .sol file.
                * testsuite/libamf.all/test_sol.cpp: Include as_object.h. Create
                an output file and test all it's elements.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/cygnal/testsuite/cygnal.all/Makefile.am?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5199&r2=1.5200
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.cpp?cvsroot=gnash&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.h?cvsroot=gnash&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/sol.cpp?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/sol.h?cvsroot=gnash&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_sol.cpp?cvsroot=gnash&r1=1.2&r2=1.3

Patches:
Index: cygnal/testsuite/cygnal.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/cygnal/testsuite/cygnal.all/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- cygnal/testsuite/cygnal.all/Makefile.am     12 Dec 2007 23:56:29 -0000      
1.2
+++ cygnal/testsuite/cygnal.all/Makefile.am     18 Dec 2007 01:55:17 -0000      
1.3
@@ -35,6 +35,7 @@
         -I$(top_srcdir)/libamf \
         -I$(top_srcdir)/libbase \
         -I$(top_srcdir)/cygnal \
+        -I$(top_srcdir)/server \
         -DLOCALEDIR=\"$(localedir)\" \
        $(BOOST_CFLAGS) \
        $(PTHREAD_CFLAGS)

Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5199
retrieving revision 1.5200
diff -u -b -r1.5199 -r1.5200
--- ChangeLog   18 Dec 2007 00:09:47 -0000      1.5199
+++ ChangeLog   18 Dec 2007 01:55:17 -0000      1.5200
@@ -1,3 +1,18 @@
+2007-12-17  Rob Savoye  <address@hidden>
+
+       * cygnal/testsuite/cygnal.all/Makefile.am: Add server to include
+       paths.
+       * libamf/amf.{cpp,h}: Include as_objecth Don't make swapBytes
+       static, we want to use it elsewhere. Add methods for creating
+       elements, and encoding elements.
+       * libamf/sol.cpp: Store elements in a vactor as they get
+       added. Format a header for a .sol file. Write a SOL object to disk
+       as an .sol file.
+       * libamf/sol.h: Use boost cstdint.hpp instead of homegrown
+       typedefs. Write a SOL object to disk as an .sol file.
+       * testsuite/libamf.all/test_sol.cpp: Include as_object.h. Create
+       an output file and test all it's elements.
+
 2007-12-17 Sandro Santilli <address@hidden>
 
        * server/parser/action_buffer.cpp: don't be noisy about overriding

Index: libamf/amf.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.cpp,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- libamf/amf.cpp      15 Dec 2007 06:58:40 -0000      1.44
+++ libamf/amf.cpp      18 Dec 2007 01:55:18 -0000      1.45
@@ -32,6 +32,7 @@
 
 #include "log.h"
 #include "amf.h"
+#include "as_object.h"
 #include "amfutf8.h"
 #include <boost/cstdint.hpp> // for boost::?int??_t
 
@@ -112,7 +113,7 @@
 /// anything if we happen to be on a big-endian machine.
 ///
 /// Returns its first parameter, pointing to the (maybe-byte-swapped) data.
-static void *
+void *
 swapBytes(void *word, int size)
 {
     union {
@@ -757,11 +758,217 @@
     return num;
 }
 
+AMF::amf_element_t *
+AMF::createElement(amf_element_t *el, astype_e type,
+                 std::string &name, uint8_t *data, int nbytes)
+{
+    GNASH_REPORT_FUNCTION;
+    log_debug("Creating element %s", name.c_str());
+    
+    el->type = type;
+    el->name = name;
+    el->length = nbytes;
+    el->data = data;
+    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, std::string &name, amfnum_t 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 uint8_t[AMF_NUMBER_SIZE + 1];
+    memset(el->data, 0, AMF_NUMBER_SIZE + 1);
+    memcpy(el->data, &data, AMF_NUMBER_SIZE);
+
+    return el;
+}
+
+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, 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 uint8_t[AMF_NUMBER_SIZE + 1];
+    memset(el->data, 0, AMF_NUMBER_SIZE + 1);
+    memcpy(el->data, &data, AMF_NUMBER_SIZE);
+
+    return el;
+}
+
+AMF::amf_element_t *
+AMF::createElement(amf_element_t *el, const char *name, const char *data)
+{
+    GNASH_REPORT_FUNCTION;
+    log_debug("Creating element %s", name);
+
+    el->type = AMF::STRING;
+    el->name = name;
+    el->length = strlen(data);
+    char *str = const_cast<char *>(data);
+    el->data = reinterpret_cast<uint8_t *>(str);
+    return el;
+}
+
+AMF::amf_element_t *
+AMF::createElement(amf_element_t *el, std::string &name, std::string &data)
+{
+    GNASH_REPORT_FUNCTION;
+    log_debug("Creating element %s", name.c_str());
+
+    el->type = AMF::STRING;
+    el->name = name;
+    el->length = data.size();
+    char *str = const_cast<char *>(data.c_str());
+    el->data = reinterpret_cast<uint8_t *>(str);
+    return el;
+}
+
+AMF::amf_element_t *
+AMF::createElement(amf_element_t *el, const char *name, bool data)
+{
+    GNASH_REPORT_FUNCTION;
+    string str = name;
+    return createElement(el, str, data);
+}
+
+AMF::amf_element_t *
+AMF::createElement(AMF::amf_element_t *el, std::string &name, bool data)
+{
+    GNASH_REPORT_FUNCTION;
+    log_debug("Creating element %s", name.c_str());
+
+    el->type = AMF::BOOLEAN;
+    el->name = name;
+    el->length = 1;
+    el->data = new uint8_t[sizeof(uint16_t)];
+    memset(el->data, 0, sizeof(uint16_t));
+    *el->data = data;
+    return el;
+}
+
+
+AMF::amf_element_t *
+createElement(AMF::amf_element_t *el, std::string &name,
+             boost::intrusive_ptr<gnash::as_object> &data)
+{
+    GNASH_REPORT_FUNCTION;
+    log_debug("Creating element %s", name.c_str());
+
+    el->type = AMF::OBJECT;
+    el->name = name;
+    el->length = sizeof(data);
+    el->data = new uint8_t[sizeof(uint16_t)];
+    memset(el->data, 0, sizeof(uint16_t));
+    memcpy(el->data, (char *)&data, el->length);
+    return el;
+}
+
+AMF::amf_element_t *
+createElement(AMF::amf_element_t *el, const char *name,
+             boost::intrusive_ptr<gnash::as_object> &data)
+{
+    GNASH_REPORT_FUNCTION;
+    string str = name;
+    return createElement(el, str, data);
+}
+
+uint8_t *
+AMF::encodeVariable(amf_element_t *el)
+{
+    GNASH_REPORT_FUNCTION;
+    int outsize = el->name.size() + el->length + 5;
+    uint8_t *out = new uint8_t[outsize];
+    memset(out, 0, outsize);
+    uint8_t *tmpptr = out;
+
+    // Add the length of the string for the name of the variable
+    size_t length = el->name.size();
+    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);
+    tmpptr += length;
+    // Add the type of the variable's data
+    *tmpptr++ = el->type;
+    // 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];
+         memcpy(tmpptr, &enclength, 2);
+         tmpptr += sizeof(uint16_t);
+         break;
+      case AMF::NUMBER:
+         swapBytes(el->data, AMF_NUMBER_SIZE);
+         memcpy(tmpptr, el->data, AMF_NUMBER_SIZE);
+         break;
+      default:
+       enclength = el->length;
+       swapBytes(&enclength, 2);
+       memcpy(tmpptr, &enclength, 2);
+       tmpptr += sizeof(uint16_t);
+       // Now the data for the variable
+       memcpy(tmpptr, el->data, el->length);
+    }
+    
+    return out;    
+}
+
 uint8_t *
-AMF::encodeVariable(amf_element_t & /* el */)
+AMF::encodeVariable(amf_element_t &el)
 {
     GNASH_REPORT_FUNCTION;
-    return NULL;
+    int outsize = el.name.size() + el.length + 5;
+    uint8_t *out = new uint8_t[outsize];
+    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;    
 }
 
 uint8_t *
@@ -1177,21 +1384,26 @@
           uint8_t* tmp = new uint8_t[AMF_NUMBER_SIZE+1];
           memset(tmp, 0, AMF_NUMBER_SIZE+1);
           memcpy(tmp, buffer, AMF_NUMBER_SIZE);
+         swapBytes(tmp, AMF_NUMBER_SIZE);
           el->data = tmp;
+#if 1
           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);
+#endif
           tmpptr += 8;
+         el->length = AMF_NUMBER_SIZE;
           break;
         }
       case BOOLEAN:
         {
 //          int value = *tmpptr;
-          uint8_t* tmp = new uint8_t[1];
-          memcpy(tmp, tmpptr, 1); 
-          el->data = tmp;
+         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());
@@ -1199,7 +1411,6 @@
          break;
         }
       case STRING:
-      {
          // extractString returns a printable char *
          length = ntohs((*(const short *)tmpptr) & 0xffff);
           tmpptr += sizeof(short);
@@ -1209,7 +1420,6 @@
 //           log_msg(_("Variable \"%s\" is: %s"), el->name.c_str(), 
v.c_str()); // el->data);
           tmpptr += length;
           break;
-      }
       case OBJECT:
          while (*(tmpptr++) != AMF::OBJECT_END) {
              log_msg("Look for end of object...");
@@ -1221,14 +1431,12 @@
          // 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;
           break;
-      }
       case REFERENCE:
       case ECMA_ARRAY:
                        // FIXME this shouldn't fall thru

Index: libamf/amf.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- libamf/amf.h        15 Dec 2007 06:58:40 -0000      1.23
+++ libamf/amf.h        18 Dec 2007 01:55:18 -0000      1.24
@@ -27,6 +27,8 @@
 #include <cstring>
 #include <map>
 
+#include "as_object.h"
+
 #include "amfutf8.h"
 #include <boost/cstdint.hpp>
 
@@ -34,10 +36,10 @@
 {
 
 # if __WORDSIZE == 64
-typedef long amfnum_t;
+typedef unsigned long amfnum_t;
 #define AMFNUM_F "%ld"
 #else
-typedef long long amfnum_t;
+typedef unsigned long long amfnum_t;
 #define AMFNUM_F "%lld"
 #endif
 // TIDO FIXME: this will be longer then the actual amfnum_t 
@@ -172,7 +174,7 @@
 
     struct amf_element_t {
         astype_e       type;
-        short          length;
+        int16_t        length;
         std::string    name;
         uint8_t        *data;
 
@@ -223,6 +225,32 @@
     };
 
     /// 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,
+                                std::string &name, uint8_t *data, int nbytes);
+    amf_element_t *createElement(amf_element_t *el, 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, 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, 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, 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, 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);
     //
     /// @return a newly allocated byte array,
     /// to be deleted by caller using delete [] operator, or NULL
@@ -235,6 +263,7 @@
     /// to be deleted by caller using delete [] operator, or NULL
     ///
     uint8_t* encodeVariable(amf_element_t &el);
+    uint8_t* encodeVariable(amf_element_t *el);
 
     /// Encode a boolean variable. This is a name followed by a boolean value.
     //
@@ -326,6 +355,9 @@
 };
 
  
+void *swapBytes(void *word, int size);
+
+
 } // end of amf namespace
 
 // end of _AMF_H_

Index: libamf/sol.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/sol.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libamf/sol.cpp      15 Dec 2007 16:05:55 -0000      1.1
+++ libamf/sol.cpp      18 Dec 2007 01:55:18 -0000      1.2
@@ -54,12 +54,13 @@
 // Padding      - 4 bytes
 // After this is a series of AMF objects
 const short SOL_MAGIC = 0xbf00;
-const char *SOL_FILETYPE = "TCSO";
+//char *SOL_FILETYPE = "TCSO";
 const short SOL_BLOCK_MARK = 0x0004;
 
 namespace amf
 {
 SOL::SOL()
+    : _filesize(0)
 {
     GNASH_REPORT_FUNCTION;
 }
@@ -80,24 +81,193 @@
 {
 }
 
+void
+SOL::addObj(AMF::amf_element_t &el)
+{
+    GNASH_REPORT_FUNCTION;
+    _amfobjs.push_back(el);
+    _filesize += el.name.size() + el.length + 5;
+}
+
 bool
 SOL::formatHeader(vector<unsigned char> &data)
 {
     GNASH_REPORT_FUNCTION;
 }
 
+// name is the object name
 bool
 SOL::formatHeader(std::string &name)
 {
+    return formatHeader(name, _filesize);
+}
+
+bool
+SOL::formatHeader(std::string &name, int filesize)
+{
     GNASH_REPORT_FUNCTION;
+    uint32_t i;
+
+    // First we add the magic number. All SOL data is in big-endian format,
+    // so we swap it first.
+    uint16_t swapped = SOL_MAGIC;
+//    swapped = htons(swapped);
+    uint8_t *ptr = reinterpret_cast<uint8_t *>(&swapped);
+    for (i=0; i<sizeof(uint16_t); i++) {
+        _header.push_back(ptr[i]);
+    }
+
+    // Next is the file size to be created. We adjust it as the filesize
+    // includes the padding in the header, the mystery bytes, and the
+    // padding, plus the length of the name itself.
+    filesize += name.size() + 16;
+    uint32_t len = filesize;
+    len = htonl(len);
+    ptr = reinterpret_cast<uint8_t *>(&len);
+    for (i=0; i<sizeof(uint32_t); i++) {
+        _header.push_back(ptr[i]);
+    }
+
+    // Then the mystery block, but as the value never seems to every change,
+    // we just built it the same way it always is.
+    // first is the TCSO, we have no idea what this stands for.
+//    ptr = reinterpret_cast<uint8_t *>(const_cast<uint8_t *>("TCSO");
+    ptr = (uint8_t *)"TCSO";
+    for (i=0; i<sizeof(uint32_t); i++) {
+        _header.push_back(ptr[i]);
+    }
+    // then the 0x0004 bytes, also a mystery
+    swapped = SOL_BLOCK_MARK;
+    swapped = htons(swapped);
+    ptr = reinterpret_cast<uint8_t *>(&swapped);
+    for (i=0; i<sizeof(uint16_t); i++) {
+        _header.push_back(ptr[i]);
+    }
+    // finally a bunch of zeros to pad things for this field
+    for (i=0; i<sizeof(uint32_t); i++) {
+        _header.push_back('\0');
+    }
+
+    // Encode the name. This is not a string object, which has a type field
+    // one byte field precedding the length as a file type of AMF::STRING.
+    //  First the length in two bytes
+    swapped = name.size();
+    swapped = htons(swapped);
+    ptr = reinterpret_cast<uint8_t *>(&swapped);
+    for (i=0; i<sizeof(uint16_t); i++) {
+        _header.push_back(ptr[i]);
+    }
+    // then the string itself
+    ptr = (uint8_t *)name.c_str();
+    for (i=0; i<name.size(); i++) {
+        _header.push_back(ptr[i]);
+    }
+    
+    // finally a bunch of zeros to pad things at the end of the header
+    for (i=0; i<sizeof(uint32_t); i++) {
+        _header.push_back('\0');
+    }
+
+#if 0
+    unsigned char *hexint;
+    hexint = new unsigned char[(_header.size() + 3) *3];
+    
+    hexify(hexint, (unsigned char *)_header, _header.size(), true);
+    log_msg (_("%s: SOL file header is: \n%s"), __FUNCTION__, (char *)hexint);
+    delete hexint;
+#endif    
+    
 }    
 
 // write the data to disk as a .sol file
+
 bool
-SOL::writeFile(std::string &filespec)
+SOL::writeFile(string &filespec, const char *name)
 {
     GNASH_REPORT_FUNCTION;
-    ofstream ofs("filename", ios::binary);
+    string str = name;
+    return writeFile(filespec, str);
+}
+
+bool
+SOL::writeFile(const char *filespec, const char *name)
+{
+    GNASH_REPORT_FUNCTION;
+    string str1 = filespec;
+    string str2 = name;
+    return writeFile(str1, str2);
+}
+
+bool
+SOL::writeFile(string &filespec, string &name)
+{
+    GNASH_REPORT_FUNCTION;
+    ofstream ofs("test.sol", ios::binary);
+    vector<uint8_t>::iterator it;
+    vector<AMF::amf_element_t>::iterator ita; 
+    AMF amf_obj;
+    char *ptr;
+    
+    char *body = new char[_filesize]; // FIXME: bogus size!
+    memset(body, 0, _filesize);
+    ptr = body;
+    
+    for (ita = _amfobjs.begin(); ita != _amfobjs.end(); ita++) {
+        AMF::amf_element_t *el = &(*(ita));
+        int outsize = el->name.size() + el->length + 5;
+        uint8_t *foo = amf_obj.encodeVariable(el); 
+        switch (el->type) {
+         case AMF::BOOLEAN:
+//           *ptr++ = el->data[0];
+             outsize = el->name.size() + 5;
+             memcpy(ptr, foo, outsize);
+             ptr += outsize;
+             break;
+         case AMF::OBJECT:
+             outsize = el->name.size() + 5;
+             memcpy(ptr, foo, outsize);
+             ptr += outsize;
+             *ptr++ = AMF::OBJECT_END;
+             *ptr++ = 0;       // objects are terminated too!
+             break;
+         case AMF::NUMBER:
+             outsize = el->name.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) {
+                 memcpy(ptr, foo, outsize+1);
+                 ptr += outsize+1;
+             } else {          // null terminate the string
+                 memcpy(ptr, foo, outsize);
+                 ptr += outsize;
+                 *ptr++ = 0;
+             }
+             break;
+         default:
+             memcpy(ptr, foo, outsize);
+             ptr += outsize;
+       }
+       delete foo;
+    }
+
+    _filesize = ptr - body;
+    int len = name.size() + sizeof(uint16_t) + 16;
+    char *head = new char[len + 4];
+    memset(head, 0, len);
+    ptr = head;
+    formatHeader(name);
+    for (it = _header.begin(); it != _header.end(); it++) {
+        *ptr++ = (*(it));
+    }
+    
+    ofs.write(head, _header.size());
+//    ofs.write(body, (ptr - body));
+    ofs.write(body, _filesize);
+    ofs.close();
 }
 
 // read the .sol file from disk
@@ -131,9 +301,15 @@
 //        char *marker = ptr;
         ptr += 10;
         
-        if ((memcmp(buf, &SOL_MAGIC, 2) == 0) && (_filesize - 6 == length)) {
+        if (memcmp(buf, &SOL_MAGIC, 2) == 0) {
+            if (_filesize - 6 == length) {
             log_debug("%s is an SOL file", filespec.c_str());
         } else {
+                log_error("%s looks like an SOL file, but the length is wrong",
+                          filespec.c_str());
+            }
+            
+        } else {
             log_error("%s isn't an SOL file", filespec.c_str());
         }
 
@@ -187,6 +363,9 @@
         }
         if (el->type == AMF::NUMBER) {
             double *dd = (double *)el->data;
+            double ddd = *((double *)el->data);
+           swapBytes(&ddd, 8);
+            cerr << ddd << " ";
             cerr << *dd << "    ";
             hexint = new uint8_t[(sizeof(double) *3) + 3];
             hexify(hexint, el->data, 8, false);

Index: libamf/sol.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/sol.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- libamf/sol.h        15 Dec 2007 16:05:55 -0000      1.1
+++ libamf/sol.h        18 Dec 2007 01:55:18 -0000      1.2
@@ -22,6 +22,7 @@
 #include "config.h"
 #endif
 
+#include <boost/cstdint.hpp>
 #include <string>
 #include <vector>
 #include "amf.h"
@@ -46,27 +47,34 @@
     size_t size() { return _amfobjs.size(); };
 
     // extract the header
-    bool extractHeader(std::vector<unsigned char> &data);
+    bool extractHeader(std::vector<uint8_t> &data);
     bool extractHeader(std::string &filespec);
 
     // Create the header
-    bool formatHeader(std::vector<unsigned char> &data);
+    bool formatHeader(std::vector<uint8_t> &data);
     bool formatHeader(std::string &name);
+    bool formatHeader(std::string &name, int filesize);
 
     // write the data to disk as a .sol file
-    bool writeFile(std::string &filespec);
+    bool writeFile(std::string &filespec, std::string &objname);
+    bool writeFile(std::string &filespec, const char *objname);
+    bool writeFile(const char *filespec, const char *objname);
     
     // read the .sol file from disk
     bool readFile(std::string &filespec);
 
+    
+    std::vector<uint8_t> getHeader() { return _header; };
+
     // Add the AMF objects that are the data of the file
-    void addObj(AMF::amf_element_t &x) { _amfobjs.push_back(x); };
+    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 dump();
  private:
-    std::vector<unsigned char> _data;
+    std::vector<uint8_t> _header;
+    std::vector<uint8_t> _data;
     std::string      _objname;
     std::string      _filespec;
     std::vector<AMF::amf_element_t> _amfobjs;

Index: testsuite/libamf.all/test_sol.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/test_sol.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- testsuite/libamf.all/test_sol.cpp   15 Dec 2007 17:13:58 -0000      1.2
+++ testsuite/libamf.all/test_sol.cpp   18 Dec 2007 01:55:18 -0000      1.3
@@ -26,6 +26,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#include "as_object.h"
+
 extern "C"{
 #include <unistd.h>
 #ifdef HAVE_GETOPT_H
@@ -55,9 +57,9 @@
 
 static TestState runtest;
 
-bool test_read();
-bool test_write();
-bool test_sol();
+bool test_read(std::string &filespec);
+bool test_write(std::string &filespec);
+bool test_sol(std::string &filespec);
 
 LogFile& dbglogfile = LogFile::getDefaultInstance();
 
@@ -82,30 +84,34 @@
         }
     }
 
-    test_read();
-    test_write();
+    // Read a premade .sol file
+    string filespec = SRCDIR;
+    filespec += "/settings.sol";    
+    test_read(filespec);
+
+    // Write a .sol file
+    filespec = "test.sol";
+    test_write(filespec);
+//    test_read(filespec);
+    
 //    test_sol();
 }
 
 bool
-test_read()
+test_read(std::string &filespec)
 {
     struct stat st;
 
-    string filespec = SRCDIR;
-    filespec += "/settings.sol";
-    
     if (stat(filespec.c_str(), &st) == 0) {
         SOL sol;
-        int fd, ret;
         char *buf;
-        amfnum_t *num;
         
         buf = new char[st.st_size + 1];
 
         sol.readFile(filespec);
         vector<AMF::amf_element_t> els = sol.getElements();
 
+        if (els.size() > 1) {
         string str = reinterpret_cast<const char *>(els[2].data);
 
         // Make sure multiple elements of varying datatypes are checked for.
@@ -118,27 +124,211 @@
         } else {
             runtest.fail("Read SOL file");
         }
-//        sol.dump();
+        } else {
+            runtest.fail("Read SOL file");
+        }
+        sol.dump();
     }
 }
 
 bool
-test_write()
+test_write(std::string &filespec)
 {
+    SOL sol;
+    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;
+
+    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)) {
+        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)) {
+        runtest.pass("gain number encoded/extracted");
+    } else {
+        runtest.fail("gain number encoded/extracted");
+    }
+    
+    
+    amf_obj.createElement(&el, "echosuppression", false);
+    sol.addObj(el);
+    if ((el.name == "echosuppression") &&
+        (el.type == AMF::BOOLEAN) &&
+        (*el.data == 0) &&
+        (el.length == 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");
+    }
+    
+
+    string name = "defaultmicrophone";
+    string data = "/dev/input/mic";
+    amf_obj.createElement(&el, name, 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())) {
+        runtest.pass("defaultmicrophone set");
+    } else {
+        runtest.fail("defaultmicrophone set");
+    }
+
+    amf_obj.createElement(&el, "defaultcamera", "");
+    sol.addObj(el);
+    if ((el.name == "defaultcamera") &&
+        (el.type == AMF::STRING) &&
+        (*el.data == 0) &&
+        (el.length == 0)) {
+        runtest.pass("defaultcamera set");
+    } else {
+        runtest.fail("defaultcamea set");
+    }
+
+    dub = 100.0;
+    amf_obj.createElement(&el, "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)) {
+        runtest.pass("defaultklimit set");
+    } else {
+        runtest.fail("defaultklimit set");
+    }
+
+    amf_obj.createElement(&el, "defaultalways", false);
+    sol.addObj(el);
+    if ((el.name == "defaultalways") &&
+        (el.type == AMF::BOOLEAN) &&
+        (*el.data == 0) &&
+        (el.length == 1)) {
+        runtest.pass("defaultalways set");
+    } else {
+        runtest.fail("defaultalways set");
+    }
+
+    amf_obj.createElement(&el, "crossdomainAllow", true);
+    sol.addObj(el);
+    if ((el.name == "crossdomainAllow") &&
+        (el.type == AMF::BOOLEAN) &&
+        (*el.data == 1) &&
+        (el.length == 1)) {
+        runtest.pass("crossdomainAllow set");
+    } else {
+        runtest.fail("crossdomainAllow set");
+    }
+
+    amf_obj.createElement(&el, "crossdomainAlways", true);
+    sol.addObj(el);
+    if ((el.name == "crossdomainAlways") &&
+        (el.type == AMF::BOOLEAN) &&
+        (*el.data == 1) &&
+        (el.length == 1)) {
+        runtest.pass("crossdomainAlways set");
+    } else {
+        runtest.fail("crossdomainAlways set");
+    }
     
+    amf_obj.createElement(&el, "allowThirdPartyLSOAccess", true);
+    sol.addObj(el);
+    if ((el.name == "allowThirdPartyLSOAccess") &&
+        (el.type == AMF::BOOLEAN) &&
+        (*el.data == 1) &&
+        (el.length == 1)) {
+        runtest.pass("allowThirdPartyLSOAccess set");
+    } else {
+        runtest.fail("allowThirdPartyLSOAccess set");
+    }
+
+    // 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");
+    } else {
+        runtest.fail("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;
+    }
+    sol.addObj(el);
+
+    amf_obj.createElement(&el, "localSecPath", "");
+    sol.addObj(el);
+    if ((el.name == "localSecPath") &&
+        (el.type == AMF::STRING) &&
+        (*el.data == 0) &&
+        (el.length == 0)) {
+        runtest.pass("localSecPath set");
+    } else {
+        runtest.fail("localSecPath set");
+    }
+
+    // Grabbed from GDB when reading this huge value
+    dub = 1.8379389592608646e-304;
+    swapBytes(&dub, 8);
+    
+    amf_obj.createElement(&el, "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)) {
+        runtest.pass("localSecPathTime set");
+    } else {
+        runtest.fail("localSecPathTime set");
+    }
+
+    sol.dump();
+    // now write the data to disk
+    sol.writeFile(filespec, "settings");
 }
 
 // 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.
 bool
-test_sol()
+test_sol(std::string &filespec)
 {
     struct stat st;
 
-    string filespec = SRCDIR;
-    filespec += "/settings.sol";
-    
     if (stat(filespec.c_str(), &st) == 0) {
         AMF amf_obj;
         int fd, ret;




reply via email to

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