gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10653: add test for borken floating


From: rob
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10653: add test for borken floating point when compiling optimized.
Date: Wed, 04 Mar 2009 10:31:11 -0700
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10653
committer: address@hidden
branch nick: trunk
timestamp: Wed 2009-03-04 10:31:11 -0700
message:
  add test for borken floating point when compiling optimized.
  add -ffloat-store is floating point is broken when optimized.
  merge from branch.
added:
  libamf/amf_msg.cpp
  libamf/amf_msg.h
  testsuite/libamf.all/test_amfmsg.cpp
modified:
  configure.ac
  libamf/Makefile.am
  libcore/asobj/Makefile.am
  testsuite/libamf.all/Makefile.am
    ------------------------------------------------------------
    revno: 10646.1.1
    committer: address@hidden
    branch nick: flv
    timestamp: Mon 2009-03-02 20:42:10 -0700
    message:
      new code and test case for AMF remoting calls.
    added:
      libamf/amf_msg.cpp
      libamf/amf_msg.h
      testsuite/libamf.all/test_amfmsg.cpp
    ------------------------------------------------------------
    revno: 10646.1.2
    committer: address@hidden
    branch nick: flv
    timestamp: Mon 2009-03-02 20:42:32 -0700
    message:
      add new files.
    modified:
      libamf/Makefile.am
      testsuite/libamf.all/Makefile.am
    ------------------------------------------------------------
    revno: 10646.1.3
    committer: address@hidden
    branch nick: flv
    timestamp: Tue 2009-03-03 15:20:40 -0700
    message:
      add support for encoding packets, messages, and all the appropriate 
headers.
      add test cases to test packet encoding.
    modified:
      libamf/amf_msg.cpp
      libamf/amf_msg.h
      testsuite/libamf.all/test_amfmsg.cpp
    ------------------------------------------------------------
    revno: 10648.2.1
    committer: address@hidden
    branch nick: trunk
    timestamp: Tue 2009-03-03 16:39:05 -0700
    message:
      add support for AMF remoting call,  packet header and messages.
    added:
      libamf/amf_msg.cpp
      libamf/amf_msg.h
      testsuite/libamf.all/test_amfmsg.cpp
    modified:
      libamf/Makefile.am
      testsuite/libamf.all/Makefile.am
    ------------------------------------------------------------
    revno: 10650.1.1
    committer: address@hidden
    branch nick: trunk
    timestamp: Tue 2009-03-03 16:49:57 -0700
    message:
      add support for AMF remoting call,  packet header and messages.
    added:
      libamf/amf_msg.cpp
      libamf/amf_msg.h
      testsuite/libamf.all/test_amfmsg.cpp
    modified:
      libamf/Makefile.am
      testsuite/libamf.all/Makefile.am
=== modified file 'configure.ac'
--- a/configure.ac      2009-03-04 09:35:50 +0000
+++ b/configure.ac      2009-03-04 17:31:11 +0000
@@ -1346,6 +1346,35 @@
   AC_DEFINE(HAVE_STRINGCASECMP, [1], [Has strcasecmp])
 )
 
+dnl if test x$cross_compiling = xno; then
+AC_LANG_PUSH(C++)
+AC_MSG_CHECKING([to see if float formatting is broken])
+AC_RUN_IFELSE([
+  AC_LANG_PROGRAM([#include <cmath>], [
+     double d = 3.0935415006117e+23;
+     double s;
+     d /= 1000.0;
+     s = std::fmod(d, 86400.0);
+//        testFloat(d, s);
+     if (static_cast<int>(s) != 61440) {
+         return 1;
+      }
+    ],                         dnl end of LANG_PROGRAM
+     broken_float=yes,          dnl true
+      broken_float=no,          dnl false
+      broken_float=no           dnl cross compiling
+)])
+AC_LANG_POP(C++)
+dnl fi
+
+if test x${broken_float} = xyes; then
+  AC_MSG_RESULT([yes])
+  AC_DEFINE(HAVE_BROKEN_FLOAT, [1], [Has broken float support])
+else
+  AC_MSG_RESULT([no])
+fi
+AM_CONDITIONAL(BROKEN_FLOAT, [ test x$broken_float = xyes ])
+
 dnl See if ipc_perm structure has the ipc_perm.key field, and if so,
 dnl which variant of the name is used.
 ipc_key=no

=== modified file 'libamf/Makefile.am'
--- a/libamf/Makefile.am        2009-02-27 06:46:40 +0000
+++ b/libamf/Makefile.am        2009-03-03 03:42:32 +0000
@@ -21,6 +21,7 @@
 pkglib_LTLIBRARIES = libgnashamf.la
 libgnashamf_la_SOURCES = \
        amf.cpp \
+       amf_msg.cpp \
        buffer.cpp \
        element.cpp \
        lcshm.cpp \
@@ -51,6 +52,7 @@
 noinst_HEADERS = \
        amfutf8.h \
        amf.h \
+       amf_msg.h \
        buffer.h \
        element.h \
        flv.h \

=== added file 'libamf/amf_msg.cpp'
--- a/libamf/amf_msg.cpp        1970-01-01 00:00:00 +0000
+++ b/libamf/amf_msg.cpp        2009-03-03 22:20:40 +0000
@@ -0,0 +1,323 @@
+// amf.cpp:  AMF (Action Message Format) rpc marshalling, for Gnash.
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 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
+//
+
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+#include "log.h"
+#include "GnashException.h"
+#include "buffer.h"
+#include "amf.h"
+#include "amf_msg.h"
+#include "element.h"
+#include "network.h"
+#include <boost/cstdint.hpp> // for boost::?int??_t
+
+using namespace std;
+using namespace gnash;
+
+namespace amf 
+{
+
+boost::shared_ptr<amf::Buffer> 
+AMF_msg::encodeContextHeader(boost::uint16_t version, boost::uint16_t headers,
+                            boost::uint16_t messages)
+{
+//    GNASH_REPORT_FUNCTION;
+    size_t size = sizeof(AMF_msg::context_header_t);
+    boost::shared_ptr<amf::Buffer> buf (new amf::Buffer(size));
+
+    *buf = htons(version);
+    *buf += htons(headers);
+    *buf += htons(messages);
+        
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+AMF_msg::encodeContextHeader(AMF_msg::context_header_t *head)
+{
+//    GNASH_REPORT_FUNCTION;
+    return encodeContextHeader(head->version, head->headers, head->messages);
+}
+
+//  example message header::
+//  00 06 67 65 74 77 61 79                <- getway, message #1
+//  00 04 2f 32 32 39                      <- /229, operation name
+//  00 00 00 0e                                   <- byte length of message
+boost::shared_ptr<amf::Buffer>
+AMF_msg::encodeMsgHeader(AMF_msg::message_header_t *head)
+{
+//    GNASH_REPORT_FUNCTION;
+    // The size of the buffer are the two strings, their lenght fields, and 
the integer.
+    size_t size = head->target.size() + head->response.size() + 
sizeof(boost::uint32_t)
+        + (sizeof(boost::uint16_t) * 2);
+    boost::shared_ptr<amf::Buffer> buf (new 
amf::Buffer(sizeof(AMF_msg::message_header_t)));
+
+    // Encode the target URI, which usually looks something like ."getway"
+    boost::uint16_t length = head->target.size();    
+    *buf = length;
+    *buf += head->target;
+
+    // Encode the response URI, which usually looks something like "/229"
+    length = head->response.size();
+    *buf += length;
+    *buf += head->target;
+
+    // Encode the size of the encoded message
+    *buf += static_cast<boost::uint32_t>(head->size);
+    
+    return buf;
+}
+
+// These methods parse the raw data of the AMF packet
+boost::shared_ptr<AMF_msg::context_header_t>
+AMF_msg::parseContextHeader(amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return parseContextHeader(data.reference(), data.size());
+}
+
+boost::shared_ptr<AMF_msg::context_header_t>
+AMF_msg::parseContextHeader(boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<AMF_msg::context_header_t> msg (new 
AMF_msg::context_header_t);
+
+    boost::uint16_t tmpnum = *reinterpret_cast<boost::uint16_t *>(data);
+    msg->version  = tmpnum;
+    tmpnum = *reinterpret_cast<boost::uint16_t *>(data + 
sizeof(boost::uint16_t));
+    msg->headers   = ntohs(tmpnum);
+    tmpnum = *reinterpret_cast<boost::uint16_t *>(data + 
sizeof(boost::uint32_t));
+    msg->messages = ntohs(tmpnum);
+
+    return msg;
+}
+
+boost::shared_ptr<AMF_msg::message_header_t>
+AMF_msg::parseMessageHeader(amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return parseMessageHeader(data.reference(), data.size());
+}
+
+boost::shared_ptr<AMF_msg::message_header_t>
+AMF_msg::parseMessageHeader(boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+    AMF amf;
+    boost::uint8_t *tmpptr = data;
+    boost::shared_ptr<AMF_msg::message_header_t> msg (new 
AMF_msg::message_header_t);
+
+    // The target is a standard length->bytes field
+    boost::uint16_t length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    if (length == 0) {
+        boost::format msg("Length of string shouldn't be zero! 
amf_msg.cpp::%1%(): %2%");
+        msg % __FUNCTION__ % __LINE__;
+        throw GnashException(msg.str());
+    }
+    tmpptr += sizeof(boost::uint16_t);
+    string str1(reinterpret_cast<const char *>(tmpptr), length);
+    msg->target = str1;
+    if ((tmpptr - data) > size) {
+        boost::format msg("Trying to read past the end of data! Wants %1% 
bytes, given %2% bytes");
+        msg % length % size;
+        throw GnashException(msg.str());
+    } else {
+        tmpptr += length;
+    }
+    
+    // The response is a standard length->bytes field
+    length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+    if (length == 0) {
+        boost::format msg("Length of string shouldn't be zero! 
amf_msg.cpp::%1%(): %2%");
+        msg % __FUNCTION__ % __LINE__;
+        throw GnashException(msg.str());
+    }
+    tmpptr += sizeof(boost::uint16_t);
+    string str2(reinterpret_cast<const char *>(tmpptr), length);
+    msg->response = str2;
+    tmpptr += length;
+    if ((tmpptr - data) > size) {
+        boost::format msg("Trying to read past the end of data! Wants %1% 
bytes, given %2% bytes");
+        msg % length % size;
+        throw GnashException(msg.str());
+    }    
+
+    // The length is a 4 word integer
+    msg->size = ntohl((*(boost::uint32_t *)tmpptr));
+
+    if (msg->target.empty()) {
+        log_error("AMF Message \'target\' field missing!");
+    }
+    if (msg->response.empty()) {
+        log_error("AMF Message \'reply\' field missing!");
+    }
+    if (msg->size == 0) {
+        log_error("AMF Message \'size\' field missing!");
+    } else {
+        msg->size = size;
+    }
+
+//    AMF_msg::dump(*msg);
+    return msg;
+}
+
+boost::shared_ptr<AMF_msg::context_header_t>
+AMF_msg::parseAMFPacket(amf::Buffer &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    return parseAMFPacket(data.reference(), data.size());
+}
+
+boost::shared_ptr<AMF_msg::context_header_t>
+AMF_msg::parseAMFPacket(boost::uint8_t *data, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+//    _messages.push_back();
+    boost::uint8_t *ptr = data + sizeof(AMF_msg::context_header_t);
+    boost::shared_ptr<context_header_t> header = 
AMF_msg::parseContextHeader(data, size);
+    
+    AMF amf;
+    /// Read all the messages from the AMF packet
+    try {
+        for (int i=0; i<header->messages; i++) {
+            boost::shared_ptr<AMF_msg::amf_message_t> msgpkt(new 
AMF_msg::amf_message_t);
+            boost::shared_ptr<AMF_msg::message_header_t> msghead = 
AMF_msg::parseMessageHeader(ptr, size);
+            if (msghead) {
+                ptr += msghead->target.size() + msghead->response.size()
+                    + (sizeof(boost::uint16_t) * 2)
+                    + (sizeof(boost::uint32_t));
+                boost::shared_ptr<amf::Element> el = amf.extractAMF(ptr, 
ptr+size);
+                msgpkt->header.target = msghead->target;
+                msgpkt->header.response = msghead->response;
+                msgpkt->header.size = msghead->size;
+                msgpkt->data = el;
+                ptr += amf.totalsize();
+                
+                _messages.push_back(msgpkt);
+            }
+        }
+    } catch(std::exception& e) {
+        log_error("Error parsing the AMF packet: \n\t%s", e.what());
+    }
+        
+    return header;
+}
+
+boost::shared_ptr<amf::Buffer>
+AMF_msg::encodeAMFPacket(const std::string &target,
+                         const std::string &response, size_t size)
+{
+}
+
+boost::shared_ptr<amf::Buffer>
+AMF_msg::encodeAMFPacket()
+{
+//    GNASH_REPORT_FUNCTION;
+    boost::shared_ptr<amf::Buffer> buf(new amf::Buffer);
+
+    // Encode the packet header
+    boost::shared_ptr<amf::Buffer> buf1 = encodeContextHeader(0, 0, 
_messages.size());
+    *buf = buf1;
+
+    // Now encode all the messages
+
+    vector<boost::shared_ptr<AMF_msg::amf_message_t> >::iterator it;
+    for (it = _messages.begin(); it != _messages.end(); it++) {
+        boost::shared_ptr<AMF_msg::amf_message_t> msg = (*(it));
+
+        boost::shared_ptr<amf::Buffer> buf2 = 
encodeMsgHeader(msg->header.target,
+                                                            
msg->header.response,
+                                                            msg->header.size);
+
+//     AMF_msg::dump(msg->header);
+//     msg->data->dump();
+        boost::shared_ptr<amf::Buffer> buf3 = msg->data->encode();
+       *buf += buf2;
+       *buf += buf3;
+    }
+
+    return buf;
+}
+
+boost::shared_ptr<amf::Buffer>
+AMF_msg::encodeMsgHeader(const std::string &target,
+                         const std::string &response, size_t size)
+{
+//    GNASH_REPORT_FUNCTION;
+    size_t total = target.size() + sizeof(boost::uint16_t);
+    total += response.size() + sizeof(boost::uint16_t);
+    total += sizeof(boost::uint32_t);
+    
+    boost::shared_ptr<amf::Buffer> buf (new amf::Buffer(total));
+    boost::uint16_t length = target.size();
+    swapBytes(&length, sizeof(boost::uint16_t));
+    *buf += length;
+    *buf += target;
+
+    length = response.size();
+    swapBytes(&length, sizeof(boost::uint16_t));
+    *buf += length;
+    *buf += response;
+
+    boost::uint32_t swapped = htonl(size);
+    *buf += swapped;
+    
+    return buf;
+}    
+
+void
+AMF_msg::dump(AMF_msg::message_header_t &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    cout << "Target is: " << data.target << endl;
+    cout << "Response is: " << data.response << endl;
+    cout << "Data size is: " << data.size << endl;
+}
+
+void
+AMF_msg::dump(AMF_msg::context_header_t &data)
+{
+//    GNASH_REPORT_FUNCTION;
+    cout << "AMF Version: " << data.version << endl;
+    cout << "Number of headers: " << data.headers << endl;
+    cout << "Number of messages: " << data.messages << endl;
+}
+
+void
+AMF_msg::dump()
+{
+//    GNASH_REPORT_FUNCTION;
+    cout << "AMF Packet has " << _messages.size() << " messages." << endl;
+    vector<boost::shared_ptr<AMF_msg::amf_message_t> >::iterator it;
+    for (it = _messages.begin(); it != _messages.end(); it++) {
+        boost::shared_ptr<AMF_msg::amf_message_t> msg = (*(it));
+        AMF_msg::dump(msg->header);
+        msg->data->dump();
+    }
+}
+
+
+} // end of amf namespace
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== added file 'libamf/amf_msg.h'
--- a/libamf/amf_msg.h  1970-01-01 00:00:00 +0000
+++ b/libamf/amf_msg.h  2009-03-03 22:20:40 +0000
@@ -0,0 +1,125 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009 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
+
+// This file is for the low level support for encoding and decoding AMF 
objects.
+// As this class has no data associated with it, all the methods are static as
+// they are for convenience only.
+// All the encoding methods return a Buffer class, which is simply an array on
+// of unsigned bytes, and a byte count.
+// The only extraction classes parse either a raw AMF object or the larger
+// "variable"
+
+#ifndef _AMF_MSG_H_
+#define _AMF_MSG_H_
+
+#include <string>
+#include <vector>
+
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "element.h"
+#include "dsodefs.h"
+
+/// Action Message Format specific classes of libamf.
+namespace amf 
+{
+
+// forward declaration
+class Buffer;
+class Element;
+
+/// All numbers in AMF format are 8 byte doubles.
+/// Binary representation of an ActionScript object.
+//
+/// AMF is used to send objects, whether to a SharedObject .sol file,
+/// a memory based LocalConnection segment, or over an RTMP connection
+/// for streaming.
+///
+class DSOEXPORT AMF_msg {
+  public:
+    typedef enum {
+        AMF0 = 0x00,
+        AMF3 = 0x11
+    } amf_version_e;
+    typedef struct {
+        boost::uint16_t version;
+        boost::uint16_t headers;
+        boost::uint16_t messages;
+    } context_header_t;
+    typedef struct {
+        std::string     target;
+        std::string     response;
+        size_t          size;
+    } message_header_t;
+    typedef struct {
+        message_header_t header;
+        boost::shared_ptr<amf::Element> data;
+    } amf_message_t;
+
+    size_t addMessage(boost::shared_ptr<amf_message_t> msg)
+    {
+        _messages.push_back(msg); return _messages.size();
+    };
+    boost::shared_ptr<amf_message_t> &getMessage(int x) { return _messages[x]; 
};
+    size_t messageCount() { return _messages.size(); };
+    
+    // These methods create the raw data of the AMF packet from Elements
+    static boost::shared_ptr<amf::Buffer> encodeContextHeader(context_header_t 
*head);
+    static boost::shared_ptr<amf::Buffer> encodeContextHeader(boost::uint16_t 
version,
+                                                             boost::uint16_t 
headers,
+                                                             boost::uint16_t 
messages);
+
+    static boost::shared_ptr<amf::Buffer> encodeMsgHeader(message_header_t 
*head);
+    static boost::shared_ptr<amf::Buffer> encodeMsgHeader(const std::string 
&target,
+                                          const std::string &response, size_t 
size);
+    
+    // These methods parse the raw data of the AMF packet into data structures
+    static boost::shared_ptr<context_header_t> parseContextHeader(amf::Buffer 
&data);
+    static boost::shared_ptr<context_header_t> 
parseContextHeader(boost::uint8_t *data, size_t size);
+    
+    static boost::shared_ptr<message_header_t> parseMessageHeader(amf::Buffer 
&data);
+    static boost::shared_ptr<message_header_t> 
parseMessageHeader(boost::uint8_t *data, size_t size);
+
+    // These methods parse the entire packet. which consists of multiple 
messages
+    boost::shared_ptr<context_header_t> parseAMFPacket(amf::Buffer &buf);
+    boost::shared_ptr<context_header_t> parseAMFPacket(boost::uint8_t *data,
+                                                      size_t size);
+
+    // This methods create an entire packet from multiple messages, already 
parsed in
+    boost::shared_ptr<amf::Buffer> encodeAMFPacket();
+    boost::shared_ptr<amf::Buffer> encodeAMFPacket(const std::string &target,
+                                    const std::string &response, size_t size);
+    
+    static void dump(context_header_t &data);
+    static void dump(message_header_t &data);
+    void dump();
+    
+private:
+    std::vector<boost::shared_ptr<amf_message_t> > _messages;
+//     context_header_t    _context_header;
+};
+
+} // end of amf namespace
+
+// end of _AMF_MSG_H_
+#endif
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== modified file 'libcore/asobj/Makefile.am'
--- a/libcore/asobj/Makefile.am 2009-02-27 06:46:40 +0000
+++ b/libcore/asobj/Makefile.am 2009-03-04 17:31:11 +0000
@@ -18,6 +18,11 @@
 
 AUTOMAKE_OPTIONS = 
 
+# if the compiler has broken flaot support when optimized
+if BROKEN_FLOAT
+AM_CXXFLAGS = $(AM_CXXFLAGS) -ffloat-store
+endif
+
 noinst_LTLIBRARIES = libgnashasobjs.la 
 
 AM_CPPFLAGS = \
@@ -191,6 +196,12 @@
                                $(SDL_LIBS)
 endif
 
+# if the compiler has broken flaot support when optimized
+# if BROKEN_FLOAT
+# Date.lo Date.o:
+#      $(MAKE) CXXFLAGS=\"$(CXXFLAGS) -ffloat-store\"
+# endif
+
 #libgnashasobjs_la_LDFLAGS = -release $(VERSION) -no-undefined -export-dynamic
 
 if WIN32

=== modified file 'testsuite/libamf.all/Makefile.am'
--- a/testsuite/libamf.all/Makefile.am  2009-02-27 06:46:40 +0000
+++ b/testsuite/libamf.all/Makefile.am  2009-03-03 03:42:32 +0000
@@ -46,6 +46,7 @@
 
 check_PROGRAMS = \
        test_amf \
+       test_amfmsg \
        test_buffer \
        test_el \
        test_sol \
@@ -65,6 +66,9 @@
 test_amf_SOURCES = test_amf.cpp
 test_amf_LDADD = $(AM_LDFLAGS)
 
+test_amfmsg_SOURCES = test_amfmsg.cpp
+test_amfmsg_LDADD = $(AM_LDFLAGS)
+
 test_lc_SOURCES = test_lc.cpp
 test_lc_LDADD = $(AM_LDFLAGS)
 

=== added file 'testsuite/libamf.all/test_amfmsg.cpp'
--- a/testsuite/libamf.all/test_amfmsg.cpp      1970-01-01 00:00:00 +0000
+++ b/testsuite/libamf.all/test_amfmsg.cpp      2009-03-03 23:39:05 +0000
@@ -0,0 +1,263 @@
+// 
+//   Copyright (C) 2008, 2009 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 "gnashconfig.h"
+#endif
+
+#ifdef HAVE_DEJAGNU_H
+
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <log.h>
+#include <iostream>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+#include "GnashException.h"
+#include "check.h"
+//#include "dejagnu.h"
+#include "as_object.h"
+#include "arg_parser.h"
+#include "amf.h"
+#include "amf_msg.h"
+#include "buffer.h"
+#include "network.h"
+#include "element.h"
+#include "gmemory.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+
+static void usage (void);
+
+// Prototypes for test cases
+static void test_encoding();
+
+// Enable the display of memory allocation and timing data
+static bool memdebug = false;
+
+// We use the Memory profiling class to check the malloc buffers
+// in the kernel to make sure the allocations and frees happen
+// the way we expect them too. There is no real other way to tell.
+#if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
+Memory *mem = 0;
+#endif
+
+TestState& runtest=_runtest;
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+
+int
+main(int argc, char *argv[])
+{
+    const Arg_parser::Option opts[] =
+        {
+            { 'h', "help",          Arg_parser::no  },
+            { 'v', "verbose",       Arg_parser::no  },
+            { 'w', "write",         Arg_parser::no  },
+// Unless you have support for memory debugging turned on, and
+// you have support for the Linux mallinfo() system call,
+// this option is totally useless. This doesn't really matter
+// as the memory testing is primarily used only during
+// debugging or development.
+            { 'm', "memstats",      Arg_parser::no  },
+            { 'd', "dump",          Arg_parser::no  },
+        };
+    
+    Arg_parser parser(argc, argv, opts);
+    if( ! parser.error().empty() ) {
+        cout << parser.error() << endl;
+        exit(EXIT_FAILURE);
+    }
+    
+    for( int i = 0; i < parser.arguments(); ++i ) {
+        const int code = parser.code(i);
+        try {
+            switch( code ) {
+              case 'h':
+                  usage ();
+                  exit(EXIT_SUCCESS);
+              case 'v':
+                    dbglogfile.setVerbosity();
+                    // This happens once per 'v' flag 
+                    log_debug(_("Verbose output turned on"));
+                    break;
+              case 'm':
+                    // This happens once per 'v' flag 
+                    log_debug(_("Enabling memory statistics"));
+                    memdebug = true;
+                    break;
+              case 'w':
+                  rcfile.useWriteLog(true); // dbglogfile.setWriteDisk(true);
+                  log_debug(_("Logging to disk enabled"));
+                  break;
+                  
+           }
+        }
+        
+        catch (Arg_parser::ArgParserException &e) {
+            cerr << _("Error parsing command line options: ") << e.what() << 
endl;
+            cerr << _("This is a Gnash bug.") << endl;
+        }
+    }
+
+#if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
+    if (memdebug) {
+        mem = new Memory;
+        mem->startStats();
+    }
+#endif
+    
+    // run the tests
+    test_encoding();
+}
+
+void
+test_encoding()
+{
+//     00 06 67 65 74 77 61 79                <- getway, message #1
+//  00 04 2f 32 32 39                      <- /229, operation name
+//  00 00 00 0e                                <- byte length of message
+//     0a 00 00 00 01                  <- array, 1 item
+//        00 41 70 43 87 20 00 00 00
+//
+//  00 06 67 65 74 77 61 79                <- getway, message #2
+//  00 04 2f 32 33 30                      <- /230, operation name
+//  00 00 00 0e                                <- byte length of message
+//     0a 00 00 00 01                  <- array, 1 item
+//        00 41 70 43 ba 00 00 00 00
+//
+//  00 06 67 65 74 77 61 79                <- getway, message #3
+//  00 04 2f 32 33 31                      <- /231, operation name
+//  00 00 00 0e                                <- byte length of message
+//     0a 00 00 00 01                  <- array, 1 item
+//        00 41 70 43 ac e0 00 00 00
+    boost::shared_ptr<Buffer> buf1(new Buffer("00 00 00 00 00 03 00 06 67 65 
74 77 61 79 00 04 2f 32 32 39 00 00 00 0e 0a 00 00 00 01 00 41 70 43 87 20 00 
00 00 00 06 67 65 74 77 61 79 00 04 2f 32 33 30 00 00 00 0e 0a 00 00 00 01 00 
41 70 43 ba 00 00 00 00 00 06 67 65 74 77 61 79 00 04 2f 32 33 31 00 00 00 0e 
0a 00 00 00 01 00 41 70 43 ac e0 00 00 00"));
+    double num = *(reinterpret_cast<double *>(buf1->reference()));
+    swapBytes(&num, amf::AMF0_NUMBER_SIZE); // we always encode in big endian 
format
+
+    AMF_msg amsg;
+    boost::shared_ptr<AMF_msg::context_header_t> head1 =
+        amsg.parseAMFPacket(buf1->reference(), buf1->size());
+
+//    amsg.dump(*head1);
+//    amsg.dump();
+    double dub1 = amsg.getMessage(0)->data->getProperty(0)->to_number();
+    double dub2 = amsg.getMessage(1)->data->getProperty(0)->to_number();
+    double dub3 = amsg.getMessage(2)->data->getProperty(0)->to_number();
+    
+    if ((amsg.messageCount() == 3)
+        && (amsg.getMessage(0)->data->getType() == Element::STRICT_ARRAY_AMF0)
+        && (dub1 == 0x1043872)
+        && (amsg.getMessage(1)->data->getType() == Element::STRICT_ARRAY_AMF0)
+        && (amsg.getMessage(2)->data->getType() == Element::STRICT_ARRAY_AMF0)
+        ) {
+        runtest.pass("AMF_msg::parseAMFPacket()");
+    } else {
+        runtest.fail("AMF_msg::parseAMFPacket()");
+    }
+
+    // Build a new message packet from scratch and make sure it matches the 
real one
+    AMF_msg top;
+    
+    boost::shared_ptr<amf::Element> getway1(new Element);
+    getway1->makeStrictArray();
+    boost::shared_ptr<amf::Element> data1(new Element);
+    data1->makeNumber(dub1);
+    getway1->addProperty(data1);
+    boost::shared_ptr<AMF_msg::amf_message_t> msg1(new AMF_msg::amf_message_t);
+    msg1->header.target = "getway";
+    msg1->header.response = "/229";
+    msg1->header.size = 14;
+    msg1->data = getway1;
+    top.addMessage(msg1);
+    
+    boost::shared_ptr<amf::Element> getway2(new Element);
+    getway2->makeStrictArray();
+    boost::shared_ptr<amf::Element> data2(new Element);
+    data2->makeNumber(dub2);
+    getway2->addProperty(data2);
+    boost::shared_ptr<AMF_msg::amf_message_t> msg2(new AMF_msg::amf_message_t);
+    msg2->header.target = "getway";
+    msg2->header.response = "/230";
+    msg2->header.size = 14;
+    msg2->data = getway2;
+    top.addMessage(msg2);
+    
+    boost::shared_ptr<amf::Element> getway3(new Element);
+    getway3->makeStrictArray();
+    boost::shared_ptr<amf::Element> data3(new Element);
+    data3->makeNumber(dub3);
+    getway3->addProperty(data3);
+    boost::shared_ptr<AMF_msg::amf_message_t> msg3(new AMF_msg::amf_message_t);
+    msg3->header.target = "getway";
+    msg3->header.response = "/231";
+    msg3->header.size = 14;
+    msg3->data = getway3;
+    top.addMessage(msg3);
+
+    boost::shared_ptr<amf::Buffer> buf2 = top.encodeMsgHeader("getway", 
"/229", 14);
+    boost::uint8_t *ptr1 = buf1->reference() + 
sizeof(AMF_msg::context_header_t);
+
+
+    if (memcmp(ptr1, buf2->reference(), buf2->size()) == 0) {
+        runtest.pass("AMF_msg::encodeMsgHeader()");
+    } else {
+        runtest.fail("AMF_msg::encodeMsgHeader()");
+    }
+    
+    boost::shared_ptr<amf::Buffer> buf3 = top.encodeAMFPacket();
+    if (memcmp(buf1->reference(), buf3->reference(), buf3->allocated()) == 0) {
+        runtest.pass("AMF_msg::encodeAMFPacket()");
+    } else {
+        runtest.fail("AMF_msg::encodeAMFPacket()");
+    }
+//    buf3->dump();
+//    top.dump();
+//
+}
+
+
+static void
+usage (void)
+{
+    cerr << "This program tests AMF support in the AMF library." << endl
+         << endl
+         << _("Usage: test_amf [options...]") << endl
+         << _("  -h,  --help          Print this help and exit") << endl
+         << _("  -v,  --verbose       Output verbose debug info") << endl
+         << _("  -m,  --memdebug      Output memory statistics") << endl
+         << endl;
+}
+
+#else
+
+int
+main(int /*argc*/, char /* *argv[]*/)
+{
+  // nop
+  return 0;  
+}
+
+#endif


reply via email to

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