示例#1
0
        public Entity(Stream stream, int id, int type, ISymbolTable symbolTable, IonLoader loader)
        {
            using var reader = new BinaryReader(stream, Encoding.UTF8, true);
            Signature        = Encoding.ASCII.GetString(reader.ReadBytes(4));
            if (Signature != EntitySignature)
            {
                throw new Exception("Invalid signature");
            }

            Version = reader.ReadUInt16();
            if (!_allowedVersions.Contains(Version))
            {
                throw new Exception($"Version not supported ({Version})");
            }

            Length = reader.ReadUInt32();
            if (Length < MinHeaderLength)
            {
                throw new Exception("Header too short");
            }

            // Duplicated in KfxContainer
            // 10 = number of bytes read so far
            var containerInfoData = new MemoryStream(stream.ReadBytes((int)Length - 10));
            var entityInfo        = loader.LoadSingle <IonStruct>(containerInfoData);

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

            var compressionType = entityInfo.GetField(KfxSymbols.BcComprType).IntValue;

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

            var drmScheme = entityInfo.GetField(KfxSymbols.BcDrmScheme).IntValue;

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

            FragmentId   = symbolTable.FindKnownSymbol(id);
            FragmentType = symbolTable.FindKnownSymbol(type);

            Value = RawFragmentTypes.Contains(FragmentType)
                ? new IonBlob(new ReadOnlySpan <byte>(stream.ReadToEnd()))
                : ((IonDatagram)loader.Load(stream.ReadToEnd())).Single();

            // Skipping annotation handling for now

            //if ftype == fid and ftype in ROOT_FRAGMENT_TYPES and not self.pure:

            //fid = "$348"

            //return YJFragment(fid = fid if fid != "$348" else None, ftype = ftype, value = self.value)
        }
示例#2
0
        public void Decimal_Invalid(string fileName)
        {
            var fileInfo = GetFile(BadDir, fileName);

            IonLoader.WithReaderOptions(new ReaderOptions {
                Format = ReaderFormat.Text
            }).Load(fileInfo);
        }
示例#3
0
 private static void RoundTrip_AssertBinary(IIonValue datagram, ISymbolTable readerTable)
 {
     using (var ms = new MemoryStream())
     {
         using (var writer = IonBinaryWriterBuilder.Build(ms, readerTable.GetImportedTables()))
         {
             datagram.WriteTo(writer);
             writer.Finish();
             var bin       = ms.ToArray();
             var catalog   = Symbols.GetReaderCatalog(readerTable);
             var datagram2 = IonLoader.WithReaderOptions(new ReaderOptions {
                 Catalog = catalog, Format = ReaderFormat.Binary
             }).Load(bin);
             AssertDatagramEquivalent(datagram, datagram2);
         }
     }
 }
示例#4
0
        private static void RoundTrip_AssertText(IIonValue datagram, ISymbolTable readerTable)
        {
            var sw     = new StringWriter();
            var writer = IonTextWriterBuilder.Build(sw, new IonTextOptions {
                PrettyPrint = true
            }, readerTable.GetImportedTables());

            datagram.WriteTo(writer);
            writer.Finish();
            var text = sw.ToString();

            Console.WriteLine(text);
            var catalog   = Symbols.GetReaderCatalog(readerTable);
            var datagram2 = IonLoader.WithReaderOptions(new ReaderOptions {
                Catalog = catalog
            }).Load(text);

            AssertDatagramEquivalent(datagram, datagram2);
        }
示例#5
0
        private static IIonValue LoadFile(FileInfo fi, out ISymbolTable readerTable)
        {
            if (fi.Name == "utf16.ion")
            {
                return(IonLoader
                       .WithReaderOptions(new ReaderOptions {
                    Encoding = new UnicodeEncoding(true, true)
                })
                       .Load(fi, out readerTable));
            }

            if (fi.Name == "utf32.ion")
            {
                return(IonLoader
                       .WithReaderOptions(new ReaderOptions {
                    Encoding = new UTF32Encoding(true, true)
                })
                       .Load(fi, out readerTable));
            }

            var tree = IonLoader.Default.Load(fi, out readerTable);

            return(tree);
        }
示例#6
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();
        }
示例#7
0
 public void LoadBad(FileInfo fi)
 {
     IonLoader.WithReaderOptions(new ReaderOptions {
         Format = ReaderFormat.Text
     }).Load(fi);
 }