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); }
/// <summary> /// Test for single-value bool /// </summary> public static void SingleBool(IIonReader reader, bool value) { Assert.AreEqual(IonType.Bool, reader.MoveNext()); Assert.AreEqual(value, reader.BoolValue()); }
//empty content public static void Empty(IIonReader reader) { //also convieniently testing symtab Assert.IsNotNull(reader.GetSymbolTable()); Assert.AreEqual(IonType.None, reader.MoveNext()); }
/// <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); }
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); }