You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/11/28 18:49:31 UTC

svn commit: r480141 [11/38] - in /harmony/enhanced/jdktools/trunk/modules/jpda: ./ doc/ doc/images/ make/ src/ src/common/ src/common/other/ src/common/other/jpda/ src/common/other/jpda/jdwp/ src/common/other/jpda/jdwp/agent/ src/common/other/jpda/jdwp...

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.cpp?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.cpp Tue Nov 28 09:49:08 2006
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Pavel N. Vyssotski
+ * @version $Revision: 1.7 $
+ */
+// OptionParser.cpp
+
+#include <cstring>
+
+#include "AgentBase.h"
+#include "MemoryManager.h"
+#include "AgentException.h"
+#include "Log.h"
+
+#include "OptionParser.h"
+
+using namespace jdwp;
+using namespace std;
+
+OptionParser::OptionParser() throw()
+{
+    m_optionCount = 0;
+    m_optionString = 0;
+    m_options = 0;
+    m_help = false;
+    m_suspend = true;
+    m_server = false;
+    m_timeout = 0;
+    m_transport = 0;
+    m_address = 0;
+    m_log = 0;
+    m_kindFilter = 0;
+    m_srcFilter = 0;
+}
+
+bool OptionParser::AsciiToBool(const char *str) throw(IllegalArgumentException)
+{
+    if (strcmp("y", str) == 0) {
+        return true;
+    } else if (strcmp("n", str) == 0) {
+        return false;
+    } else {
+        throw IllegalArgumentException();
+    }
+}
+
+void OptionParser::Parse(const char* str) throw(AgentException)
+{
+    size_t i;
+    int k;
+
+    if (str == 0)
+        return;
+
+    const size_t len = strlen(str);
+    if (len == 0)
+        return;
+
+    for (i = 0; i < len; i++) {
+        if (str[i] == ',') {
+            m_optionCount++;
+        } else if (str[i] == '"') {
+            if (i > 0 && str[i-1] != '=') {
+                throw IllegalArgumentException();
+            }
+            i++;
+            while (i < len && str[i] != '"') {
+                i++;
+            }
+            if (i+1 < len && str[i+1] != ',') {
+                throw IllegalArgumentException();
+            }
+        }
+    }
+    m_optionCount++;
+
+    m_optionString = reinterpret_cast<char*>(AgentBase::GetMemoryManager().
+        Allocate(len + 1 JDWP_FILE_LINE));
+    strcpy(m_optionString, str);
+
+    m_options = reinterpret_cast<Option*>(AgentBase::GetMemoryManager().
+        Allocate(m_optionCount * sizeof(Option) JDWP_FILE_LINE));
+
+    m_options[0].name = m_optionString;
+    m_options[0].value = "";
+    k = 0;
+    for (i = 0; i < len && k < m_optionCount; i++) {
+        if (m_optionString[i] == '=') {
+            m_optionString[i] = '\0';
+            m_options[k].value = &m_optionString[i+1];
+        } else if (m_optionString[i] == ',') {
+            m_optionString[i] = '\0';
+            k++;
+            m_options[k].name = &m_optionString[i+1];
+            m_options[k].value = "";
+        } else if (m_optionString[i] == '"') {
+            m_optionString[i] = '\0';
+            m_options[k].value = &m_optionString[i+1];
+            i++;
+            while (i < len && m_optionString[i] != '"') {
+                i++;
+            }
+            if (i < len) {
+                m_optionString[i] = '\0';
+            }
+        }
+    }
+
+    for (k = 0; k < m_optionCount; k++) {
+        if (strcmp("transport", m_options[k].name) == 0) {
+            m_transport = m_options[k].value;
+        } else if (strcmp("address", m_options[k].name) == 0) {
+            m_address = m_options[k].value;
+        } else if (strcmp("timeout", m_options[k].name) == 0) {
+            m_timeout = atol(m_options[k].value);
+        } else if (strcmp("suspend", m_options[k].name) == 0) {
+            m_suspend = AsciiToBool(m_options[k].value);
+        } else if (strcmp("server", m_options[k].name) == 0) {
+            m_server = AsciiToBool(m_options[k].value);
+        } else if (strcmp("help", m_options[k].name) == 0) {
+            m_help = true;
+#ifndef NDEBUG
+        } else if (strcmp("log", m_options[k].name) == 0) {
+            m_log = m_options[k].value;
+        } else if (strcmp("trace", m_options[k].name) == 0) {
+            m_kindFilter = m_options[k].value;
+        } else if (strcmp("src", m_options[k].name) == 0) {
+            m_srcFilter = m_options[k].value;
+#endif // NDEBUG
+        }
+    }
+}
+
+OptionParser::~OptionParser() throw()
+{
+    if (m_optionString != 0)
+        AgentBase::GetMemoryManager().Free(m_optionString JDWP_FILE_LINE);
+    if (m_options != 0)
+        AgentBase::GetMemoryManager().Free(m_options JDWP_FILE_LINE);
+}
+
+const char *OptionParser::FindOptionValue(const char *name) const throw()
+{
+    for (int i = 0; i < m_optionCount; i++) {
+        if (strcmp(name, m_options[i].name) == 0) {
+            return m_options[i].value;
+        }
+    }
+    return 0;
+}

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.h?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.h (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.h Tue Nov 28 09:49:08 2006
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, 
+ * as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Pavel N. Vyssotski
+ * @version $Revision: 1.8.2.1 $
+ */
+
+/**
+ * @file
+ * OptionParser.h
+ *
+ * Provides access to startup options and actual capabilities of the agent.
+ * Parses command-line options of the agent.
+ */
+
+#ifndef _OPTION_PARSER_H_
+#define _OPTION_PARSER_H_
+
+#include "AgentBase.h"
+
+namespace jdwp {
+
+    /**
+     * The class provides certain means for parsing and manipulating agent options
+     * that are passed to the command line of the target VM.
+     */
+    class OptionParser : public AgentBase {
+
+    public:
+
+        /**
+         * A constructor.
+         */
+        OptionParser() throw();
+
+        /**
+         * A destructor.
+         */
+        ~OptionParser() throw();
+
+        /**
+         * Parses the input string containing the arguments passed to the agent.
+         *
+         * @param str - the string containing agent arguments
+         */
+        void Parse(const char* str) throw(AgentException);
+
+        /**
+         * Returns a number of parsed options.
+         */
+        int GetOptionCount() const throw() {
+            return m_optionCount;
+        }
+
+        /**
+         * Gets an option name and value by the index.
+         *
+         * @param i     - the option index 
+         * @param name  - the option name
+         * @param value - the option value
+         */
+        void GetOptionByIndex(int i, const char *&name, const char *&value)
+                const throw(InvalidIndexException) {
+            if (i < m_optionCount) {
+                name = m_options[i].name;
+                value = m_options[i].value;
+            } else {
+                throw InvalidIndexException();
+            }
+        }
+
+        /**
+         * Looks for an option with the given name.
+         *
+         * @param name - the option name
+         */
+        const char *FindOptionValue(const char *name) const throw();
+
+        /**
+         * Returns a value for the agent's <code>help</code> option.
+         *
+         * @return Boolean.
+         */
+        bool GetHelp() const throw() {
+            return m_help;
+        }
+
+        /**
+         * Returns a value for the agent's <code>suspend</code> option.
+         *
+         * @return Boolean.
+         */
+        bool GetSuspend() const throw() {
+            return m_suspend;
+        }
+
+        /**
+         * Returns a value for the agent's <code>server</code> option.
+         *
+         * @return Boolean.
+         */
+        bool GetServer() const throw() {
+            return m_server;
+        }
+
+        /**
+         * Returns a time-out value for transport operations.
+         *
+         * @return Java long value.
+         */
+        jlong GetTimeout() const throw() {
+            return m_timeout;
+        }
+
+        /**
+         * Returns the name of the JDWP transport.
+         *
+         * @return Zero-terminated string.
+         */
+        const char *GetTransport() const throw() {
+            return m_transport;
+        }
+
+        /**
+         * Returns the address for the socket transport to connect to.
+         *
+         * @return Zero-terminated string.
+         */
+        const char *GetAddress() const throw() {
+            return m_address;
+        }
+
+        /**
+         * Returns the name for log file.
+         *
+         * @return Zero-terminated string.
+         */
+        const char *GetLog() const throw() {
+            return m_log;
+        }
+
+        /**
+         * Returns the log kind filter.
+         *
+         * @return Zero-terminated string.
+         */
+        const char *GetTraceKindFilter() const throw() {
+            return m_kindFilter;
+        }
+
+        /**
+         * Returns the source-files filter.
+         *
+         * @return Zero-terminated string.
+         */
+        const char *GetTraceSrcFilter() const throw() {
+            return m_srcFilter;
+        }
+
+    private:
+
+        /**
+         * The helper structure containing the option pair: name and value.
+         */
+        struct Option {
+            const char *name;
+            const char *value;
+        };
+
+        /**
+         * The helper converting string to boolean.
+         *
+         * @param str - the input null-terminated string
+         *
+         * @exception IllegalArgumentException.
+         */
+        bool AsciiToBool(const char *str) throw(IllegalArgumentException);
+
+        int m_optionCount;
+        char *m_optionString;
+        Option *m_options;
+
+        bool m_help;
+        bool m_suspend;
+        bool m_server;
+        jlong m_timeout;
+        const char *m_transport;
+        const char *m_address;
+        const char *m_log;
+        const char *m_kindFilter;
+        const char *m_srcFilter;
+    };
+
+} // namespace jdwp
+
+#endif // _OPTION_PARSER_H_

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/OptionParser.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.cpp?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.cpp Tue Nov 28 09:49:08 2006
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Vitaly A. Provodin
+ * @version $Revision: 1.22 $
+ */
+#include "PacketDispatcher.h"
+#include "TransportManager.h"
+#include "AgentException.h"
+#include "ThreadManager.h"
+#include "EventDispatcher.h"
+#include "ObjectManager.h"
+#include "ClassManager.h"
+#include "RequestManager.h"
+#include "OptionParser.h"
+
+using namespace jdwp;
+
+//-----------------------------------------------------------------------------
+
+PacketDispatcher::PacketDispatcher() throw()
+    :AgentBase()
+{
+    m_isProcessed = false;
+    m_isRunning = false;
+    m_completionMonitor = 0;
+    m_executionMonitor = 0;
+}
+
+//-----------------------------------------------------------------------------
+
+void
+PacketDispatcher::Init(JNIEnv *jni) throw(AgentException)
+{
+    JDWP_TRACE_ENTRY("Init(" << jni << ")");
+
+    m_completionMonitor = new AgentMonitor("_agent_Packet_Dispatcher_completion");
+    m_executionMonitor = new AgentMonitor("_agent_Packet_Dispatcher_execution");
+}
+
+void
+PacketDispatcher::Start(JNIEnv *jni) throw(AgentException)
+{
+    JDWP_TRACE_ENTRY("Start(" << jni << ")");
+
+    JDWP_ASSERT(!m_isProcessed);
+
+    try
+    {
+        GetThreadManager().RunAgentThread(jni, StartFunction, this,
+            JVMTI_THREAD_MAX_PRIORITY, "_jdwp_PacketDispatcher");
+    }
+    catch (const AgentException& e)
+    {
+        JDWP_ASSERT(e.ErrCode() != JDWP_ERROR_NULL_POINTER);
+        JDWP_ASSERT(e.ErrCode() != JDWP_ERROR_INVALID_PRIORITY);
+
+        throw e;
+    }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void
+PacketDispatcher::Run(JNIEnv *jni)
+{
+    JDWP_TRACE_ENTRY("Run(" << jni << ")");
+
+    m_isRunning = true;
+
+    MonitorAutoLock lock(m_completionMonitor JDWP_FILE_LINE);
+    TransportManager &transport = GetTransportManager();
+    
+    try
+    {
+        // run multiplle sessions in a loop
+        for (; ;)
+        {
+            // connect for new session
+            JDWP_TRACE_PROG("Run: start new session");
+            try
+            {
+                transport.Connect();
+            }
+            catch (const TransportException& e)
+            {
+                JDWP_TRACE_PROG("Run: Exception in connection: "
+                                << e.what() << " [" << e.ErrCode() 
+                                << "/" << e.TransportErrorCode() << "]");
+                if (!IsDead()) {
+                    JDWP_DIE(e.what() << " [" << e.ErrCode() << "/"
+                                << e.TransportErrorCode() << "]: " 
+                                << GetTransportManager().GetLastTransportError());
+                }
+                break;
+            }
+
+            // start session and execute commands
+            try
+            {
+                // add internal request for automatic VMDeath event with no modifiers
+                GetRequestManager().AddInternalRequest(jni,
+                    new AgentEventRequest(JDWP_EVENT_VM_DEATH, JDWP_SUSPEND_NONE));
+
+                // release events
+                GetEventDispatcher().ReleaseEvents();
+
+                // read and execute commands
+                m_isProcessed = true;
+                while (m_isProcessed)
+                {
+                    // read command
+                    try {
+                        JDWP_TRACE_PROG("Run: handle next command");
+                        m_cmdParser.ReadCommand();
+                        if (m_cmdParser.command.GetLength() == 0)
+                        break;
+                    }
+                    catch (const TransportException& e)
+                    {
+                        JDWP_TRACE_PROG("Run: Exception in reading command: " 
+                            << e.what() << " [" << e.ErrCode() 
+                            << "/" << e.TransportErrorCode() << "]");
+                        if (m_isProcessed && !IsDead())
+                        {
+                            char* msg = GetTransportManager().GetLastTransportError();
+                            AgentAutoFree af(msg JDWP_FILE_LINE);
+
+                            if (e.TransportErrorCode() == JDWPTRANSPORT_ERROR_OUT_OF_MEMORY) {
+                                JDWP_DIE(e.what() << " [" << e.ErrCode() << "/"
+                                            << e.TransportErrorCode() << "]: " << msg);
+                            } else {
+                                JDWP_ERROR(e.what() << " [" << e.ErrCode() << "/"
+                                            << e.TransportErrorCode() << "]: " << msg);
+                            }
+                        }
+                        break;
+                    }
+
+                    // execute command and prevent from reset while execution
+                    {
+                        MonitorAutoLock lock(m_executionMonitor JDWP_FILE_LINE);
+                        m_cmdDispatcher.ExecCommand(jni, &m_cmdParser);
+                    }
+                }
+            }
+            catch (const AgentException& e)
+            {
+                JDWP_TRACE_PROG("Run: Exception in executing command: "
+                                << e.what() << " [" << e.ErrCode() << "]");
+                if (!IsDead()) {
+                    JDWP_ERROR(e.what() << " [" << e.ErrCode() << "]");
+                }
+            }
+
+            // reset all modules after session finished
+            JDWP_TRACE_PROG("Run: reset session");
+            ResetAll(jni);
+
+            // no more sessions if VMDeath event occured
+            if (IsDead()) {
+                JDWP_TRACE_PROG("Run: VM is dead -> shutdown");
+                break;
+            }
+
+            // no more sessions in attach mode
+            if (!GetOptionParser().GetServer()) {
+                JDWP_TRACE_PROG("Run: attach mode -> shutdown");
+                break;
+            }
+        }
+    }
+    catch (const AgentException& e)
+    {
+        JDWP_TRACE_PROG("Run: Exception in PacketDispatcher: "
+                        << e.what() << " [" << e.ErrCode() << "]");
+        if (!IsDead()) {
+            JDWP_DIE(e.what() << " [" << e.ErrCode() << "]"); 
+        }
+    }
+
+    // stop also EventDispatcher thread
+    try 
+    {
+        JDWP_TRACE_PROG("Run: stop EventDispatcher");
+        GetEventDispatcher().Stop(jni);
+    }
+    catch (const AgentException& e)
+    {
+        JDWP_TRACE_PROG("Run: Exception in stopping EventDispatcher: "
+                        << e.what() << " [" << e.ErrCode() << "]");
+    }
+
+    m_isRunning = false;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+PacketDispatcher::Stop() throw(AgentException)
+{
+    JDWP_TRACE_ENTRY("Stop()");
+
+    if (!m_isRunning) return;
+
+    // cause thread loop to break
+    m_isProcessed = false;
+    
+    // wait for thread finished
+    {
+        MonitorAutoLock lock(m_completionMonitor JDWP_FILE_LINE);
+    }
+    JDWP_ASSERT(!m_isRunning);
+
+    // EventDispatcher is also stopped
+}
+
+void 
+PacketDispatcher::Clean(JNIEnv *jni) throw(AgentException)
+{
+    JDWP_TRACE_ENTRY("Clean(" << jni << ')');
+
+    JDWP_TRACE_PROG("Clean: clean internal data");
+
+    if (m_completionMonitor != 0) {
+        delete m_completionMonitor;
+        m_completionMonitor = 0;
+    }
+
+    if (m_executionMonitor != 0) {
+        delete m_executionMonitor;
+        m_executionMonitor = 0;
+    }
+}
+
+void 
+PacketDispatcher::Reset(JNIEnv *jni) throw(AgentException)
+{ 
+    JDWP_TRACE_ENTRY("Reset(" << jni << ')');
+
+    // cause thread loop to break
+    JDWP_TRACE_PROG("Reset: reset session");
+    m_isProcessed = false; 
+}
+
+void 
+PacketDispatcher::ResetAll(JNIEnv *jni) throw(AgentException)
+{
+    JDWP_TRACE_ENTRY("ResetAll(" << jni << ")");
+
+    // reset all modules, but not while executing current command 
+    if (m_executionMonitor != 0) {
+        MonitorAutoLock lock(m_executionMonitor JDWP_FILE_LINE);
+
+        JDWP_TRACE_PROG("ResetAll: reset all modules");
+
+        GetThreadManager().Reset(jni);
+        GetRequestManager().Reset(jni);
+        GetEventDispatcher().Reset(jni);
+        GetTransportManager().Reset();
+        GetPacketDispatcher().Reset(jni);
+        GetClassManager().Reset(jni);
+        GetObjectManager().Reset(jni);
+    }
+}
+
+void 
+PacketDispatcher::ShutdownAll(JNIEnv *jni) throw(AgentException)
+{
+    // trace entry before cleaning LogManager
+    {
+        JDWP_TRACE_ENTRY("ShutdownAll(" << jni << ")");
+
+        // close transport first, but not while executing current command
+        JDWP_TRACE_PROG("ShutdownAll: close agent connection");
+        if (m_executionMonitor != 0) {
+            MonitorAutoLock lock(m_executionMonitor JDWP_FILE_LINE);
+            GetTransportManager().Clean();
+        }
+
+        // stop PacketDispatcher and EventDispatcher threads, and reset all modules
+        JDWP_TRACE_PROG("ShutdownAll: stop agent threads");
+        GetPacketDispatcher().Stop();
+
+        // clean all modules
+        JDWP_TRACE_PROG("ShutdownAll: clean agent modules");
+        GetPacketDispatcher().Clean(jni);
+        GetThreadManager().Clean(jni);
+        GetRequestManager().Clean(jni);
+        GetEventDispatcher().Clean(jni);
+        GetObjectManager().Clean(jni);
+        GetClassManager().Clean(jni);
+    }
+
+    // clean LogManager and close log
+    GetLogManager().Clean();
+}
+
+
+//-----------------------------------------------------------------------------
+
+void JNICALL
+PacketDispatcher::StartFunction(jvmtiEnv* jvmti_env, JNIEnv* jni, void* arg)
+{
+    JDWP_TRACE_ENTRY("StartFunction(" << jvmti_env << "," << jni << "," << arg << ")");
+
+    (reinterpret_cast<PacketDispatcher *>(arg))->Run(jni);
+}

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.h?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.h (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.h Tue Nov 28 09:49:08 2006
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, 
+ * as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Vitaly A. Provodin
+ * @version $Revision: 1.8.2.1 $
+ */
+
+/**
+ * @file
+ * PacketDispatcher.h
+ *
+ * Reads command packets from the transport, wraps and passes them to
+ * CommandDispatcher.
+ * Operates in a separate agent thread.
+ */
+
+#ifndef _PACKET_DISPATCHER_H_
+#define _PACKET_DISPATCHER_H_
+
+#include "AgentBase.h"
+#include "AgentException.h"
+#include "PacketParser.h"
+#include "CommandDispatcher.h"
+
+
+namespace jdwp {
+
+    class AgentMonitor;
+
+    /**
+     * Unwraps JDWP commands and passes them to <code>CommandDispatcher</code>
+     * for executing.
+     * The JDWP agent has only one object of <code>PacketDispatcher</code> that
+     * is started at the startup routine in a separate thread.
+     * <code>PacketDispatcher</code> reads command packets from the active
+     * JDWP transport via <code>TransportManager</code>, unwraps them and passes
+     * to <code>CommandDispatcher</code>. In case <code>CommandDispatcher</code>
+     * can not execute the obtained JDWP command, <code>PacketDispatcher</code>
+     * composes the corresponding reply packet, according to the JDWP 
+     * specification, and sends it back to the JDWP transport.
+     * 
+     * @see CommandDispatcher
+     * @see TransportManager
+     */
+    class PacketDispatcher : public AgentBase
+    {
+    public:
+
+        /**
+         * Constructs a new <code>PacketDispatcher</code> object.
+         */
+        PacketDispatcher() throw();
+
+        /**
+         * Initializes the <code>PacketDispatcher</code>'s thread.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void Init(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Starts the <code>PacketDispatcher</code>'s thread.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void Start(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Stops the <code>PacketDispatcher</code>'s thread.
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void Stop() throw(AgentException);
+
+        /**
+         * Resets the <code>PacketDispatcher</code> object.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void Reset(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Cleans the <code>PacketDispatcher</code> object.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void Clean(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Resets all agent modules.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void ResetAll(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Shutdowns all agent modules.
+         *
+         * @param jni - the JNI interface pointer
+         *
+         * @exception If any error occurs, <code>AgentException</code> is thrown.
+         */
+        void ShutdownAll(JNIEnv *jni) throw(AgentException);
+
+        /**
+         * Determines if the <code>PacketDispatcher</code> object is already
+         * started.
+         */
+        bool IsProcessed() const {return m_isProcessed;}
+
+    protected:
+
+        /**
+         * Main execution function of the dispatcher processing
+         * commands from the debugger.
+         *
+         * @param jni - the JNI interface pointer
+         */
+        void Run(JNIEnv *jni);
+
+        /**
+         * Starts <code>PacketDispatcher</code> thread.
+         * The given function is passed as the <code>proc</code> parameter of
+         * <code>ThreadManager::RunAgentThread</code>. The <code>arg</code>
+         * parameter must be a pointer to the agent's
+         * <code>PacketDisptacher</code> object.
+         *
+         * @param jvmti - the JVMTI interface pointer
+         * @param jni   - the JNI interface pointer
+         * @param arg   - the agent's <code>PacketDisptacher</code> object pointer
+         */
+        static void JNICALL
+            StartFunction(jvmtiEnv* jvmti, JNIEnv* jni, void* arg);
+
+    private:
+        volatile bool       m_isProcessed;
+        volatile bool       m_isRunning;
+        CommandParser       m_cmdParser;
+        CommandDispatcher   m_cmdDispatcher;
+        AgentMonitor*       m_completionMonitor;
+        AgentMonitor*       m_executionMonitor;
+
+    };//class PacketDispatcher
+
+}//jdwp
+
+#endif //_PACKET_DISPATCHER_H_

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketDispatcher.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketParser.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketParser.cpp?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketParser.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketParser.cpp Tue Nov 28 09:49:08 2006
@@ -0,0 +1,845 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Anton V. Karnachuk
+ * @version $Revision: 1.18 $
+ */
+// PacketParser.cpp: implementation of the PacketParser class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "PacketParser.h"
+#include "jdwpTypes.h"
+#include "MemoryManager.h"
+#include "ObjectManager.h"
+#include "TransportManager.h"
+#include "ClassManager.h"
+
+#include <cstring>
+
+using namespace jdwp;
+
+// Constant defining increment for m_registeredObjectIDTable
+const int REGISTERED_OBJECTID_TABLE_STEP = 0x10;
+
+const size_t ALLOCATION_STEP = 0x10;
+const jbyte PACKET_IS_UNINITIALIZED = 0x03;
+
+// GCList
+PacketWrapper::GCList::GCList() :
+    m_memoryRefAllocatedSize(0),
+    m_memoryRef(0),
+    m_memoryRefPosition(0),
+    m_globalRefAllocatedSize(0),
+    m_globalRef(0),
+    m_globalRefPosition(0)
+{
+}
+
+void PacketWrapper::GCList::Reset(JNIEnv *jni) {
+    if (m_memoryRef != 0) {
+        while (m_memoryRefPosition-- > 0) {
+            GetMemoryManager().Free(m_memoryRef[m_memoryRefPosition] JDWP_FILE_LINE);
+        }
+        GetMemoryManager().Free(m_memoryRef JDWP_FILE_LINE);
+        m_memoryRef = 0;
+        m_memoryRefAllocatedSize = 0;
+        m_memoryRefPosition = 0;
+    }
+
+    if (m_globalRef != 0) {
+        while (m_globalRefPosition-- > 0) {
+            jni->DeleteGlobalRef(m_globalRef[m_globalRefPosition]);
+        }
+        GetMemoryManager().Free(m_globalRef JDWP_FILE_LINE);
+        m_globalRef = 0;
+        m_globalRefAllocatedSize = 0;
+        m_globalRefPosition = 0;
+    }
+}
+
+void PacketWrapper::GCList::StoreStringRef(char* ref) throw (OutOfMemoryException) {
+    if (m_memoryRefPosition >= m_memoryRefAllocatedSize) {
+        // then reallocate buffer
+        size_t oldAllocatedSize = this->m_memoryRefAllocatedSize;
+        if (m_memoryRefAllocatedSize<ALLOCATION_STEP)
+            m_memoryRefAllocatedSize += ALLOCATION_STEP;
+        else
+            m_memoryRefAllocatedSize *= 2;
+
+        m_memoryRef = static_cast<char**>
+            (GetMemoryManager().Reallocate(m_memoryRef,
+                 oldAllocatedSize * sizeof(char*),
+                 m_memoryRefAllocatedSize * sizeof(char*) JDWP_FILE_LINE));
+    }
+    m_memoryRef[m_memoryRefPosition++] = ref;
+}
+
+void PacketWrapper::GCList::StoreGlobalRef(jobject globalRef) throw (OutOfMemoryException) {
+    if (m_globalRefPosition >= m_globalRefAllocatedSize) {
+        // then reallocate buffer
+        size_t oldAllocatedSize = m_globalRefAllocatedSize;
+        if (m_globalRefAllocatedSize < ALLOCATION_STEP) {
+            m_globalRefAllocatedSize += ALLOCATION_STEP;
+        } else {
+            m_globalRefAllocatedSize *= 2;
+        }
+
+        m_globalRef = static_cast<jobject*>
+            (GetMemoryManager().Reallocate(m_globalRef,
+                 oldAllocatedSize * sizeof(jobject),
+                 m_globalRefAllocatedSize * sizeof(jobject) JDWP_FILE_LINE));
+    }
+    m_globalRef[m_globalRefPosition++] = globalRef;
+}
+
+void PacketWrapper::GCList::MoveData(GCList* to) {
+    to->m_memoryRefAllocatedSize = m_memoryRefAllocatedSize;
+    to->m_memoryRef = m_memoryRef;
+    to->m_memoryRefPosition = m_memoryRefPosition;
+
+    m_memoryRefAllocatedSize = 0;
+    m_memoryRef = 0;
+    m_memoryRefPosition = 0;
+
+    to->m_globalRefAllocatedSize = m_globalRefAllocatedSize;
+    to->m_globalRef = m_globalRef;
+    to->m_globalRefPosition = m_globalRefPosition;
+
+    m_globalRefAllocatedSize = 0;
+    m_globalRef = 0;
+    m_globalRefPosition = 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+// PacketWrapper
+//////////////////////////////////////////////////////////////////////
+
+PacketWrapper::PacketWrapper() :
+    m_packet(),
+    m_garbageList()
+{
+    this->m_packet.type.cmd.flags = PACKET_IS_UNINITIALIZED;
+}
+
+void PacketWrapper::Reset(JNIEnv *jni) {
+    // clear links
+    m_garbageList.Reset(jni);
+
+    // free packet's data
+    if (m_packet.type.cmd.data!=0) {
+        GetMemoryManager().Free(m_packet.type.cmd.data JDWP_FILE_LINE);
+        m_packet.type.cmd.data = 0;
+    }
+
+    m_packet.type.cmd.flags = PACKET_IS_UNINITIALIZED;
+}
+
+bool PacketWrapper::IsPacketInitialized() {
+    return ((m_packet.type.cmd.flags & PACKET_IS_UNINITIALIZED) == 0);
+}
+
+void PacketWrapper::MoveData(JNIEnv *jni, PacketWrapper* to) {
+    to->Reset(jni);
+
+    // move m_garbageList data to other PacketWrapper
+    to->m_garbageList.MoveData(&to->m_garbageList);
+
+    // move m_packet to packetWrapper
+    memcpy(&to->m_packet, &m_packet, sizeof(m_packet));
+    m_packet.type.cmd.data = 0;
+    m_packet.type.cmd.len = 0;
+    m_packet.type.cmd.flags = PACKET_IS_UNINITIALIZED;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// InputPacketParser - sequential reading of m_packet data
+//////////////////////////////////////////////////////////////////////
+
+void InputPacketParser::ReadPacketFromTransport() throw (TransportException) {
+    JDWP_ASSERT(!IsPacketInitialized());
+    GetTransportManager().Read(&m_packet);
+}
+
+void InputPacketParser::ReadBigEndianData(void* data, int len) throw (InternalErrorException) {
+    JDWP_ASSERT(IsPacketInitialized());
+
+    if (m_position+len>m_packet.type.cmd.len-JDWP_MIN_PACKET_LENGTH) {
+        throw InternalErrorException();
+    }
+  
+    #if IS_BIG_ENDIAN_PLATFORM
+    jbyte* from = static_cast<jbyte*>(&m_packet.type.cmd.data[m_position]);
+    jbyte* to = static_cast<jbyte*>(data);
+    for (int i=0; i<len; i++) {
+        to[i] = from[len-i-1];
+    }    
+    #else
+    memcpy(data, &m_packet.type.cmd.data[m_position], length);
+    #endif
+    m_position += len;
+}
+
+void InputPacketParser::ReadRawData(void* data, int len) throw (InternalErrorException) {
+    JDWP_ASSERT(IsPacketInitialized());
+
+    if (m_position+len>m_packet.type.cmd.len-JDWP_MIN_PACKET_LENGTH) {
+        throw InternalErrorException();
+    }
+  
+    memcpy(data, &m_packet.type.cmd.data[m_position], len);
+    
+    m_position += len;
+}
+
+
+
+jbyte InputPacketParser::ReadByte() throw (InternalErrorException) {
+    jbyte data = 0;
+    ReadBigEndianData(&data, sizeof(jbyte));
+    return data;
+}
+
+jboolean InputPacketParser::ReadBoolean() throw (InternalErrorException) {
+    jboolean data = 0;
+    ReadBigEndianData(&data, sizeof(jboolean));
+    return data;
+}
+
+jint InputPacketParser::ReadInt() throw (InternalErrorException) {
+    jint res = 0;
+    ReadBigEndianData(&res, sizeof(jint));
+    return res;
+}
+
+jlong InputPacketParser::ReadLong() throw (InternalErrorException) {
+    jlong data = 0;
+    ReadBigEndianData(&data, sizeof(jlong));
+    return data;
+}
+
+ObjectID InputPacketParser::ReadRawObjectID() throw (InternalErrorException) {
+    ObjectID data = 0;
+    ReadBigEndianData(&data, OBJECT_ID_SIZE);
+    return data;
+}
+
+jobject InputPacketParser::ReadObjectIDOrNull(JNIEnv *jni) throw (AgentException) {
+    // read raw ObjectID and check for null
+    ObjectID oid = ReadRawObjectID();
+    if (oid == 0) {
+        return 0;
+    }
+
+    // convert to jobject (actually to WeakReference or GlobalReference)
+    jobject obj = GetObjectManager().MapFromObjectID(jni, oid);
+    JDWP_ASSERT(obj !=  NULL);
+
+    // make GlobalReference and check if WeakReference was freed
+    jobject ref = jni->NewGlobalRef(obj);
+    if (ref == 0) {
+        if (jni->IsSameObject(obj, 0)) {
+            throw AgentException(JDWP_ERROR_INVALID_OBJECT);
+        } else {
+            throw OutOfMemoryException();
+        }
+    }
+
+    // store GlobalReference for futher disposal
+    m_garbageList.StoreGlobalRef(ref);
+    return ref;
+}
+
+jobject InputPacketParser::ReadObjectID(JNIEnv *jni) throw (AgentException) {
+    jobject obj = ReadObjectIDOrNull(jni);
+    if (obj == 0) {
+        throw AgentException(JDWP_ERROR_INVALID_OBJECT);
+    }
+    return obj;
+}
+
+jclass InputPacketParser::ReadReferenceTypeIDOrNull(JNIEnv *jni) throw (AgentException) {
+    ReferenceTypeID rtid = 0;
+    ReadBigEndianData(&rtid, REFERENCE_TYPE_ID_SIZE);
+    if (rtid == 0) {
+        return 0;
+    }
+
+    // convert to jclass (actually to WeakReference or GlobalReference)
+    jclass cls = GetObjectManager().MapFromReferenceTypeID(jni, rtid);
+    JDWP_ASSERT(cls != 0);
+    
+    // make GlobalReference and check if WeakReference was freed
+    jclass ref = static_cast<jclass>(jni->NewGlobalRef(cls));
+    if (ref == 0) {
+        if (jni->IsSameObject(cls, 0)) {
+            throw AgentException(JDWP_ERROR_INVALID_OBJECT);
+        } else {
+            throw OutOfMemoryException();
+        }
+    }
+
+    // store GlobalReference for futher disposal
+    m_garbageList.StoreGlobalRef(ref);
+    return ref;
+}
+
+jclass InputPacketParser::ReadReferenceTypeID(JNIEnv *jni) throw (AgentException) {
+    jclass cls = ReadReferenceTypeIDOrNull(jni);
+    if (cls == 0) {
+        throw AgentException(JDWP_ERROR_INVALID_OBJECT);
+    }
+    return cls;
+}
+
+jfieldID InputPacketParser::ReadFieldID(JNIEnv *jni) throw (AgentException) {
+    FieldID fid = 0;
+    ReadBigEndianData(&fid, FIELD_ID_SIZE);
+    jfieldID res = GetObjectManager().MapFromFieldID(jni, fid);
+    return res;
+}
+
+jmethodID InputPacketParser::ReadMethodID(JNIEnv *jni) throw (AgentException) {
+    MethodID mid = 0;
+    ReadBigEndianData(&mid, METHOD_ID_SIZE);
+    jmethodID res = GetObjectManager().MapFromMethodID(jni, mid);
+    return res;
+}
+
+jint InputPacketParser::ReadFrameID(JNIEnv *jni) throw (AgentException) {
+    FrameID fid;
+    ReadBigEndianData(&fid, FRAME_ID_SIZE);
+    jint res = GetObjectManager().MapFromFrameID(jni, fid);
+    return res;
+}
+
+jdwpLocation InputPacketParser::ReadLocation(JNIEnv *jni) throw (AgentException) {
+    jdwpLocation res;
+    res.typeTag = static_cast<jdwpTypeTag>(ReadByte());
+    res.classID = ReadReferenceTypeID(jni);
+    res.methodID = ReadMethodID(jni);
+    res.loc = ReadLong();
+    return res;
+}
+
+jthread InputPacketParser::ReadThreadID(JNIEnv *jni) throw (AgentException) {
+    return static_cast<jthread>(ReadObjectID(jni));
+}
+
+jthreadGroup InputPacketParser::ReadThreadGroupID(JNIEnv *jni) throw (AgentException) {
+    return static_cast<jthreadGroup>(ReadObjectID(jni));
+}
+
+jstring InputPacketParser::ReadStringID(JNIEnv *jni) throw (AgentException) {
+    return static_cast<jstring>(ReadObjectID(jni));
+}
+
+jarray InputPacketParser::ReadArrayID(JNIEnv *jni) throw (AgentException) {
+    return static_cast<jarray>(ReadObjectID(jni));
+}
+
+char* InputPacketParser::ReadStringNoFree()  throw (InternalErrorException, OutOfMemoryException) {
+    jint len = ReadInt();
+    if (m_position+len>m_packet.type.cmd.len) {
+        throw InternalErrorException();
+    }
+    char* res = static_cast<char*>(GetMemoryManager().Allocate(len+1 JDWP_FILE_LINE));
+    strncpy(res, reinterpret_cast<char*>(&m_packet.type.cmd.data[m_position]), len);
+    res[len] = '\0';
+    m_position += len;
+    return res;
+}
+
+char* InputPacketParser::ReadString()  throw (InternalErrorException, OutOfMemoryException) {
+    char* res = ReadStringNoFree();
+    m_garbageList.StoreStringRef(res);
+    return res;
+}
+
+jdwpTaggedValue InputPacketParser::ReadValue(JNIEnv *jni)  throw (AgentException) {
+    //The first byte is a signature byte which is used to identify the type
+    jdwpTaggedValue tv;
+    tv.tag = static_cast<jdwpTag>(ReadByte());
+    tv.value = ReadUntaggedValue(jni, tv.tag);
+    return tv;
+}
+
+jvalue InputPacketParser::ReadUntaggedValue(JNIEnv *jni, jdwpTag tagPtr)  throw (AgentException) {
+    jvalue value;
+
+    switch (tagPtr) {
+    case JDWP_TAG_ARRAY:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_BYTE:
+        value.b = ReadByte();
+        break;
+    case JDWP_TAG_CHAR:
+        value.c = ReadChar();
+        break;
+    case JDWP_TAG_OBJECT:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_FLOAT:
+        value.f = ReadFloat();
+        break;
+    case JDWP_TAG_DOUBLE:
+        value.d = ReadDouble();
+        break;
+    case JDWP_TAG_INT:
+        value.i = ReadInt();
+        break;
+    case JDWP_TAG_LONG:
+        value.j = ReadLong();
+        break;
+    case JDWP_TAG_SHORT:
+        value.s = ReadShort();
+        break;
+    case JDWP_TAG_VOID:
+        // read nothing
+        break;
+    case JDWP_TAG_BOOLEAN:
+        value.z = ReadBoolean();
+        break;
+    case JDWP_TAG_STRING:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_THREAD:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_THREAD_GROUP:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_CLASS_LOADER:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    case JDWP_TAG_CLASS_OBJECT:
+        value.l = ReadObjectIDOrNull(jni);
+        break;
+    default: JDWP_ERROR("Illegal jdwp-tag value: " << tagPtr);
+    }
+    return value;
+}
+
+// InputPacket's private methods
+
+jchar InputPacketParser::ReadChar() throw (InternalErrorException) {
+    jchar data = 0;
+    ReadBigEndianData(&data, sizeof(jchar));
+    return data;
+}
+jshort InputPacketParser::ReadShort() throw (InternalErrorException) {
+    jshort data = 0;
+    ReadBigEndianData(&data, sizeof(jshort));
+    return data;
+}
+
+jfloat InputPacketParser::ReadFloat() throw (InternalErrorException) {
+    jfloat data = 0;
+    ReadBigEndianData(&data, sizeof(jfloat));
+    return data;
+}
+jdouble InputPacketParser::ReadDouble() throw (InternalErrorException) {
+    jdouble data = 0;
+    ReadBigEndianData(&data, sizeof(jdouble));
+    return data;
+}
+
+void InputPacketParser::Reset(JNIEnv *jni) {
+    PacketWrapper::Reset(jni);
+    m_position = 0;
+}
+
+void InputPacketParser::MoveData(JNIEnv *jni, InputPacketParser* to) {
+    PacketWrapper::MoveData(jni, to);
+    m_position = 0;
+}
+
+//////////////////////////////////////////////////////////////////////
+// OutputPacketComposer - sequential writing of m_packet data
+//////////////////////////////////////////////////////////////////////
+void OutputPacketComposer::WritePacketToTransport() throw (TransportException) {
+    JDWP_ASSERT(IsPacketInitialized());
+    GetTransportManager().Write(&m_packet);
+    if ( GetError() == JDWP_ERROR_NONE ) {
+       IncreaseObjectIDRefCounts();
+    }
+}
+
+void OutputPacketComposer::AllocateMemoryForData(int length) throw (OutOfMemoryException) {
+    size_t newPosition = m_position + static_cast<size_t>(length);
+    if (newPosition >= m_allocatedSize) {
+        // then reallocate buffer
+        size_t newAllocatedSize = m_allocatedSize + ALLOCATION_STEP;
+        while (newPosition >= newAllocatedSize) {
+            if (newAllocatedSize < ALLOCATION_STEP)
+                newAllocatedSize += ALLOCATION_STEP;
+            else
+                newAllocatedSize *= 2;
+        }
+        m_packet.type.cmd.data = static_cast<jbyte*>
+            (GetMemoryManager().Reallocate(m_packet.type.cmd.data, 
+                m_allocatedSize, newAllocatedSize JDWP_FILE_LINE));
+        m_allocatedSize = newAllocatedSize;
+    }
+}
+
+
+void OutputPacketComposer::WriteRawData(const void* data, int length) throw (OutOfMemoryException) {
+    AllocateMemoryForData(length);
+    
+    memcpy(&m_packet.type.cmd.data[m_position], data, length);
+    
+    m_position += length;
+    m_packet.type.cmd.len += length;
+}
+
+
+void OutputPacketComposer::WriteBigEndianData(void* data, int length) throw (OutOfMemoryException) {
+    JDWP_ASSERT(length <= sizeof(jlong));
+    AllocateMemoryForData(length);
+    
+    #if IS_BIG_ENDIAN_PLATFORM
+        const jbyte* from = static_cast<jbyte*>(const_cast<void*>(data));
+        jbyte* to = static_cast<jbyte*>(&m_packet.type.cmd.data[m_position]);
+        for (int i=0; i<length; i++) {
+            to[i] = from[length-i-1];
+        }
+    
+    #else 
+        memcpy(&m_packet.type.cmd.data[m_position], data, length);
+    #endif
+    m_position += length;
+    m_packet.type.cmd.len += length;
+     
+}
+
+void OutputPacketComposer::WriteByte(jbyte value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteBoolean(jboolean value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteInt(jint value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteLong(jlong value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+
+void OutputPacketComposer::WriteObjectID(JNIEnv *jni, jobject value) throw (AgentException) {
+    ObjectID id = GetObjectManager().MapToObjectID(jni, value);
+    WriteBigEndianData(&id, OBJECT_ID_SIZE);
+    RegisterObjectID(id);
+}
+
+void OutputPacketComposer::WriteReferenceTypeID(JNIEnv *jni, jclass value) throw (OutOfMemoryException) {
+    ReferenceTypeID id = GetObjectManager().MapToReferenceTypeID(jni, value);
+    WriteBigEndianData(&id, REFERENCE_TYPE_ID_SIZE);
+}
+
+void OutputPacketComposer::WriteFieldID(JNIEnv *jni, jfieldID value) throw (OutOfMemoryException) {
+    FieldID id = GetObjectManager().MapToFieldID(jni, value);
+    WriteBigEndianData(&id, FIELD_ID_SIZE);
+}
+
+void OutputPacketComposer::WriteMethodID(JNIEnv *jni, jmethodID value) throw (OutOfMemoryException) {
+    MethodID id = GetObjectManager().MapToMethodID(jni, value);
+    WriteBigEndianData(&id, METHOD_ID_SIZE);
+}
+
+void OutputPacketComposer::WriteFrameID(JNIEnv *jni, jthread jvmThread, jint frameDepth, jint framesCount) 
+throw (OutOfMemoryException) {
+    FrameID id = GetObjectManager().MapToFrameID(jni, jvmThread, frameDepth, framesCount);
+    WriteBigEndianData(&id, FRAME_ID_SIZE);
+}
+
+void OutputPacketComposer::WriteLocation(JNIEnv *jni, jdwpTypeTag typeTag, jclass clazz, 
+                                         jmethodID method, jlocation location) 
+throw (OutOfMemoryException) {
+    WriteByte(static_cast<jbyte>(typeTag));
+    WriteReferenceTypeID(jni, clazz);
+    WriteMethodID(jni, method);
+    WriteLong(static_cast<jlong>(location));
+}
+
+void OutputPacketComposer::WriteLocation(JNIEnv *jni, jdwpLocation *location) throw (OutOfMemoryException) {
+    WriteLocation(jni, location->typeTag, location->classID, location->methodID, location->loc);
+}
+
+void OutputPacketComposer::WriteThreadID(JNIEnv *jni, jthread value) throw (OutOfMemoryException) {
+    WriteObjectID(jni, value);
+}
+
+void OutputPacketComposer::WriteThreadGroupID(JNIEnv *jni, jthreadGroup value) throw (OutOfMemoryException) {
+    WriteObjectID(jni, value);
+}
+
+void OutputPacketComposer::WriteStringID(JNIEnv *jni, jstring value) throw (OutOfMemoryException) {
+    WriteObjectID(jni, value);
+}
+
+void OutputPacketComposer::WriteArrayID(JNIEnv *jni, jarray value) throw (OutOfMemoryException) {
+    WriteObjectID(jni, value);
+}
+
+void OutputPacketComposer::WriteString(const char* value) throw (OutOfMemoryException) {
+    jint len = static_cast<jint>((value == 0) ? 0 : std::strlen(value));
+    WriteString(value, len);
+}
+
+void OutputPacketComposer::WriteString(const char* value, jint length) throw (OutOfMemoryException) {
+    WriteBigEndianData(&length, sizeof(jint));
+    if (length > 0) {
+        WriteRawData(value, length);
+    }
+}
+
+void OutputPacketComposer::WriteUntaggedValue(JNIEnv *jni, jdwpTag tag, jvalue value) 
+throw (OutOfMemoryException) {
+    //The first byte is a signature byte which is used to identify the type
+    switch (tag) {
+    case JDWP_TAG_ARRAY:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_BYTE:
+        WriteByte(value.b);
+        break;
+    case JDWP_TAG_CHAR:
+        WriteChar(value.c);
+        break;
+    case JDWP_TAG_OBJECT:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_FLOAT:
+        WriteFloat(value.f);
+        break;
+    case JDWP_TAG_DOUBLE:
+        WriteDouble(value.d);
+        break;
+    case JDWP_TAG_INT:
+        WriteInt(value.i);
+        break;
+    case JDWP_TAG_LONG:
+        WriteLong(value.j);
+        break;
+    case JDWP_TAG_SHORT:
+        WriteShort(value.s);
+        break;
+    case JDWP_TAG_VOID:
+        // read nothing
+        break;
+    case JDWP_TAG_BOOLEAN:
+        WriteBoolean(value.z);
+        break;
+    case JDWP_TAG_STRING:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_THREAD:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_THREAD_GROUP:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_CLASS_LOADER:
+        WriteObjectID(jni, value.l);
+        break;
+    case JDWP_TAG_CLASS_OBJECT:
+        WriteObjectID(jni, value.l);
+        break;
+    default: JDWP_ERROR("Illegal jdwp-tag value: " << tag);
+    }
+}
+
+void OutputPacketComposer::WriteValue(JNIEnv *jni, jdwpTag tag, jvalue value) throw (OutOfMemoryException) {
+    WriteByte(static_cast<jbyte>(tag));
+    WriteUntaggedValue(jni, tag, value);
+}
+
+void OutputPacketComposer::WriteTaggedObjectID(JNIEnv *jni, jobject object) throw (OutOfMemoryException) {
+    jdwpTag tag = GetClassManager().GetJdwpTag(jni, object);
+    WriteByte(static_cast<jbyte>(tag));
+    WriteObjectID(jni, object);
+}
+
+void OutputPacketComposer::WriteValues(JNIEnv *jni, jdwpTag tag, 
+                           jint length, jvalue* value) throw (OutOfMemoryException) {
+    WriteByte(static_cast<jbyte>(tag));
+    WriteInt(length);
+    for (int i=0; i<length; i++)
+        WriteUntaggedValue(jni, tag, value[i]);
+}
+
+void OutputPacketComposer::WriteByteArray(jbyte* byte, jint length) throw (OutOfMemoryException) {
+    WriteInt(length);
+    WriteRawData(byte, length);
+}
+
+void OutputPacketComposer::Reset(JNIEnv *jni) {
+    PacketWrapper::Reset(jni);
+    m_position = 0;
+    m_allocatedSize = 0;
+    if (m_registeredObjectIDCount != 0) {
+        GetMemoryManager().Free(m_registeredObjectIDTable JDWP_FILE_LINE);
+        m_registeredObjectIDTable = 0;
+        m_registeredObjectIDCount = 0;
+        m_registeredObjectIDTableSise = 0;
+    }
+}
+
+void OutputPacketComposer::MoveData(JNIEnv *jni, OutputPacketComposer* to) {
+    PacketWrapper::MoveData(jni, to);
+    m_position = 0;
+    m_allocatedSize = 0;
+}
+
+// OutputPacketComposer's private methods
+void OutputPacketComposer::WriteChar(jchar value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteShort(jshort value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteFloat(jfloat value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+void OutputPacketComposer::WriteDouble(jdouble value) throw (OutOfMemoryException) {
+    WriteBigEndianData(&value, sizeof(value));
+}
+
+void OutputPacketComposer::RegisterObjectID(ObjectID objectID)
+    throw (AgentException) {
+
+    if ( objectID == JDWP_OBJECT_ID_NULL ) {
+        return;
+    }
+
+    if ( m_registeredObjectIDCount == m_registeredObjectIDTableSise ) {
+
+        if ( m_registeredObjectIDCount == 0 ) {
+            m_registeredObjectIDTable = reinterpret_cast<ObjectID*>
+                (AgentBase::GetMemoryManager().Allocate(sizeof(ObjectID) 
+                * REGISTERED_OBJECTID_TABLE_STEP JDWP_FILE_LINE));
+            // can be: OutOfMemoryException, InternalErrorException 
+            m_registeredObjectIDTableSise = REGISTERED_OBJECTID_TABLE_STEP;
+        } else {
+            m_registeredObjectIDTableSise
+                = m_registeredObjectIDTableSise + REGISTERED_OBJECTID_TABLE_STEP;
+            m_registeredObjectIDTable = reinterpret_cast<ObjectID*>
+                (AgentBase::GetMemoryManager().Reallocate(m_registeredObjectIDTable,
+                static_cast<size_t>(sizeof(ObjectID) * (m_registeredObjectIDTableSise-REGISTERED_OBJECTID_TABLE_STEP)),
+                static_cast<size_t>(sizeof(ObjectID) * m_registeredObjectIDTableSise) JDWP_FILE_LINE));
+            // can be: OutOfMemoryException, InternalErrorException
+        }
+    }
+    m_registeredObjectIDTable[m_registeredObjectIDCount++] = objectID;
+}
+
+void OutputPacketComposer::IncreaseObjectIDRefCounts() {
+    for ( int i=0; i < m_registeredObjectIDCount; i++) {
+        GetObjectManager().IncreaseIDRefCount(m_registeredObjectIDTable[i]);
+    }
+}
+
+// new reply
+void OutputPacketComposer::CreateJDWPReply(jint id, jdwpError errorCode) throw (InternalErrorException) {
+    JDWP_ASSERT(!IsPacketInitialized());
+    m_packet.type.reply.id = id;
+    m_packet.type.reply.len = JDWP_MIN_PACKET_LENGTH;
+    m_packet.type.reply.flags = JDWP_FLAG_REPLY_PACKET;
+    m_packet.type.reply.errorCode = errorCode;
+}
+
+// new event
+void OutputPacketComposer::CreateJDWPEvent(jint id, jdwpCommandSet commandSet, jdwpCommand command) 
+throw (InternalErrorException) {
+    JDWP_ASSERT(!IsPacketInitialized());
+    m_packet.type.cmd.id = id;
+    m_packet.type.cmd.len = JDWP_MIN_PACKET_LENGTH;
+    m_packet.type.cmd.flags = 0;
+    m_packet.type.cmd.cmdSet = commandSet;
+    m_packet.type.cmd.cmd = command;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// CommandParser
+///////////////////////////////////////////////////////////////////////////////
+
+void CommandParser::ReadCommand() throw (TransportException) {
+    command.ReadPacketFromTransport();
+    reply.CreateJDWPReply(command.GetId(), JDWP_ERROR_NONE);
+}
+
+void CommandParser::WriteReply(JNIEnv *jni) throw (TransportException) {
+    reply.WritePacketToTransport();
+    Reset(jni);
+}
+
+void CommandParser::Reset(JNIEnv *jni) {
+    command.Reset(jni);
+    reply.Reset(jni);
+}
+
+void CommandParser::MoveData(JNIEnv *jni, CommandParser* to) {
+    command.MoveData(jni, &to->command);
+    reply.MoveData(jni, &to->reply);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// EventComposer
+///////////////////////////////////////////////////////////////////////////////
+
+EventComposer::EventComposer(jint id,
+    jdwpCommandSet commandSet, jdwpCommand command, jdwpSuspendPolicy sp)
+{
+    event.CreateJDWPEvent(id, commandSet, command);
+    m_suspendPolicy = sp;
+    m_thread = 0;
+    m_isSent = false;
+    m_isWaiting = false;
+    m_isReleased = false;
+    m_isAutoDeathEvent = false;
+    event.WriteByte(sp);
+}
+
+void EventComposer::WriteThread(JNIEnv *jni, jthread thread)
+    throw (OutOfMemoryException)
+{
+    event.WriteThreadID(jni, thread);
+    m_thread = jni->NewGlobalRef(thread);
+    if (m_thread == 0) {
+        throw OutOfMemoryException();
+    }
+}
+
+void EventComposer::Reset(JNIEnv *jni)
+{
+    if (m_thread != 0) {
+        jni->DeleteGlobalRef(m_thread);
+        m_thread = 0;
+    }
+    event.Reset(jni);
+}
+
+void EventComposer::WriteEvent(JNIEnv *jni) throw (TransportException)
+{
+    event.WritePacketToTransport();
+    m_isSent = true;
+    event.Reset(jni);
+}

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/core/PacketParser.cpp
------------------------------------------------------------------------------
    svn:eol-style = native