/// <remarks>See text/twolayer.ion for content</remarks> public static void TwoLayer_TestStepoutSkip(IIonReader reader) { Assert.AreEqual(IonType.Struct, reader.MoveNext()); reader.StepIn(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("open", reader.CurrentFieldName); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("structure", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("open", reader.CurrentFieldName); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("structure", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.Int, reader.MoveNext()); Assert.AreEqual("int", reader.CurrentFieldName); //1st skip reader.StepOut(); Assert.AreEqual(IonType.Int, reader.MoveNext()); Assert.AreEqual("int", reader.CurrentFieldName); //2nd skip reader.StepOut(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("this is a string", reader.StringValue()); Assert.AreEqual(IonType.Bool, reader.MoveNext()); Assert.AreEqual(true, reader.BoolValue()); }
/// <summary> /// Test for a typical json-style message /// </summary> public static void Combined1(IIonReader reader) { Assert.AreEqual(IonType.Struct, reader.MoveNext()); reader.StepIn(); Assert.IsTrue(reader.IsInStruct); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("menu", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("id", reader.CurrentFieldName); Assert.AreEqual("file", reader.StringValue()); Assert.AreEqual(IonType.List, reader.MoveNext()); Assert.AreEqual("popup", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("Open", reader.StringValue()); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("Load", reader.StringValue()); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("Close", reader.StringValue()); reader.StepOut(); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("deep1", reader.CurrentFieldName); reader.StepIn(); Assert.IsTrue(reader.IsInStruct); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("deep2", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.Struct, reader.MoveNext()); Assert.AreEqual("deep3", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.String, reader.MoveNext()); Assert.AreEqual("deep4val", reader.CurrentFieldName); Assert.AreEqual("enddeep", reader.StringValue()); reader.StepOut(); reader.StepOut(); reader.StepOut(); Assert.AreEqual(IonType.List, reader.MoveNext()); Assert.AreEqual("positions", reader.CurrentFieldName); reader.StepIn(); Assert.AreEqual(IonType.Int, reader.MoveNext()); Assert.AreEqual(1234, reader.IntValue()); Assert.AreEqual(IonType.Int, reader.MoveNext()); Assert.AreEqual(5678, reader.IntValue()); Assert.AreEqual(IonType.Int, reader.MoveNext()); Assert.AreEqual(90, reader.IntValue()); reader.StepOut(); reader.StepOut(); reader.StepOut(); Assert.AreEqual(0, reader.CurrentDepth); }
private void WriteContainerRecursively(IonType type, IIonReader reader) { Debug.Assert(type.IsContainer(), "type IsContainer is false"); this.StepIn(type); reader.StepIn(); while ((type = reader.MoveNext()) != IonType.None) { this.WriteValueRecursively(type, reader); } reader.StepOut(); this.StepOut(); }
public static void FlatScalar(IIonReader reader) { //a flat struct of scalar values: //boolean:true //str:"yes" //integer:123456 //longInt:int.Max*2 //bigInt:long.Max*10 //double:2213.1267567f reader.MoveNext(); Assert.AreEqual(IonType.Struct, reader.CurrentType); reader.StepIn(); Assert.IsTrue(reader.IsInStruct); Assert.AreEqual(1, reader.CurrentDepth); reader.MoveNext(); Assert.AreEqual("boolean", reader.CurrentFieldName); Assert.AreEqual(IonType.Bool, reader.CurrentType); Assert.IsTrue(reader.BoolValue()); reader.MoveNext(); Assert.AreEqual("str", reader.CurrentFieldName); Assert.AreEqual(IonType.String, reader.CurrentType); Assert.AreEqual("yes", reader.StringValue()); reader.MoveNext(); Assert.AreEqual("integer", reader.CurrentFieldName); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual(123456, reader.IntValue()); reader.MoveNext(); Assert.AreEqual("longInt", reader.CurrentFieldName); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual((long)int.MaxValue * 2, reader.LongValue()); reader.MoveNext(); Assert.AreEqual("bigInt", reader.CurrentFieldName); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual(BigInteger.Multiply(new BigInteger(long.MaxValue), 10), reader.BigIntegerValue()); reader.MoveNext(); Assert.AreEqual("double", reader.CurrentFieldName); Assert.AreEqual(IonType.Float, reader.CurrentType); Assert.AreEqual(2213.1267567, reader.DoubleValue()); Assert.AreEqual(IonType.None, reader.MoveNext()); reader.StepOut(); Assert.AreEqual(0, reader.CurrentDepth); }
//empty struct {} public static void TrivialStruct(IIonReader reader) { reader.MoveNext(); Assert.AreEqual(IonType.Struct, reader.CurrentType); reader.StepIn(); Assert.AreEqual(1, reader.CurrentDepth); Assert.AreEqual(IonType.None, reader.MoveNext()); for (var i = 0; i < 10; i++) { Assert.AreEqual(IonType.None, reader.MoveNext()); } reader.StepOut(); Assert.AreEqual(0, reader.CurrentDepth); }
/// <summary> /// Deserialize an Ion Struct into an IDictionary. /// </summary> /// /// <param name="reader">The Ion reader to be used for deserialization.</param> /// /// <returns>A Dictionary of Key type string and Value type valueType.</returns> public override IDictionary Deserialize(IIonReader reader) { reader.StepIn(); Type typedDictionaryType = typeof(Dictionary <,>).MakeGenericType(typeof(string), this.valueType); var dictionary = (IDictionary)Activator.CreateInstance(typedDictionaryType); IonType currentType; while ((currentType = reader.MoveNext()) != IonType.None) { dictionary.Add(reader.CurrentFieldName, this.serializer.Deserialize(reader, this.valueType, currentType)); } reader.StepOut(); return(dictionary); }
public static void OneBoolInStruct(IIonReader reader) { //simple datagram: {yolo:true} reader.MoveNext(); Assert.AreEqual(IonType.Struct, reader.CurrentType); reader.StepIn(); Assert.IsTrue(reader.IsInStruct); Assert.AreEqual(1, reader.CurrentDepth); reader.MoveNext(); Assert.AreEqual(IonType.Bool, reader.CurrentType); Assert.AreEqual("yolo", reader.CurrentFieldName); Assert.AreEqual(true, reader.BoolValue()); Assert.AreEqual(IonType.None, reader.MoveNext()); reader.StepOut(); Assert.AreEqual(0, reader.CurrentDepth); }
/// <inheritdoc/> public override IList Deserialize(IIonReader reader) { reader.StepIn(); var list = new ArrayList(); IonType ionType; while ((ionType = reader.MoveNext()) != IonType.None) { list.Add(this.serializer.Deserialize(reader, this.elementType, ionType)); } reader.StepOut(); if (this.listType.IsArray) { var typedArray = Array.CreateInstance(this.elementType, list.Count); for (int i = 0; i < list.Count; i++) { typedArray.SetValue(list[i], i); } return(typedArray); } if (this.listType is IEnumerable || this.listType is object) { IList typedList; if (this.listType.IsGenericType) { typedList = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(this.elementType)); } else { typedList = new ArrayList(); } foreach (var element in list) { typedList.Add(element); } return(typedList); } throw new NotSupportedException($"Don't know how to make a list of type {this.listType} with element type {this.elementType}"); }
public static bool NextIsEmptyStruct(this IIonReader reader) { if (reader.MoveNext() != IonType.Struct) { return(false); } var empty = true; reader.StepIn(); if (reader.MoveNext() != IonType.None) { empty = false; } reader.StepOut(); return(empty); }
private static IonType buildData1( List <KeyValuePair <string, string> > document, IIonReader reader, IonType type) { if (type == IonType.Struct) { reader.StepIn(); while ((type = reader.MoveNext()) != IonType.None) { switch (type) { case IonType.Bool: document.Add(new KeyValuePair <string, string>(reader.CurrentFieldName, Convert.ToString(reader.BoolValue()))); continue; case IonType.Int: document.Add(new KeyValuePair <string, string>(reader.CurrentFieldName, Convert.ToString(reader.IntValue()))); continue; case IonType.Decimal: document.Add(new KeyValuePair <string, string>(reader.CurrentFieldName, Convert.ToString((object)reader.DecimalValue()))); continue; case IonType.Timestamp: document.Add(new KeyValuePair <string, string>(reader.CurrentFieldName, Convert.ToString((object)reader.TimestampValue()))); continue; case IonType.String: document.Add(new KeyValuePair <string, string>(reader.CurrentFieldName, reader.StringValue())); continue; case IonType.Struct: int num = (int)ConnectionService.buildData1(document, reader, type); continue; default: continue; } } reader.StepOut(); } return(type); }
private static object Deserialize(IIonReader reader, Type type, IScalarConverter scalarConverter) { object t = null; if (TryDeserializeScalar(reader, type, scalarConverter, ref t)) { return(t); } if (TryDeserializeCollection(reader, type, scalarConverter, ref t)) { return(t); } //object t = Activator.CreateInstance(type); reader.StepIn(); while (reader.MoveNext() != IonType.None) { //find the property var prop = type.GetProperty(reader.CurrentFieldName, BindingFlags.Public | BindingFlags.Instance); if (prop == null) { continue; } if (!prop.CanWrite) { throw new IonException($"Property {type.Name}.{prop.Name} cannot be set"); } var propValue = Deserialize(reader, prop.PropertyType, scalarConverter); prop.SetValue(t, propValue); } reader.StepOut(); return(t); }
public static void FlatIntList(IIonReader reader) { //a flat list of ints [123,456,789] reader.MoveNext(); Assert.AreEqual(IonType.List, reader.CurrentType); reader.StepIn(); Assert.AreEqual(1, reader.CurrentDepth); reader.MoveNext(); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual(123, reader.IntValue()); reader.MoveNext(); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual(456, reader.IntValue()); reader.MoveNext(); Assert.AreEqual(IonType.Int, reader.CurrentType); Assert.AreEqual(789, reader.IntValue()); Assert.AreEqual(IonType.None, reader.MoveNext()); reader.StepOut(); Assert.AreEqual(0, reader.CurrentDepth); }
private void InternalWriteValue(IIonReader reader, int depth = 0) { IonType type = reader.CurrentType; if (type == IonType.None) { return; } if (depth > 0) { string fieldName = reader.CurrentFieldName; if (fieldName != null) { this.SetFieldName(fieldName); } } foreach (var annotation in reader.GetTypeAnnotations()) { this.AddTypeAnnotationSymbol(annotation); } if (reader.CurrentIsNull) { this.WriteNull(type); } else { switch (type) { case IonType.Bool: this.WriteBool(reader.BoolValue()); break; case IonType.Int: this.WriteInt(reader.BigIntegerValue()); break; case IonType.Float: this.WriteFloat(reader.DoubleValue()); break; case IonType.Decimal: this.WriteDecimal(reader.DecimalValue()); break; case IonType.Timestamp: this.WriteTimestamp(reader.TimestampValue()); break; case IonType.Symbol: this.WriteSymbolToken(reader.SymbolValue()); break; case IonType.String: this.WriteString(reader.StringValue()); break; case IonType.Clob: this.WriteClob(reader.NewByteArray()); break; case IonType.Blob: this.WriteBlob(reader.NewByteArray()); break; case IonType.List: this.StepIn(IonType.List); break; case IonType.Sexp: this.StepIn(IonType.Sexp); break; case IonType.Struct: this.StepIn(IonType.Struct); break; default: throw new InvalidOperationException("Unexpected type '" + type + "'"); } if (type.IsContainer()) { reader.StepIn(); this.InternalWriteValues(reader, depth + 1); this.StepOut(); reader.StepOut(); } } }
private static bool TryDeserializeCollection(IIonReader reader, Type type, IScalarConverter scalarConverter, ref object result) { if (!typeof(IEnumerable).IsAssignableFrom(type)) { return(false); } //special case of byte array if (TryDeserializeByteArray(reader, type, scalarConverter, ref result)) { return(true); } if (reader.CurrentType != IonType.List) { return(false); } //figure out collection type Type elementType, constructedListType = null; if (type.IsArray) { elementType = type.GetElementType(); } else { var generics = type.GetGenericArguments(); if (generics.Length == 0) { throw new IonException("Must specify collection type"); } var listType = typeof(List <>); elementType = generics[0]; constructedListType = listType.MakeGenericType(elementType); if (!type.IsAssignableFrom(constructedListType)) { throw new IonException("Must be collection"); } } reader.StepIn(); var arrayList = new ArrayList(); while (reader.MoveNext() != IonType.None) { var element = Deserialize(reader, elementType, scalarConverter); arrayList.Add(element); } if (type.IsArray) { var arr = Array.CreateInstance(elementType, arrayList.Count); for (var i = 0; i < arrayList.Count; i++) { arr.SetValue(arrayList[i], i); } result = arr; } else { var list = (IList)Activator.CreateInstance(constructedListType); foreach (var item in arrayList) { list.Add(item); } result = list; } reader.StepOut(); return(true); }
/// <inheritdoc/> public override object Deserialize(IIonReader reader) { object targetObject = null; ConstructorInfo ionConstructor = null; ParameterInfo[] parameters = null; object[] constructorArgs = null; Dictionary <string, int> constructorArgIndexMap = null; // Map Ion annotation to C# type. We don't check if the type has IonAnnotateType attribute or not, // because the Ion annotation could be written by: // 1. IonAnnotateType attribute // 2. IncludeTypeInformation option // 3. custom TypeAnnotator option var annotations = reader.GetTypeAnnotations(); if (annotations.Length > 0) { var typeName = annotations[0]; Type typeToCreate = null; if (this.options.AnnotatedTypeAssemblies != null) { foreach (string assemblyName in this.options.AnnotatedTypeAssemblies) { if ((typeToCreate = Type.GetType(this.FullName(typeName, assemblyName))) != null) { break; } } } else { foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { if ((typeToCreate = assembly.GetType(typeName)) != null) { break; } } } // Check typeToCreate is a derived class from targetType if (typeToCreate != null && this.targetType.IsAssignableFrom(typeToCreate)) { this.targetType = typeToCreate; } } // Determine if we are using an annotated constructor. var ionConstructors = this.targetType.GetConstructors(BINDINGS).Where(IsIonConstructor).Take(2); if (ionConstructors.Any()) { if (ionConstructors.Count() > 1) { throw new InvalidOperationException( $"Only one constructor in class {this.targetType.Name} may be annotated with the [IonConstructor] attribute and more than one was detected"); } ionConstructor = ionConstructors.First(); parameters = ionConstructor.GetParameters(); constructorArgs = new object[parameters.Length]; constructorArgIndexMap = this.BuildConstructorArgIndexMap(parameters); } else { // If we are not using an annotated constructor, then we need to construct the object before stepping // into the reader in case we need to read the type annotations during construction. targetObject = this.options.ObjectFactory.Create(this.options, reader, this.targetType); } reader.StepIn(); // Read the Ion and organize deserialized results into three categories: // 1. Values to be set via annotated methods. // 2. Properties to be set. // 3. Fields to be set. // Any of these deserialized results may also be used for the annotated constructor (if there is one). var deserializedMethods = new List <(MethodInfo, object)>(); var deserializedProperties = new List <(PropertyInfo, object)>(); var deserializedFields = new List <(FieldInfo, object)>(); IonType ionType; while ((ionType = reader.MoveNext()) != IonType.None) { MethodInfo method; PropertyInfo property; FieldInfo field; object deserialized = null; bool currentIonFieldProcessed = false; // Check if current Ion field has an annotated method. if ((method = this.FindSetter(reader.CurrentFieldName)) != null) { if (this.TryDeserializeMethod(method, reader, ionType, out deserialized)) { deserializedMethods.Add((method, deserialized)); } currentIonFieldProcessed = true; } // Check if current Ion field is a .NET property. else if ((property = this.FindProperty(reader.CurrentFieldName)) != null) { if (this.TryDeserializeProperty(property, reader, ionType, out deserialized)) { deserializedProperties.Add((property, deserialized)); } currentIonFieldProcessed = true; } // Check if current Ion field is a .NET field. else if ((field = this.FindField(reader.CurrentFieldName)) != null) { if (this.TryDeserializeField(field, reader, ionType, out deserialized)) { deserializedFields.Add((field, deserialized)); } currentIonFieldProcessed = true; } // Check if current Ion field is also an argument for an annotated constructor. if (constructorArgIndexMap != null && constructorArgIndexMap.ContainsKey(reader.CurrentFieldName)) { var index = constructorArgIndexMap[reader.CurrentFieldName]; // Deserialize current Ion field only if it was not already // processed by the above method/property/field logic. if (!currentIonFieldProcessed) { deserialized = this.ionSerializer.Deserialize(reader, parameters[index].ParameterType, ionType); } constructorArgs[index] = deserialized; } } reader.StepOut(); // Construct object with annotated constructor if we have one. if (ionConstructor != null) { targetObject = ionConstructor.Invoke(constructorArgs); } // Set values with annotated methods. foreach (var(method, deserialized) in deserializedMethods) { method.Invoke(targetObject, new[] { deserialized }); } // Set properties. foreach (var(property, deserialized) in deserializedProperties) { property.SetValue(targetObject, deserialized); } // Set fields. foreach (var(field, deserialized) in deserializedFields) { field.SetValue(targetObject, deserialized); } return(targetObject); }
public static void Compare(IIonReader it1, IIonReader it2) { while (HasNext(it1, it2)) { IonType t1 = it1.CurrentType; IonType t2 = it2.CurrentType; if (t1 != t2 && !t1.Equals(t2)) { Assert.AreEqual(t1, t2, "ion type"); } if (t1 == IonType.None) { break; } if (it1.IsInStruct) { CompareFieldNames(it1, it2); } CompareAnnotations(it1, it2); CompareAnnotationSymbols(it1, it2); CompareHasAnnotations(it1, it2); bool isNull = it1.CurrentIsNull; Assert.AreEqual(isNull, it2.CurrentIsNull); switch (t1) { case IonType.Null: Assert.IsTrue(it1.CurrentIsNull); Assert.IsTrue(it2.CurrentIsNull); break; case IonType.Bool: case IonType.Int: case IonType.Float: case IonType.Decimal: case IonType.Timestamp: case IonType.String: case IonType.Symbol: case IonType.Blob: case IonType.Clob: CompareScalars(t1, isNull, it1, it2); break; case IonType.Struct: case IonType.List: case IonType.Sexp: it1.StepIn(); it2.StepIn(); Compare(it1, it2); it1.StepOut(); it2.StepOut(); break; default: throw new InvalidOperationException(); } } Assert.IsFalse(HasNext(it1, it2)); }
public static ISymbolTable ImportReaderTable(IIonReader reader, ICatalog catalog, bool isOnStruct) { var table = reader.GetSymbolTable() as ReaderLocalTable ?? new ReaderLocalTable(reader.GetSymbolTable()); var imports = table.Imports; var symbols = table.OwnSymbols; var newSymbols = new List <string>(); if (!isOnStruct) { reader.MoveNext(); } Debug.Assert( reader.CurrentType == IonType.Struct, "Invalid symbol table image passed in reader " + reader.CurrentType + " encountered when a struct was expected."); Debug.Assert( SystemSymbols.IonSymbolTable.Equals(reader.GetTypeAnnotations()[0]), "Local symbol tables must be annotated by " + SystemSymbols.IonSymbolTable + "."); // Assume that we're standing before a struct. reader.StepIn(); IonType fieldType; bool foundImport = false; bool foundLocals = false; while ((fieldType = reader.MoveNext()) != IonType.None) { if (reader.CurrentIsNull) { continue; } var sid = reader.GetFieldNameSymbol().Sid; if (sid == SymbolToken.UnknownSid) { // This is a user-defined IonReader or a pure DOM, fall // back to text. sid = SystemSymbols.ResolveSidForSymbolTableField(reader.CurrentFieldName); } switch (sid) { case SystemSymbols.SymbolsSid: // As per the spec, other field types are treated as // empty lists. if (foundLocals) { throw new IonException("Multiple symbol fields found within a single local symbol table."); } foundLocals = true; if (fieldType == IonType.List) { ReadSymbolList(reader, newSymbols); } break; case SystemSymbols.ImportsSid: if (foundImport) { throw new IonException("Multiple imports fields found within a single local symbol table."); } foundImport = true; if (fieldType == IonType.List) { // List of symbol tables to imports. ReadImportList(reader, catalog, imports); } // Trying to import the current table. else if (fieldType == IonType.Symbol && reader.GetSymbolTable().IsLocal && (SystemSymbols.IonSymbolTable.Equals(reader.StringValue()) || reader.IntValue() == SystemSymbols.IonSymbolTableSid)) { var currentSymbolTable = reader.GetSymbolTable(); var declaredSymbols = currentSymbolTable.GetDeclaredSymbolNames(); if (foundLocals) { // Ordering matters. Maintain order as 'symbols' // and 'imports' fields can come in any order. newSymbols.InsertRange(0, declaredSymbols); } else { newSymbols.AddRange(declaredSymbols); } } break; default: // As per the spec, any other field is ignored. break; } } reader.StepOut(); symbols.Clear(); // If there were prior imports and now only a system table is // seen, then start fresh again as prior imports no longer matter. if (imports.Count > 1 && !foundImport && foundLocals) { imports.RemoveAll(symbolTable => symbolTable.IsSubstitute == true); } symbols.AddRange(newSymbols); table.Refresh(); return(table); }