Exemplo n.º 1
0
        public static async Task <byte[]> CreateAsync(Problem problem, IOptions <ApplicationConfig> options)
        {
            await using var stream = new MemoryStream();
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
            {
                var metaEntry = archive.CreateEntry("version");
                await using var metaStream = metaEntry.Open();
                await metaStream.WriteAsync(Encoding.UTF8.GetBytes("2"));

                metaStream.Close();

                var config       = new ProblemConfig(problem);
                var configString = JsonConvert.SerializeObject(config);
                var configEntry  = archive.CreateEntry("config.json");
                await using var configStream = configEntry.Open();
                await configStream.WriteAsync(Encoding.UTF8.GetBytes(configString));

                configStream.Close();

                var descriptionEntry = archive.CreateEntry("problem/description.md");
                await using var descriptionStream = descriptionEntry.Open();
                await descriptionStream.WriteAsync(Encoding.UTF8.GetBytes(problem.Description));

                descriptionStream.Close();

                foreach (var dataFile in problem.TestCases.Select(tc => tc.Input))
                {
                    var dataEntry = archive.CreateEntry(Path.Combine("tests", dataFile).Replace('\\', '/'));
                    var fullPath  = Path.Combine(options.Value.DataPath, "tests", problem.Id.ToString(), dataFile);
                    await using var dataStream = dataEntry.Open();
                    await using var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
                    await fileStream.CopyToAsync(dataStream);

                    dataStream.Close();
                    fileStream.Close();
                }
            }

            // ZipArchive must be disposed before getting bytes of zip file.
            // See https://stackoverflow.com/questions/40175391/invalid-zip-file-after-creating-it
            if (stream.CanSeek)
            {
                stream.Seek(0, SeekOrigin.Begin);
            }

            return(stream.ToArray());
        }
Exemplo n.º 2
0
        public static async Task <byte[]> CreateAsync(Problem problem, IOptions <ApplicationConfig> options)
        {
            await using var stream = new MemoryStream();
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
            {
                var metaEntry = archive.CreateEntry("version");
                await using var metaStream = metaEntry.Open();
                await metaStream.WriteAsync(Encoding.UTF8.GetBytes("2"));

                metaStream.Close();

                var config       = new ProblemConfig(problem);
                var configString = JsonConvert.SerializeObject(config);
                var configEntry  = archive.CreateEntry("config.json");
                await using var configStream = configEntry.Open();
                await configStream.WriteAsync(Encoding.UTF8.GetBytes(configString));

                configStream.Close();

                var pairs = new List <KeyValuePair <string, string> >
                {
                    new KeyValuePair <string, string>("problem/description.md", problem.Description),
                    new KeyValuePair <string, string>("problem/input-format.md", problem.InputFormat),
                    new KeyValuePair <string, string>("problem/output-format.md", problem.OutputFormat),
                    new KeyValuePair <string, string>("problem/footnote.md", problem.FootNote)
                };
                foreach (var pair in pairs)
                {
                    if (pair.Value != null)
                    {
                        var fileEntry = archive.CreateEntry(pair.Key);
                        await using var fileStream = fileEntry.Open();
                        await fileStream.WriteAsync(Encoding.UTF8.GetBytes(pair.Value));

                        fileStream.Close();
                    }
                }

                if (problem.HasSpecialJudge)
                {
                    var checkerEntry = archive.CreateEntry("checker.cpp");
                    await using var checkerStream = checkerEntry.Open();
                    await checkerStream.WriteAsync(Convert.FromBase64String(problem.SpecialJudgeProgram.Code));

                    checkerStream.Close();
                }

                int index = 0;
                foreach (var sample in problem.SampleCases)
                {
                    ++index;
                    var inputEntry = archive.CreateEntry(Path.Combine("samples", index + ".in").Replace('\\', '/'));
                    await using var inputStream = inputEntry.Open();
                    await inputStream.WriteAsync(Convert.FromBase64String(sample.Input));

                    inputStream.Close();

                    var outputEntry = archive.CreateEntry(Path.Combine("samples", index + ".out").Replace('\\', '/'));
                    await using var outputStream = outputEntry.Open();
                    await outputStream.WriteAsync(Convert.FromBase64String(sample.Output));

                    outputStream.Close();
                }

                foreach (var test in problem.TestCases)
                {
                    var inputFile = Path.Combine(options.Value.DataPath, "tests", problem.Id.ToString(), test.Input);
                    await using (var fileStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
                    {
                        var inputEntry = archive.CreateEntry(Path.Combine("tests", test.Input).Replace('\\', '/'));
                        await using var inputStream = inputEntry.Open();
                        await fileStream.CopyToAsync(inputStream);

                        inputStream.Close();
                    }

                    var outputFile = Path.Combine(options.Value.DataPath, "tests", problem.Id.ToString(), test.Output);
                    await using (var fileStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
                    {
                        var outputEntry = archive.CreateEntry(Path.Combine("tests", test.Output).Replace('\\', '/'));
                        await using var outputStream = outputEntry.Open();
                        await fileStream.CopyToAsync(outputStream);

                        outputStream.Close();
                    }
                }
            }

            // ZipArchive must be disposed before getting bytes of zip file.
            // See https://stackoverflow.com/questions/40175391/invalid-zip-file-after-creating-it
            if (stream.CanSeek)
            {
                stream.Seek(0, SeekOrigin.Begin);
            }

            return(stream.ToArray());
        }