Обычное чтение правильно сформированного двоичного файла

Я пытаюсь прочитать содержимое файлов карты/модели игры в программу для написания небольшого средства просмотра моделей и тестирования некоторых функций DirectX. Форматы файлов модели/карты по своей природе разбиты на части, и я знаю формат этих файлов. Я могу легко читать файлы, анализируя отдельные фрагменты, используя такой подход:

class FileType1 {
    private Chunk1 c1;
    private Chunk2 c2; // etc

    public void Read(BinaryReader reader) {
        c1 = new Chunk1(reader);
        c2 = new Chunk2(reader);
    }
}

Тем не менее, я пытаюсь придумать способ общего чтения этих файлов, указав формат, которого придерживается файл (т. Е. Chunk1, за которым следует Chunk2 и т. д. и т. д.), чтобы читатель мог убедиться, что файл имеет соответствующую структуру. Я могу использовать суперкласс Chunk и фабрику Chunk для общего чтения всех фрагментов в любом заданном файле. По сути, я хотел бы дополнить это дополнительными функциями валидатора структуры (или чего-то подобного), чтобы получить метод, похожий на этот:

public void Read(BinaryReader reader, ChunkFileFormat format) {
    while (!EOF) {
        char[] chunkID = reader.ReadChars(4);
        Chunk c = chunkFactory.Create(chunkID);
        if (c.GetType() != format.Next.GetType())
            throw new Exception("File format is invalid");
        format.SetCurrentRecord(c);
    }
}

Идея здесь заключается в том, что класс ChunkFileFormat определяет структуру файла, указывая, какой тип фрагмента, как ожидается, будет следующим чтением из двоичного потока. Это позволило бы подклассам ChunkFileFormat задавать макет этого конкретного формата, а единый метод чтения можно было бы использовать для чтения всех различных форматов файлов, разделенных на фрагменты, вместо того, чтобы писать многословный и повторяющийся метод для каждого.

Мой вопрос: кто-нибудь знает о шаблонах проектирования или подходах, которые могли бы справиться с этой ситуацией? Проект, над которым я работаю, в настоящее время находится на C#, хотя мне были бы интересны решения на C++ (или любом другом языке в этом отношении).

Заранее спасибо!


person Community    schedule 14.09.2009    source источник


Ответы (2)


Такие правила легко написать с помощью автомата с конечными состояниями.

Каждый фрагмент должен изменить состояние, в котором вы находитесь. Каждое состояние после этого ожидает определенных фрагментов. Если вы встретите чанк, который не должен встречаться в текущем, это ошибка.

person Vincent Robert    schedule 15.09.2009
comment
Спасибо, это, вероятно, решение, которое я ищу, теперь нужно реализовать :-) спасибо, что указали мне правильное направление. - person ; 18.09.2009

Вы можете создать формальное описание формата, используя DataScript/antlr, и он создаст для вас код синтаксического анализа и ввода-вывода (Java или C++).

person Razzupaltuff    schedule 14.09.2009
comment
Спасибо, я посмотрю на это, но я не уверен, что это именно то, что мне нужно. - person ; 15.09.2009