file_source fs(url, ios_base::in | ios_base::binary);
if(!fs.is_open())
{
... error, just quit.
}
auto_ptr<filtering_istream> fis(new filtering_istream);
fis->push(gzip_decompressor());
fis->push(fs);
try
{// хочу проверить, действительно ли входной файл запакован.
fis->rdbuf()->sgetc();// Хакерство всё это. Но как сделать правильно?
}
catch(std::ios::failure &)
{// неа, не запакован, значит просто файл, читаем без gzip фильтра.
fis.reset(new filtering_istream);
fis->push(fs);
}
// ну и, типа, можно читать:
fis->read(...);
Оно работает, но неправильно — если файл большой, то вроде ок, но если маленький, то не работает, как я понял, fs
прочитывается весь в буфер и потом не read не работает, т.к. eof выставляется. В общем бардак. Как правильно?
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
kan_izh wrote:
> Кто юзает? > Мне нужно следующее: > > file_source fs(url, ios_base::in | ios_base::binary); > if(!fs.is_open()) > { > ... error, just quit. > } > auto_ptr<filtering_istream> fis(new filtering_istream); > fis->push(gzip_decompressor()); > fis->push(fs); > try > {// хочу проверить, действительно ли входной файл запакован. > fis->rdbuf()->sgetc();// Хакерство всё это. Но как сделать правильно? > } > catch(std::ios::failure &) > {// неа, не запакован, значит просто файл, читаем без gzip фильтра. > fis.reset(new filtering_istream); > fis->push(fs); > } > // ну и, типа, можно читать: > fis->read(...); > > > Оно работает, но неправильно — если файл большой, то вроде ок, но если > маленький, то не работает, как я понял, fs > прочитывается весь в буфер и потом не read не работает, т.к. eof > выставляется. В общем бардак. Как правильно?
Что ты собираешься делать с данными? Если ты не собираешься использовать
operator>>, то может быть не стоит использовать iostreams вообще.
-- Maxim Yegorushkin
No Microsoft product was used in any way to write or send this text.
If you use a Microsoft product to read it, you're doing so at your own risk
MaximE wrote:
> Что ты собираешься делать с данными? Если ты не собираешься использовать > operator>>, то может быть не стоит использовать iostreams вообще.
А что? Всё так плохо? А то оно, вообще говоря, работает. Но я просто извращаюсь, используя один и тот же файл дважды...
оно и глючит. Можно, вообще-то файл открывать второй раз, но это мне кажется некрасивым...
Просто более-менее удобной в использовании библиотеки gzip я не нашел... Притом тут легко можно на bzip2 поменять при
желании. И ещё я прикручиваю шифрование, т.е. на самом деле у меня такой код:
kan_izh wrote:
> MaximE wrote: > >> Что ты собираешься делать с данными? Если ты не собираешься использовать >> operator>>, то может быть не стоит использовать iostreams вообще. > А что? Всё так плохо?
На мой взгляд нет особого смысла использовать потоки, если не используешь <<, >>. Если все, что нужно, это абстрагироваться от read/write, то может быть
достаточно интерфейса на подобие такого:
С таким интерфейсом легко построить стэк (f)read->decrypt->uncompress, или любой
другой, не ломая голову над тонкостями реализации streambuf.
> А то оно, вообще говоря, работает. Но я просто > извращаюсь, используя один и тот же файл дважды... > оно и глючит. Можно, вообще-то файл открывать второй раз, но это мне > кажется некрасивым...
Может попробовать когда открываешь поток второй раз сделать ему .clear() ?
-- Maxim Yegorushkin
No Microsoft product was used in any way to write or send this text.
If you use a Microsoft product to read it, you're doing so at your own risk
MaximE wrote:
>> > Что ты собираешься делать с данными? Если ты не собираешься использовать >> > operator>>, то может быть не стоит использовать iostreams вообще. >> А что? Всё так плохо? > На мой взгляд нет особого смысла использовать потоки, если не > используешь <<, >> >. Если все, что нужно, это абстрагироваться от read/write, то может быть > достаточно интерфейса на подобие такого:
Нужно возможность несколько обработчиков в цепочку выстроить.
> struct source > { > virtual ~source() {} > virtual ssize_t read(void*, size_t) = 0; > }; > > > > С таким интерфейсом легко построить стэк (f)read->decrypt->uncompress, > или любой > другой, не ломая голову над тонкостями реализации streambuf.
Тоже самое ещё для write, плюс найти gzip вменяемый, плюс согласовать с шифровальщиком...
В общем, сделать тоже самое, только с нуля.
на boost::iostreams уж больно всё красиво и удобно... но пара грабель...
>> А то оно, вообще говоря, работает. Но я просто >> извращаюсь, используя один и тот же файл дважды... >> оно и глючит. Можно, вообще-то файл открывать второй раз, но это мне >> кажется некрасивым... > > Может попробовать когда открываешь поток второй раз сделать ему .clear() ?
Не помогло. Вот такое пока оставил, вроде работает:
kan_izh wrote:
> MaximE wrote: > >> > > Что ты собираешься делать с данными? Если ты не собираешься > использовать >> > > operator>>, то может быть не стоит использовать iostreams вообще. >> > А что? Всё так плохо? >> На мой взгляд нет особого смысла использовать потоки, если не >> используешь <<, >> > >. Если все, что нужно, это абстрагироваться от read/write, то может быть >> достаточно интерфейса на подобие такого: > Нужно возможность несколько обработчиков в цепочку выстроить.
> Тоже самое ещё для write, плюс найти gzip вменяемый, плюс согласовать с > шифровальщиком... > В общем, сделать тоже самое, только с нуля. > на boost::iostreams уж больно всё красиво и удобно... но пара грабель...
Согласен, выглядит красиво.
-- Maxim Yegorushkin
No Microsoft product was used in any way to write or send this text.
If you use a Microsoft product to read it, you're doing so at your own risk
При компиляции получил:
Warning 1 warning C4251: 'transformer::f' : class 'boost::function<Signature>' needs to have dll-interface to be used by clients of class 'transformer' c:\my_projects\src\boosttest\iotest\iotest\iotestdll.h 67
gok wrote: > При компиляции получил: > Warning 1 warning C4251: 'transformer::f' : class > 'boost::function<Signature>' needs to have dll-interface to be used by > clients of class 'transformer' > c:\my_projects\src\boosttest\iotest\iotest\iotestdll.h 67 > Как "открыть" функцию f для клиента?
Это достаточно сложный вопрос, кстати.
В данном случае можно игнорировать это предупреждение (и подавить его с
помощью "#pragma warning(disable:4251)" ).
Все члены класса boost::function — inline'овые, так что если DLL и
клиент совместимы по layout'у классов, то все будет работать нормально.
Проблемы возникнут если у клиента и DLL, например, разные параметры
дефолтного выравнивания членов структур. От этого можно в некоторой
мере защититься таким образом:
//В самом начале h-файла#include <boost/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#include <boost/function.hpp>
#include ...
...
class _IOTESTLIB transformer : public source
{
public:
source* src;
boost::function<char(char)> f;
...
//В конце h-файла#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
Однако, это не поможет если function.hpp включили до твоего файла. Так
что единственный надежный способ — следить за совместимостью ABI.