Пример #1
0
        public static ICatalog GetCatalog()
        {
            var catalog   = new SimpleCatalog();
            var yjSymbols = SharedSymbolTable.NewSharedSymbolTable("YJ_symbols", 10, null, YjSymbols);

            catalog.PutTable(yjSymbols);
            return(catalog);
        }
Пример #2
0
        public void GetTable_BestMatch(int expected, int requested, int[] available)
        {
            const string tName = "T";
            var          map   = new Dictionary <int, ISymbolTable>();
            var          cat   = new SimpleCatalog();

            foreach (var a in available)
            {
                map.Add(a, SharedSymbolTable.NewSharedSymbolTable(tName, a, null, new[] { "yes", "no" }));
                cat.PutTable(map[a]);
            }

            Assert.AreEqual(expected, cat.GetTable(tName, requested).Version);
        }
Пример #3
0
        /// <summary>
        /// Returns a catalog that contains all shared symbol tables that the reader has read so far.
        /// </summary>
        /// <param name="readerTable">The reader's local symbol table. Typically obtained by calling <see cref="IIonReader.GetSymbolTable"/>.</param>
        /// <remarks>
        /// Normally when a text or binary Ion data with shared symbol tables is read, the materialized object (such as
        /// a .Net POCO object or an <see cref="IonDotnet.Tree.IonDatagram"/> does not have the reference to these tables.
        /// As such, systems that want to reuse those shared tables should extract them after reading through all the values.
        /// This method provides a shortcut to do get a catalog that contains those tables.
        /// </remarks>
        public static ICatalog GetReaderCatalog(ISymbolTable readerTable)
        {
            var catalog = new SimpleCatalog();

            foreach (var importedTable in readerTable.GetImportedTables())
            {
                Debug.Assert(importedTable.IsShared);
                if (importedTable.IsSystem || importedTable.IsSubstitute)
                {
                    continue;
                }

                catalog.PutTable(importedTable);
            }

            return(catalog);
        }
Пример #4
0
        public void OneTable_MissingVersion()
        {
            const string tName = "T";
            var          cat   = new SimpleCatalog();

            Assert.IsNull(cat.GetTable(tName));
            Assert.IsNull(cat.GetTable(tName, 3));

            var t1 = SharedSymbolTable.NewSharedSymbolTable(tName, 1, null, new[] { "yes", "no" });

            cat.PutTable(t1);
            Assert.AreSame(t1, cat.GetTable(tName));
            Assert.AreSame(t1, cat.GetTable(tName, 1));
            Assert.AreSame(t1, cat.GetTable(tName, 5));

            var t2 = SharedSymbolTable.NewSharedSymbolTable(tName, 2, null, new[] { "yes", "no", "maybe" });

            cat.PutTable(t2);
            Assert.AreSame(t1, cat.GetTable(tName, 1));
            Assert.AreSame(t2, cat.GetTable(tName, 2));
            Assert.AreSame(t2, cat.GetTable(tName, 5));
        }
Пример #5
0
        public KfxContainer(Stream fs)
        {
            var catalog = new SimpleCatalog();

            catalog.PutTable(YjSymbolTable);

            var loader = IonLoader.WithReaderOptions(new ReaderOptions
            {
                Encoding = Encoding.UTF8,
                Format   = ReaderFormat.Detect,
                Catalog  = catalog
            });

            var header            = new KfxHeader(fs);
            var containerInfoData = new MemoryStream(fs.ReadBytes((int)header.ContainerInfoOffset, (int)header.ContainerInfoLength, SeekOrigin.Begin));

            var containerInfo = loader.LoadSingle <IonStruct>(containerInfoData);

            if (containerInfo == null)
            {
                throw new Exception("Bad container or something");
            }

            var containerId = containerInfo.GetById <IonString>(409).StringValue;

            var compressionType = containerInfo.GetById <IonInt>(410).IntValue;

            if (compressionType != DefaultCompressionType)
            {
                throw new Exception($"Unexpected bcComprType ({compressionType})");
            }

            var drmScheme = containerInfo.GetById <IonInt>(411).IntValue;

            if (drmScheme != DefaultDrmScheme)
            {
                throw new Exception($"Unexpected bcDRMScheme ({drmScheme})");
            }

            var          docSymbolOffset = containerInfo.GetById <IonInt>(415);
            var          docSymbolLength = containerInfo.GetById <IonInt>(416);
            ISymbolTable docSymbols      = null;

            if (docSymbolLength.LongValue > 0)
            {
                var docSymbolData = new MemoryStream(fs.ReadBytes(docSymbolOffset.IntValue, docSymbolLength.IntValue, SeekOrigin.Begin));
                loader.Load(docSymbolData, out docSymbols);
            }

            var chunkSize = containerInfo.GetById <IonInt>(412).IntValue;

            if (chunkSize != DefaultChunkSize)
            {
                throw new Exception($"Unexpected bcChunkSize in container {containerId} info ({chunkSize})");
            }

            if (header.Version > 1)
            {
                var formatCapabilitiesOffset = containerInfo.GetById <IonInt>(594).IntValue;
                var formatCapabilitiesLength = containerInfo.GetById <IonInt>(595).IntValue;
                if (formatCapabilitiesLength > 0)
                {
                    var formatCapabilitiesData = new MemoryStream(fs.ReadBytes(formatCapabilitiesOffset, formatCapabilitiesLength, SeekOrigin.Begin));
                    FormatCapabilities = loader.Load(formatCapabilitiesData).Single() as IonList;
                }
            }

            var indexTableOffset = containerInfo.GetById <IonInt>(413).IntValue;
            var indexTableLength = containerInfo.GetById <IonInt>(414).IntValue;

            // Python checks for extra info in container

            fs.Seek(header.Length, SeekOrigin.Begin);
            var payloadSha1 = fs.ReadToEnd().Sha1().ToHexString().ToLowerInvariant();

            fs.Seek(header.ContainerInfoOffset + header.ContainerInfoLength, SeekOrigin.Begin);
            var kfxGenInfoData = Encoding.UTF8.GetString(fs.ReadBytes((int)(header.Length - header.ContainerInfoOffset - header.ContainerInfoLength)));
            var kfxGenInfo     = JsonConvert.DeserializeObject <KeyValuePair <string, string>[]>(kfxGenInfoData)
                                 .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            if (kfxGenInfo.GetOrDefault("kfxgen_payload_sha1") != payloadSha1)
            {
                throw new Exception($"Incorrect kfxgen_payload_sha1 in container {containerId}");
            }
            if (kfxGenInfo.GetOrDefault("kfxgen_acr") != containerId)
            {
                throw new Exception($"Unexpected kfxgen_acr in container {containerId}");
            }

            var typeNums = new HashSet <int>();

            if (indexTableLength > 0)
            {
                var entityTable = fs.ReadBytes(indexTableOffset, indexTableLength, SeekOrigin.Begin);
                using var reader = new BinaryReader(new MemoryStream(entityTable), Encoding.UTF8, true);
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    var id           = reader.ReadInt32();
                    var type         = reader.ReadInt32();
                    var entityOffset = (int)reader.ReadInt64();
                    var entityLength = (int)reader.ReadInt64();

                    typeNums.Add(type);

                    var entityStart = (int)header.Length + entityOffset;
                    if (entityStart + entityLength > fs.Length)
                    {
                        throw new Exception($"Container {containerId} is not large enough for entity end (offset {entityStart + entityLength})");
                    }

                    var entityData = new MemoryStream(fs.ReadBytes(entityStart, entityLength, SeekOrigin.Begin));
                    Entities.Add(new Entity(entityData, id, type, docSymbols, loader));
                }
            }

            ContainerFormat containerFormat;

            if (typeNums.Intersect(KfxMainContainerFragmentIdNums).Any())
            {
                containerFormat = ContainerFormat.KfxMain;
            }
            else if (typeNums.Intersect(KfxMetadataContainerFragmentIdNums).Any())
            {
                containerFormat = ContainerFormat.KfxMetadata;
            }
            else if (typeNums.Intersect(KfxAttachableContainerFragmentIdNums).Any())
            {
                containerFormat = ContainerFormat.KfxAttachable;
            }
            else
            {
                containerFormat = ContainerFormat.KfxUnknown;
            }

            var kfxAppVersion     = kfxGenInfo.GetOrDefault("appVersion") ?? kfxGenInfo.GetOrDefault("kfxgen_application_version");
            var kfxPackageVersion = kfxGenInfo.GetOrDefault("buildVersion") ?? kfxGenInfo.GetOrDefault("kfxgen_package_version");

            ContainerInfo = new KfxContainerInfo
            {
                Header                   = header,
                ContainerId              = containerId,
                ChunkSize                = chunkSize,
                CompressionType          = compressionType,
                DrmScheme                = drmScheme,
                KfxGenApplicationVersion = kfxAppVersion,
                KfxGenPackageVersion     = kfxPackageVersion,
                ContainerFormat          = containerFormat
            };

            SetMetadata();
        }
Пример #6
0
        public void WriterReader()
        {
            var catalog = new SimpleCatalog();
            var table1  = SharedSymbolTable.NewSharedSymbolTable("table1", 1, null, new[] { "s1", "s2" });
            var table2  = SharedSymbolTable.NewSharedSymbolTable("table2", 1, null, new[] { "s3", "s4" });

            catalog.PutTable(table1);
            catalog.PutTable(table2);

            var stream = new MemoryStream();

            byte[] output;
            using (var binWriter = new ManagedBinaryWriter(stream, new[] { table1, table2 }))
            {
                binWriter.StepIn(IonType.Struct);
                binWriter.SetFieldName("s1");
                binWriter.WriteSymbol("s2");
                binWriter.SetFieldName("s3");
                binWriter.WriteSymbol("s4");
                binWriter.StepOut();
                binWriter.Finish();
                Assert.AreEqual(binWriter.SymbolTable.GetImportedMaxId(), binWriter.SymbolTable.MaxId);

                output = stream.ToArray();
            }

            var reader = IonReaderBuilder.Build(new MemoryStream(output));

            Assert.AreEqual(IonType.Struct, reader.MoveNext());
            reader.StepIn();
            Assert.AreEqual(IonType.Symbol, reader.MoveNext());
            var fns = reader.GetFieldNameSymbol();

            Assert.AreEqual(10, fns.Sid);
            Assert.IsNull(fns.Text);
            Assert.ThrowsException <UnknownSymbolException>(() => reader.CurrentFieldName);
            Assert.AreEqual(11, reader.SymbolValue().Sid);

            Assert.AreEqual(IonType.Symbol, reader.MoveNext());
            fns = reader.GetFieldNameSymbol();
            Assert.AreEqual(12, fns.Sid);
            Assert.IsNull(fns.Text);
            Assert.ThrowsException <UnknownSymbolException>(() => reader.CurrentFieldName);
            Assert.AreEqual(13, reader.SymbolValue().Sid);

            //make sure that a reader with the correct imports can read it
            var reader2 = new UserBinaryReader(new MemoryStream(output), catalog);

            Assert.AreEqual(IonType.Struct, reader2.MoveNext());
            var localTable = reader2.GetSymbolTable();

            Console.WriteLine(localTable.Find("s1").ToString());
            reader2.StepIn();
            Assert.AreEqual(IonType.Symbol, reader2.MoveNext());
            Assert.AreEqual("s1", reader2.CurrentFieldName);
            Assert.AreEqual("s2", reader2.SymbolValue().Text);

            Assert.AreEqual(IonType.Symbol, reader2.MoveNext());
            Assert.AreEqual("s3", reader2.CurrentFieldName);
            Assert.AreEqual("s4", reader2.SymbolValue().Text);
        }