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