[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libamf/amf.cpp libamf/amf.h lib...
From: |
Rob Savoye |
Subject: |
[Gnash-commit] gnash ChangeLog libamf/amf.cpp libamf/amf.h lib... |
Date: |
Sun, 13 Apr 2008 23:46:34 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Rob Savoye <rsavoye> 08/04/13 23:46:33
Modified files:
. : ChangeLog
libamf : amf.cpp amf.h buffer.cpp element.cpp element.h
testsuite/libamf.all: Makefile.am test_buffer.cpp test_el.cpp
test_number.cpp
Added files:
testsuite/libamf.all: test_amf.cpp
Log message:
* libamf/buffer.cpp: Redesign the ::resize() method. Add more
::copy() methods for bool and doubles.
* libamf/element.cpp: When invoking one of the make* methods for
initializing an object, all allocate memory if none has been
done so
yet. Implement a few more object creation types.
* libamf/element.h: Add a few more object creation methods.
* testsuite/libamf.all/test_buffer.cpp: Test new ::copy()
methods. Default to a nop if DejaGnu isn't installed.
* testsuite/libamf.all/test_el.cpp: Use arg_parser instead of
getopt. Default to a nop if DejaGnu isn't installed. Add more
tests for construction, and the making of Elements.
* testsuite/libamf.all/test_amf.cpp: New test case for AMF
class.
* testsuite/libamf.all/Makefile.am: Add test_amf.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6265&r2=1.6266
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.cpp?cvsroot=gnash&r1=1.70&r2=1.71
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.h?cvsroot=gnash&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/buffer.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.cpp?cvsroot=gnash&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.h?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/Makefile.am?cvsroot=gnash&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_buffer.cpp?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_el.cpp?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_number.cpp?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/libamf.all/test_amf.cpp?cvsroot=gnash&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6265
retrieving revision 1.6266
diff -u -b -r1.6265 -r1.6266
--- ChangeLog 13 Apr 2008 18:27:42 -0000 1.6265
+++ ChangeLog 13 Apr 2008 23:46:31 -0000 1.6266
@@ -1,3 +1,15 @@
+2008-04-13 Rob Savoye <address@hidden>
+
+ * libamf/amf.cpp: Boolsa re two bytes for AMF, so use a uint16-t,
+ not a bool when copying data. If the name is set, then it's a
+ variable for encoding.
+` * libamf/amf.h: Use Network::byte_t instead of char for constants.
+ * libamf/element.cpp: Elements, encode thyself instead of leaving
+ it for an AMF object to do it.
+ * testsuite/libamf.all/test_el.cpp: Test the children too.
+ * testsuite/libamf.all/test_amf.cpp: Test the AMF class.
+ * testsuite/libamf.all
+
2008-04-13 Benjamin Wolsey <address@hidden>
* server/asobj/System.cpp: add windowlessDisable, reorder.
@@ -11,7 +23,7 @@
* libamf/element.h: Add private method to check the data buffer to
replace often duplicated code.
* testsuite/libamf.all/test_el.cpp: Add more make* tests, add
- tests for == and = operaators.
+ tests for == and = operators.
2008-04-11 Rob Savoye <address@hidden>
@@ -26,6 +38,8 @@
* testsuite/libamf.all/test_el.cpp: Use arg_parser instead of
getopt. Default to a nop if DejaGnu isn't installed. Add more
tests for construction, and the making of Elements.
+ * testsuite/libamf.all/test_amf.cpp: New test case for AMF class.
+ * testsuite/libamf.all/Makefile.am: Add test_amf.
2008-04-11 Rob Savoye <address@hidden>
Index: libamf/amf.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.cpp,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -b -r1.70 -r1.71
--- libamf/amf.cpp 11 Apr 2008 19:02:34 -0000 1.70
+++ libamf/amf.cpp 13 Apr 2008 23:46:32 -0000 1.71
@@ -312,24 +312,44 @@
// Encode a boolean value. 0 for false, 1 for true
Buffer *buf = new Buffer(AMF_HEADER_SIZE);
buf->append(Element::BOOLEAN);
- bool x = flag;
+ boost::uint16_t x = flag;
swapBytes(&x, 2);
buf->append(x);
return buf;
}
+/// Encode the end of an object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+Buffer *
+AMF::encodeObjectEnd()
+{
+ GNASH_REPORT_FUNCTION;
+ Buffer *buf = new Buffer(1);
+ buf->append(TERMINATOR);
+
+ return buf;
+}
+
+#if 0
/// Encode an object
///
/// @return a binary AMF packet in big endian format (header,data) which
/// needs to be deleted[] after being used.
///
Buffer *
-AMF::encodeObject(Network::byte_t *data, int size)
+AMF::encodeObject(Element *el)
{
-// GNASH_REPORT_FUNCTION;
- // Encode an XML object. The data follows a 4 byte length
- // field. (which must be big-endian)
+ GNASH_REPORT_FUNCTION;
+ AMF amf_obj;
+
+ for (size_t i=0; i< el->childrenSize(); i++) {
+// Buffer *var = amf_obj.encodeVariable();
+// Element *child = el[i];
+#if 0
Buffer *buf = new Buffer(AMF_HEADER_SIZE + size);
buf->append(Element::OBJECT);
boost::uint32_t num = size;
@@ -338,7 +358,12 @@
buf->append(data, size);
return buf;
+#endif
+// child.dump();
+ }
+
}
+#endif
/// Encode an "Undefined" object
///
@@ -375,7 +400,8 @@
/// @return a binary AMF packet in big endian format (header,data) which
/// needs to be deleted[] after being used.
///
-Buffer *encodeDate(Network::byte_t *data)
+Buffer *
+AMF::encodeDate(Network::byte_t *data)
{
// GNASH_REPORT_FUNCTION;
Buffer *buf = new Buffer(AMF_HEADER_SIZE);
@@ -498,7 +524,6 @@
return 0;
}
-
/// Encode a Strict Array
///
/// @return a binary AMF packet in big endian format (header,data) which
@@ -521,7 +546,7 @@
Buffer *
AMF::encodeString(const string &str)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
boost::uint16_t length;
Buffer *buf = new Buffer(str.size() + AMF_HEADER_SIZE);
@@ -531,7 +556,7 @@
// doesn't get written when encoding a string as it has a byte count
// instead.
length = str.size();
- log_debug("Encoded data size is going to be %d", length);
+// log_debug("Encoded data size is going to be %d", length);
swapBytes(&length, 2);
buf->append(length);
buf->append(str);
@@ -539,6 +564,29 @@
return buf;
}
+/// Encode a NULL string object, which is a string with no data.
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+Buffer *
+AMF::encodeNullString()
+{
+// GNASH_REPORT_FUNCTION;
+ boost::uint16_t length;
+
+ Buffer *buf = new Buffer(AMF_HEADER_SIZE);
+ buf->append(Element::STRING);
+ // when a string is stored in an element, we add a NULL terminator so
+ // it can be printed by to_string() efficiently. The NULL terminator
+ // doesn't get written when encoding a string as it has a byte count
+ // instead.
+ length = 0;
+ buf->append(length);
+
+ return buf;
+}
+
/// \brief Write an AMF element
///
/// This encodes the data supplied to an AMF formatted one. As the
@@ -560,75 +608,96 @@
AMF::encodeElement(Element *el)
{
// GNASH_REPORT_FUNCTION;
+ Buffer *buf = 0;
+ Buffer *tmp;
+
+ size_t outsize = el->getNameSize() + AMF_VAR_HEADER_SIZE;
+ buf = new Buffer(outsize);
+ // If the name field is set, it's a "variable", followed by the data
+ if (el->getName()) {
+ // Add the length of the string for the name of the variable
+ size_t length = el->getNameSize();
+ boost::uint16_t enclength = length;
+ swapBytes(&enclength, 2);
+ buf->copy(enclength);
+ // Now the name itself
+ string name = el->getName();
+ if (name.size() > 0) {
+ buf->append(name);
+ }
+ }
+
+ // Encode the element's data
switch (el->getType()) {
case Element::NOTYPE:
return 0;
break;
case Element::NUMBER:
- return encodeNumber(el->to_number());
+ tmp = encodeNumber(el->to_number());
break;
case Element::BOOLEAN:
- return encodeBoolean(el->to_bool());
+ tmp = encodeBoolean(el->to_bool());
break;
case Element::STRING:
- return encodeString(el->to_string());
+ tmp = encodeString(el->to_string());
break;
case Element::OBJECT:
- return encodeObject(el->getData(), el->getLength());
+ tmp = el->encode();
break;
case Element::MOVIECLIP:
- return encodeMovieClip(el->getData(), el->getLength());
+ tmp = encodeMovieClip(el->getData(), el->getLength());
break;
case Element::NULL_VALUE:
- return encodeNull();
+ tmp = encodeNull();
break;
case Element::UNDEFINED:
- return encodeUndefined();
+ tmp = encodeUndefined();
break;
case Element::REFERENCE:
- return encodeReference(el->getData(), el->getLength());
+ tmp = encodeReference(el->getData(), el->getLength());
break;
case Element::ECMA_ARRAY:
- return encodeECMAArray(el->getData(), el->getLength());
+ tmp = encodeECMAArray(el->getData(), el->getLength());
break;
// The Object End gets added when creating the object, so we can jusy
ignore it here.
case Element::OBJECT_END:
+ tmp = encodeObjectEnd();
break;
case Element::STRICT_ARRAY:
- return encodeStrictArray(el->getData(), el->getLength());
+ tmp = encodeStrictArray(el->getData(), el->getLength());
break;
case Element::DATE:
-// return encodeDate(el->getData());
+ tmp = encodeDate(el->getData());
break;
case Element::LONG_STRING:
- return encodeLongString(el->getData(), el->getLength());
+ tmp = encodeLongString(el->getData(), el->getLength());
break;
case Element::UNSUPPORTED:
- return encodeUnsupported();
+ tmp = encodeUnsupported();
break;
case Element::RECORD_SET:
- return encodeRecordSet(el->getData(), el->getLength());
+ tmp = encodeRecordSet(el->getData(), el->getLength());
break;
case Element::XML_OBJECT:
- return encodeXMLObject(el->getData(), el->getLength());
+ tmp = encodeXMLObject(el->getData(), el->getLength());
// Encode an XML object. The data follows a 4 byte length
// field. (which must be big-endian)
break;
case Element::TYPED_OBJECT:
- return encodeTypedObject(el->getData(), el->getLength());
+// tmp = encodeTypedObject(el->getData(), el->getLength());
break;
// This is a Gnash specific value
case Element::VARIABLE:
- return 0;
- break;
case Element::FUNCTION:
- return 0;
break;
};
- // you should never get here
- return 0;
+ buf->append(tmp);
+// log_debug("Encoded buf size is %d", buf->size());
+ delete tmp;
+
+ return buf;
}
#if 0
@@ -975,10 +1044,13 @@
swapBytes(&enclength, 2);
buf->copy(enclength);
- string xxx = el->getName(); // FIXME: stupid name
- if (xxx.size() > 0) {
- buf->append(xxx);
+ if (el->getName()) {
+ string name = el->getName();
+ if (name.size() > 0) {
+ buf->append(name);
}
+ }
+
// Add the type of the variable's data
buf->append(el->getType());
// Booleans appear to be encoded weird. Just a short after
@@ -1156,7 +1228,7 @@
// characters, then the string value
// Check the type of the element data
- Element::amf_type_e type = *(Element::amf_type_e *)tmpptr;
+ Element::amf_type_e type = *(reinterpret_cast<Element::amf_type_e
*>(tmpptr));
tmpptr++; // skip the header byte
AMF amf_obj;
Index: libamf/amf.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- libamf/amf.h 11 Apr 2008 19:02:34 -0000 1.38
+++ libamf/amf.h 13 Apr 2008 23:46:32 -0000 1.39
@@ -51,22 +51,22 @@
// The header of an AMF object is a type filed (1 byte), followed by a
// length field. (short)
-const char AMF_HEADER_SIZE = 3;
+const gnash::Network::byte_t AMF_HEADER_SIZE = 3;
// A variable is a little different. It always assumes the the first field is
// a string that's the variable name, then the type byte like a regular AMF
// object and length is used for the data. So a variable object header is
// then only 5 bytes instead of the 6 that one assumes would be used.
-const char AMF_VAR_HEADER_SIZE = 5;
+const gnash::Network::byte_t AMF_VAR_HEADER_SIZE = 5;
// FIXME: this should go away
const int AMF_PACKET_SIZE = 128;
// Use a zero version till now till we know what this should be.
-const char AMF_VERSION = 0;
+const gnash::Network::byte_t AMF_VERSION = 0;
// For terminating sequences, a byte with value 0x09 is used.
-const char TERMINATOR = 0x09;
+const gnash::Network::byte_t TERMINATOR = 0x09;
// An AMF object is the binary representation of an ActionScript object. AMF
// is used to send objects, wheather to a SharedObject .sol file, a memory
based
@@ -124,6 +124,10 @@
///
static Buffer *encodeString(const std::string &str);
+ /// @return a binary AMF packet in big endian format (header,data)
+ ///
+ static Buffer *encodeNullString();
+
/// Encode a Boolean object
///
/// @return a binary AMF packet in big endian format (header,data)
@@ -206,33 +210,28 @@
///
/// @return a binary AMF packet in big endian format (header,data)
///
- static Buffer *encodeObject(gnash::Network::byte_t *data, int size);
+ static Buffer *encodeObject(Element *el);
- /// Encode a 64 bit number
+ /// Encode the end of an object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- static Buffer *encodeNumber(double num);
+ static Buffer *encodeObjectEnd();
- /// Encode a element.
+ /// Encode a 64 bit number
///
/// @return a binary AMF packet in big endian format (header,data)
-
- /// @return a newly allocated byte array.
- /// to be deleted by caller using delete [] operator, or NULL
///
- static Buffer *encodeElement(amf::Element *el);
+ static Buffer *encodeNumber(double num);
-#if 0
- /// Encode an array of elements.
+ /// Encode a element.
///
/// @return a binary AMF packet in big endian format (header,data)
/// @return a newly allocated byte array.
/// to be deleted by caller using delete [] operator, or NULL
///
- static std::vector<gnash::Network::byte_t>
*encodeElement(std::vector<amf::Element *> &els);
-#endif
+ static Buffer *encodeElement(amf::Element *el);
/// Encode a variable.
//
@@ -245,6 +244,7 @@
/// to be deleted by caller using delete [] operator, or NULL
///
Buffer *encodeVariable(amf::Element *el);
+ static Buffer *encodeVariableHeader(const std::string &name);
//
// Methods for extracting data from big endian formatted raw AMF data.
Index: libamf/buffer.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/buffer.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libamf/buffer.cpp 12 Apr 2008 03:59:32 -0000 1.6
+++ libamf/buffer.cpp 13 Apr 2008 23:46:32 -0000 1.7
@@ -104,7 +104,6 @@
void
Buffer::copy(boost::uint16_t length)
{
- GNASH_REPORT_FUNCTION;
Network::byte_t *data = reinterpret_cast<Network::byte_t *>(&length);
std::copy(data, data + sizeof(boost::uint16_t), _ptr);
_seekptr = _ptr + sizeof(boost::uint16_t);
@@ -113,7 +112,7 @@
void
Buffer::copy(double num)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
Network::byte_t *ptr = reinterpret_cast<Network::byte_t *>(&num);
std::copy(ptr, ptr + amf::AMF_NUMBER_SIZE, _ptr);
_seekptr = _ptr + amf::AMF_NUMBER_SIZE;
@@ -450,7 +449,7 @@
size_t diff =_seekptr - _ptr;
Network::byte_t *tmp = new Network::byte_t[size];
// And copy ourselves into it
- if (size > _nbytes) {
+ if (size >= _nbytes) {
std::copy(_ptr, _ptr + _nbytes, tmp);
// Delete the old block, it's unused now
delete[] _ptr;
Index: libamf/element.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- libamf/element.cpp 12 Apr 2008 17:22:44 -0000 1.20
+++ libamf/element.cpp 13 Apr 2008 23:46:32 -0000 1.21
@@ -80,6 +80,9 @@
for (size_t i=0; i< _children.size(); i++) {
delete _children[i];
}
+ if (_name) {
+ delete[] _name;
+ }
}
Element::Element(Network::byte_t *indata)
@@ -390,13 +393,56 @@
}
return false;
};
-Network::byte_t
-Element::operator[](int x)
+
+Buffer *
+Element::encode()
{
-// GNASH_REPORT_FUNCTION;
- if (_buffer) {
- return *_buffer->at(x);
+ GNASH_REPORT_FUNCTION;
+ Buffer *buf = 0;
+ if (_type == Element::OBJECT) {
+ // FIXME: we probably want a better size, to avoid the other
+ // appends from having to resize and copy the data all the time.
+ buf = new Buffer(AMF_HEADER_SIZE);
+// buf->clear();
+ buf->append(Element::OBJECT);
+ size_t length = getNameSize();
+ boost::uint16_t enclength = length;
+ swapBytes(&enclength, 2);
+ buf->append(enclength);
+
+ string name = _name;
+ if (name.size() > 0) {
+ buf->append(name);
+ }
+
+ for (size_t i=0; i<_children.size(); i++) {
+ Buffer *partial = AMF::encodeElement(_children[i]);
+// log_debug("Encoded partial size is %d", partial->size());
+ if (partial) {
+ buf->append(partial);
+ delete partial;
+ } else {
+ break;
}
+ }
+ buf->append(TERMINATOR);
+ _buffer = buf;
+ return buf;
+ } else {
+ return AMF::encodeElement(this);
+ }
+
+ return 0;
+}
+
+Element *
+Element::operator[](int index)
+{
+ GNASH_REPORT_FUNCTION;
+ if (index <= _children.size()) {
+ return _children[index];
+ }
+
return 0;
};
Index: libamf/element.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- libamf/element.h 12 Apr 2008 17:22:44 -0000 1.17
+++ libamf/element.h 13 Apr 2008 23:46:33 -0000 1.18
@@ -146,7 +146,7 @@
Element &operator=(Element &);
Element &operator=(Element *);
- gnash::Network::byte_t operator[](int x);
+ Element *operator[](int x);
gnash::Network::byte_t *getData();
boost::uint16_t getLength();
@@ -169,9 +169,13 @@
void setName(gnash::Network::byte_t *name, size_t x);
// Manipulate the children Elements of an object
+ void addChild(Element &el) { _children.push_back(&el); };
void addChild(Element *el) { _children.push_back(el); };
Element *popChild() { return _children.front(); };
size_t childrenSize() { return _children.size(); };
+// std::vector<Element *> &getChildren() { return _children; };
+
+ amf::Buffer *encode();
void dump();
private:
Index: testsuite/libamf.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/Makefile.am,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- testsuite/libamf.all/Makefile.am 6 Apr 2008 18:11:33 -0000 1.20
+++ testsuite/libamf.all/Makefile.am 13 Apr 2008 23:46:33 -0000 1.21
@@ -49,18 +49,22 @@
check_PROGRAMS = \
+ test_amf \
test_buffer \
test_el \
test_sol \
test_lc
-test_el_SOURCES = test_el.cpp ../../libamf/element.cpp
+test_el_SOURCES = test_el.cpp
test_el_LDADD = $(AM_LDFLAGS)
test_sol_SOURCES = test_sol.cpp
test_sol_LDADD = $(AM_LDFLAGS)
test_sol_DEPENDENCIES = $(solfiles)
+test_amf_SOURCES = test_amf.cpp
+test_amf_LDADD = $(AM_LDFLAGS)
+
test_lc_SOURCES = test_lc.cpp
test_lc_LDADD = $(AM_LDFLAGS)
Index: testsuite/libamf.all/test_buffer.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/test_buffer.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- testsuite/libamf.all/test_buffer.cpp 12 Apr 2008 03:59:33 -0000
1.5
+++ testsuite/libamf.all/test_buffer.cpp 13 Apr 2008 23:46:33 -0000
1.6
@@ -240,18 +240,6 @@
runtest.fail ("Buffer::copy(double)");
}
#endif
-
-#if 0
- bool flag = true;
- Buffer buf5;
- buf5.clear();
- buf5.copy(flag);
- if (*(buf5.reference()) == 1) {
- runtest.pass ("Buffer::copy(bool)");
- } else {
- runtest.fail ("Buffer::copy(bool)");
- }
-#endif
}
void
@@ -580,7 +568,7 @@
{
cout << _("test_buffer - test Buffer class") << endl
<< endl
- << _("Usage: cygnal [options...]") << endl
+ << _("Usage: test_buffer [options...]") << endl
<< _(" -h, --help Print this help and exit") << endl
<< _(" -v, --verbose Output verbose debug info") << endl
<< _(" -m, --memdebug Output memory statistics") << endl
Index: testsuite/libamf.all/test_el.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/test_el.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- testsuite/libamf.all/test_el.cpp 12 Apr 2008 17:22:44 -0000 1.7
+++ testsuite/libamf.all/test_el.cpp 13 Apr 2008 23:46:33 -0000 1.8
@@ -46,15 +46,12 @@
static void usage (void);
-bool test_read(std::string &filespec);
-bool test_write(std::string &filespec);
-bool test_sol(std::string &filespec);
-
// Prototypes for test cases
static void test_construct();
static void test_destruct();
static void test_make();
static void test_operators();
+static void test_children();
// Enable the display of memory allocation and timing data
static bool memdebug = false;
@@ -116,6 +113,30 @@
test_make();
test_operators();
test_destruct();
+ test_children();
+}
+
+void
+test_children()
+{
+ Element top;
+ top.makeObject("app");
+
+ Element *child1 = new Element;
+ child1->makeString("child one");
+ top.addChild(child1);
+
+ Element *child2 = new Element;
+ child2->makeString("child two");
+ top.addChild(child2);
+
+ if (top.childrenSize() == 2) {
+ runtest.pass("Adding children");
+ } else {
+ runtest.fail("Adding children");
+ }
+
+// top.dump();
}
void
@@ -256,20 +277,6 @@
{
}
-// amf::Element::makeNumber(std::string const&, double)
-// amf::Element::makeObject(unsigned char*, unsigned int)
-// amf::Element::makeString(char const*, unsigned int)
-// amf::Element::makeString(unsigned char*, unsigned int)
-// amf::Element::makeString(std::string const&, std::string const&)
-// amf::Element::makeBoolean(std::string const&, bool)
-// amf::Element::makeECMAArray(unsigned char*, unsigned int)
-// amf::Element::makeMovieClip(unsigned char*, unsigned int)
-// amf::Element::makeRecordSet(unsigned char*, unsigned int)
-// amf::Element::makeReference(unsigned char*, unsigned int)
-// amf::Element::makeXMLObject(unsigned char*, unsigned int)
-// amf::Element::makeLongString(unsigned char*, unsigned int)
-// amf::Element::makeStrictArray(unsigned char*, unsigned int)
-// amf::Element::makeTypedObject(unsigned char*, unsigned int)
void
test_make()
{
@@ -425,6 +432,20 @@
runtest.fail("Remade boolean as a double element");
}
+// amf::Element::makeNumber(std::string const&, double)
+// amf::Element::makeObject(unsigned char*, unsigned int)
+// amf::Element::makeString(char const*, unsigned int)
+// amf::Element::makeString(unsigned char*, unsigned int)
+// amf::Element::makeString(std::string const&, std::string const&)
+// amf::Element::makeBoolean(std::string const&, bool)
+// amf::Element::makeECMAArray(unsigned char*, unsigned int)
+// amf::Element::makeMovieClip(unsigned char*, unsigned int)
+// amf::Element::makeRecordSet(unsigned char*, unsigned int)
+// amf::Element::makeReference(unsigned char*, unsigned int)
+// amf::Element::makeXMLObject(unsigned char*, unsigned int)
+// amf::Element::makeLongString(unsigned char*, unsigned int)
+// amf::Element::makeStrictArray(unsigned char*, unsigned int)
+// amf::Element::makeTypedObject(unsigned char*, unsigned int)
}
@@ -471,7 +492,7 @@
{
cerr << "This program tests AMF Element support in the AMF library." <<
endl
<< endl
- << _("Usage: cygnal [options...]") << endl
+ << _("Usage: test_el [options...]") << endl
<< _(" -h, --help Print this help and exit") << endl
<< _(" -v, --verbose Output verbose debug info") << endl
<< _(" -m, --memdebug Output memory statistics") << endl
Index: testsuite/libamf.all/test_number.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/libamf.all/test_number.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- testsuite/libamf.all/test_number.cpp 21 Jan 2008 23:26:49 -0000
1.12
+++ testsuite/libamf.all/test_number.cpp 13 Apr 2008 23:46:33 -0000
1.13
@@ -88,11 +88,11 @@
{
AMF amf_obj;
int fd, ret;
- char *buf[AMF_NUMBER_SIZE+1];
double num;
Element el;
boost::uint8_t *ptr;
+ char *buf[AMF_NUMBER_SIZE+1];
memset(buf, 0, AMF_NUMBER_SIZE+1);
string filespec = SRCDIR;
filespec += "/f03f.amf";
Index: testsuite/libamf.all/test_amf.cpp
===================================================================
RCS file: testsuite/libamf.all/test_amf.cpp
diff -N testsuite/libamf.all/test_amf.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/libamf.all/test_amf.cpp 13 Apr 2008 23:46:33 -0000 1.1
@@ -0,0 +1,313 @@
+//
+// Copyright (C) 2008 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 "dejagnu.h"
+#include "as_object.h"
+#include "arg_parser.h"
+#include "buffer.h"
+#include "network.h"
+#include "amf.h"
+#include "element.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+
+static void usage (void);
+
+// Prototypes for test cases
+static void test_encoding();
+static void test_string();
+static void test_object();
+static void test_boolean();
+
+// Enable the display of memory allocation and timing data
+static bool memdebug = false;
+
+TestState runtest;
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+RcInitFile& rcfile = RcInitFile::getDefaultInstance();
+
+// These next two functions are borrowed from Libgloss, part of the GNU
binutils,
+// of which I am the primary author and copyright holder.
+// convert an ascii hex digit to a number.
+// param is hex digit.
+// returns a decimal digit.
+Network::byte_t
+hex2digit (Network::byte_t digit)
+{
+ if (digit == 0)
+ return 0;
+
+ if (digit >= '0' && digit <= '9')
+ return digit - '0';
+ if (digit >= 'a' && digit <= 'f')
+ return digit - 'a' + 10;
+ if (digit >= 'A' && digit <= 'F')
+ return digit - 'A' + 10;
+
+ // shouldn't ever get this far
+ return -1;
+}
+
+// Convert the hex array pointed to by buf into binary to be placed in mem
+Buffer *
+hex2mem(const char *str)
+{
+ size_t count = strlen(str);
+ Network::byte_t ch = 0;
+ Buffer *buf = new Buffer(count + 12);
+ buf->clear();
+
+ Network::byte_t *ptr = const_cast<Network::byte_t
*>(reinterpret_cast<const Network::byte_t *>(str));
+
+ for (size_t i=0; i<count; i++) {
+ if (*ptr == ' ') { // skip spaces.
+ ptr++;
+ continue;
+ }
+ ch = hex2digit(*ptr++) << 4;
+ ch |= hex2digit(*ptr++);
+ buf->append(ch);
+ }
+ return buf;
+}
+
+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 },
+ { '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;
+ }
+ }
+
+ // run the tests
+ test_encoding();
+ test_object();
+}
+
+void
+test_encoding()
+{
+ // This is a 8 byte wide double data type in hex
+ const char *x = "40 83 38 00 00 00 00 00";
+ Buffer *buf1 = hex2mem(x);
+ double num = *(double *)buf1->reference();
+ swapBytes(&num, amf::AMF_NUMBER_SIZE); // we alwasy encode in big endian
format
+ Buffer *encnum = AMF::encodeNumber(num);
+ // A number AMF object has only one header byte, which is the type field.
+ if ((*encnum->reference() == Element::NUMBER) &&
+ (memcmp(buf1->reference(), encnum->reference()+1,
amf::AMF_NUMBER_SIZE) == 0)) {
+ runtest.pass("Encoded AMF Number");
+ } else {
+ runtest.fail("Encoded AMF Number");
+ }
+ delete buf1;
+ delete encnum;
+
+ // Encode a boolean. Although we know a bool is only one character, for
AMF,
+ // it's actually a two byte short instead.
+ bool flag = true;
+ const char *x2 = "00 01";
+ Buffer *buf2 = hex2mem(x2);
+ boost::uint16_t sht = *(boost::uint16_t *)buf2->reference();
+ swapBytes(&sht, sizeof(boost::uint16_t)); // we always encode in big
endian format
+ Buffer *encbool = AMF::encodeBoolean(flag);
+ // A boolean AMF object has only one header byte, which is the type field.
+ // The data is always encoded as a two byte value, even though *we* know a
bool is just
+ // one. Obviously AMF goes back to the days of 16 bit ints, and bool was
the same size.
+ // Ya gotta love old K&R C code for binary formats.
+ if ((*encbool->reference() == Element::BOOLEAN) &&
+ (encbool->size() == 3) &&
+ (memcmp(buf2->reference(), encbool->reference()+1,
sizeof(boost::uint16_t)) == 0)) {
+ runtest.pass("Encoded AMF Boolean");
+ } else {
+ runtest.fail("Encoded AMF Boolean");
+ }
+ delete buf2;
+ delete encbool;
+
+ // Encode a String.
+ string str = "Jerry Garcia rules";
+ Buffer *encstr = AMF::encodeString(str);
+ // A String AMF object has a 3 bytes head, the type, and a two byte length.
+ if ((*encstr->reference() == Element::STRING) &&
+ (encstr->size() == str.size() + AMF_HEADER_SIZE) &&
+ (memcmp(encstr->reference() + 3, str.c_str(), str.size()) == 0)) {
+ runtest.pass("Encoded AMF String");
+ } else {
+ runtest.fail("Encoded AMF String");
+ }
+ delete encstr;
+
+ // Encode a NULL String.
+ Buffer *encnull = AMF::encodeNullString();
+ boost::uint16_t len = *(boost::uint16_t *)(encnull->reference() + 1);
+ // A NULL String AMF object has just 3 bytes, the type, and a two byte
length, which is zero.
+ if ((*encnull->reference() == Element::STRING) &&
+ (encnull->size() == AMF_HEADER_SIZE) &&
+ (len == 0)) {
+ runtest.pass("Encoded AMF NULL String");
+ } else {
+ runtest.fail("Encoded AMF NULL String");
+ }
+ delete encnull;
+}
+
+void
+test_object()
+{
+ Element top;
+ top.makeObject("app");
+
+ Element *child1 = new Element;
+ child1->makeString("child one");
+ top.addChild(child1);
+
+ Element *child2 = new Element;
+ child2->makeString("child two");
+ top.addChild(child2);
+
+ if (top.childrenSize() == 2) {
+ runtest.pass("Adding children");
+ } else {
+ runtest.fail("Adding children");
+ }
+
+ // Encode an object
+ string str = "application";
+ Buffer *encobj = top.encode();
+ if (encobj == 0) {
+ runtest.unresolved("Encoded Object");
+ return;
+ }
+
+ const char *x = "03 00 03 61 70 70 02 00 09 63 68 69 6c 64 20 6f 6e 65 02
00 09 63 68 69 6c 64 20 74 77 6f 09";
+ Buffer *buf1 = hex2mem(x);
+
+#if 0
+ if ((*(reinterpret_cast<Element::amf_type_e *>(encobj->reference())) ==
Element::OBJECT) &&
+ (memcmp(buf1->reference(), encobj->reference(), 31) == 0)) {
+ runtest.pass("Encoded Object");
+ } else {
+ runtest.fail("Encoded Object");
+ }
+#endif
+ delete buf1;
+}
+
+// amf::encodeDate(unsigned char*)
+// amf::AMF::encodeLongString(unsigned char*, int)
+// amf::AMF::encodeStrictArray(unsigned char*, int)
+// amf::AMF::encodeTypedObject(unsigned char*, int)
+// amf::AMF::encodeUnsupported()
+// amf::AMF::encodeNull()
+// amf::AMF::encodeObject(unsigned char*, int)
+// amf::AMF::encodeString(std::string const&)
+// amf::AMF::encodeElement(amf::Element*)
+// amf::AMF::encodeVariable(amf::Element*)
+// amf::AMF::encodeECMAArray(unsigned char*, int)
+// amf::AMF::encodeMovieClip(unsigned char*, int)
+// amf::AMF::encodeRecordSet(unsigned char*, int)
+// amf::AMF::encodeReference(unsigned char*, int)
+// amf::AMF::encodeUndefined()
+// amf::AMF::encodeXMLObject(unsigned char*, int)
+
+// amf::AMF::extractAMF(unsigned char*)
+// amf::AMF::extractVariable(unsigned char*)
+
+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
+
+