public static T Parse <T>(string message, IUserInterface userInterface = null, bool throwJsonException = true) where T : CMakeMessage { try { CMakeMessage cMakeMessage; JObject content = JObject.Parse(message, new JsonLoadSettings { LineInfoHandling = LineInfoHandling.Ignore }); userInterface?.WriteVerbose(content.ToString(Formatting.Indented)); switch (content["type"].Value <string>()) { case "hello": cMakeMessage = CMakeHelloMessage.Create(content); break; case "reply": cMakeMessage = CMakeReplyMessage.Create(content); break; case "progress": cMakeMessage = CMakeProgressMessage.Create(); break; case "message": cMakeMessage = CMakeMessageMessage.Create(content); break; case "signal": userInterface?.WriteVerbose("Received signal message from cmake server. Signal messages are ignored."); return(null); default: throw new FormattableException($"Unknown message type {content["type"].Value<string>()}.{Environment.NewLine}" + $"Complete message: {message}"); } if (cMakeMessage is T converted) { return(converted); } throw new FormattableException($"Expected message of type {typeof(T)}, but message was of type {cMakeMessage.GetType()}"); } catch (JsonReaderException e) { if (throwJsonException) { throw new FormattableException($"Error while parsing the response json{Environment.NewLine}{message}.", e); } return(null); } }
private async Task <CMakeReplyMessage> WaitForReply(string type) { CMakeProgressMessage progressMessage = null; CMakeMessageMessage messageMessage = null; CMakeMessage message = null; do { foreach (string singleMessage in await serverStream.ReadMessage() .TimeoutAfter(CMakeServerTimeout) .ConfigureAwait(false)) { //Expect at least a progress message after default timeout message = ParseMessage(singleMessage); if (message is CMakeReplyMessage replyMessage) { CheckCookieAndType(replyMessage); return(replyMessage); } } } while (progressMessage != null || messageMessage != null || message == null); throw new InvalidOperationException("This is not possible."); void CheckCookieAndType(CMakeBaseResponseMessage responseMessage) { if (!string.IsNullOrEmpty(cookie) && responseMessage.Cookie != cookie) { throw new FormattableException($"Expected a message with the cookie {cookie}, " + $"but got a message with the cookie {responseMessage.Cookie}. " + "Someone else is taking to the server unexpectedly."); } if (responseMessage.ResponseType != type) { throw new FormattableException($"Expected a message in response to {type}, " + $"but got a message in response to {responseMessage.ResponseType}. " + "Someone else is taking to the server unexpectedly " + "or the server is confusing."); } } CMakeMessage ParseMessage(string singleMessage) { CMakeMessage parsedMessage = CMakeMessage.Parse <CMakeMessage>(singleMessage, userInterface); progressMessage = parsedMessage as CMakeProgressMessage; messageMessage = parsedMessage as CMakeMessageMessage; if (messageMessage != null) { CheckCookieAndType(messageMessage); if (messageMessage.Title.Contains("error", StringComparison.OrdinalIgnoreCase)) { throw new FormattableException($"CMake discovered an error.{Environment.NewLine}" + $"{messageMessage.Title}{Environment.NewLine}" + $"==================================={Environment.NewLine}" + $"{messageMessage.Message}"); } } return(parsedMessage); } }