Пример #1
0
        /// <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());
        }
Пример #2
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);
        }
Пример #3
0
        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();
        }
Пример #4
0
        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);
        }
Пример #5
0
        //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);
        }
Пример #7
0
 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);
 }
Пример #8
0
        /// <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}");
        }
Пример #9
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        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));
        }
Пример #17
0
        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);
        }