예제 #1
0
		/// <summary> Collect stats on outgoing messages </summary>
		public virtual void  messageSent(DMessage msg)
		{
			int type = msg.Type;
			if (type < 0 || type >= DMessage.OutSIZE)
				type = DMessage.OutSIZE;
			
			System.Object outLock = OutLock;
			lock (outLock)
			{
				m_outCounts[type] += 1;
				System.Threading.Monitor.PulseAll(outLock); // tell anyone who is waiting that a message has been sent
			}
		}
        /// <summary> Collect stats on outgoing messages </summary>
        public virtual void  messageSent(DMessage msg)
        {
            int type = msg.Type;

            if (type < 0 || type >= DMessage.OutSIZE)
            {
                type = DMessage.OutSIZE;
            }

            System.Object outLock = OutLock;
            lock (outLock)
            {
                m_outCounts[type] += 1;
                System.Threading.Monitor.PulseAll(outLock);                 // tell anyone who is waiting that a message has been sent
            }
        }
예제 #3
0
        /// <summary> Main rx loop which waits for commands and then issues them to anyone listening.</summary>
        internal virtual void  listenForMessages()
        {
            DProtocolNotifierIF[] listeners = new DProtocolNotifierIF[0];

            while (!m_stopRx)
            {
                /* read the data */
                try
                {
                    DMessage msg = rxMessage();

                    /* Now traverse our list of interested parties and let them deal with the message */
                    listeners = (DProtocolNotifierIF[])m_listeners.ToArray(typeof(DProtocolNotifierIF)); // copy the array to avoid multithreading problems
                    for (int i = 0; i < listeners.Length; ++i)
                    {
                        DProtocolNotifierIF elem = listeners[i];
                        try
                        {
                            elem.messageArrived(msg, this);
                        }
                        catch (Exception exc)
                        /* catch unchecked exceptions */
                        {
                            if (Trace.error)
                            {
                                Console.Error.WriteLine("Error in listener parsing incoming message :"); //$NON-NLS-1$
                                Console.Error.WriteLine(msg.inToString(16));
                                Console.Error.Write(exc.StackTrace);
                                Console.Error.Flush();
                            }
                        }
                        msg.reset(); /* allow others to reparse the message */
                    }

                    /* now dispose with the message */
                    DMessageCache.free(msg);
                }
                //catch (IOException e)
                //{
                //    // this is a healthy exception that we simply ignore, since it means we haven't seen
                //    // data for a while; is all.
                //}
                finally
                {
                }
            }
        }
예제 #4
0
        /// <summary> Transmit the message down the socket.
        ///
        /// This function is not synchronized; it is only called from one place, which is
        /// PlayerSession.sendMessage().  That function is synchronized.
        /// </summary>
        internal virtual void  txMessage(DMessage message)
        {
            int size    = message.Size;
            int command = message.Type;

            //System.out.println("txMessage: " + DMessage.outTypeName(command) + " size=" + size);

            writeDWord(size);
            writeDWord(command);
            writeData(message.Data, size);

            m_out.Flush();
            lock (this)
            {
                m_msgTx++;
            }
            MessageCounter.messageSent(message);
        }
        /// <summary> Collect stats on the messages </summary>
        public virtual void  messageArrived(DMessage msg, DProtocol which)
        {
            /* extract type */
            int type = msg.Type;

            //		System.out.println("msg counter ="+type);

            /* anything we don't know about goes in a special slot at the end of the array. */
            if (type < 0 || type >= DMessage.InSIZE)
            {
                type = DMessage.InSIZE;
            }

            System.Object inLock = InLock;
            lock (inLock)
            {
                m_inCounts[type] += 1;
                System.Threading.Monitor.PulseAll(inLock);                 // tell anyone who is waiting that a message has been received
            }
        }
예제 #6
0
		/// <summary> Put a DMessage into the cache for reuse</summary>
		public static void  free(DMessage msg)
		{
			int index = size2Index(msg.Size);
			
			msg.clear(); /* clear stuff up for re-use */
			
			/* 
			* If it is too big we don't store cache, assuming
			* the GC can do a better job than us at reusing the memory,
			* Otherwise we put it in our cache
			*/
			if (index < 0)
			{
			}
			else if (m_cache[index] != null)
			{
			}
			/* bad => need to use a Vector in the array to house multiple DMessages */
			else
				m_cache[index] = msg;
		}
예제 #7
0
        /// <summary> Put a DMessage into the cache for reuse</summary>
        public static void  free(DMessage msg)
        {
            int index = size2Index(msg.Size);

            msg.clear();             /* clear stuff up for re-use */

            /*
             * If it is too big we don't store cache, assuming
             * the GC can do a better job than us at reusing the memory,
             * Otherwise we put it in our cache
             */
            if (index < 0)
            {
            }
            else if (m_cache[index] != null)
            {
            }
            /* bad => need to use a Vector in the array to house multiple DMessages */
            else
            {
                m_cache[index] = msg;
            }
        }
예제 #8
0
        /// <summary> Get the next message on the input stream, using the context contained within
        /// the message itself to demark its end
        /// </summary>
        private DMessage rxMessage()
        {
            long size    = readDWord();
            long command = readDWord();

            //System.out.println("rxMessage: " + DMessage.inTypeName(command) + " size=" + size);

            if (size < 0 || command < 0)
            {
                throw new IOException("socket closed");                 //$NON-NLS-1$
            }

            /*
             * Ask our message cache for a message
             */
            DMessage message = DMessageCache.alloc((int)size);

            byte[] messageContent = message.Data;
            int    offset         = 0;

            /* block until we get the entire message, which may come in pieces */
            while (offset < size)
            {
                int count = m_in.Read(messageContent, offset, (int)size - offset);
                //m_ReceivedLog.Add(messageContent, offset, count);
                offset += count;
            }

            /* now we have the data of the message, set its type and we are done */
            message.Type = (int)command;
            lock (this)
            {
                m_msgRx++;
            }
            return(message);
        }
예제 #9
0
		/// <summary> Obtain a DMessage from the cache if possible, otherwise make one for me.</summary>
		public static DMessage alloc(int size)
		{
			DMessage msg;
			
			int index = size2Index(size);
			
			/*
			* We see if this could possibly be found in our cache,
			* if so, then see if there is one for us to use,
			* otherwise create a new one 
			*/
			if (index < 0)
				msg = new DMessage(size);
			else if (m_cache[index] == null)
				msg = new DMessage(size);
			else
			{
				msg = m_cache[index];
				m_cache[index] = null;
			}
			
			//		System.out.println("msgsize="+size+uft());
			return msg;
		}
예제 #10
0
		/// <summary> Collect stats on the messages </summary>
		public virtual void  messageArrived(DMessage msg, DProtocol which)
		{
			/* extract type */
			int type = msg.Type;
			
			//		System.out.println("msg counter ="+type);
			
			/* anything we don't know about goes in a special slot at the end of the array. */
			if (type < 0 || type >= DMessage.InSIZE)
				type = DMessage.InSIZE;
			
			System.Object inLock = InLock;
			lock (inLock)
			{
				m_inCounts[type] += 1;
				System.Threading.Monitor.PulseAll(inLock); // tell anyone who is waiting that a message has been received
			}
		}
예제 #11
0
		/// <summary> Transmit the message down the socket.
		/// 
		/// This function is not synchronized; it is only called from one place, which is
		/// PlayerSession.sendMessage().  That function is synchronized.
		/// </summary>
		internal virtual void  txMessage(DMessage message)
		{
			int size = message.Size;
			int command = message.Type;
			
			//System.out.println("txMessage: " + DMessage.outTypeName(command) + " size=" + size);
			
			writeDWord(size);
			writeDWord(command);
			writeData(message.Data, size);
			
			m_out.Flush();
			lock (this)
			{
				m_msgTx++;
			}
			MessageCounter.messageSent(message);
		}
예제 #12
0
		//
		// Debug purposes only.  Dump contents of our messages to the screen
		// and/or file.
		//
		internal virtual void trace(DMessage dm, bool in_Renamed)
		{
			lock (this)
			{
				try
				{
					if (m_debugMsgOn)
						Console.Out.WriteLine((in_Renamed)?dm.inToString(m_debugMsgSize):dm.outToString(m_debugMsgSize));
					
					if (m_debugMsgFileOn)
					{
						traceFile().Write((in_Renamed)?dm.inToString(m_debugMsgFileSize):dm.outToString(m_debugMsgFileSize));
						m_trace.Write(s_newline);
						m_trace.Flush();
					}
				}
				catch (Exception)
				{
				}
			}
		}
예제 #13
0
		/// <summary> This is the core routine for decoding incoming messages and deciding what should be
		/// done with them.  We have registered ourself with DProtocol to be notified when any
		/// incoming messages have been received.
		/// 
		/// It is important to note that we should not rely on the contents of the message
		/// since it may be reused after we exit this method.
		/// </summary>
		public virtual void  messageArrived(DMessage msg, DProtocol which)
		{
			if (m_debugMsgOn || m_debugMsgFileOn)
				trace(msg, true);
			
			/* at this point we just open up a big switch statement and walk through all possible cases */
			int type = msg.Type;
			switch (type)
			{
				
				case DMessage.InExit: 
				{
					m_isConnected = false;
					break;
				}
				
				
				case DMessage.InProcessTag: 
				{
					// need to send a response to this message to keep the player going
					sendMessage(DMessage.OutProcessedTag);
					break;
				}
				
				
				case DMessage.InAskBreakpoints: 
				//			case DMessage.InBreakAt:
				case DMessage.InBreakAtExt: 
				{
					m_isHalted = true;
					break;
				}
				
				
				case DMessage.InContinue: 
				{
					m_isHalted = false;
					break;
				}
				
				
				case DMessage.InOption: 
				{
                    String s = msg.getString();
                    String v = msg.getString();
					
					// add it to our properties, for DEBUG purposes only
					m_prefs[s] = v;
					break;
				}
				
				
				default: 
				{
					/*
					* Simple indicator that we have received a message.  We
					* put this indicator in default so that InProcessTag msgs
					* wouldn't generate false triggers.  Mainly, we want to
					* reset our timeout counter when we receive trace messages.
					*/
					m_incoming = true;
					break;
				}
				
			}
			
			// something came in so assume that we can now talk
			// to the player
			m_lastResponse = true;
		}
예제 #14
0
		// use default timeout
		internal virtual bool simpleRequestResponseMessage(DMessage msg, int msgType)
		{
			return simpleRequestResponseMessage(msg, msgType, - 1);
		}
예제 #15
0
		/// <summary> Send our message and assume that the next response that is received is
		/// ours.  Primitive but there is no use in setting up a full request / response
		/// pattern since the player doesn't follow it.
		/// 
		/// </summary>
		/// <returns> false is no response.
		/// </returns>
		internal virtual bool simpleRequestResponseMessage(DMessage msg, int msgType, int timeout)
		{
			bool response = false;
			
			// use default or user supplied timeout
			timeout = (timeout > 0)?timeout:getPreference(SessionManager.PREF_RESPONSE_TIMEOUT);
			
			// note the number of messages of this type before our send
			DMessageCounter msgCounter = MessageCounter;
			long num = msgCounter.getInCount(msgType);
			long expect = num + 1;
			
			// send the message
			sendMessage(msg);
			
			long startTime = (DateTime.Now.Ticks - 621355968000000000) / 10000;
			//		System.out.println("sending- "+DMessage.outTypeName(msg.getType())+",timeout="+timeout+",start="+start);
			
			// now wait till we see a message come in
			m_incoming = false;
			lock (msgCounter.InLock)
			{
				while ((expect > msgCounter.getInCount(msgType)) && (DateTime.Now.Ticks - 621355968000000000) / 10000 < startTime + timeout && Connected)
				{
					// block until the message counter tells us that some message has been received
					try
					{
						System.Threading.Monitor.Wait(msgCounter.InLock, TimeSpan.FromMilliseconds(timeout));
					}
					catch (System.Threading.ThreadInterruptedException e)
					{
						// this should never happen
						Console.Error.Write(e.StackTrace);
                        Console.Error.Flush();
                    }
					
					// if we see incoming messages, then we should reset our timeout
					lock (this)
					{
						if (m_incoming)
						{
							startTime = (DateTime.Now.Ticks - 621355968000000000) / 10000;
							m_incoming = false;
						}
					}
				}
			}
			
			if (msgCounter.getInCount(msgType) >= expect)
				response = true;
			else if (timeout <= 0 && Trace.error)
				Trace.trace("Timed-out waiting for " + DMessage.inTypeName(msgType) + " response to message " + msg.outToString()); //$NON-NLS-1$ //$NON-NLS-2$
			
			//		long endTime = System.currentTimeMillis();
			//		System.out.println("    response- "+response+",timeout="+timeout+",elapsed="+(endTime-startTime));
			m_lastResponse = response;
			return response;
		}
예제 #16
0
		/// <summary> Send a fully formed message and release it when done</summary>
		internal virtual void  sendMessage(DMessage dm)
		{
			lock (this)
			{
				try
				{
					m_protocol.txMessage(dm);
					
					if (m_debugMsgOn || m_debugMsgFileOn)
						trace(dm, false);
				}
				catch (IOException io)
				{
					if (Trace.error)
					{
						Trace.trace("Attempt to send message " + dm.outToString() + " failed"); //$NON-NLS-1$ //$NON-NLS-2$
                        Console.Error.Write(io.StackTrace);
                        Console.Error.Flush();
                    }
				}
				DMessageCache.free(dm);
			}
		}
예제 #17
0
		internal virtual DVariable extractVariable(DMessage msg)
		{
            DVariable v = extractVariable(msg, msg.getString());
			return v;
		}
예제 #18
0
		/// <summary> This is the core routine for decoding incoming messages and deciding what should be
		/// done with them.  We have registered ourself with DProtocol to be notified when any
		/// incoming messages have been received.
		/// 
		/// It is important to note that we should not rely on the contents of the message
		/// since it may be reused after we exit this method.
		/// </summary>
		public virtual void  messageArrived(DMessage msg, DProtocol which)
		{
			/* at this point we just open up a big switch statement and walk through all possible cases */
			int type = msg.Type;
			//		System.out.println("manager msg = "+DMessage.inTypeName(type));
			
			switch (type)
			{
				
				case DMessage.InVersion: 
				{
                    long ver = msg.getDWord();
					m_playerVersion = (int) ver;
					break;
				}
				
				
				case DMessage.InErrorExecLimit: 
				{
					handleFaultEvent(new RecursionLimitFault());
					break;
				}
				
				
				case DMessage.InErrorWith: 
				{
					handleFaultEvent(new InvalidWithFault());
					break;
				}
				
				
				case DMessage.InErrorProtoLimit: 
				{
					handleFaultEvent(new ProtoLimitFault());
					break;
				}
				
				
				case DMessage.InErrorURLOpen: 
				{
                    String url = msg.getString();
					handleFaultEvent(new InvalidURLFault(url));
					break;
				}
				
				
				case DMessage.InErrorTarget: 
				{
                    String name = msg.getString();
					handleFaultEvent(new InvalidTargetFault(name));
					break;
				}
				
				
				case DMessage.InErrorException: 
				{
                    long offset = msg.getDWord();
					// As of FP9, the player will also send the "toString()" message
					// of the exception.  But for backward compatibility with older
					// players, we won't assume that that is there.
					String exceptionMessage;
					if (msg.Remaining > 0)
                        exceptionMessage = msg.getString();
					else
						exceptionMessage = ""; //$NON-NLS-1$
					handleFaultEvent(new ExceptionFault(exceptionMessage));
					break;
				}
				
				
				case DMessage.InErrorStackUnderflow: 
				{
                    long offset = msg.getDWord();
					handleFaultEvent(new StackUnderFlowFault());
					break;
				}
				
				
				case DMessage.InErrorZeroDivide: 
				{
                    long offset = msg.getDWord();
					handleFaultEvent(new DivideByZeroFault());
					break;
				}
				
				
				case DMessage.InErrorScriptStuck: 
				{
					handleFaultEvent(new ScriptTimeoutFault());
					break;
				}
				
				
				case DMessage.InErrorConsole: 
				{
                    String s = msg.getString();
					handleFaultEvent(new ConsoleErrorFault(s));
					break;
				}
				
				
				case DMessage.InTrace: 
				{
                    String text = msg.getString();
					addEvent(new TraceEvent(text));
					break;
				}
				
				
				case DMessage.InSquelch: 
				{
                    long state = msg.getDWord();
					m_squelchEnabled = (state != 0)?true:false;
					break;
				}
				
				
				case DMessage.InParam: 
				{
                    String name = msg.getString();
                    String value = msg.getString();
					
					// here's where we get movie = URL and password which I'm not sure what to do with?
					//				System.out.println(name+"="+value);
					m_parms[name] = value;
					
					// if string is a "movie", then this is a URL
					if (name.StartsWith("movie"))
					//$NON-NLS-1$
						m_uri = convertToURI(value);
					break;
				}
				
				
				case DMessage.InPlaceObject: 
				{
                    long objId = msg.getDWord();
					String path = msg.getString();
					//				m_bag.placeObject((int)objId, path);
					break;
				}
				
				
				case DMessage.InSetProperty: 
				{
                    long objId = msg.getDWord();
					int item = msg.getWord();
                    String value = msg.getString();
					break;
				}
				
				
				case DMessage.InNewObject: 
				{
                    long objId = msg.getDWord();
					break;
				}
				
				
				case DMessage.InRemoveObject: 
				{
                    long objId = msg.getDWord();
					//				m_bag.removeObject((int)objId);
					break;
				}
				
				
				case DMessage.InSetVariable: 
				{
                    long objId = msg.getDWord();
                    String name = msg.getString();
					int dType = msg.getWord();
                    int flags = (int)msg.getDWord();
                    String value = msg.getString();
					
					//				m_bag.createVariable((int)objId, name, dType, flags, value);
					break;
				}
				
				
				case DMessage.InDeleteVariable: 
				{
                    long objId = msg.getDWord();
                    String name = msg.getString();
					//				m_bag.deleteVariable((int)objId, name);
					break;
				}
				
				
				case DMessage.InScript: 
				{
                    int module = (int)msg.getDWord();
                    int bitmap = (int)msg.getDWord();
                    String name = msg.getString(); // in "basepath;package;filename" format
                    String text = msg.getString();
					int swfIndex = - 1;
					
					/* new in flash player 9: player tells us what swf this is for */
					if (msg.Remaining >= 4)
                        swfIndex = (int)msg.getDWord();
					
					lock (m_source)
					{
						// create new source file
						if (putSource(swfIndex, module, bitmap, name, text))
						{
							// have we changed the list since last query
							if (!m_sourceListModified)
								addEvent(new FileListModifiedEvent());
							
							m_sourceListModified = true; /* current source list is stale */
						}
					}
					break;
				}
				
				
				case DMessage.InRemoveScript: 
				{
                    long module = msg.getDWord();
					lock (m_source)
					{
						if (removeSource((int) module))
						{
							// have we changed the list since last query
							if (!m_sourceListModified)
								addEvent(new FileListModifiedEvent());
							
							m_sourceListModified = true; /* current source list is stale */
						}
					}
					break;
				}
				
				
				case DMessage.InAskBreakpoints: 
				{
					// the player has just loaded a swf and we know the player
					// has halted, waiting for us to continue.  The only caveat
					// is that it looks like it still does a number of things in
					// the background which take a few seconds to complete.
					if (m_suspendInfo == null)
						m_suspendInfo = new DSuspendInfo(SuspendReason.ScriptLoaded, 0, 0, 0, 0);
					break;
				}
				
				
				case DMessage.InBreakAt: 
				{
                    long bp = msg.getDWord();
                    long id = msg.getDWord();
                    String stack = msg.getString();
					//				System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16)+",id="+id+",stack=\n"+stack);
					
					//System.out.println("InBreakAt");
					
					int module = DLocation.decodeFile(bp);
					int line = DLocation.decodeLine(bp);
					addEvent(new BreakEvent(module, line));
					break;
				}
				
				
				case DMessage.InContinue: 
				{
					/* we are running again so trash all our variable contents */
					continuing();
					break;
				}
				
				
				case DMessage.InSetLocalVariables: 
				{
                    long objId = msg.getDWord();
					//				m_bag.markObjectLocal((int)objId, true);
					break;
				}
				
				
				case DMessage.InSetBreakpoint: 
				{
                    long count = msg.getDWord();
					while (count-- > 0)
					{
                        long bp = msg.getDWord();
						
						int fileId = DLocation.decodeFile(bp);
						int line = DLocation.decodeLine(bp);
						
						DModule file = getSource(fileId);
						DLocation l = new DLocation(file, line);
						
						if (file != null)
							addBreakpoint((int) bp, l);
					}
					break;
				}
				
				
				case DMessage.InNumScript: 
				{
					/* lets us know how many scripts there are */
                    int num = (int)msg.getDWord();
					DSwfInfo swf;
					
					/*
					* New as of flash player 9: another dword indicating which swf this is for.
					* That means we don't have to guess whether this is for an old SWF
					* which has just had some more modules loaded, or for a new SWF!
					*/
					if (msg.Remaining >= 4)
					{
                        int swfIndex = (int)msg.getDWord();
						swf = getOrCreateSwfInfo(swfIndex);
						m_lastSwfInfo = swf;
					}
					else
					{
						/* This is not flash player 9 (or it is an early build of fp9).
						*
						* We use this message as a trigger that a new swf has been loaded, so make sure
						* we are ready to accept the scripts.
						*/
						swf = ActiveSwfInfo;
					}
					
					// It is NOT an error for the player to have sent us a new,
					// different sourceExpectedCount from whatever we had before!
					// In fact, this happens all the time, whenever a SWF has more
					// than one ABC.
					swf.SourceExpectedCount = num;
					break;
				}
				
				
				case DMessage.InRemoveBreakpoint: 
				{
                    long count = msg.getDWord();
					while (count-- > 0)
					{
                        long bp = msg.getDWord();
						removeBreakpoint((int) bp);
					}
					break;
				}
				
				
				case DMessage.InBreakAtExt: 
				{
                    long bp = msg.getDWord();
                    long num = msg.getDWord();
					
					//				System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16));
					/* we have stack info to store away */
					clearFrames(); // just in case
					int depth = 0;
					while (num-- > 0)
					{
                        long bpi = msg.getDWord();
                        long id = msg.getDWord();
                        String stack = msg.getString();
						int module = DLocation.decodeFile(bpi);
						int line = DLocation.decodeLine(bpi);
						DModule m = getSource(module);
						DStackContext c = new DStackContext(module, line, m, (int) id, stack, depth);
						// If addFrame() returns false, that means it chose to ignore this
						// frame, so we do NOT want to increment our depth for the next
						// time through the loop.  If it returns true, then we do want to.
						if (addFrame(c))
							++depth;
						//					System.out.println("   this="+id+",@"+(bpi&0xffff)+":"+(bpi>>16)+",stack="+stack);
					}
					mapOldFramesToNew();
					break;
				}
				
				
				case DMessage.InFrame: 
				{
					// For InFrame the first element is really our frame id
					DValue frame = null;
					DVariable child = null;
					System.Collections.ArrayList v = new System.Collections.ArrayList();
					System.Collections.ArrayList registers = new System.Collections.ArrayList();

                    int depth = (int)msg.getDWord(); // depth of frame
					
					// make sure we have a valid depth
					if (depth > - 1)
					{
						// first thing is number of registers
                        int num = (int)msg.getDWord();
						for (int i = 0; i < num; i++)
							registers.Add(extractRegister(msg, i + 1));
					}
					
					int currentArg = - 1;
					bool gettingScopeChain = false;
					
					// then our frame itself
					while (msg.Remaining > 0)
					{
                        long frameId = msg.getDWord();
						
						if (frame == null)
						{
							frame = getOrCreateValue(frameId);
							extractVariable(msg); // put the rest of the info in the trash
						}
						else
						{
							child = extractVariable(msg);
							if (currentArg == - 1 && child.getName().Equals(ARGUMENTS_MARKER))
							{
								currentArg = 0;
								gettingScopeChain = false;
							}
							else if (child.getName().Equals(SCOPE_CHAIN_MARKER))
							{
								currentArg = - 1;
								gettingScopeChain = true;
							}
							else if (currentArg >= 0)
							{
								// work around a compiler bug: If the variable's name is "undefined",
								// then change its name to "_argN", where "N" is the argument index,
								// e.g. _arg1, _arg2, etc.
								++currentArg;
								if (child.getName().Equals("undefined"))
								//$NON-NLS-1$
									child.setName("_arg" + currentArg); //$NON-NLS-1$
							}
							
							// All args and locals get added as "children" of
							// the frame; but scope chain entries do not.
							if (!gettingScopeChain)
								addVariableMember(frameId, child);
							
							// Everything gets added to the ordered list of
							// variables that came in.
							v.Add(child);
						}
					}
					
					// let's transfer our newly gained knowledge into the stack context
					if (depth == 0)
						populateRootNode(frame, v);
					else
						populateFrame(depth, v);
					
					break;
				}
				
				
				case DMessage.InOption: 
				{
                    String s = msg.getString();
                    String v = msg.getString();
					m_options[s] = v;
					break;
				}
				
				
				case DMessage.InGetVariable: 
				{
					// For InGetVariable the first element is the original entity we requested
					DValue parent = null;
					DVariable child = null;
					String definingClass = null;
					int level = 0;
					int highestLevelWithMembers = - 1;
					System.Collections.IList classes = new System.Collections.ArrayList();
					
					while (msg.Remaining > 0)
					{
                        long parentId = msg.getDWord();
						
						// build or get parent node
						if (parent == null)
						{
                            String name = msg.getString();
							
							// pull the contents of the node which normally are disposed of except if we did a 0,name call
							m_lastInGetVariable = extractVariable(msg, name);
							
							parent = getOrCreateValue(parentId);
						}
						else
						{
							// extract the child and add it to the parent.
							child = extractVariable(msg);
							if (showMember(child))
							{
								if (child.isAttributeSet(VariableAttribute.IS_DYNAMIC))
								{
									// Dynamic attributes always come in marked as a member of
									// class "Object"; but to the user, it makes more sense to
									// consider them as members of the topmost class.
									if (classes.Count > 0)
									{
										child.setDefiningClass(0, (String) classes[0]);
										highestLevelWithMembers = Math.Max(highestLevelWithMembers, 0);
									}
								}
								else
								{
									child.setDefiningClass(level, definingClass);
									if (definingClass != null)
									{
										highestLevelWithMembers = Math.Max(highestLevelWithMembers, level);
									}
								}
								addVariableMember(parent.Id, child);
							}
							else
							{
								if (isTraits(child))
								{
									definingClass = child.QualifiedName;
									level = classes.Count;
									
									// If the traits name end with "$", then it represents a class object --
									// in other words, the variables inside it are static variables of that
									// class.  In that case, we need to juggle the information.  For example,
									// if we are told that a variable is a member of "MyClass$", we actually
									// store it into the information for "MyClass".
									if (definingClass.EndsWith("$"))
									{
										//$NON-NLS-1$
										String classWithoutDollar = definingClass.Substring(0, (definingClass.Length - 1) - (0));
										int indexOfClass = classes.IndexOf(classWithoutDollar);
										if (indexOfClass != - 1)
										{
											level = indexOfClass;
											definingClass = classWithoutDollar;
										}
									}
									
									// It wasn't static -- so, add this class to the end of the list of classes
									if (level == classes.Count)
									{
										classes.Add(definingClass);
									}
								}
							}
						}
					}
					
					if (parent != null && parent.getClassHierarchy(true) == null)
					{
                        String[] classesArray = new String[classes.Count];
                        int index = 0;

                        foreach (String className in classes)
                        {
                            classesArray[index++] = className;
                        }

						parent.setClassHierarchy(classesArray, highestLevelWithMembers + 1);
					}
					
					break;
				}
				
				
				case DMessage.InWatch: 
				// for AS2; sends 16-bit ID field
				case DMessage.InWatch2:  // for AS3; sends 32-bit ID field
					{
						// This message is sent whenever a watchpoint is added
						// modified or removed.
						//
						// For an addition, flags will be non-zero and
						// success will be true.
						//
						// For a modification flags  will be non-zero.
						// and oldFlags will be non-zero and success
						// will be true.  Additionally oldFlags will not
						// be equal to flags.
						//
						// For a removal flags will be zero.  oldFlags
						// will be non-zero.
						//
						// flags identifies the type of watchpoint added,
						// see WatchKind.
						//
						// success indicates whether the operation was successful
						//
						// request.   It will be associated with the watchpoint.
                        int success = msg.getWord();
                        int oldFlags = msg.getWord();
                        int oldTag = msg.getWord();
                        int flags = msg.getWord();
                        int tag = msg.getWord();
						// for AS2, the ID came in above as a Word.  For AS3, the above value is
						// bogus, and it has been sent again as a DWord.
                        int id = (int)((type == DMessage.InWatch2) ? msg.getDWord() : msg.getWord());
                        String name = msg.getString();
						
						if (success != 0)
						{
							if (flags == 0)
							{
								removeWatchpoint(oldTag);
							}
							else
							{
								// modification or addition is the same to us
								// a new watch is created and added into the table
								// while any old entry if it exists is removed.
								removeWatchpoint(oldTag);
								DWatch w = new DWatch(id, name, flags, tag);
								addWatchpoint(w);
							}
						}
						break;
					}
				
				
				case DMessage.InGetSwf: 
				{
					// we only house the swf temporarily, PlayerSession then
					// pieces it back into swfinfo record.  Also, we don't
					// send any extra data in the message so that we need not
					// copy the bytes.
					m_swf = msg.Data;
					break;
				}
				
				
				case DMessage.InGetSwd: 
				{
					// we only house the swd temporarily, PlayerSession then
					// pieces it back into swfinfo record.
					m_swd = msg.Data;
					break;
				}
				
				
				case DMessage.InBreakReason: 
					{
						// the id map 1-1 with out SuspendReason interface constants
                        int suspendReason = msg.getWord();
                        int suspendPlayer = msg.getWord(); // item index of player
                        int breakOffset = (int)msg.getDWord(); // current script offset
                        int prevBreakOffset = (int)msg.getDWord(); // prev script offset
                        int nextBreakOffset = (int)msg.getDWord(); // next script offset
						m_suspendInfo = new DSuspendInfo(suspendReason, suspendPlayer, breakOffset, prevBreakOffset, nextBreakOffset);
						
						// augment the current frame with this information.  It
						// should work ok since we only get this message after a
						// InBreakAtExt message
						try
						{
							DStackContext c = getFrame(0);
							c.Offset = breakOffset;
							c.SwfIndex = suspendPlayer;
						}
						catch (Exception e)
						{
							if (Trace.error)
							{
								Trace.trace("Oh my god, gag me with a spoon...getFrame(0) call failed"); //$NON-NLS-1$
                                Console.Error.Write(e.StackTrace);
                                Console.Error.Flush();
                            }
						}
						break;
					}
					
					// obtain raw action script byte codes
				
				case DMessage.InGetActions: 
					{
                        int item = msg.getWord();
                        int rsvd = msg.getWord();
                        int at = (int)msg.getDWord();
                        int len = (int)msg.getDWord();
						int i = 0;
						
						m_actions = (len <= 0)?null:new byte[len];
						while (len-- > 0)
                            m_actions[i++] = (byte)msg.getByte();
						
						break;
					}
					
					// obtain data about a SWF
				
				case DMessage.InSwfInfo: 
					{
                        int count = msg.getWord();
						for (int i = 0; i < count; i++)
						{
                            long index = msg.getDWord();
                            long id = msg.getDWord();
							
							// get it
							DSwfInfo info = getOrCreateSwfInfo((int) index);
							
							// remember which was last seen
							m_lastSwfInfo = info;
							
							if (id != 0)
							{
                                bool debugComing = (msg.getByte() == 0) ? false : true;
                                byte vmVersion = (byte)msg.getByte(); // AS vm version number (1 = avm+, 0 == avm-)
                                int rsvd1 = msg.getWord();

                                long swfSize = msg.getDWord();
                                long swdSize = msg.getDWord();
                                long scriptCount = msg.getDWord();
                                long offsetCount = msg.getDWord();
                                long breakpointCount = msg.getDWord();

                                long port = msg.getDWord();
                                String path = msg.getString();
                                String url = msg.getString();
                                String host = msg.getString();
								
								// now we read in the swd debugging map (which provides
								// local to global mappings of the script ids
                                long num = msg.getDWord();
								IntMap local2global = new IntMap();
								int minId = Int32.MaxValue;
								int maxId = Int32.MinValue;
								for (int j = 0; j < num; j++)
								{
                                    long local = msg.getDWord();
                                    long global = msg.getDWord();
									local2global.put((int) local, (Int32) global);
									minId = ((int) global < minId)?(int) global:minId;
									maxId = ((int) global > maxId)?(int) global:maxId;
								}
								
								// If its a new record then the swf size would have been unknown at creation time
								bool justCreated = (info.SwfSize == 0);
								
								// if we are a avm+ engine then we don't wait for the swd to load
								if (vmVersion > 0)
								{
									debugComing = false;
									info.VmVersion = vmVersion;
									info.setPopulated(); // added by mmorearty on 9/5/05 for RSL debugging
								}
								
								// update this swfinfo with the lastest data
								info.freshen(id, path, url, host, port, debugComing, swfSize, swdSize, breakpointCount, offsetCount, scriptCount, local2global, minId, maxId);
								// now tie any scripts that have been loaded into this swfinfo object
								tieScriptsToSwf(info);
								
								// notify if its newly created
								if (justCreated)
									addEvent(new SwfLoadedEvent(id, (int) index, path, url, host, port, swfSize));
							}
							else
							{
								// note our state before marking it
								bool alreadyUnloaded = info.isUnloaded();
								
								// clear it out
								info.setUnloaded();
								
								// notify if this information is new.
								if (!alreadyUnloaded)
									addEvent(new SwfUnloadedEvent(info.Id, info.Path, (int) index));
							}
							//					System.out.println("[SWFLOAD] Loaded "+path+", size="+swfSize+", scripts="+scriptCount);
						}
						break;
					}
					
					// obtain the constant pool of some player
				
				case DMessage.InConstantPool: 
					{
                        int item = msg.getWord();
                        int count = (int)msg.getDWord();
						
						String[] pool = new String[count];
						for (int i = 0; i < count; i++)
						{
                            long id = msg.getDWord();
							DVariable var = extractVariable(msg);
							
							// we only need the contents of the variable
							pool[i] = var.getValue().ValueAsString;
						}
						m_lastConstantPool = pool;
						break;
					}
					
					// obtain one or more function name line number mappings.
				
				case DMessage.InGetFncNames: 
				{
                    long id = msg.getDWord(); // module id
                    long count = msg.getDWord(); // number of entries
					
					// get the DModule
					DModule m = getSource((int) id);
					if (m != null)
					{
						for (int i = 0; i < count; i++)
						{
                            int offset = (int)msg.getDWord();
                            int firstLine = (int)msg.getDWord();
                            int lastLine = (int)msg.getDWord();
                            String name = msg.getString();
							
							// now add the entries
							m.addLineFunctionInfo(offset, firstLine, lastLine, name);
						}
					}
					break;
				}
				
				
				default: 
				{
					break;
				}
				
			}
		}
예제 #19
0
		/// <summary> Does the job of pulling together a variable based on
		/// the type of object encountered.
		/// </summary>
		internal virtual DVariable extractAtom(DMessage msg, String name, int oType, int flags)
		{
			int vType = VariableType.UNKNOWN;
			Object value = null;
			String typeName = ""; //$NON-NLS-1$
			String className = ""; //$NON-NLS-1$
			
			/* now we vary depending upon type */
			switch (oType)
			{
				
				case DMessage.kNumberType: 
				{
                    String s = msg.getString();
					double dval = 0;
					try
					{
                        System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo();
                        dval = Double.Parse(s, nfi);
                    }
					catch (FormatException)
					{
					}
					
					value = (double) dval;
					vType = VariableType.NUMBER;
					typeName = "Number"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kBooleanType: 
				{
                    int bval = msg.getByte();
					value = (bval == 0)?false:true;
					vType = VariableType.BOOLEAN;
					typeName = "Boolean"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kStringType: 
				{
                    String s = msg.getString();
					
					value = s;
					vType = VariableType.STRING;
					typeName = "String"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kObjectType: 
				case DMessage.kNamespaceType: 
				{
                    long oid = msg.getDWord();
                    long cType = (oid == -1) ? 0 : msg.getDWord();
                    int isFnc = (oid == -1) ? 0 : msg.getWord();
                    int rsvd = (oid == -1) ? 0 : msg.getWord();
                    typeName = (oid == -1) ? "" : msg.getString(); //$NON-NLS-1$
					className = DVariable.classNameFor(cType, false);
					
					value = (long) oid;
					vType = (isFnc == 0)?VariableType.OBJECT:VariableType.FUNCTION;
					break;
				}
				
				
				case DMessage.kMovieClipType: 
				{
                    long oid = msg.getDWord();
                    long cType = (oid == -1) ? 0 : msg.getDWord();
                    long rsvd = (oid == -1) ? 0 : msg.getDWord();
                    typeName = (oid == -1) ? "" : msg.getString(); //$NON-NLS-1$
					className = DVariable.classNameFor(cType, true);
					
					value = (long) oid;
					vType = VariableType.MOVIECLIP;
					break;
				}
				
				
				case DMessage.kNullType: 
				{
					vType = VariableType.NULL;
					typeName = "null"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kUndefinedType: 
				{
					vType = VariableType.UNDEFINED;
					typeName = "undefined"; //$NON-NLS-1$
					break;
				}
				
				
				case DMessage.kTraitsType: 
				{
					// This one is special: When passed to the debugger, it indicates
					// that the "variable" is not a variable at all, but rather is a
					// class name.  For example, if class Y extends class X, then
					// we will send a kDTypeTraits for class Y; then we'll send all the
					// members of class Y; then we'll send a kDTypeTraits for class X;
					// and then we'll send all the members of class X.  This is only
					// used by the AVM+ debugger.
					vType = VariableType.UNKNOWN;
					typeName = Value.TRAITS_TYPE_NAME;
					break;
				}
				
				
				case DMessage.kReferenceType: 
				case DMessage.kArrayType: 
				case DMessage.kObjectEndType: 
				case DMessage.kStrictArrayType: 
				case DMessage.kDateType: 
				case DMessage.kLongStringType: 
				case DMessage.kUnsupportedType: 
				case DMessage.kRecordSetType: 
				case DMessage.kXMLType: 
				case DMessage.kTypedObjectType: 
				case DMessage.kAvmPlusObjectType: 
				default: 
				{
					//				System.out.println("<unknown>");
					break;
				}
				}
			
			// create the variable based on the content we received.
			DValue valueObject = null;
			if (value is Int64)
			{
				valueObject = getValue((long) ((Int64) value));
			}
			
			if (valueObject == null)
			{
				valueObject = new DValue(vType, typeName, className, toAttributes(flags), value);
				
				if (value is Int64 && (toAttributes(flags) & VariableAttribute.HAS_GETTER) == 0)
					putValue((long) ((Int64) value), valueObject);
			}
			else
			{
				valueObject.setType(vType);
				valueObject.setTypeName(typeName);
				valueObject.setClassName(className);
				valueObject.setAttributes(toAttributes(flags));
				valueObject.Value = value;
			}
			
			DVariable var = new DVariable(name, valueObject);
			return var;
		}
예제 #20
0
		/// <summary> Extracts an builds a register variable</summary>
		internal virtual DVariable extractRegister(DMessage msg, int number)
		{
            int oType = msg.getWord();
			return extractAtom(msg, "$" + number, oType, 0); //$NON-NLS-1$
		}
예제 #21
0
		/// <summary> Build a variable based on the information we can extract from the messsage</summary>
		internal virtual DVariable extractVariable(DMessage msg, String name)
		{
            int oType = msg.getWord();
            int flags = (int)msg.getDWord();
			return extractAtom(msg, name, oType, flags);
		}