gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog libamf/lcshm.h libamf/lcshm.cpp


From: Rob Savoye
Subject: [Gnash-commit] gnash ChangeLog libamf/lcshm.h libamf/lcshm.cpp
Date: Sun, 30 Dec 2007 16:18:05 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    07/12/30 16:18:05

Modified files:
        .              : ChangeLog 
Added files:
        libamf         : lcshm.h lcshm.cpp 

Log message:
                * libamf/lcshm.{cpp,h}: New LcShm class for manipulating AMF
                objects as used within LocalConnection shared memory segments.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libamf/lcshm.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5275&r2=1.5276

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5275
retrieving revision 1.5276
diff -u -b -r1.5275 -r1.5276
--- ChangeLog   30 Dec 2007 11:03:49 -0000      1.5275
+++ ChangeLog   30 Dec 2007 16:18:05 -0000      1.5276
@@ -1,3 +1,8 @@
+2007-12-30  Rob Savoye  <address@hidden>
+
+       * libamf/lcshm.{cpp,h}: New LcShm class for manipulating AMF
+       objects as used within LocalConnection shared memory segments.
+
 2007-12-30 Sandro Santilli <address@hidden>
 
        * configure.ac,
@@ -20,6 +25,12 @@
 
 2007-12-29  Rob Savoye  <address@hidden>
 
+       * utilities/dumpshm.cpp: Add support to search through all sysv
+       style shared memory segments and look for the LocalConnection
+       one so the user doesn't have to know anything to find it.
+       * configure.ac: Add test for the key field of ipc_perm data
+       structure used by shmctl() to get the key.
+
        * testsuite/misc-swfc.all/Makefile.am: Add TEST_CASES to
        CLEANFILES.
 
@@ -34,7 +45,7 @@
          by ref rather then by pointer.
        * server/parser/action_buffer.{cpp,h}: add a movie_definition
          reference in code segments, and provide a getDefinitionURL()
-         method to retrive the originatin url.
+         method to retrive the originating url.
        * server/parser/button_character_def.{cpp,h}, 
          server/swf/DoActionTag.h, server/swf/DoInitActionTag.h,
          server/swf/PlaceObject2Tag.{h,cpp}:

Index: libamf/lcshm.h
===================================================================
RCS file: libamf/lcshm.h
diff -N libamf/lcshm.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libamf/lcshm.h      30 Dec 2007 16:18:04 -0000      1.1
@@ -0,0 +1,101 @@
+// 
+//   Copyright (C) 2005, 2006, 2007 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
+
+#ifndef __LCSHM_H__
+#define __LCSHM_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/cstdint.hpp>
+#include <string>
+#include <vector>
+
+#include "amf.h"
+#include "shm.h"
+
+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 Listener {
+public:
+    Listener();
+    Listener(boost::uint8_t *baseaddr);
+    ~Listener();
+    bool addListener(std::string &name);
+    bool findListener(std::string &name);
+    bool removeListener(std::string &name);
+    std::vector<std::string> *listListeners();
+    void setBaseAddress(boost::uint8_t *addr) { _baseaddr = addr; };
+protected:
+    std::string _name;
+    boost::uint8_t *_baseaddr;
+};
+
+class LcShm : public Listener, public Shm {
+public:
+    typedef struct {
+        uint32_t unknown1;
+        uint32_t unknown2;
+        uint32_t timestamp; // number of milliseconds that have elapsed since 
the system was started
+        uint32_t length;
+    } lc_header_t;
+    typedef struct {
+        std::string connection_name;
+        std::string protocol;
+        std::string method_name;
+        std::vector<amf::AMF::amf_element_t> data; // this can be any AMF data 
type
+    } lc_message_t;
+    typedef struct {
+       std::string connection_name;
+       std::string hostname;
+        bool domain;
+        double unknown_num1;
+        double unknown_num2;
+    } lc_object_t;
+    LcShm();
+    ~LcShm();
+    bool connect(std::string &name);
+    void close(void);
+    void send(std::string &name, std::string &dataname, 
amf::AMF::amf_element_t data);
+    void recv(std::string &name, std::string &dataname, 
amf::AMF::amf_element_t *data);
+    std::vector<amf::AMF::amf_element_t> parseBody(boost::uint8_t *data);
+    boost::uint8_t *parseHeader(boost::uint8_t *data);
+    boost::uint8_t *formatHeader(boost::uint8_t *data);
+    bool addObject(amf::AMF::amf_element_t &el);
+    size_t size() { return _amfobjs.size(); };
+    std::vector<amf::AMF::amf_element_t> getElements() { return _amfobjs; };
+private:
+    uint8_t *_baseaddr;
+    lc_header_t _header;
+    lc_object_t _object;
+    std::vector<amf::AMF::amf_element_t> _amfobjs;
+};
+
+} // end of gnash namespace
+
+// __LCSHM_H__
+#endif
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
+

Index: libamf/lcshm.cpp
===================================================================
RCS file: libamf/lcshm.cpp
diff -N libamf/lcshm.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libamf/lcshm.cpp    30 Dec 2007 16:18:04 -0000      1.1
@@ -0,0 +1,338 @@
+//
+//   Copyright (C) 2005, 2006, 2007 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 "config.h"
+#endif
+
+#include <unistd.h>
+#include <cerrno>
+#include <cstring>
+#include <boost/cstdint.hpp>
+
+#include "log.h"
+#include "amf.h"
+#include "lcshm.h"
+
+using namespace std;
+using namespace amf;
+
+// Some facts:
+//     * The header is 16 bytes,
+//     * The message can be up to 40k,
+//     * The listeners block starts at 40k+16 = 40976 bytes,
+//     * To add a listener, simply append its name in the listeners list (null 
terminated strings)
+
+namespace gnash {
+
+// The maximum 
+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;
+
+// This doesn't exist on all systems, but here's the vaue used on Unix.
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 64
+#endif
+
+// \class LocalConnection
+/// \brief Open a connection between two SWF movies so they can send
+/// each other Flash Objects to be executed.
+///
+LcShm::LcShm()
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+LcShm::~LcShm()
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+Listener::Listener()
+    : _baseaddr(0)
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+Listener::Listener(boost::uint8_t *x)
+{
+    GNASH_REPORT_FUNCTION;
+    _baseaddr = x;
+}
+
+Listener::~Listener()
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+// see if a connection name exists in our list of listeners
+bool
+Listener::findListener(std::string &name)
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
+    char *item = reinterpret_cast<char *>(addr);
+    // Walk through the list to the end
+    while (*item != 0) {
+        if (name == item) {
+            return true;
+        }
+        item += strlen(item)+1;
+    }
+    
+    return false;
+}
+
+bool
+Listener::addListener(std::string &name)
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
+    char *item = reinterpret_cast<char *>(addr);
+    // Walk to the end of the list
+    while ((item[0] != 0) && (item[1] != 0)) {
+        item += strlen(item)+1;
+    }
+
+    if (findListener(name)) {
+        return true;
+    }
+    
+    // Add ourselves to the list
+    if (memcpy(item, name.c_str(), name.size()) == 0) {
+        return false;
+    }
+
+    // Add the two mystery two strings or number that follows the name.
+    // These vary somewhat, but as test cases produces these values, we'll
+    // use them till we're sure what these actually represent.
+    item += name.size() + 1;
+    const char *x1 = "::3";
+    if (!memcpy(item, x1, 4)) {
+        return false;
+    }
+    item += 4;
+    const char *x2 = "::4";
+    if (!memcpy(item, x2, 4)) {
+        return false;
+    }
+    
+    return true;
+}
+
+bool
+Listener::removeListener(std::string &name)
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
+
+    char *item = reinterpret_cast<char *>(addr);
+    while (*item != 0) {
+        if (name == item) {
+            int len = strlen(item) + 1;
+            while (*item != 0) {
+                strcpy(item, item + len);
+                item += len + 1;
+            }
+            return true;
+        }
+        item += strlen(item) + 1;
+    }
+    return false;
+}
+
+std::vector<std::string> *
+Listener::listListeners()
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *addr = _baseaddr + LC_LISTENERS_START;
+
+    vector<string> *listeners = new vector<string>;
+    const char *item = reinterpret_cast<const char *>(addr);
+    while (*item != 0) {
+        listeners->push_back(item);
+        item += strlen(item) + 1;
+    }    
+
+    return listeners;
+}
+
+/// \brief Closes (disconnects) the LcShm object.
+void
+LcShm::close()
+{
+    GNASH_REPORT_FUNCTION;
+    closeMem();
+}
+
+boost::uint8_t *
+LcShm::parseElement(amf::AMF::amf_element_t *el, boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+    boost::uint8_t *ptr = reinterpret_cast<uint8_t *>(data);
+    AMF::astype_e type = (AMF::astype_e)*ptr;
+    switch (type) {
+      case AMF::NUMBER:
+          double dub = 50.0;
+          amf_obj.createElement(&el, "gain", dub);
+          break;
+      case AMF::STRING:
+          amf_obj.createElement(&el, name, data);
+          break;
+      default:
+          break;
+    };
+}
+
+
+vector<AMF::amf_element_t> 
+LcShm::parseBody(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+
+    boost::uint8_t *ptr = reinterpret_cast<uint8_t *>(data);
+    AMF::astype_e type = (AMF::astype_e)*ptr;
+//    log_msg(_("Type is %s"), astype_str[type]);
+    AMF::amf_element_t el;
+    AMF amf;
+
+#if 0
+    while ((*(ptr) != 0) || (*(ptr) != 0) || (*(ptr) != 0)) {
+        switch (type) {
+          case AMF::NUMBER:
+              double dub = 50.0;
+              amf_obj.createElement(&el, "gain", dub);
+              break;
+          case AMF::STRING:
+              amf_obj.createElement(&el, name, data);
+              break;
+          default:
+              break;
+        };
+        
+        addObject(el);
+//        ptr = amf.readElement(ptr);
+        printf("FIXME:");
+    };
+#endif
+    
+    return _amfobjs;
+}
+
+// From what I can tell by exaimining the memory segment, after the
+// raw 16 bytes is a LocalConnection object. This appears to have the
+// following data types:
+// String - This appears to the connection name, and looks like
+//          "localhost:lc_replay"
+// String - This appears to be the hostname of the connection, and at
+//          least in my tests, has always been "localhost".
+// Boolean - In all the files I've looked at, this has always been
+//           TRUE. I assume this is the domain security flag.
+// Number - No idea what this number represents.
+// Number - No idea what this number represents.
+// NULL terminator
+// AMF objects - this is followed by the AMF objects that have been
+// added to the LocalConnection. This can be up to 40k long. While
+// other web sites have claimed there is a length field in the initial
+// shared memory segment header, I've never seen one in my tests.
+boost::uint8_t *
+LcShm::parseHeader(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+    boost::uint8_t *ptr = data;
+    
+    memcpy(&_header, ptr, LC_HEADER_SIZE);
+//     memcpy(&_object, data + LC_HEADER_SIZE, _header.length);
+    log_debug("Timestamp: %ud", _header.timestamp);
+    log_debug("Length: %ud", _header.length);
+//     log_debug("Connection: %s", _object.connection_name);
+//     log_debug("name: %s", _object.hostname);
+    ptr += LC_HEADER_SIZE;
+    AMF amf;
+    _object.connection_name = amf.extractString(ptr);
+    ptr += _object.connection_name.size() + 3;
+    _object.hostname = amf.extractString(ptr);
+    ptr += _object.hostname.size() + 3;
+    _object.domain = ptr + 2;
+    ptr += 3;
+    _object.unknown_num1 = amf.extractNumber(ptr);
+    ptr += AMF_NUMBER_SIZE + 1;
+    _object.unknown_num1 = amf.extractNumber(ptr);
+    ptr += AMF_NUMBER_SIZE + 2;
+
+//    memcpy(&_object, data + LC_HEADER_SIZE, _header.length);
+    log_debug("Connection: %s", _object.connection_name.c_str());
+    log_debug("name: %s", _object.hostname.c_str());
+
+    return ptr;
+}
+
+boost::uint8_t *
+LcShm::formatHeader(boost::uint8_t *data)
+{
+    GNASH_REPORT_FUNCTION;
+}
+
+/// \brief Prepares the LcShm object to receive commands from a
+/// LcShm.send() command.
+/// 
+/// The name is a symbolic name like "lc_name", that is used by the
+/// send() command to signify which local connection to send the
+/// object to.
+bool
+LcShm::connect(string &name)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    _name = name;
+    
+    if (Shm::attach(name.c_str(), true) == false) {
+        return false;
+    }
+
+    if (Shm::getAddr() <= 0) {
+        log_error("Failed to open shared memory segment: \"%s\"", 
name.c_str());
+        return false; 
+    }
+    
+    Listener::setBaseAddress(reinterpret_cast<uint8_t *>(Shm::getAddr()));
+    
+    return true;
+}
+
+bool
+LcShm::addObject(AMF::amf_element_t &el)
+{
+    GNASH_REPORT_FUNCTION;
+    
+}
+
+/// \brief Invokes a method on a specified LcShm object.
+void
+LcShm::send(std::string &name, std::string &dataname, amf::AMF::amf_element_t 
data)
+{
+    
+    log_unimpl (__FUNCTION__);
+}
+
+} // end of gnash namespace




reply via email to

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