[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10653: add test for borken floating point when compiling optimized.,
rob <=