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);
        }
Example #2
0
 /// <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());
 }
Example #3
0
 //empty content
 public static void Empty(IIonReader reader)
 {
     //also convieniently testing symtab
     Assert.IsNotNull(reader.GetSymbolTable());
     Assert.AreEqual(IonType.None, reader.MoveNext());
 }
Example #4
0
        /// <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);
        }