func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) files := archive.Glob("*.xml") PanicIf(len(files) == 0, "Task file not found") PanicIf(len(files) > 1, "Several xml files found in the archive") reader, err := archive.Open(files[0]) PanicIf(err) defer reader.Close() container := new(Container) utils.NewXmlDecoder(reader).Decode(container) problem := container.Problem PanicIf(problem == nil, "Problem node not found") p := &model.Problem{ Title: problem.Title, Author: problem.Author, TimeLimit: float32(problem.TimeLimit), MemoryLimit: float32(problem.MemoryLimit), Statement: parseSGML(problem.Statement), Constraints: parseSGML(problem.Constraints), InputFormat: parseSGML(problem.InputFormat), OutputFormat: parseSGML(problem.OutputFormat), Generators: make(map[string]*model.Generator), Solutions: make(map[string]*model.Solution), Images: make(model.ImagesDict), } getSample := func(res *SampleResource) string { if res.Source != "" { data, err := archive.ReadFile(res.Source) PanicIf(err) return string(data) } return res.Text } p.Samples = make([]model.Sample, len(problem.Samples)) for i, sample := range problem.Samples { p.Samples[i].Input = getSample(&sample.SampleIn) p.Samples[i].Output = getSample(&sample.SampleOut) } for _, picture := range problem.Pictures { data, err := archive.ReadFile(picture.Source) PanicIf(err) p.Images[picture.Name] = data } for _, generator := range problem.Generators { addGenerator(archive, p, &generator) } for _, genRange := range problem.GeneratorRanges { for j := genRange.From; j <= genRange.To; j++ { generator := genRange.Generator generator.Name = applyTestRank(generator.Name, j) generator.Source = applyTestRank(generator.Source, j) addGenerator(archive, p, &generator) } } for _, solution := range problem.Solutions { lang := getLanguage(solution.LanguageCode, solution.Source) PanicIf(lang == nil, "Unknown solution language") data, err := archive.ReadFile(solution.Source) PanicIf(err) p.Solutions[solution.Name] = &model.Solution{ Name: solution.Name, Language: lang.Name, SourceCode: string(data), } } convertTest := func(t *model.Test, test *Test) { t.Points = test.Points if in := test.InputFile; in != nil { if in.Source != "" { data, err := archive.ReadFile(in.Source) PanicIf(err) t.Input = model.ConstTestData(data) } else if in.Generator != "" || in.Parameters != "" { if t.Input == nil { t.Input = &model.GeneratedInput{} } if in.Generator != "" { t.Input.(*model.GeneratedInput).Generator = in.Generator } if in.Parameters != "" { t.Input.(*model.GeneratedInput).Parameters = in.Parameters } } } if out := test.OutputFile; out != nil { if out.Source != "" { data, err := archive.ReadFile(out.Source) PanicIf(err) t.Output = model.ConstSolutionData(data) } else if out.Solution != "" { t.Output = &model.SolutionOutput{Solution: out.Solution} } } } addTestGroup := func(test *Test) { for rank := range stringRange(test.Rank) { if rank < 1 { continue } for len(p.Tests) < rank { p.Tests = append(p.Tests, model.Test{}) } processedTest := *test if in := processedTest.InputFile; in != nil { processedTest.InputFile = &InputFile{ Generator: applyTestRank(in.Generator, rank), Source: applyTestRank(in.Source, rank), Parameters: applyTestRank(in.Parameters, rank), GenerateAll: in.GenerateAll, } } if out := processedTest.OutputFile; out != nil { processedTest.OutputFile = &OutputFile{ Solution: applyTestRank(out.Solution, rank), Source: applyTestRank(out.Source, rank), } } convertTest(&p.Tests[rank-1], &processedTest) } } for _, testRange := range problem.TestRanges { test := Test{ Rank: fmt.Sprintf("%d-%d", testRange.From, testRange.To), TestDataMixin: testRange.TestDataMixin, } addTestGroup(&test) } for _, test := range problem.Tests { addTestGroup(&test) } for i, test := range p.Tests { if test.Input == nil || test.Output == nil { Panic("Test %d: incomplete input or output section", i+1) } } return []*model.Problem{p}, nil }