public static ArchiveMetaData ReadMetaData(Stream stream)
        {
            if (!stream.CanRead)
            {
                throw new IOException("this stream does not support read access");
            }

            stream.Position = 0;

            using (var reader = new BinaryReader(stream, Encoding.UTF8, true))
            {
                // read magic-number (3 bytes)
                const int magicNumberSize = 3;
                if (Encoding.ASCII.GetString(reader.ReadBytes(magicNumberSize)) != "PRA")
                {
                    throw new FormatException("invalid PRA header");
                }

                // read length of the json metadata (4 bytes)
                const int metadataLnegthSize = 4;
                var       metadataLnegth     = reader.ReadInt32();

                // read the json metadata
                var metadataBuffer = reader.ReadBytes(metadataLnegth);
                var metadataJson   = Encoding.UTF8.GetString(metadataBuffer);
                var metadataRaw    = ArchiveMetaDataRaw.FromJson(metadataJson);

                if (metadataRaw.Version != 1)
                {
                    throw new FormatException("format version is not supported");
                }

                return(new ArchiveMetaData(metadataRaw, magicNumberSize + metadataLnegthSize + metadataLnegth));
            }
        }
        public static void Write(Stream stream, IReadOnlyCollection <ArchiveItem> items)
        {
            if (!stream.CanWrite)
            {
                throw new IOException("this stream does not support write access");
            }

            var metadataRaw  = ArchiveMetaDataRaw.Build(items);
            var metadataJson = metadataRaw.ToJson();

            stream.Position = 0;

            using (var writer = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                // write magic-number (3 bytes)
                writer.Write(Encoding.ASCII.GetBytes("PRA"));

                // write length of the json metadata (4 bytes)
                writer.Write(metadataJson.Length);

                // write the json metadata
                writer.Write(Encoding.UTF8.GetBytes(metadataJson));

                // file data
                foreach (var file in items)
                {
                    writer.Write(file.Buffer.ToArray());
                }
            }
        }
 public ArchiveMetaData(ArchiveMetaDataRaw metadataRaw, int payloadBeginOffset)
 {
     this.Raw = metadataRaw;
     this.PayloadBeginOffset = payloadBeginOffset;
 }