public static void TestDeserializationToNull(StringBuilder builder, Type type, String str, Int32 expectedLengthUsed) { Object obj; Int32 offset = Sos.Deserialize(out obj, type, str, 0, str.Length); Console.WriteLine("String '{0}' Object After Deserialization '{1}'", str, obj); Assert.AreEqual(expectedLengthUsed, offset); Assert.IsNull(obj); }
public static void TestSerializer(StringBuilder builder, Object obj) { builder.Length = 0; obj.SerializeObject(builder); String seralizationString = builder.ToString(); //Console.WriteLine("SerializationString '{0}'", seralizationString); Object newObject = null; Int32 offset = -1; try { offset = Sos.Deserialize(out newObject, obj.GetType(), seralizationString, 0, seralizationString.Length); } catch (Exception e) { throw new Exception(String.Format("Deserialization failed: {0}. Serialized string was '{1}'", e, seralizationString), e); } /* * String objString; * try * { * objString = obj.ToString(); * } * catch (NullReferenceException) * { * objString = "[NullReferenceException in ToString() Method]"; * } * String newObjectString; * try * { * newObjectString = newObject.ToString(); * } * catch (NullReferenceException) * { * newObjectString = "[NullReferenceException in ToString() Method]"; * } * Console.WriteLine("Before Serialization '{0}' ({1}) SerializeString '{2}' After '{3}' ({4})", * objString, obj.GetType(), seralizationString, newObjectString, newObject.GetType()); */ Assert.AreEqual(seralizationString.Length, offset); String diffMessage = obj.Diff(newObject); if (diffMessage != null) { Assert.Fail(diffMessage); } }
public static void TestDeserializeFormatException(StringBuilder builder, Type type, String str) { Object obj; try { Int32 offset = Sos.Deserialize(out obj, type, str, 0, str.Length); Assert.Fail("Expected FormatException but didn't get one for string '{0}'", str); } catch (FormatException e) { Console.WriteLine("String '{0}' Produced FormatException '{1}'", str, e.Message); } }
public void FullUTF16CharacterTestCoverage() { StringBuilder builder = new StringBuilder(); Util.TestDeserialization(builder, '\0', @"""\0"""); Util.TestDeserialization(builder, '\n', @"""\n"""); Util.TestDeserialization(builder, '\r', @"""\r"""); Util.TestDeserialization(builder, '\t', @"""\t"""); Util.TestDeserialization(builder, '\\', @"""\\"""); Util.TestDeserialization(builder, '\xab', @"""\xab"""); Util.TestDeserialization(builder, '\x9F', @"""\x9F"""); Util.TestDeserialization(builder, '\uabCe', @"""\uabCe"""); Util.TestDeserialization(builder, '\u9F3C', @"""\u9F3C"""); //Util.TestDeserialization(builder, '\a', @"""\a"""); //Util.TestDeserialization(builder, '\b', @"""\b"""); //Util.TestDeserialization(builder, '\f', @"""\f"""); //Util.TestDeserialization(builder, '\v', @"""\v"""); for (Int32 cAsInt = 0; cAsInt <= 65535; cAsInt++) { Char c = (Char)cAsInt; String seralizationString = c.SerializeChar(); Object newObject = null; Int32 offset = -1; try { offset = Sos.Deserialize(out newObject, typeof(Char), seralizationString, 0, seralizationString.Length); } catch (Exception e) { throw new Exception(String.Format("Deserialization failed: {0}. Serialized string was '{1}'", e, seralizationString), e); } //Console.WriteLine("Before Serialization '{0}' ({1}) SerializeString '{2}' After '{3}' ({4})", // c, typeof(Char), seralizationString, newObject, newObject.GetType()); Assert.AreEqual(seralizationString.Length, offset); String diffMessage = c.Diff(newObject); if (diffMessage != null) { Assert.Fail(diffMessage); } } }
public static void TestDeserialization(StringBuilder builder, Object expectedObject, String str, Int32 expectedLengthUsed) { Object newObject; Int32 offset = Sos.Deserialize(out newObject, expectedObject.GetType(), str, 0, str.Length); Console.WriteLine("String '{0}' Object After Deserialization '{1}'", str, newObject); String diffMessage = expectedObject.Diff(newObject); if (diffMessage != null) { Assert.Fail(diffMessage); } Assert.AreEqual(expectedLengthUsed, offset); }
void ThrowExceptionFromCall(String methodName, NpcReturnLine returnLine) { Type exceptionType; try { exceptionType = staticClientTypeFinder.FindType(returnLine.sosTypeName); } catch (InvalidOperationException) { //Console.WriteLine("Could not find type '{0}'", returnLine.sosTypeName); goto INVALID_EXCEPTION; } Object exceptionObject; try { Int32 offset = Sos.Deserialize(out exceptionObject, exceptionType, returnLine.sosSerializationString, 0, returnLine.sosSerializationString.Length); if (offset != returnLine.sosSerializationString.Length) { goto INVALID_EXCEPTION; } } catch (Exception) { //Console.WriteLine("Faild to deserialize exception '{0}'", returnLine.sosTypeName); goto INVALID_EXCEPTION; } try { Exception e = (Exception)exceptionObject; throw e; } catch (InvalidCastException) { //Console.WriteLine("Could not cast '{0}' to Exception", exceptionObject.GetType().Name); goto INVALID_EXCEPTION; } INVALID_EXCEPTION: throw new Exception(String.Format("Method '{0}' threw exception {1}: '{2}'", methodName, returnLine.sosTypeName, returnLine.exceptionMessage)); }
// // Throws NpcErrorException for an npc error // public NpcReturnLine(String returnLine) { Boolean success = returnLine.StartsWith(NpcReturnObject.NpcReturnLineSuccessPrefix); if (success || returnLine.StartsWith(NpcReturnObject.NpcReturnLineExceptionPrefix)) { String noPrefixReturnLine; if (success) { noPrefixReturnLine = returnLine.Substring(NpcReturnLineSuccessPrefix.Length); if (noPrefixReturnLine.Equals("Void")) { this.exceptionMessage = null; this.sosTypeName = "Void"; this.sosSerializationString = null; return; } } else { noPrefixReturnLine = returnLine.Substring(NpcReturnLineExceptionPrefix.Length); // // Exception Message // Object exceptionMessageObject; Int32 offset = Sos.Deserialize(out exceptionMessageObject, typeof(String), noPrefixReturnLine, 0, noPrefixReturnLine.Length); this.exceptionMessage = (String)exceptionMessageObject; if (offset >= noPrefixReturnLine.Length - 1) { InvalidReturnLine(returnLine, "Missing exception type and serialized exception"); } noPrefixReturnLine = noPrefixReturnLine.Substring(offset + 1); } // // Get the return type // Int32 spaceIndex = noPrefixReturnLine.IndexOf(' '); if (spaceIndex < 0 || spaceIndex >= noPrefixReturnLine.Length - 1) { InvalidReturnLine(returnLine, "missing the return value"); } if (spaceIndex == 0) { InvalidReturnLine(returnLine, "After 'Success' prefix there were 2 spaces in a row"); } this.sosTypeName = noPrefixReturnLine.Remove(spaceIndex); this.sosSerializationString = noPrefixReturnLine.Substring(spaceIndex + 1); return; } if (returnLine.StartsWith(NpcReturnObject.NpcReturnLineNpcErrorPrefix)) { String errorCode; returnLine.Peel(out errorCode); errorCode = errorCode.Peel(out returnLine); throw new NpcErrorException((NpcErrorCode)Enum.Parse(typeof(NpcErrorCode), errorCode), returnLine); } InvalidReturnLine(returnLine, String.Format("does not start with '{0}','{1}' or '{2}'", NpcReturnObject.NpcReturnLineSuccessPrefix, NpcReturnObject.NpcReturnLineNpcErrorPrefix, NpcReturnObject.NpcReturnLineExceptionPrefix)); }
public static Object[] CreateParameterObjects(ParameterInfo[] parameterInfos, params String[] parameterStrings) { int parameterStringsLength = (parameterStrings == null) ? 0 : parameterStrings.Length; int parameterInfosLength = (parameterInfos == null) ? 0 : parameterInfos.Length; if (parameterInfosLength != parameterStringsLength) { throw new InvalidOperationException(String.Format("Expected {0} arguments but got {1}", parameterInfosLength, parameterStringsLength)); } if (parameterStringsLength <= 0) { return(null); } Object[] parameterObjects = new Object[parameterStringsLength]; for (int i = 0; i < parameterStringsLength; i++) { String parameterString = parameterStrings[i]; ParameterInfo parameterInfo = parameterInfos[i]; Type parameterType = parameterInfos[i].ParameterType; //Console.WriteLine("Parameter {0} Type={1}", parameterInfo.Name, parameterType); // // Add quotes if parameter is string type and it is missing quotes // if (parameterType == typeof(String) && !parameterString.Equals("null")) { if (parameterString.Length <= 0) { parameterString = "null"; // default to null for empty string } else { if (parameterString[0] != '"') { // // make sure the string does not contain any whitespace or quotes // if (parameterString.IndexOfAny(InvalidCharsForNonQuotedStrings) >= 0) { throw new InvalidOperationException(String.Format( "You provided a non-quoted string with invalid characters '{0}' (invalid characters include whitespace, backslashes or quotes)", parameterString)); } parameterString = "\"" + parameterString + "\""; } } } Int32 deserialationIndex; try { deserialationIndex = Sos.Deserialize( out parameterObjects[i], parameterType, parameterString, 0, parameterString.Length); } catch (Exception e) { throw new InvalidOperationException(String.Format("Failed to deserialize argument {0} ({1}) of type {2}: {3}", i + 1, parameterInfo.Name, parameterType.SosTypeName(), e.Message), e); } if (deserialationIndex != parameterString.Length) { throw new InvalidOperationException(String.Format( "Argument {0} (type={1}) has {2} characters but deserializtion only used {3} characters", i, parameterType, parameterString.Length, deserialationIndex)); } } return(parameterObjects); }
// expectedReturnType can be null, but providing the expected return type makes it unnecessary to search // each assembly for the type Object PerformCall(Type expectedReturnType, String methodName, String rawNpcLine) { if (threadSafe) { Monitor.Enter(serverEndPoint); } try { // // The reason for the retry logic is because if the underlying socket is disconnected, it may not // fail until after a send and a receive...so the socket should be reconnected and the request should // be repeated only once. // for (UInt32 attempt = 0; ; attempt++) { try { Connect(); socketLineReader.socket.Send(Encoding.UTF8.GetBytes(rawNpcLine.ToString())); String returnLineString = socketLineReader.ReadLine(); if (returnLineString == null) { if (attempt == 0) { Dispose(); continue; // Retry } throw UnexpectedClose(); } NpcReturnLine returnLine = new NpcReturnLine(returnLineString); if (returnLine.exceptionMessage != null) { ThrowExceptionFromCall(methodName, returnLine); } if (expectedReturnType == null) { if (returnLine.sosTypeName.Equals("Void")) { return(null); } expectedReturnType = GetTypeFromSosTypeName(returnLine.sosTypeName); } else { if (!returnLine.sosTypeName.Equals(expectedReturnType.SosTypeName())) { throw new InvalidOperationException(String.Format("Expected return type to be {0} but was {1}", expectedReturnType.SosTypeName(), returnLine.sosTypeName)); } } if (expectedReturnType == typeof(void)) { return(null); } Object returnObject; Int32 valueStringOffset = Sos.Deserialize(out returnObject, expectedReturnType, returnLine.sosSerializationString, 0, returnLine.sosSerializationString.Length); if (valueStringOffset != returnLine.sosSerializationString.Length) { throw new InvalidOperationException(String.Format( "Used {0} characters to deserialize object of type '{1}' but the serialization string had {2} characters", valueStringOffset, expectedReturnType.SosTypeName(), returnLine.sosSerializationString.Length)); } return(returnObject); } catch (SocketException) { if (socketLineReader != null) { socketLineReader.Dispose(); socketLineReader = null; } if (attempt == 0) { continue; // Retry } throw; } } } finally { if (threadSafe) { Monitor.Exit(serverEndPoint); } } }