/// <summary> /// Wraps IConnector.Connect. In addition, writes data to a sink if MillipedeConnector is /// initialized with Mode.Record. The returning ITransport is wrapped in a /// MillipedeTransport. /// </summary> /// <seealso cref="IConnector.Connect"/> public ITransport Connect(string address, string port, IDictionary<string, string> capabilities) { switch (recorder.Mode) { case MillipedeMode.Unconfigured: case MillipedeMode.PassThrough: default: return underlyingConnector.Connect(address, port, capabilities); case MillipedeMode.Playback: // Wait until a connection event comes in MillipedeEvent connectEvent = recorder.WaitForReplayEvent(milliDescriptor, MillipedeEventType.Connected, MillipedeEventType.Exception); if(connectEvent.Type == MillipedeEventType.Exception) { throw (Exception)connectEvent.Context; } if(connectEvent.Type == MillipedeEventType.Connected) { MemoryStream stream = new MemoryStream(connectEvent.Message); BinaryFormatter formatter = new BinaryFormatter(); object milliTransportDescriptor = formatter.Deserialize(stream); string transportName = (string)formatter.Deserialize(stream); Dictionary<string, string> ignored = (Dictionary<string, string>)formatter.Deserialize(stream); Reliability reliability = (Reliability)formatter.Deserialize(stream); Ordering ordering = (Ordering)formatter.Deserialize(stream); uint maxPacketSize = (uint)formatter.Deserialize(stream); // FIXME: should we be checking the capabilities? Probably...! ITransport mockTransport = new MillipedeTransport(recorder, milliTransportDescriptor, transportName, capabilities, reliability, ordering, maxPacketSize); return mockTransport; } throw new InvalidStateException("invalid event type for Connect()!", connectEvent); case MillipedeMode.Record: ITransport transport; try { transport = underlyingConnector.Connect(address, port, capabilities); object milliTransportDesriptor = recorder.GenerateDescriptor(transport); MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, milliTransportDesriptor); formatter.Serialize(stream, transport.Name); formatter.Serialize(stream, capabilities); formatter.Serialize(stream, transport.Reliability); formatter.Serialize(stream, transport.Ordering); formatter.Serialize(stream, transport.MaximumPacketSize); ITransport mockTransport = new MillipedeTransport(transport, recorder, milliTransportDesriptor); recorder.Record(new MillipedeEvent(milliDescriptor, MillipedeEventType.Connected, stream.ToArray())); return mockTransport; } catch(GTException e) { recorder.Record(new MillipedeEvent(milliDescriptor, MillipedeEventType.Exception, e)); throw; } } }
/// <summary> /// Wraps IAcceptor.Update. /// </summary> /// <see cref="IAcceptor.Update"/> public override void Update() { switch (recorder.Mode) { case MillipedeMode.Unconfigured: case MillipedeMode.PassThrough: default: underlyingAcceptor.Update(); return; case MillipedeMode.Record: try { underlyingAcceptor.Update(); } catch(GTException ex) { recorder.Record(new MillipedeEvent(milliDescriptor, MillipedeEventType.Exception, ex)); throw; } return; case MillipedeMode.Playback: // or if recorder.Mode == MillipedeMode.PassThrough? // See if there's an event and process it if so MillipedeEvent e = recorder.CheckReplayEvent(milliDescriptor, MillipedeEventType.NewClient, MillipedeEventType.Exception); if(e == null) { return; } if(e.Type == MillipedeEventType.Exception) { throw (Exception)e.Context; } Debug.Assert(e.Type == MillipedeEventType.NewClient); MemoryStream stream = new MemoryStream(e.Message); BinaryFormatter formatter = new BinaryFormatter(); object milliTransportDescriptor = formatter.Deserialize(stream); string transportName = (string)formatter.Deserialize(stream); Dictionary<string, string> capabilities = (Dictionary<string, string>)formatter.Deserialize(stream); Reliability reliability = (Reliability)formatter.Deserialize(stream); Ordering ordering = (Ordering)formatter.Deserialize(stream); uint maxPacketSize = (uint)formatter.Deserialize(stream); ITransport mockTransport = new MillipedeTransport(recorder, milliTransportDescriptor, transportName, capabilities, reliability, ordering, maxPacketSize); NotifyNewTransport(mockTransport, capabilities); return; } }