public override Dictionary<String, Option> match(Dictionary<String, Option> variables, TransactionalStreamReader input, out List<Option> fields) { input.startTransaction(); Dictionary<String, Option> myEnv = variables; fields = new List<Option>(); foreach (Rule rule in rules) { List<Option> newFields; myEnv = rule.match(myEnv, input, out newFields); if (myEnv == null) break; if (newFields != null) fields.AddRange(newFields); } if (myEnv == null) { input.cancelTransaction(); if (failSilently) return variables; else return null; } else { if (this.name != null) myEnv[name] = new OptionArray(name, input.getTransactionData()); input.commitTransaction(); return myEnv; } }
public void cancelTransactionTest() { Stream stream = new MemoryStream(); TransactionalStreamReader target = new TransactionalStreamReader(stream); // Przygotuj dane testowe stream.WriteByte(9); stream.WriteByte(20); stream.WriteByte(31); stream.WriteByte(42); stream.Seek(0, SeekOrigin.Begin); target.startTransaction(); Assert.AreEqual(target.ReadByte(), 9); Assert.AreEqual(target.ReadByte(), 20); target.cancelTransaction(); target.startTransaction(); Assert.AreEqual(target.ReadByte(), 9); Assert.AreEqual(target.ReadByte(), 20); Assert.AreEqual(target.ReadByte(), 31); Assert.AreEqual(target.ReadByte(), 42); target.cancelTransaction(); Assert.AreEqual(stream.ReadByte(), -1); // Cały strumien został zjedzony }
public override bool match(TransactionalStreamReader s) { // First, read whatever is in the stream int newValue = 0; s.startTransaction(); for (int i = 0; i < Size; i++) { newValue |= s.ReadByte() << (8*i); } if (MinValue > newValue || newValue > MaxValue) { s.cancelTransaction(); return false; } if (myValue == null) { Value = newValue; s.commitTransaction(); return true; } else // myValue != null if (myValue == newValue) { s.commitTransaction(); return true; } else { s.cancelTransaction(); return false; } }
public override bool match(TransactionalStreamReader s) { // FIXME: wczytywanie vs. dopasowanie tablic s.startTransaction(); foreach (Option o in OptionsArray) if (!o.match(s)) { s.cancelTransaction(); return false; } s.commitTransaction(); return true; }
/// <summary> /// Zaczyna odczytywanie danych, kontynuuje do zakończenia strumienia lub wywołania stop() (TODO: faktycznie wprowadź stop()) /// Ta metoda będzie wywoływać messageReceived i messageSent. /// </summary> /// <param name="inStream">strumień z którego czytane będą dane</param> /// <param name="outStream">strumień do którego wysyłane będą odpowiedzi</param> public void run(Stream inStream, Stream outStream) { TransactionalStreamReader transStream = new TransactionalStreamReader(inStream); while (transStream.isReadable()) { // Zmienne środowiskowe dla tej transakcji Dictionary<String,Option> env = new Dictionary<string,Option>(); foreach(Option opt in options) env.Add(opt.Name, opt); List<Option> fields; transStream.startTransaction(); env = this.msg_start_mark.match(env, transStream, out fields); if (env == null) throw new NotImplementedException("Should wait for next msg_start_mark"); Dictionary<String, Option> nextEnv = null; nextEnv = matchIncoming(env, transStream, new List<Message>(), out fields); if (nextEnv == null) throw new NotImplementedException("Should wait for next msg_start_mark (no requestMsg matched)"); env = nextEnv; FullMessage msgIn = new FullMessage(fields); if(messageReceived != null) messageReceived(msgIn, new List<Option>(env.Values)); Transaction transaction = null; foreach (Device d in this.RegisteredDevices) { Dictionary<String, Option> deviceEnv = new Dictionary<string, Option>(env); foreach (Option opt in d.Options) { deviceEnv.Add(opt.Name, opt); } foreach (Transaction t in d.Transactions) { Dictionary<String, Option> transEnv = new Dictionary<string,Option>(deviceEnv); transEnv = t.match(transEnv); if (transEnv != null) { transaction = t; env = transEnv; break; } } if (transaction != null) break; } if (transaction == null) throw new NotImplementedException("No transaction matched, wait for next message"); List<byte[]> output; nextEnv = matchOutgoing(env, new List<Message>(), out output, out fields); if(nextEnv == null) throw new NotImplementedException("No outgoing message matched, wait for next message"); FullMessage msgOut = new FullMessage(fields); if (messageSent != null) messageSent(transaction, msgIn, msgOut, new List<Option>(env.Values)); foreach (byte[] data in output) outStream.Write(data, 0, data.Length); } }
public Dictionary<string, Option> matchIncoming(Dictionary<string, Option> env, TransactionalStreamReader transStream, List<Message> excluded, out List<Option> fields) { List<Message> oldExcluded = excludedSoFar; excludedSoFar = excluded; Dictionary<String, Option> nextEnv = null; fields = new List<Option>(); foreach (Message msg in requestMsgs) { if (!excluded.Contains(msg)) { List<Option> newFields; Message oldCurrentMsg = currentMessage; currentMessage = msg; transStream.startTransaction(); nextEnv = msg.match(env, transStream, out newFields); currentMessage = oldCurrentMsg; if (nextEnv == null) transStream.cancelTransaction(); else { if (newFields != null) fields.AddRange(newFields); transStream.commitTransaction(); break; } } } excludedSoFar = oldExcluded; return nextEnv; }