[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: |
Fri, 01 Feb 2008 01:42:41 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Rob Savoye <rsavoye> 08/02/01 01:42:41
Modified files:
. : ChangeLog
libamf : amf.cpp amf.h element.cpp element.h lcshm.cpp
lcshm.h
Log message:
* libamf/amf.cpp: Oops, return original pointer as returned by
new, not the incremented pointer. Use :encodeElement() for
strings. Encode an array of AMF objects.
* libamf/amf.h: Make all the encoding methods static.
* libamf/element.{cpp,h}: Add function and variable data types,
internal to Gnash. Initialize with an array of AMF objects.
Create
a new function block object in memory. Don't return nan, BSD
doesn't support it.
* libamf/lcshm.cpp: Correctly remove Listeners. Format a memory
segment header. Send now works, and puts AMF objects into the
memory segment.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5543&r2=1.5544
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.cpp?cvsroot=gnash&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/amf.h?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/element.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.h?cvsroot=gnash&r1=1.6&r2=1.7
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5543
retrieving revision 1.5544
diff -u -b -r1.5543 -r1.5544
--- ChangeLog 1 Feb 2008 01:30:28 -0000 1.5543
+++ ChangeLog 1 Feb 2008 01:42:40 -0000 1.5544
@@ -1,5 +1,17 @@
2008-01-31 Rob Savoye <address@hidden>
+ * libamf/amf.cpp: Oops, return original pointer as returned by
+ new, not the incremented pointer. Use :encodeElement() for
+ strings. Encode an array of AMF objects.
+ * libamf/amf.h: Make all the encoding methods static.
+ * libamf/element.{cpp,h}: Add function and variable data types,
+ internal to Gnash. Initialize with an array of AMF objects. Create
+ a new function block object in memory. Don't return nan, BSD
+ doesn't support it.
+ * libamf/lcshm.cpp: Correctly remove Listeners. Format a memory
+ segment header. Send now works, and puts AMF objects into the
+ memory segment.
+
* configure.ac: Add test for IPC_INFO, which isn't portable to
BSD.
* server/asobj/LocalConnection.cpp: Don;t define any LC constants
Index: libamf/amf.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- libamf/amf.cpp 31 Jan 2008 11:25:57 -0000 1.58
+++ libamf/amf.cpp 1 Feb 2008 01:42:40 -0000 1.59
@@ -162,8 +162,7 @@
AMF::readElements(boost::uint8_t *in)
{
GNASH_REPORT_FUNCTION;
-
- boost::uint8_t *x = in;
+boost::uint8_t *x = in;
astype_e type = (astype_e)*x;
bool boolshift;
const char *mstr = NULL;
@@ -265,33 +264,6 @@
// Methods for encoding data into big endian formatted raw AMF data.
//
-/// Encode a string object
-///
-/// @return a binary AMF packet in big endian format (header,data) which
-/// needs to be deleted[] after being used.
-///
-boost::uint8_t *
-AMF::encodeString(const char *str)
-{
-// GNASH_REPORT_FUNCTION;
- boost::uint16_t length;
-
- int pktsize = strlen(str) + AMF_HEADER_SIZE;
- // Encode a string value. The data follows a 2 byte length
- // field. (which must be big-endian)
- boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
- memset(x, 0, pktsize);
- *x++ = Element::STRING;
- log_debug("Encoded data size is going to be %d", length);
- swapBytes(&length, 2);
- memcpy(x, &length, 2);
- x += 2;
- memcpy(x, str, pktsize - AMF_HEADER_SIZE);
- x += pktsize - AMF_HEADER_SIZE;
-
- return x;
-}
-
/// Encode a 64 bit number
///
/// @return a binary AMF packet in big endian format (header,data) which
@@ -304,15 +276,16 @@
int pktsize = AMF_NUMBER_SIZE + AMF_HEADER_SIZE;
double num;
// Encode the data as a 64 bit, big-endian, numeric value
- boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+ boost::uint8_t *ptr = new boost::uint8_t[pktsize + 1];
+ boost::uint8_t *x = ptr;
memset(x, 0, pktsize);
*x++ = (char)Element::NUMBER;
memcpy(&num, &indata, AMF_NUMBER_SIZE);
swapBytes(&num, AMF_NUMBER_SIZE);
memcpy(x, &num, AMF_NUMBER_SIZE);
- x += pktsize - AMF_HEADER_SIZE;
+// x += pktsize - AMF_HEADER_SIZE;
- return x;
+ return ptr;
}
/// Encode a Boolean object
@@ -328,15 +301,17 @@
// GNASH_REPORT_FUNCTION;
int pktsize = AMF_HEADER_SIZE;
- boost::uint8_t* x = new boost::uint8_t[pktsize + 1];
+ boost::uint8_t*ptr = new boost::uint8_t[pktsize + 1];
+ boost::uint8_t* x = ptr;
memset(x, 0, pktsize);
// Encode a boolean value. 0 for false, 1 for true
*x++ = (char)Element::BOOLEAN;
+ x++;
*x = flag;
- swapBytes(x, 2);
- x += sizeof(boost::uint16_t);
+// swapBytes(x, 2);
+// x += sizeof(boost::uint16_t);
- return x;
+ return ptr;
}
/// Encode an object
@@ -545,6 +520,35 @@
return 0;
}
+/// Encode a string object
+///
+/// @return a binary AMF packet in big endian format (header,data) which
+/// needs to be deleted[] after being used.
+///
+boost::uint8_t *
+AMF::encodeElement(const char *str)
+{
+// GNASH_REPORT_FUNCTION;
+ boost::uint16_t length;
+
+ int pktsize = strlen(str) + AMF_HEADER_SIZE;
+ // Encode a string value. The data follows a 2 byte length
+ // field. (which must be big-endian)
+ boost::uint8_t *ptr = new boost::uint8_t[pktsize + 1];
+ boost::uint8_t *x = ptr;
+ memset(x, 0, pktsize);
+ *x++ = Element::STRING;
+ length = strlen(str);
+ log_debug("Encoded data size is going to be %d", length);
+ swapBytes(&length, 2);
+ memcpy(x, &length, 2);
+ x += 2;
+ memcpy(x, str, pktsize - AMF_HEADER_SIZE);
+ x += pktsize - AMF_HEADER_SIZE;
+
+ return ptr;
+}
+
/// \brief Write an AMF element
///
/// This encodes the data supplied to an AMF formatted one. As the
@@ -572,13 +576,13 @@
return 0;
break;
case Element::NUMBER:
- return encodeNumber(*(reinterpret_cast<double *>(el->getData())));
+ return encodeNumber(el->to_number());
break;
case Element::BOOLEAN:
- return encodeBoolean(*(reinterpret_cast<bool *>(el->getData())));
+ return encodeBoolean(el->to_bool());
break;
case Element::STRING:
- return encodeBoolean(*(reinterpret_cast<const char
*>(el->getData())));
+ return encodeElement(el->to_string());
break;
case Element::OBJECT:
return encodeObject(el->getData(), el->getLength());
@@ -634,6 +638,85 @@
return 0;
}
+/// Encode an array of elements.
+///
+/// @return a binary AMF packet in big endian format (header,data)
+
+/// @return a newly allocated byte array.
+/// to be deleted by caller using delete [] operator, or NULL
+///
+vector<boost::uint8_t> *
+AMF::encodeElement(vector<amf::Element *> &data)
+{
+ GNASH_REPORT_FUNCTION;
+
+ int size = 0;
+ bool pad = false;
+
+ // Calculate how large the buffer has to be.
+ vector<amf::Element *>::iterator ait;
+ cerr << "# of Elements in file: " << data.size() << endl;
+ for (ait = data.begin(); ait != data.end(); ait++) {
+ amf::Element *el = (*(ait));
+ size += el->getLength() + AMF_HEADER_SIZE;
+// el->dump();
+ }
+ vector<boost::uint8_t> *vec = new vector<boost::uint8_t>;
+ boost::uint8_t* ptr = new boost::uint8_t[size + 1];
+ memset(ptr, 0, size + 1);
+
+ boost::uint8_t *x = ptr;
+ size = 0;
+ for (ait = data.begin(); ait != data.end(); ait++) {
+ amf::Element *el = (*(ait));
+// el->dump();
+ boost::uint8_t *tmp = encodeElement(el);
+ boost::uint8_t *y = tmp;
+#if 0
+ boost::uint8_t *hexint;
+ hexint = new boost::uint8_t[(el->getLength() + 4) *3];
+ hexify((boost::uint8_t *)hexint, (boost::uint8_t *)tmp,
+ el->getLength() + AMF_HEADER_SIZE, true);
+ log_msg(_("The packet head is: 0x%s"), hexint);
+#endif
+ // The 'pad' in this case is a serious hack. I think it
+ // may be an artifact, but one guess is it's a 16bit word
+ // aligned memory segment due to some ancient heritage in
+ // the other player, so after a 3 byte bool, and two 9 byte
+ // numbers, another byte is needed for padding.
+ // My guess is the pattern of boolean->number->number->methodname
+ // is a function block ID. I need to dp more testing with a
+ // wider variety of sef movies that use LocalConnection to
+ // really tell.
+ if (el->getType() == Element::NUMBER) {
+ size = AMF_NUMBER_SIZE + 1;
+ pad = true;
+ }
+ if (el->getType() == Element::STRING) {
+ if (pad) {
+ vec->push_back('\0');
+ pad = false;
+ }
+ size = el->getLength() + AMF_HEADER_SIZE;
+ }
+ if (el->getType() == Element::FUNCTION) {
+ // _children
+ }
+ if (el->getType() == Element::BOOLEAN) {
+ size = 3;
+ }
+ for (int i=0; i<size; i++) {
+ boost::uint8_t c = *y;
+ y++;
+// printf("0x%x(%c) ", c, (isalpha(c)) ? c : '.');
+ vec->push_back(c);
+ }
+// delete[] tmp;
+ }
+ return vec;
+}
+
+
#if 0
/// \brief \ Each RTMP header consists of the following:
///
@@ -1387,8 +1470,6 @@
boost::uint8_t *tmpptr;
// uint8_t hexint[(bytes*2)+1];
- boost::uint8_t* hexint;
-
short length;
if (in == 0) {
@@ -1401,6 +1482,7 @@
// }
#if 0
+ boost::uint8_t* hexint;
hexint = (boost::uint8_t*) malloc((bytes * 3) + 12);
hexify((boost::uint8_t *)hexint, (boost::uint8_t *)in, bytes, true);
log_msg(_("The packet body is: 0x%s"), hexint);
@@ -1462,7 +1544,7 @@
case Element::XML_OBJECT:
case Element::TYPED_OBJECT:
default:
- log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)type);
+// log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)type);
return 0;
}
Index: libamf/amf.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/amf.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- libamf/amf.h 31 Jan 2008 11:25:57 -0000 1.30
+++ libamf/amf.h 1 Feb 2008 01:42:41 -0000 1.31
@@ -144,97 +144,97 @@
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeString(const char *str);
+ static boost::uint8_t *encodeElement(const char *str);
/// Encode a Boolean object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeBoolean(bool flag);
+ static boost::uint8_t *encodeBoolean(bool flag);
/// Encode an "Undefined" object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeUndefined();
+ static boost::uint8_t *encodeUndefined();
/// Encode a "NULL" object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeNull();
+ static boost::uint8_t *encodeNull();
/// Encode a "Unsupported" object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeUnsupported();
+ static boost::uint8_t *encodeUnsupported();
/// Encode an XML object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeXMLObject(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeXMLObject(boost::uint8_t *data, int size);
/// Encode a Typed Object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeTypedObject(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeTypedObject(boost::uint8_t *data, int size);
/// Encode a Reference to an object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeReference(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeReference(boost::uint8_t *data, int size);
/// Encode a Movie Clip
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeMovieClip(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeMovieClip(boost::uint8_t *data, int size);
/// Encode an ECMA Array
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeECMAArray(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeECMAArray(boost::uint8_t *data, int size);
/// Encode a long string
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeLongString(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeLongString(boost::uint8_t *data, int size);
/// Encode a Record Set
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeRecordSet(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeRecordSet(boost::uint8_t *data, int size);
/// Encode a Date
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeDate(boost::uint8_t *data);
+ static boost::uint8_t *encodeDate(boost::uint8_t *data);
/// Encode a Strict Array
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeStrictArray(boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeStrictArray(boost::uint8_t *data, int size);
/// Encode an object
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeObject(const boost::uint8_t *data, int size);
+ static boost::uint8_t *encodeObject(const boost::uint8_t *data, int size);
/// Encode a 64 bit number
///
/// @return a binary AMF packet in big endian format (header,data)
///
- boost::uint8_t *encodeNumber(double num);
+ static boost::uint8_t *encodeNumber(double num);
/// Encode a element.
///
@@ -243,7 +243,16 @@
/// @return a newly allocated byte array.
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t *encodeElement(amf::Element *el);
+ static boost::uint8_t *encodeElement(amf::Element *el);
+
+ /// Encode an array of elements.
+ ///
+ /// @return a binary AMF packet in big endian format (header,data)
+
+ /// @return a newly allocated byte array.
+ /// to be deleted by caller using delete [] operator, or NULL
+ ///
+ static std::vector<boost::uint8_t> *encodeElement(std::vector<amf::Element
*> &els);
/// Encode a variable.
//
@@ -271,40 +280,40 @@
///
/// @return an amf packet (header,data)
///
- boost::uint8_t* encodeElement(Element::astype_e type, const void *in, int
nbytes);
+ static boost::uint8_t* encodeElement(Element::astype_e type, const void
*in, int nbytes);
/// @return a newly allocated byte array,
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t* encodeVariable(const char *name);
+ static boost::uint8_t* encodeVariable(const char *name);
/// Encode a boolean variable. This is a name followed by a boolean value.
//
/// @return a newly allocated byte array,
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t* encodeVariable(const char *name, bool flag);
+ static boost::uint8_t* encodeVariable(const char *name, bool flag);
/// Encode a variable.
//
/// @return a newly allocated byte array,
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t* encodeVariable(const char *name, double num);
+ static boost::uint8_t* encodeVariable(const char *name, double num);
/// Encode a variable.
//
/// @return a newly allocated byte array,
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t* encodeVariable(std::string &name, std::string &val);
+ static boost::uint8_t* encodeVariable(std::string &name, std::string &val);
/// Encode a variable.
//
/// @return a newly allocated byte array,
/// to be deleted by caller using delete [] operator, or NULL
///
- boost::uint8_t* encodeVariable(const char *name, const char *val);
+ static boost::uint8_t* encodeVariable(const char *name, const char *val);
void *encodeRTMPHeader(int amf_index, amf_headersize_e head_size, int
total_size,
content_types_e type, amfsource_e routing);
@@ -331,6 +340,7 @@
boost::uint8_t *extractElement(amf::Element *el, boost::uint8_t *in);
boost::uint8_t *extractVariable(amf::Element *el, boost::uint8_t *in);
+
#if 0
// FIXME: these should return an Element, and then use to_*() to convert.
char *extractString(const boost::uint8_t* in);
Index: libamf/element.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- libamf/element.cpp 31 Jan 2008 10:27:06 -0000 1.8
+++ libamf/element.cpp 1 Feb 2008 01:42:41 -0000 1.9
@@ -23,6 +23,8 @@
#include <string>
#include <vector>
+#include <cmath>
+#include <climits>
#include "log.h"
#include "amf.h"
@@ -54,7 +56,9 @@
"Unsupported",
"Recordset",
"XMLObject",
- "TypedObject"
+ "TypedObject",
+ "Varible (gnash)",
+ "Function (gnash)"
};
Element::Element()
@@ -72,44 +76,91 @@
if (_data) {
delete [] _data;
}
+ for (size_t i=0; i< _children.size(); i++) {
+ delete _children[i];
+ }
}
Element::Element(boost::uint8_t *indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(indata);
}
Element::Element(double indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(indata);
}
+// Element(vector<double> &indata)
+// {
+// GNASH_REPORT_FUNCTION;
+// init(indata);
+// }
+
Element::Element(const string &indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(indata);
}
Element::Element(const string &name, const string &indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(name, indata);
}
Element::Element(const string &name, bool indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(name, indata);
}
Element::Element(bool indata)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
init(indata);
}
+// Create a function block for AMF
+Element::Element(bool flag, double unknown1, double unknown2,
+ const string &methodname)
+{
+ GNASH_REPORT_FUNCTION;
+ init(flag, unknown1, unknown2, methodname);
+}
+
+Element &
+Element::init(bool flag, double unknown1, double unknown2,
+ const string &methodname)
+{
+ GNASH_REPORT_FUNCTION;
+ _type = Element::FUNCTION;
+ if (methodname.size()) {
+ _name = methodname;
+ }
+
+ // Build up the children for the function block
+ Element *el = new Element(flag);
+ _children.push_back(el);
+
+ el = new Element(unknown1);
+ _children.push_back(el);
+
+ el = new Element(unknown2);
+ _children.push_back(el);
+
+ el = new Element(methodname);
+ _children.push_back(el);
+
+ _length = 3
+ + ((AMF_HEADER_SIZE + AMF_NUMBER_SIZE) * 2)
+ + methodname.size() + AMF_HEADER_SIZE;
+// memcpy(_data, &indata, _length);
+ return *this;
+}
+
Element &
Element::init(double indata)
{
@@ -197,7 +248,8 @@
if (_data) {
return *(reinterpret_cast<double *>(_data));
}
- return nan("NaN");
+// return ::nan("NaN");
+ return -1.0;
}
const char *
@@ -287,6 +339,19 @@
}
Element &
+Element::makeBoolean(bool &data)
+{
+// GNASH_REPORT_FUNCTION;
+
+ _type = Element::BOOLEAN;
+ _length = 1;
+ _data = new boost::uint8_t[2];
+ memset(_data, 0, 2);
+ _data[1]= data;
+ return *this;
+}
+
+Element &
Element::makeBoolean(boost::uint8_t *data)
{
// GNASH_REPORT_FUNCTION;
@@ -488,17 +553,19 @@
// GNASH_REPORT_FUNCTION;
if (_name.size()) {
- cerr << "Dumping AMF Varible: " << _name << endl;
+ cerr << "AMF object name: " << _name << endl;
}
cerr << astype_str[_type] << ": ";
switch (_type) {
+ case Element::NOTYPE:
+ break;
case Element::NUMBER:
- cerr << "AMF Numeric value: " << to_number() << endl;
+ cerr << to_number() << endl;
break;
case Element::BOOLEAN:
- cerr << "AMF Boolean value: " << (to_bool() ? "true" : "false") <<
endl;
+ cerr << (to_bool() ? "true" : "false") << endl;
break;
case Element::STRING:
cerr << "(" << _length << " bytes): ";
@@ -528,10 +595,17 @@
hexify((boost::uint8_t *)hexint, _data, _length, false);
cerr << "AMF data is: 0x%s" << hexint << endl;
break;
+ case Element::VARIABLE:
+ case Element::FUNCTION:
+ cerr << "# of children in object: " << _children.size() << endl;
+ for (size_t i=0; i< _children.size(); i++) {
+ _children[i]->dump();
+ }
+ break;
default:
- log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)_type);
+// log_unimpl("%s: type %d", __PRETTY_FUNCTION__, (int)_type);
+ break;
}
-
}
} // end of amf namespace
Index: libamf/element.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/element.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- libamf/element.h 25 Jan 2008 18:08:00 -0000 1.7
+++ libamf/element.h 1 Feb 2008 01:42:41 -0000 1.8
@@ -56,29 +56,38 @@
RECORD_SET=0x0e,
XML_OBJECT=0x0f,
TYPED_OBJECT=0x10,
- VARIABLE=0x11 // this isn't part of the AMF spec, it's used
internally
+ // these aren't part of the AMF spec, they're used internally
+ VARIABLE=0x11,
+ FUNCTION=0x12
} astype_e;
Element();
Element(boost::uint8_t *data);
Element(double data);
+ Element(std::vector<double> &data);
Element(const std::string &data);
Element(const std::string &name, const std::string &data);
Element(bool data);
Element(const std::string &name, bool data);
+ // Create a function block for AMF
+ Element(bool, double, double, const std::string &str);
~Element();
void clear();
boost::uint8_t *init(boost::uint8_t *data);
Element &init(const std::string &name, double data);
Element &init(double data);
+ Element &init(std::vector<double> &data);
Element &init(const std::string &name, const std::string &data);
Element &init(const std::string &data);
Element &init(const std::string &name, bool data);
Element &init(bool data);
+ // Create a function block for AMF
+ Element &init(bool, double, double, const std::string &str);
// These create the other "special" AMF types.
Element &makeString(boost::uint8_t *data, int size);
Element &makeNumber(boost::uint8_t *data);
Element &makeBoolean(boost::uint8_t *data);
+ Element &makeBoolean(bool &data);
Element &makeUndefined();
Element &makeUndefined(const std::string &name);
Element &makeNull();
@@ -126,6 +135,7 @@
boost::int16_t _length;
std::string _name;
boost::uint8_t *_data;
+ std::vector<Element *> _children;
}; // end of class definition
Index: libamf/lcshm.cpp
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libamf/lcshm.cpp 25 Jan 2008 18:48:29 -0000 1.6
+++ libamf/lcshm.cpp 1 Feb 2008 01:42:41 -0000 1.7
@@ -45,6 +45,9 @@
namespace gnash {
// The maximum
+// although a bool is one byte, it appears to be a short in AMF,
+// plus the type byte.
+const int AMF_BOOLEAN_SIZE = 3;
const int LC_HEADER_SIZE = 16;
const int MAX_LC_HEADER_SIZE = 40960;
const int LC_LISTENERS_START = MAX_LC_HEADER_SIZE + LC_HEADER_SIZE;
@@ -109,7 +112,7 @@
// see if a connection name exists in our list of listeners
bool
-Listener::findListener(std::string &name)
+Listener::findListener(const string &name)
{
// GNASH_REPORT_FUNCTION;
@@ -127,7 +130,7 @@
}
bool
-Listener::addListener(std::string &name)
+Listener::addListener(const string &name)
{
GNASH_REPORT_FUNCTION;
@@ -156,7 +159,7 @@
return false;
}
item += 4;
- const char *x2 = "::4";
+ const char *x2 = "::2";
if (!memcpy(item, x2, 4)) {
return false;
}
@@ -164,28 +167,36 @@
return true;
}
+// I don't believe this function is support by other swf players,
+// but we do, as it's nice to remove oneself from the listeners
+// list so nobody knows we were here listening.
bool
-Listener::removeListener(std::string &name)
+Listener::removeListener(const string &name)
{
GNASH_REPORT_FUNCTION;
boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
+ int len;
char *item = reinterpret_cast<char *>(addr);
while (*item != 0) {
if (name == item) {
- int len = strlen(item) + 1;
while (*item != 0) {
+ len = strlen(item) + 8 + 1;
strcpy(item, item + len);
- item += len + 1;
+ item += len + strlen(item + len);
}
+
+ memset(item - len, 0, len);
return true;
}
item += strlen(item) + 1;
}
+
return false;
}
+// Get a list of alll the listeners waiting on this channel
auto_ptr< vector<string> >
Listener::listListeners()
{
@@ -251,7 +262,9 @@
continue;
}
}
+ if (el->getType() != Element::NOTYPE) {
addObject(el);
+ }
};
return _amfobjs;
@@ -291,12 +304,19 @@
Element *el = new amf::Element;
AMF amf;
ptr = amf.extractElement(el, ptr);
+ if (ptr == 0) {
+ log_error("Didn't extract element from byte stream!");
+ return 0;
+ }
+
_object.connection_name = el->to_string();
delete el;
el = new amf::Element;
ptr = amf.extractElement(el, ptr);
+ if (ptr != 0) {
_object.hostname = el->to_string();
+ }
delete el;
// el = new amf::Element;
@@ -326,10 +346,35 @@
}
boost::uint8_t *
-LcShm::formatHeader(boost::uint8_t * /*data*/)
+LcShm::formatHeader(const std::string &con, const std::string &host, bool
domain)
{
-// GNASH_REPORT_FUNCTION;
- return NULL;
+ GNASH_REPORT_FUNCTION;
+// boost::uint8_t *ptr = data + LC_HEADER_SIZE;
+ int size = con.size() + host.size() + 9;
+
+ boost::uint8_t *header = new boost::uint8_t[size + 1];
+ boost::uint8_t *ptr = header;
+
+ // This is the initial 16 bytes of the header
+ memset(ptr, 0, size + 1);
+ *ptr = 1;
+ ptr += 3;
+ *ptr = 1;
+ ptr = header + LC_HEADER_SIZE;
+
+ // Which is then always followed by 3 AMF objects.
+ boost::uint8_t *tmp = AMF::encodeElement(con.c_str());
+ memcpy(ptr, tmp, con.size());
+ ptr += con.size();
+ delete[] tmp;
+
+ tmp = AMF::encodeElement(host.c_str());
+ memcpy(ptr, tmp, host.size());
+ ptr += host.size();
+
+ delete[] ptr;
+
+// return ptr;
}
/// \brief Prepares the LcShm object to receive commands from a
@@ -339,12 +384,16 @@
/// send() command to signify which local connection to send the
/// object to.
bool
-LcShm::connect(string &name)
+LcShm::connect(const string &name)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
_name = name;
+ // the name here is optional, Gnash will pick a good default.
+ // When using sysv shared memory segments in compatibility mode,
+ // the name is ignored, and the SHMkey is specified in the user's
+ // ~/.gnashrc file.
if (Shm::attach(name.c_str(), true) == false) {
return false;
}
@@ -355,8 +404,13 @@
}
Listener::setBaseAddress(reinterpret_cast<uint8_t *>(Shm::getAddr()));
+ _baseaddr = reinterpret_cast<uint8_t *>(Shm::getAddr());
boost::uint8_t *ptr = parseHeader(Listener::getBaseAddress());
- vector<amf::Element *> ellist = parseBody(ptr);
+// vector<amf::Element *> ellist = parseBody(ptr);
+// log_debug("Base address is: 0x%x, 0x%x",
+// (unsigned int)Listener::getBaseAddress(), (unsigned
int)_baseaddr);
+
+ addListener(name);
return true;
}
@@ -364,7 +418,7 @@
bool
LcShm::connect(key_t key)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
if (Shm::attach(key, true) == false) {
return false;
@@ -376,18 +430,92 @@
}
Listener::setBaseAddress(reinterpret_cast<uint8_t *>(Shm::getAddr()));
+ _baseaddr = reinterpret_cast<uint8_t *>(Shm::getAddr());
boost::uint8_t *ptr = parseHeader(Listener::getBaseAddress());
- vector<amf::Element *> ellist = parseBody(ptr);
+// vector<amf::Element *> ellist = parseBody(ptr);
+// log_debug("Base address is: 0x%x, 0x%x",
+// (unsigned int)Listener::getBaseAddress(), (unsigned
int)_baseaddr);
return true;
}
/// \brief Invokes a method on a specified LcShm object.
void
-LcShm::send(const std::string & /*name*/, const std::string & /*dataname*/,
amf::Element * /*data*/)
+LcShm::send(const string &name, const string &domainname,
+ vector<amf::Element *> &data)
{
+ GNASH_REPORT_FUNCTION;
+
+// log_debug("Base address is: 0x%x, 0x%x",
+// (unsigned int)Listener::getBaseAddress(), (unsigned
int)_baseaddr);
+
+// formatHeader(name, domainname, _object.domain);
+
+ // Update the connection name
+ boost::uint8_t *ptr = Listener::getBaseAddress();
+ if (ptr == reinterpret_cast<boost::uint8_t *>(0)) {
+ log_error("base address not set!");
+ }
+
+// boost::uint8_t *tmp = AMF::encodeElement(name.c_str());
+// memcpy(ptr, tmp, name.size());
+// ptr += name.size() + AMF_HEADER_SIZE;
+// delete[] tmp;
+
+// tmp = AMF::encodeElement(domainname.c_str());
+// memcpy(ptr, tmp, domainname.size());
+// ptr += domainname.size() + AMF_HEADER_SIZE;
+
+// ptr += LC_HEADER_SIZE;
+ boost::uint8_t *x = ptr; // just for debugging from gdb. temporary
+
+ // This is the initial 16 bytes of the header
+ memset(ptr, 0, LC_HEADER_SIZE + 200);
+ *ptr = 1;
+ ptr += 4;
+ *ptr = 1;
+ ptr += LC_HEADER_SIZE - 4;
+
+ // Which is then always followed by 3 AMF objects.
+
+ boost::uint8_t *tmp = AMF::encodeElement(name.c_str());
+ memcpy(ptr, tmp, name.size() + AMF_HEADER_SIZE);
+ delete[] tmp;
+
+ ptr += name.size() + AMF_HEADER_SIZE;
+
+ // Update the host on the other end of the connection.
+ tmp = AMF::encodeElement(domainname.c_str());
+ memcpy(ptr, tmp, domainname.size() + AMF_HEADER_SIZE );
+ delete[] tmp;
+
+ ptr += domainname.size() + AMF_HEADER_SIZE;
+
+// // Set the domain flag to whatever it's current value is.
+// // Element domain(_object.domain);
+// tmp = AMF::encodeBoolean(_object.domain);
+// memcpy(ptr, tmp, AMF_BOOLEAN_SIZE);
+// // delete[] tmp;
+
+// ptr += AMF_BOOLEAN_SIZE;
+
+ vector<boost::uint8_t> *vec = AMF::encodeElement(data);
+ vector<boost::uint8_t>::iterator vit;
+ // Can't do a memcpy with a std::vector
+// log_debug("Number of bytes in the vector: %x", vec->size());
+ for (vit = vec->begin(); vit != vec->end(); vit++) {
+ *ptr = *vit;
+#if 0 // debugging crapola
+ if (isalpha(*ptr))
+ printf("%c ", *ptr);
+ else
+ printf("0x%x ", *ptr);
+#endif
+ ptr++;
+ }
+
+// delete[] tmp;
- log_unimpl (__FUNCTION__);
}
void
@@ -402,7 +530,7 @@
cerr << "Hostname Name:\t\t" << _object.hostname << endl;
cerr << "Domain Allowed:\t\t" << ((_object.domain) ? "true" : "false") <<
endl;
vector<amf::Element *>::iterator ait;
-// cerr << "# of Elements in file: " << _amfobjs.size() << endl;
+ cerr << "# of Elements in file: " << _amfobjs.size() << endl;
for (ait = _amfobjs.begin(); ait != _amfobjs.end(); ait++) {
amf::Element *el = (*(ait));
el->dump();
@@ -410,11 +538,11 @@
vector<string>::const_iterator lit;
auto_ptr< vector<string> > listeners ( listListeners() );
+ cerr << "# of Listeners in file: " << listeners->size() << endl;
for (lit=listeners->begin(); lit!=listeners->end(); lit++) {
string str = *lit;
if (str[0] != ':') {
cerr << "Listeners:\t" << str << endl;
-// total++;
}
}
}
Index: libamf/lcshm.h
===================================================================
RCS file: /sources/gnash/gnash/libamf/lcshm.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- libamf/lcshm.h 25 Jan 2008 18:48:29 -0000 1.6
+++ libamf/lcshm.h 1 Feb 2008 01:42:41 -0000 1.7
@@ -33,16 +33,16 @@
namespace gnash {
// Manipulate the list of LocalConnection Listeners. We've made this a separate
-// class from LocalConnection as it's used standalone for the dumpshm utility
to
-// dump the Listener lists.
+// class from LocalConnection as it's used standalone for the
+// dumpshm utility to dump the Listener lists.
class Listener {
public:
Listener();
Listener(boost::uint8_t *baseaddr);
~Listener();
- bool addListener(std::string &name);
- bool findListener(std::string &name);
- bool removeListener(std::string &name);
+ bool addListener(const std::string &name);
+ bool findListener(const std::string &name);
+ bool removeListener(const std::string &name);
std::auto_ptr< std::vector<std::string> > listListeners();
void setBaseAddress(boost::uint8_t *addr) { _baseaddr = addr; };
boost::uint8_t *getBaseAddress() { return _baseaddr; };
@@ -57,7 +57,8 @@
typedef struct {
uint32_t unknown1;
uint32_t unknown2;
- uint32_t timestamp; // number of milliseconds that have elapsed since
the system was started
+ uint32_t timestamp; // number of milliseconds that have
+ // elapsed since the system was started
uint32_t length;
} lc_header_t;
typedef struct {
@@ -77,14 +78,17 @@
LcShm(boost::uint8_t *baseaddr);
LcShm(key_t key);
~LcShm();
- bool connect(std::string &name);
+ bool connect(const std::string &name);
bool connect(key_t key);
void close(void);
- void send(const std::string &name, const std::string &dataname,
amf::Element *data);
+ void send(const std::string &name, const std::string &dataname,
+ std::vector<amf::Element *> &data);
void recv(std::string &name, std::string &dataname, amf::Element *data);
std::vector<amf::Element *> parseBody(boost::uint8_t *data);
boost::uint8_t *parseHeader(boost::uint8_t *data);
- boost::uint8_t *formatHeader(boost::uint8_t *data);
+ boost::uint8_t *formatHeader(const std::string &con, const std::string
&host, bool domain);
+ void addConnectionName(std::string &name);
+ void addHostname(std::string &name);
void addObject(amf::Element *el) { _amfobjs.push_back(el); };
size_t size() { return _amfobjs.size(); };
std::vector<amf::Element *> getElements() { return _amfobjs; };