Есть поток std::istream
Есть xml-парсер подвида SAX, который принимает этот поток на вход.
Проблема в том, что есть несколько видов xml-файлов, и хочется написать для каждого из них свой обработчик, а не пихать всю логику в один большой. Что за файл обрабатывается, можно понять по первому тегу. Т.е. надо распарсить файл до первого тега, прочитать тег, сказать "ага!", и потом, зная тип файла, парсить его заново.
Вопрос в том, как реализовать это "заново". Для этого нужно как-то отмотать поток данных назад... Про метод putback я знаю, но в данном случае я не контролирую чтение, читает парсер, я не знаю, что он там прочёл.
Есть какие-то красивые варианты? Копировать пока не хочется, там может быть довольно много. Даже "копировать первые несколько килобайт" пока не очень хочется.
Здравствуйте, ilnar, Вы писали:
I>"нельзя войти в одну реку дважды." I>не для всех типов поддерживаются произвольные перемещения.
Да. Но мне не надо произвольное. Мне надо всего лишь "запомнить" состояние, прочитать сколько-то символов, а потом снова к нему вернуться. Для этого достаточно иметь буфер, по идее это не так сложно.. Я даже свой буфер могу предоставить. Но вот перспектива прикручивать его к istream-у через создание своего класса, реализующего istream меня не радует.
Здравствуйте, SergH, Вы писали:
SH>Привет!
SH>Есть поток std::istream SH>Есть xml-парсер подвида SAX, который принимает этот поток на вход.
SH>Проблема в том, что есть несколько видов xml-файлов, и хочется написать для каждого из них свой обработчик, а не пихать всю логику в один большой. Что за файл обрабатывается, можно понять по первому тегу. Т.е. надо распарсить файл до первого тега, прочитать тег, сказать "ага!", и потом, зная тип файла, парсить его заново.
SH>Вопрос в том, как реализовать это "заново". Для этого нужно как-то отмотать поток данных назад... Про метод putback я знаю, но в данном случае я не контролирую чтение, читает парсер, я не знаю, что он там прочёл.
SH>Есть какие-то красивые варианты? Копировать пока не хочется, там может быть довольно много. Даже "копировать первые несколько килобайт" пока не очень хочется.
Я бы строил систему таким образом, что бы вообще избежать повторного парсинга. Схематично так: парсер верхнего уровня парсит корневой тег, при успешном распознавании создает экземпляр соответствующего класса, в который запихивает внутренности корневого тега. В этом виде этот объект скармливается обработчику нижнего уровня, который уже допарсивает внутренности и выполняет необходимую обработку. Обработчики нижнего уровня также могут иметь подчиненные обработчики. Таким образом можно конструировать иерархии обработчиков.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Я бы строил систему таким образом, что бы вообще избежать повторного парсинга. Схематично так: парсер верхнего уровня парсит корневой тег, при успешном распознавании создает экземпляр соответствующего класса, в который запихивает внутренности корневого тега. В этом виде этот объект скармливается обработчику нижнего уровня, который уже допарсивает внутренности и выполняет необходимую обработку. Обработчики нижнего уровня также могут иметь подчиненные обработчики. Таким образом можно конструировать иерархии обработчиков.
Так и было. А потом содержимое разных типов файлов разошлось немного дальше, и теперь у разных обработчиков разные интерфейсы... Всегда передавать все обработчики не хочется. Передавать один, с "большим" интерфейсом тоже. Видимо, всё-таки буду делать свой поток.
Эх, отвлекли на другую задачу, к этому вернусь только через недельку. Со stringstream-ом действительно работает, а вот с самодельным (не мной) потоком, реализующим unzip — надо проверить. Но всё равно большое спасибо!